diff --git a/agreement/message.go b/agreement/message.go index e372b06fbe..e62dd63b0f 100644 --- a/agreement/message.go +++ b/agreement/message.go @@ -18,7 +18,6 @@ package agreement import ( "github.com/algorand/go-algorand/protocol" - "github.com/algorand/msgp/msgp" ) // A message represents an internal message which is passed between components @@ -26,9 +25,6 @@ import ( type message struct { _struct struct{} `codec:","` - // this field is for backwards compatibility with crash state serialized using go-codec prior to explicit unexport. - // should be removed after the next consensus update. - MessageHandle msgp.Raw `codec:"MessageHandle,omitempty"` // explicitly unexport this field since we can't define serializers for interface{} type // the only implementation of this is gossip.messageMetadata which doesn't have exported fields to serialize. messageHandle MessageHandle diff --git a/agreement/message_test.go b/agreement/message_test.go index a71a29830b..4c7712c591 100644 --- a/agreement/message_test.go +++ b/agreement/message_test.go @@ -17,7 +17,6 @@ package agreement import ( - "encoding/base64" "testing" "github.com/stretchr/testify/require" @@ -25,9 +24,7 @@ import ( "github.com/algorand/go-algorand/crypto" "github.com/algorand/go-algorand/data/basics" "github.com/algorand/go-algorand/data/committee" - "github.com/algorand/go-algorand/network" "github.com/algorand/go-algorand/protocol" - "github.com/algorand/go-algorand/test/partitiontest" ) var poolAddr = basics.Address{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} @@ -83,52 +80,3 @@ func BenchmarkVoteDecoding(b *testing.B) { decodeVote(msgBytes) } } - -// TestMessageBackwardCompatibility ensures MessageHandle field can be -// properly decoded from message. -// This test is only needed for agreement state serialization switch from reflection to msgp. -func TestMessageBackwardCompatibility(t *testing.T) { - partitiontest.PartitionTest(t) - - type messageMetadata struct { - raw network.IncomingMessage - } - - encoded, err := base64.StdEncoding.DecodeString("iaZCdW5kbGWAr0NvbXBvdW5kTWVzc2FnZYKoUHJvcG9zYWyApFZvdGWArU1lc3NhZ2VIYW5kbGWAqFByb3Bvc2FsgKNUYWeiUFC1VW5hdXRoZW50aWNhdGVkQnVuZGxlgLdVbmF1dGhlbnRpY2F0ZWRQcm9wb3NhbICzVW5hdXRoZW50aWNhdGVkVm90ZYCkVm90ZYA=") - require.NoError(t, err) - - // run on master f57a276 to get the encoded data for above - // msg := message{ - // MessageHandle: &messageMetadata{raw: network.IncomingMessage{Tag: protocol.Tag("mytag"), Data: []byte("some data")}}, - // Tag: protocol.ProposalPayloadTag, - // } - - // result := protocol.EncodeReflect(&msg) - // fmt.Println(base64.StdEncoding.EncodeToString(result)) - - // messages for all rounds after this change should not have MessageHandle set so clearing it out and re-encoding/decoding it should yield this - targetMessage := message{ - Tag: protocol.ProposalPayloadTag, - } - - require.Containsf(t, string(encoded), "MessageHandle", "encoded message does not contain MessageHandle field") - var m1, m2, m3, m4 message - // Both msgp and reflection should decode the message containing old MessageHandle successfully - err = protocol.Decode(encoded, &m1) - require.NoError(t, err) - err = protocol.DecodeReflect(encoded, &m2) - require.NoError(t, err) - // after setting MessageHandle to nil both should re-encode and decode to same values - m1.MessageHandle = nil - m2.MessageHandle = nil - e1 := protocol.Encode(&m1) - e2 := protocol.EncodeReflect(&m2) - require.Equal(t, e1, e2) - require.NotContainsf(t, string(e1), "MessageHandle", "encoded message still contains MessageHandle field") - err = protocol.DecodeReflect(e1, &m3) - require.NoError(t, err) - err = protocol.Decode(e2, &m4) - require.NoError(t, err) - require.Equal(t, m3, m4) - require.Equal(t, m3, targetMessage) -} diff --git a/agreement/msgp_gen.go b/agreement/msgp_gen.go index 16d464d39a..bb74edb62c 100644 --- a/agreement/msgp_gen.go +++ b/agreement/msgp_gen.go @@ -3081,52 +3081,37 @@ func FreshnessDataMaxSize() (s int) { // MarshalMsg implements msgp.Marshaler func (z *message) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) - // omitempty: check for empty values - zb0001Len := uint32(9) - var zb0001Mask uint16 /* 11 bits */ - if (*z).MessageHandle.MsgIsZero() { - zb0001Len-- - zb0001Mask |= 0x4 - } - // variable map header, size zb0001Len - o = append(o, 0x80|uint8(zb0001Len)) - if zb0001Len != 0 { - // string "Bundle" - o = append(o, 0xa6, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65) - o = (*z).Bundle.MarshalMsg(o) - // string "CompoundMessage" - o = append(o, 0xaf, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65) - // map header, size 2 - // string "Proposal" - o = append(o, 0x82, 0xa8, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c) - o = (*z).CompoundMessage.Proposal.MarshalMsg(o) - // string "Vote" - o = append(o, 0xa4, 0x56, 0x6f, 0x74, 0x65) - o = (*z).CompoundMessage.Vote.MarshalMsg(o) - if (zb0001Mask & 0x4) == 0 { // if not empty - // string "MessageHandle" - o = append(o, 0xad, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65) - o = (*z).MessageHandle.MarshalMsg(o) - } - // string "Proposal" - o = append(o, 0xa8, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c) - o = (*z).Proposal.MarshalMsg(o) - // string "Tag" - o = append(o, 0xa3, 0x54, 0x61, 0x67) - o = (*z).Tag.MarshalMsg(o) - // string "UnauthenticatedBundle" - o = append(o, 0xb5, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65) - o = (*z).UnauthenticatedBundle.MarshalMsg(o) - // string "UnauthenticatedProposal" - o = append(o, 0xb7, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c) - o = (*z).UnauthenticatedProposal.MarshalMsg(o) - // string "UnauthenticatedVote" - o = append(o, 0xb3, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x56, 0x6f, 0x74, 0x65) - o = (*z).UnauthenticatedVote.MarshalMsg(o) - // string "Vote" - o = append(o, 0xa4, 0x56, 0x6f, 0x74, 0x65) - o = (*z).Vote.MarshalMsg(o) - } + // map header, size 8 + // string "Bundle" + o = append(o, 0x88, 0xa6, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65) + o = (*z).Bundle.MarshalMsg(o) + // string "CompoundMessage" + o = append(o, 0xaf, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65) + // map header, size 2 + // string "Proposal" + o = append(o, 0x82, 0xa8, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c) + o = (*z).CompoundMessage.Proposal.MarshalMsg(o) + // string "Vote" + o = append(o, 0xa4, 0x56, 0x6f, 0x74, 0x65) + o = (*z).CompoundMessage.Vote.MarshalMsg(o) + // string "Proposal" + o = append(o, 0xa8, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c) + o = (*z).Proposal.MarshalMsg(o) + // string "Tag" + o = append(o, 0xa3, 0x54, 0x61, 0x67) + o = (*z).Tag.MarshalMsg(o) + // string "UnauthenticatedBundle" + o = append(o, 0xb5, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65) + o = (*z).UnauthenticatedBundle.MarshalMsg(o) + // string "UnauthenticatedProposal" + o = append(o, 0xb7, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c) + o = (*z).UnauthenticatedProposal.MarshalMsg(o) + // string "UnauthenticatedVote" + o = append(o, 0xb3, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x56, 0x6f, 0x74, 0x65) + o = (*z).UnauthenticatedVote.MarshalMsg(o) + // string "Vote" + o = append(o, 0xa4, 0x56, 0x6f, 0x74, 0x65) + o = (*z).Vote.MarshalMsg(o) return } @@ -3153,14 +3138,6 @@ func (z *message) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o [ err = msgp.WrapError(err) return } - if zb0001 > 0 { - zb0001-- - bts, err = (*z).MessageHandle.UnmarshalMsgWithState(bts, st) - if err != nil { - err = msgp.WrapError(err, "struct-from-array", "MessageHandle") - return - } - } if zb0001 > 0 { zb0001-- bts, err = (*z).Tag.UnmarshalMsgWithState(bts, st) @@ -3312,12 +3289,6 @@ func (z *message) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o [ return } switch string(field) { - case "MessageHandle": - bts, err = (*z).MessageHandle.UnmarshalMsgWithState(bts, st) - if err != nil { - err = msgp.WrapError(err, "MessageHandle") - return - } case "Tag": bts, err = (*z).Tag.UnmarshalMsgWithState(bts, st) if err != nil { @@ -3453,20 +3424,18 @@ func (_ *message) CanUnmarshalMsg(z interface{}) bool { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *message) Msgsize() (s int) { - s = 1 + 14 + (*z).MessageHandle.Msgsize() + 4 + (*z).Tag.Msgsize() + 5 + (*z).Vote.Msgsize() + 9 + (*z).Proposal.Msgsize() + 7 + (*z).Bundle.Msgsize() + 20 + (*z).UnauthenticatedVote.Msgsize() + 24 + (*z).UnauthenticatedProposal.Msgsize() + 22 + (*z).UnauthenticatedBundle.Msgsize() + 16 + 1 + 5 + (*z).CompoundMessage.Vote.Msgsize() + 9 + (*z).CompoundMessage.Proposal.Msgsize() + s = 1 + 4 + (*z).Tag.Msgsize() + 5 + (*z).Vote.Msgsize() + 9 + (*z).Proposal.Msgsize() + 7 + (*z).Bundle.Msgsize() + 20 + (*z).UnauthenticatedVote.Msgsize() + 24 + (*z).UnauthenticatedProposal.Msgsize() + 22 + (*z).UnauthenticatedBundle.Msgsize() + 16 + 1 + 5 + (*z).CompoundMessage.Vote.Msgsize() + 9 + (*z).CompoundMessage.Proposal.Msgsize() return } // MsgIsZero returns whether this is a zero value func (z *message) MsgIsZero() bool { - return ((*z).MessageHandle.MsgIsZero()) && ((*z).Tag.MsgIsZero()) && ((*z).Vote.MsgIsZero()) && ((*z).Proposal.MsgIsZero()) && ((*z).Bundle.MsgIsZero()) && ((*z).UnauthenticatedVote.MsgIsZero()) && ((*z).UnauthenticatedProposal.MsgIsZero()) && ((*z).UnauthenticatedBundle.MsgIsZero()) && (((*z).CompoundMessage.Vote.MsgIsZero()) && ((*z).CompoundMessage.Proposal.MsgIsZero())) + return ((*z).Tag.MsgIsZero()) && ((*z).Vote.MsgIsZero()) && ((*z).Proposal.MsgIsZero()) && ((*z).Bundle.MsgIsZero()) && ((*z).UnauthenticatedVote.MsgIsZero()) && ((*z).UnauthenticatedProposal.MsgIsZero()) && ((*z).UnauthenticatedBundle.MsgIsZero()) && (((*z).CompoundMessage.Vote.MsgIsZero()) && ((*z).CompoundMessage.Proposal.MsgIsZero())) } // MaxSize returns a maximum valid message size for this message type func MessageMaxSize() (s int) { - s = 1 + 14 - panic("Unable to determine max size: MaxSize() not implemented for Raw type") - s += 4 + protocol.TagMaxSize() + 5 + VoteMaxSize() + 9 + ProposalMaxSize() + 7 + BundleMaxSize() + 20 + UnauthenticatedVoteMaxSize() + 24 + UnauthenticatedProposalMaxSize() + 22 + UnauthenticatedBundleMaxSize() + 16 + 1 + 5 + UnauthenticatedVoteMaxSize() + 9 + UnauthenticatedProposalMaxSize() + s = 1 + 4 + protocol.TagMaxSize() + 5 + VoteMaxSize() + 9 + ProposalMaxSize() + 7 + BundleMaxSize() + 20 + UnauthenticatedVoteMaxSize() + 24 + UnauthenticatedProposalMaxSize() + 22 + UnauthenticatedBundleMaxSize() + 16 + 1 + 5 + UnauthenticatedVoteMaxSize() + 9 + UnauthenticatedProposalMaxSize() return } diff --git a/agreement/proposalTable_test.go b/agreement/proposalTable_test.go deleted file mode 100644 index 172a70b633..0000000000 --- a/agreement/proposalTable_test.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) 2019-2025 Algorand, Inc. -// This file is part of go-algorand -// -// go-algorand is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// go-algorand is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with go-algorand. If not, see . - -package agreement - -import ( - "encoding/base64" - "testing" - - "github.com/algorand/go-algorand/network" - "github.com/algorand/go-algorand/protocol" - "github.com/algorand/go-algorand/test/partitiontest" - "github.com/stretchr/testify/require" -) - -// This test is only necessary for transition to msgp encoding -// of the player state machine for agreement persistence -func TestProposalTableMsgpEncoding(t *testing.T) { - partitiontest.PartitionTest(t) - - type messageMetadata struct { - raw network.IncomingMessage - } - encoded, err := base64.StdEncoding.DecodeString("gqdQZW5kaW5ngQGHqUNhbmNlbGxlZMKjRXJywKVJbnB1dImmQnVuZGxlgK9Db21wb3VuZE1lc3NhZ2WCqFByb3Bvc2FsgKRWb3RlgK1NZXNzYWdlSGFuZGxlgKhQcm9wb3NhbICjVGFnolBQtVVuYXV0aGVudGljYXRlZEJ1bmRsZYC3VW5hdXRoZW50aWNhdGVkUHJvcG9zYWyAs1VuYXV0aGVudGljYXRlZFZvdGWApFZvdGWApVByb3RvgqNFcnLAp1ZlcnNpb26goVQApFRhaWzAqVRhc2tJbmRleD+rUGVuZGluZ05leHQB") - require.NoError(t, err) - - // run on master a3e90ad to get the encoded data for above - // pt := proposalTable{} - // msg := messageEvent{ - // Input: message{ - // Tag: protocol.ProposalPayloadTag, - // MessageHandle: &messageMetadata{raw: network.IncomingMessage{Tag: protocol.Tag("mytag"), Data: []byte("some data")}}, - // }, - // TaskIndex: 63} - // pt.push(&msg) - // result := protocol.EncodeReflect(&pt) - // fmt.Println(base64.StdEncoding.EncodeToString(result)) - - var ptMsgp, ptReflect proposalTable - err = protocol.Decode(encoded, &ptMsgp) - require.NoError(t, err) - err = protocol.DecodeReflect(encoded, &ptReflect) - require.NoError(t, err) - - msgMsgp := ptMsgp.pop(ptMsgp.PendingNext) - msgReflect := ptReflect.pop(ptReflect.PendingNext) - - // After setting MessageHandle to nil they should be the same - msgMsgp.Input.MessageHandle = nil - msgReflect.Input.MessageHandle = nil - require.Equal(t, msgMsgp, msgReflect) - // Check that the other fields we have manually set are still the same - require.Equal(t, msgMsgp.Input.Tag, protocol.ProposalPayloadTag) - require.Equal(t, msgMsgp.TaskIndex, uint64(63)) - -}