diff --git a/core/ibft.go b/core/ibft.go index afd9dad..2537ec4 100644 --- a/core/ibft.go +++ b/core/ibft.go @@ -1032,56 +1032,15 @@ func (i *IBFT) buildProposal(ctx context.Context, view *proto.View) *proto.IbftM return nil } - // check the messages for any previous proposal (if they have any, it's the same proposal) - var ( - previousProposal []byte - maxRound uint64 - ) - - // take previous proposal among the round change messages for the highest round - for _, msg := range rcc.RoundChangeMessages { - latestPC := messages.ExtractLatestPC(msg) - if latestPC == nil { - continue - } - - proposal := messages.ExtractProposal(latestPC.ProposalMessage) - preparedCertificateRound := proposal.Round - - // skip if message's round is equals to/less than maxRound - if previousProposal != nil && preparedCertificateRound <= maxRound { - continue - } - - lastPB := messages.ExtractLastPreparedProposal(msg) - if lastPB == nil { - continue - } - - previousProposal = lastPB.RawProposal - maxRound = preparedCertificateRound - } - - if previousProposal == nil { - // build new proposal - proposal := i.backend.BuildProposal( - &proto.View{ - Height: height, - Round: round, - }) - - return i.backend.BuildPrePrepareMessage( - proposal, - rcc, - &proto.View{ - Height: height, - Round: round, - }, - ) - } + // build always new proposal + proposal := i.backend.BuildProposal( + &proto.View{ + Height: height, + Round: round, + }) return i.backend.BuildPrePrepareMessage( - previousProposal, + proposal, rcc, &proto.View{ Height: height, @@ -1239,8 +1198,8 @@ func (i *IBFT) sendPreprepareMessage(message *proto.IbftMessage) { func (i *IBFT) sendRoundChangeMessage(height, newRound uint64) { i.transport.Multicast( i.backend.BuildRoundChangeMessage( - i.state.getLatestPreparedProposal(), - i.state.getLatestPC(), + nil, + nil, &proto.View{ Height: height, Round: newRound, diff --git a/core/ibft_test.go b/core/ibft_test.go index 735069b..92e9ce7 100644 --- a/core/ibft_test.go +++ b/core/ibft_test.go @@ -424,178 +424,6 @@ func TestRunNewRound_Proposer(t *testing.T) { assert.Nil(t, multicastedPrepare) }, ) - - t.Run( - "proposer builds proposal for round > 0 (resend last prepared proposal)", - func(t *testing.T) { - t.Parallel() - - lastPreparedProposedProposal := &proto.Proposal{ - RawProposal: []byte("dummy block"), - Round: 0, - } - - quorum := uint64(4) - ctx, cancelFn := context.WithCancel(context.Background()) - - roundChangeMessages := generateMessagesWithUniqueSender(quorum, proto.MessageType_ROUND_CHANGE) - prepareMessages := generateMessages(quorum-1, proto.MessageType_PREPARE) - - for index, message := range prepareMessages { - message.Payload = &proto.IbftMessage_PrepareData{ - PrepareData: &proto.PrepareMessage{ - ProposalHash: correctRoundMessage.hash, - }, - } - - message.From = []byte(fmt.Sprintf("node %d", index+1)) - } - - setRoundForMessages(roundChangeMessages, 1) - - // Make sure at least one RC message has a PC - payload, _ := roundChangeMessages[1].Payload.(*proto.IbftMessage_RoundChangeData) - rcData := payload.RoundChangeData - - rcData.LastPreparedProposal = lastPreparedProposedProposal - rcData.LatestPreparedCertificate = &proto.PreparedCertificate{ - ProposalMessage: &proto.IbftMessage{ - View: &proto.View{ - Height: 0, - Round: 0, - }, - From: []byte("unique node"), - Type: proto.MessageType_PREPREPARE, - Payload: &proto.IbftMessage_PreprepareData{ - PreprepareData: &proto.PrePrepareMessage{ - Proposal: lastPreparedProposedProposal, - ProposalHash: correctRoundMessage.hash, - Certificate: nil, - }, - }, - }, - PrepareMessages: prepareMessages, - } - - var ( - proposerID = []byte("unique node") - multicastedPreprepare *proto.IbftMessage = nil - multicastedPrepare *proto.IbftMessage = nil - proposal = []byte("proposal") - notifyCh = make(chan uint64, 1) - - log = mockLogger{} - transport = mockTransport{func(message *proto.IbftMessage) { - switch message.Type { - case proto.MessageType_PREPREPARE: - multicastedPreprepare = message - case proto.MessageType_PREPARE: - multicastedPrepare = message - default: - } - }} - backend = mockBackend{ - idFn: func() []byte { return proposerID }, - isProposerFn: func(proposer []byte, _ uint64, _ uint64) bool { - return bytes.Equal(proposerID, proposer) - }, - getVotingPowerFn: testCommonGetVotingPowertFnForCnt(quorum), - buildProposalFn: func(_ uint64) []byte { - return proposal - }, - buildPrepareMessageFn: func(_ []byte, view *proto.View) *proto.IbftMessage { - return &proto.IbftMessage{ - View: view, - Type: proto.MessageType_PREPARE, - Payload: &proto.IbftMessage_PrepareData{ - PrepareData: &proto.PrepareMessage{ - ProposalHash: correctRoundMessage.hash, - }, - }, - } - }, - buildPrePrepareMessageFn: func( - rawProposal []byte, - certificate *proto.RoundChangeCertificate, - view *proto.View, - ) *proto.IbftMessage { - return &proto.IbftMessage{ - View: view, - Type: proto.MessageType_PREPREPARE, - Payload: &proto.IbftMessage_PreprepareData{ - PreprepareData: &proto.PrePrepareMessage{ - Proposal: &proto.Proposal{ - RawProposal: rawProposal, - Round: 0, - }, - ProposalHash: correctRoundMessage.hash, - Certificate: certificate, - }, - }, - } - }, - } - messages = mockMessages{ - subscribeFn: func(_ messages.SubscriptionDetails) *messages.Subscription { - return &messages.Subscription{ - ID: messages.SubscriptionID(1), - SubCh: notifyCh, - } - }, - unsubscribeFn: func(_ messages.SubscriptionID) { - cancelFn() - }, - getValidMessagesFn: func( - view *proto.View, - messageType proto.MessageType, - isValid func(message *proto.IbftMessage) bool, - ) []*proto.IbftMessage { - return filterMessages( - roundChangeMessages, - isValid, - ) - }, - getExtendedRCCFn: func( - height uint64, - isValidMessage func(message *proto.IbftMessage) bool, - isValidRCC func(round uint64, messages []*proto.IbftMessage) bool, - ) []*proto.IbftMessage { - return filterMessages( - roundChangeMessages, - isValidMessage, - ) - }, - } - ) - - i := NewIBFT(log, backend, transport) - require.NoError(t, i.validatorManager.Init(0)) - i.messages = messages - i.state.setView(&proto.View{ - Height: 0, - Round: 1, - }) - - notifyCh <- 1 - - i.wg.Add(1) - i.startRound(ctx) - - i.wg.Wait() - - // Make sure the node changed the state to prepare - assert.Equal(t, prepare, i.state.name) - - // Make sure the multicasted proposal is the accepted proposal - assert.Equal(t, multicastedPreprepare, i.state.proposalMessage) - - // Make sure the correct proposal was multicasted - assert.True(t, proposalMatches(lastPreparedProposedProposal, multicastedPreprepare)) - - // Make sure the prepare message was not multicasted - assert.Nil(t, multicastedPrepare) - }, - ) } // TestRunNewRound_Validator_Zero validates the behavior diff --git a/core/state.go b/core/state.go index bee977b..6011c4f 100644 --- a/core/state.go +++ b/core/state.go @@ -83,20 +83,6 @@ func (s *state) reset(height uint64) { } } -func (s *state) getLatestPC() *proto.PreparedCertificate { - s.RLock() - defer s.RUnlock() - - return s.latestPC -} - -func (s *state) getLatestPreparedProposal() *proto.Proposal { - s.RLock() - defer s.RUnlock() - - return s.latestPreparedProposal -} - func (s *state) getProposalMessage() *proto.IbftMessage { s.RLock() defer s.RUnlock() diff --git a/go.mod b/go.mod index 8939fdf..dc1f304 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.21 require ( github.com/armon/go-metrics v0.4.1 - github.com/golang/protobuf v1.5.0 github.com/google/uuid v1.3.0 github.com/stretchr/testify v1.8.1 go.uber.org/goleak v1.2.0 diff --git a/go.sum b/go.sum index c78ed1b..206a9f2 100644 --- a/go.sum +++ b/go.sum @@ -24,7 +24,6 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -94,6 +93,7 @@ go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -106,6 +106,7 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= diff --git a/messages/helpers_test.go b/messages/helpers_test.go index b6d2836..5b36633 100644 --- a/messages/helpers_test.go +++ b/messages/helpers_test.go @@ -29,7 +29,7 @@ func TestMessages_ExtractCommittedSeals(t *testing.T) { } } - createWrongMessage := func(signer string, msgType proto.MessageType) *proto.IbftMessage { + createWrongMessage := func(_ string, msgType proto.MessageType) *proto.IbftMessage { return &proto.IbftMessage{ Type: msgType, }