From a6e7eea07f047227d84bc4308a5296caacd3615c Mon Sep 17 00:00:00 2001 From: kourin Date: Tue, 24 Jan 2023 22:37:25 +0900 Subject: [PATCH] [PoC] Fix hash calculation for proposal (#55) * Introduced the ProposedBlock (EB,r) struct. * Fixed the InsertBlock signature. * Added getEthereumBlockFromProposal state fn * Fixed all method signatures that expect a proposal. * Tests refactored and failing. * Removed unused pb type * Add round validation in reception of Proposal * Fix failing tests * Fix lint error * Rename EthereumBlock to RawProposal * Rename BuildEthereumBlock to BuildBlock * Rename getEthereumBlockFromProposal to getRawDataFromProposal * Fix function comment * Fix interface of InsertBlock * Remove ExtractEthereumBlock * Fix failed test * Reorder checks in validateProposalCommon * Rename ProposedBlock to Proposal * Fix lint error * Rename Block to Proposal * Fix comment * Rename IsValidBlock to IsValidProposal * Fix lint error * Fix lint error * Add comment in messages.proto * Fix failed tests * revert proposalMatches * Revert "revert proposalMatches" This reverts commit 57ea12f00f4b5aefe8d198c0561adfa03c6ef443. * Revert "Fix failed tests" This reverts commit 368025c938bb8f5e8d76c1393afa88b128cf2765. * Update go.mod * Fix lint errors Co-authored-by: Lazar Travica --- Makefile | 5 +- core/backend.go | 26 ++- core/byzantine_test.go | 18 +- core/consensus_test.go | 61 +++--- core/drop_test.go | 63 +++--- core/helpers_test.go | 27 +-- core/ibft.go | 32 ++- core/ibft_test.go | 229 ++++++++++++++----- core/mock_test.go | 68 +++--- core/rapid_test.go | 23 +- core/state.go | 40 ++-- go.mod | 1 + go.sum | 1 + messages/event_manager.go | 7 +- messages/helpers.go | 12 +- messages/helpers_test.go | 14 +- messages/proto/messages.pb.go | 400 ++++++++++++++++++++-------------- messages/proto/messages.proto | 17 +- 18 files changed, 656 insertions(+), 388 deletions(-) diff --git a/Makefile b/Makefile index dd6ab09..890bbb4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: lint lint-all build-dummy install-deps +.PHONY: lint lint-all build-dummy install-deps protoc FIRST_COMMIT ?= $(shell git rev-list --max-parents=0 HEAD) @@ -14,3 +14,6 @@ lint-all: install-deps: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.50.1 + +protoc: + protoc --go_out=. --go-grpc_out=. ./messages/proto/messages.proto diff --git a/core/backend.go b/core/backend.go index a9e5a30..2932344 100644 --- a/core/backend.go +++ b/core/backend.go @@ -1,3 +1,5 @@ +// Package core implements IBFT consensus +// backend.go defines interfaces of backend, that performs detailed procedure rather than consensus package core import ( @@ -9,7 +11,7 @@ import ( type MessageConstructor interface { // BuildPrePrepareMessage builds a PREPREPARE message based on the passed in proposal BuildPrePrepareMessage( - proposal []byte, + rawProposal []byte, certificate *proto.RoundChangeCertificate, view *proto.View, ) *proto.Message @@ -22,7 +24,7 @@ type MessageConstructor interface { // BuildRoundChangeMessage builds a ROUND_CHANGE message based on the passed in proposal BuildRoundChangeMessage( - proposal []byte, + proposal *proto.Proposal, certificate *proto.PreparedCertificate, view *proto.View, ) *proto.Message @@ -30,8 +32,8 @@ type MessageConstructor interface { // Verifier defines the verifier interface type Verifier interface { - // IsValidBlock checks if the proposed block is child of parent - IsValidBlock(block []byte) bool + // IsValidProposal checks if the proposal is child of parent + IsValidProposal(rawProposal []byte) bool // IsValidSender checks if signature is from sender IsValidSender(msg *proto.Message) bool @@ -40,7 +42,7 @@ type Verifier interface { IsProposer(id []byte, height, round uint64) bool // IsValidProposalHash checks if the hash matches the proposal - IsValidProposalHash(proposal, hash []byte) bool + IsValidProposalHash(proposal *proto.Proposal, hash []byte) bool // IsValidCommittedSeal checks if the seal for the proposal is valid IsValidCommittedSeal(proposal []byte, committedSeal *messages.CommittedSeal) bool @@ -52,16 +54,18 @@ type Backend interface { MessageConstructor Verifier - // BuildProposal builds a new block proposal - BuildProposal(view *proto.View) []byte + // BuildProposal builds a new proposal for the height + BuildProposal(height uint64) []byte - // InsertBlock inserts a proposal with the specified committed seals - InsertBlock(proposal []byte, committedSeals []*messages.CommittedSeal) + // InsertProposal inserts a proposal with the specified committed seals + // the reason why we are including round here is because a single committedSeal + // has signed the tuple of (rawProposal, round) + InsertProposal(proposal *proto.Proposal, committedSeals []*messages.CommittedSeal) // ID returns the validator's ID ID() []byte // HasQuorum returns true if the quorum is reached - // for the specified block height. - HasQuorum(blockNumber uint64, messages []*proto.Message, msgType proto.MessageType) bool + // for the specified height. + HasQuorum(height uint64, msgs []*proto.Message, msgType proto.MessageType) bool } diff --git a/core/byzantine_test.go b/core/byzantine_test.go index 179b23f..4fd10cf 100644 --- a/core/byzantine_test.go +++ b/core/byzantine_test.go @@ -2,16 +2,18 @@ package core import ( "bytes" - "github.com/0xPolygon/go-ibft/messages/proto" "testing" "time" + "github.com/0xPolygon/go-ibft/messages/proto" + "github.com/stretchr/testify/assert" ) func TestByzantineBehaviour(t *testing.T) { t.Parallel() + //nolint:dupl t.Run("malicious hash in proposal", func(t *testing.T) { t.Parallel() @@ -78,6 +80,7 @@ func TestByzantineBehaviour(t *testing.T) { assert.Equal(t, uint64(2), cluster.latestHeight) }) + //nolint:dupl t.Run("malicious +1 round in proposal", func(t *testing.T) { t.Parallel() @@ -112,6 +115,7 @@ func TestByzantineBehaviour(t *testing.T) { assert.Equal(t, uint64(2), cluster.latestHeight) }) + //nolint:dupl t.Run("malicious +1 round in rcc", func(t *testing.T) { t.Parallel() @@ -145,6 +149,7 @@ func TestByzantineBehaviour(t *testing.T) { assert.Equal(t, uint64(2), cluster.latestHeight) }) + //nolint:dupl t.Run("malicious +1 round in rcc and in proposal", func(t *testing.T) { t.Parallel() @@ -179,6 +184,7 @@ func TestByzantineBehaviour(t *testing.T) { assert.Equal(t, uint64(2), cluster.latestHeight) }) + //nolint:dupl t.Run("malicious +1 round in rcc and bad hash in proposal", func(t *testing.T) { t.Parallel() @@ -213,6 +219,7 @@ func TestByzantineBehaviour(t *testing.T) { assert.Equal(t, uint64(2), cluster.latestHeight) }) + //nolint:dupl t.Run("malicious +1 round in rcc and bad hash in prepare", func(t *testing.T) { t.Parallel() @@ -247,6 +254,7 @@ func TestByzantineBehaviour(t *testing.T) { assert.Equal(t, uint64(2), cluster.latestHeight) }) + //nolint:dupl t.Run("malicious +1 round in rcc and bad commit seal", func(t *testing.T) { t.Parallel() @@ -283,7 +291,7 @@ func TestByzantineBehaviour(t *testing.T) { } func createBadRoundRoundChangeFn(node *node) buildRoundChangeMessageDelegate { - return func(proposal []byte, + return func(proposal *proto.Proposal, rcc *proto.PreparedCertificate, view *proto.View) *proto.Message { if node.byzantine { @@ -441,19 +449,19 @@ func (b *mockBackendBuilder) build(node *node) *mockBackend { } return &mockBackend{ - isValidBlockFn: isValidProposal, + isValidProposalFn: isValidProposal, isValidProposalHashFn: isValidProposalHash, isValidSenderFn: nil, isValidCommittedSealFn: nil, isProposerFn: b.isProposerFn, idFn: b.idFn, - buildProposalFn: buildValidProposal, + buildProposalFn: buildValidEthereumBlock, buildPrePrepareMessageFn: b.buildPrePrepareMessageFn, buildPrepareMessageFn: b.buildPrepareMessageFn, buildCommitMessageFn: b.buildCommitMessageFn, buildRoundChangeMessageFn: b.buildRoundChangeMessageFn, - insertBlockFn: nil, + insertProposalFn: nil, hasQuorumFn: b.hasQuorumFn, } } diff --git a/core/consensus_test.go b/core/consensus_test.go index c48bb89..a9343a1 100644 --- a/core/consensus_test.go +++ b/core/consensus_test.go @@ -26,7 +26,7 @@ func generateNodeAddresses(count uint64) [][]byte { // buildBasicPreprepareMessage builds a simple preprepare message func buildBasicPreprepareMessage( - proposal []byte, + rawProposal []byte, proposalHash []byte, certificate *proto.RoundChangeCertificate, from []byte, @@ -38,7 +38,10 @@ func buildBasicPreprepareMessage( Type: proto.MessageType_PREPREPARE, Payload: &proto.Message_PreprepareData{ PreprepareData: &proto.PrePrepareMessage{ - Proposal: proposal, + Proposal: &proto.Proposal{ + RawProposal: rawProposal, + Round: view.Round, + }, Certificate: certificate, ProposalHash: proposalHash, }, @@ -86,7 +89,7 @@ func buildBasicCommitMessage( // buildBasicRoundChangeMessage builds a simple round change message func buildBasicRoundChangeMessage( - proposal []byte, + proposal *proto.Proposal, certificate *proto.PreparedCertificate, view *proto.View, from []byte, @@ -97,7 +100,7 @@ func buildBasicRoundChangeMessage( Type: proto.MessageType_ROUND_CHANGE, Payload: &proto.Message_RoundChangeData{ RoundChangeData: &proto.RoundChangeMessage{ - LastPreparedProposedBlock: proposal, + LastPreparedProposal: proposal, LatestPreparedCertificate: certificate, }, }, @@ -121,10 +124,10 @@ func quorum(numNodes uint64) uint64 { } } -func commonHasQuorumFn(numNodes uint64) func(blockNumber uint64, messages []*proto.Message, msgType proto.MessageType) bool { +func commonHasQuorumFn(numNodes uint64) func(height uint64, messages []*proto.Message, msgType proto.MessageType) bool { quorum := quorum(numNodes) - return func(blockNumber uint64, messages []*proto.Message, msgType proto.MessageType) bool { + return func(height uint64, messages []*proto.Message, msgType proto.MessageType) bool { switch msgType { case proto.MessageType_PREPREPARE: return len(messages) >= 0 @@ -141,7 +144,7 @@ func commonHasQuorumFn(numNodes uint64) func(blockNumber uint64, messages []*pro // TestConsensus_ValidFlow tests the following scenario: // N = 4 // -// - Node 0 is the proposer for block 1, round 0 +// - Node 0 is the proposer for height 1, round 0 // - Node 0 proposes a valid block B // - All nodes go through the consensus states to insert the valid block B func TestConsensus_ValidFlow(t *testing.T) { @@ -180,23 +183,25 @@ func TestConsensus_ValidFlow(t *testing.T) { } // Make sure the proposal is valid if it matches what node 0 proposed - backend.isValidBlockFn = func(newProposal []byte) bool { - return bytes.Equal(newProposal, correctRoundMessage.proposal) + backend.isValidProposalFn = func(rawProposal []byte) bool { + return bytes.Equal(rawProposal, correctRoundMessage.proposal.GetRawProposal()) } // Make sure the proposal hash matches - backend.isValidProposalHashFn = func(p []byte, ph []byte) bool { - return bytes.Equal(p, correctRoundMessage.proposal) && bytes.Equal(ph, correctRoundMessage.hash) + backend.isValidProposalHashFn = func(proposal *proto.Proposal, proposalHash []byte) bool { + return bytes.Equal(proposal.GetRawProposal(), correctRoundMessage.proposal.GetRawProposal()) && + proposal.Round == correctRoundMessage.proposal.Round && + bytes.Equal(proposalHash, correctRoundMessage.hash) } // Make sure the preprepare message is built correctly backend.buildPrePrepareMessageFn = func( - proposal []byte, + rawProposal []byte, certificate *proto.RoundChangeCertificate, view *proto.View, ) *proto.Message { return buildBasicPreprepareMessage( - proposal, + rawProposal, correctRoundMessage.hash, certificate, nodes[nodeIndex], @@ -215,7 +220,7 @@ func TestConsensus_ValidFlow(t *testing.T) { // Make sure the round change message is built correctly backend.buildRoundChangeMessageFn = func( - proposal []byte, + proposal *proto.Proposal, certificate *proto.PreparedCertificate, view *proto.View, ) *proto.Message { @@ -223,13 +228,13 @@ func TestConsensus_ValidFlow(t *testing.T) { } // Make sure the inserted proposal is noted - backend.insertBlockFn = func(proposal []byte, _ []*messages.CommittedSeal) { - insertedBlocks[nodeIndex] = proposal + backend.insertProposalFn = func(proposal *proto.Proposal, _ []*messages.CommittedSeal) { + insertedBlocks[nodeIndex] = proposal.RawProposal } // Set the proposal creation method - backend.buildProposalFn = func(_ *proto.View) []byte { - return correctRoundMessage.proposal + backend.buildProposalFn = func(_ uint64) []byte { + return correctRoundMessage.proposal.GetRawProposal() } } @@ -255,7 +260,7 @@ func TestConsensus_ValidFlow(t *testing.T) { // Make sure the inserted blocks match what node 0 proposed for _, block := range insertedBlocks { - assert.True(t, bytes.Equal(block, correctRoundMessage.proposal)) + assert.True(t, bytes.Equal(block, correctRoundMessage.proposal.GetRawProposal())) } } @@ -315,15 +320,15 @@ func TestConsensus_InvalidBlock(t *testing.T) { } // Make sure the proposal is valid if it matches what node 0 proposed - backend.isValidBlockFn = func(newProposal []byte) bool { + backend.isValidProposalFn = func(newProposal []byte) bool { // Node 1 is the proposer for round 1, // and their proposal is the only one that's valid return bytes.Equal(newProposal, proposals[1]) } // Make sure the proposal hash matches - backend.isValidProposalHashFn = func(proposal []byte, proposalHash []byte) bool { - if bytes.Equal(proposal, proposals[0]) { + backend.isValidProposalHashFn = func(proposal *proto.Proposal, proposalHash []byte) bool { + if bytes.Equal(proposal.RawProposal, proposals[0]) { return bytes.Equal(proposalHash, proposalHashes[0]) } @@ -332,12 +337,12 @@ func TestConsensus_InvalidBlock(t *testing.T) { // Make sure the preprepare message is built correctly backend.buildPrePrepareMessageFn = func( - proposal []byte, + rawProposal []byte, certificate *proto.RoundChangeCertificate, view *proto.View, ) *proto.Message { return buildBasicPreprepareMessage( - proposal, + rawProposal, proposalHashes[view.Round], certificate, nodes[nodeIndex], @@ -357,7 +362,7 @@ func TestConsensus_InvalidBlock(t *testing.T) { // Make sure the round change message is built correctly backend.buildRoundChangeMessageFn = func( - proposal []byte, + proposal *proto.Proposal, certificate *proto.PreparedCertificate, view *proto.View, ) *proto.Message { @@ -365,12 +370,12 @@ func TestConsensus_InvalidBlock(t *testing.T) { } // Make sure the inserted proposal is noted - backend.insertBlockFn = func(proposal []byte, _ []*messages.CommittedSeal) { - insertedBlocks[nodeIndex] = proposal + backend.insertProposalFn = func(proposal *proto.Proposal, _ []*messages.CommittedSeal) { + insertedBlocks[nodeIndex] = proposal.RawProposal } // Build proposal function - backend.buildProposalFn = func(_ *proto.View) []byte { + backend.buildProposalFn = func(_ uint64) []byte { return proposals[nodeIndex] } } diff --git a/core/drop_test.go b/core/drop_test.go index e3c94df..bf0e032 100644 --- a/core/drop_test.go +++ b/core/drop_test.go @@ -2,12 +2,14 @@ package core import ( "bytes" - "github.com/0xPolygon/go-ibft/messages" - "github.com/0xPolygon/go-ibft/messages/proto" + "context" "math/rand" "testing" "time" + "github.com/0xPolygon/go-ibft/messages" + "github.com/0xPolygon/go-ibft/messages/proto" + "github.com/stretchr/testify/assert" ) @@ -28,7 +30,7 @@ func TestDropAllAndRecover(t *testing.T) { node.core = NewIBFT( mockLogger{}, &mockBackend{ - isValidBlockFn: isValidProposal, + isValidProposalFn: isValidProposal, isValidProposalHashFn: isValidProposalHash, isValidSenderFn: nil, isValidCommittedSealFn: nil, @@ -36,14 +38,14 @@ func TestDropAllAndRecover(t *testing.T) { idFn: node.addr, - buildProposalFn: buildValidProposal, + buildProposalFn: buildValidEthereumBlock, buildPrePrepareMessageFn: node.buildPrePrepare, buildPrepareMessageFn: node.buildPrepare, buildCommitMessageFn: node.buildCommit, buildRoundChangeMessageFn: node.buildRoundChange, - insertBlockFn: func(proposal []byte, _ []*messages.CommittedSeal) { - insertedBlocks[i] = proposal + insertProposalFn: func(proposal *proto.Proposal, _ []*messages.CommittedSeal) { + insertedBlocks[i] = proposal.RawProposal }, hasQuorumFn: c.hasQuorumFn, }, @@ -69,12 +71,12 @@ func TestDropAllAndRecover(t *testing.T) { // Stop all nodes and make sure no blocks are written cluster.stopN(len(cluster.nodes)) - cluster.progressToHeight(5*time.Second, 2) + assert.NoError(t, cluster.progressToHeight(5*time.Second, 2)) assertNInsertedBlocks(t, 0, insertedBlocks) // Start all and expect valid blocks to be written again cluster.startN(len(cluster.nodes)) - cluster.progressToHeight(5*time.Second, 10) + assert.NoError(t, cluster.progressToHeight(5*time.Second, 10)) assertValidInsertedBlocks(t, insertedBlocks) // Make sure the inserted blocks are valid } @@ -82,6 +84,7 @@ func assertNInsertedBlocks(t *testing.T, n int, blocks [][]byte) { t.Helper() writtenBlocks := 0 + for _, block := range blocks { if !bytes.Equal(block, nil) { writtenBlocks++ @@ -95,7 +98,7 @@ func assertValidInsertedBlocks(t *testing.T, blocks [][]byte) { t.Helper() for _, block := range blocks { - assert.True(t, bytes.Equal(block, validProposal)) + assert.True(t, bytes.Equal(block, validEthereumBlock)) } } @@ -110,7 +113,7 @@ func TestMaxFaultyDroppingMessages(t *testing.T) { node.core = NewIBFT( mockLogger{}, &mockBackend{ - isValidBlockFn: isValidProposal, + isValidProposalFn: isValidProposal, isValidProposalHashFn: isValidProposalHash, isValidSenderFn: nil, isValidCommittedSealFn: nil, @@ -118,14 +121,14 @@ func TestMaxFaultyDroppingMessages(t *testing.T) { idFn: node.addr, - buildProposalFn: buildValidProposal, + buildProposalFn: buildValidEthereumBlock, buildPrePrepareMessageFn: node.buildPrePrepare, buildPrepareMessageFn: node.buildPrepare, buildCommitMessageFn: node.buildCommit, buildRoundChangeMessageFn: node.buildRoundChange, - insertBlockFn: nil, - hasQuorumFn: c.hasQuorumFn, + insertProposalFn: nil, + hasQuorumFn: c.hasQuorumFn, }, &mockTransport{multicastFn: func(message *proto.Message) { if currentNode.faulty && rand.Intn(100) < 50 { @@ -161,7 +164,7 @@ func TestAllFailAndGraduallyRecover(t *testing.T) { node.core = NewIBFT( mockLogger{}, &mockBackend{ - isValidBlockFn: isValidProposal, + isValidProposalFn: isValidProposal, isValidProposalHashFn: isValidProposalHash, isValidSenderFn: nil, isValidCommittedSealFn: nil, @@ -169,14 +172,14 @@ func TestAllFailAndGraduallyRecover(t *testing.T) { idFn: node.addr, - buildProposalFn: buildValidProposal, + buildProposalFn: buildValidEthereumBlock, buildPrePrepareMessageFn: node.buildPrePrepare, buildPrepareMessageFn: node.buildPrepare, buildCommitMessageFn: node.buildCommit, buildRoundChangeMessageFn: node.buildRoundChange, - insertBlockFn: func(proposal []byte, _ []*messages.CommittedSeal) { - insertedBlocks[nodeIndex] = proposal + insertProposalFn: func(proposal *proto.Proposal, _ []*messages.CommittedSeal) { + insertedBlocks[nodeIndex] = proposal.RawProposal }, hasQuorumFn: c.hasQuorumFn, }, @@ -193,14 +196,20 @@ func TestAllFailAndGraduallyRecover(t *testing.T) { ) // Start the main run loops - cluster.runGradualSequence(1, 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + + t.Cleanup(func() { + cancel() + }) + + cluster.runGradualSequence(ctx, 1) // Wait until the main run loops finish cluster.wg.Wait() // Make sure the inserted blocks match what node 0 proposed for _, block := range insertedBlocks { - assert.True(t, bytes.Equal(block, validProposal)) + assert.True(t, bytes.Equal(block, validEthereumBlock)) } } @@ -222,7 +231,7 @@ func TestDropMaxFaultyPlusOne(t *testing.T) { node.core = NewIBFT( mockLogger{}, &mockBackend{ - isValidBlockFn: isValidProposal, + isValidProposalFn: isValidProposal, isValidProposalHashFn: isValidProposalHash, isValidSenderFn: nil, isValidCommittedSealFn: nil, @@ -230,14 +239,14 @@ func TestDropMaxFaultyPlusOne(t *testing.T) { idFn: node.addr, - buildProposalFn: buildValidProposal, + buildProposalFn: buildValidEthereumBlock, buildPrePrepareMessageFn: node.buildPrePrepare, buildPrepareMessageFn: node.buildPrepare, buildCommitMessageFn: node.buildCommit, buildRoundChangeMessageFn: node.buildRoundChange, - insertBlockFn: nil, - hasQuorumFn: c.hasQuorumFn, + insertProposalFn: nil, + hasQuorumFn: c.hasQuorumFn, }, &mockTransport{multicastFn: c.gossip}, @@ -280,7 +289,7 @@ func TestDropMaxFaulty(t *testing.T) { node.core = NewIBFT( mockLogger{}, &mockBackend{ - isValidBlockFn: isValidProposal, + isValidProposalFn: isValidProposal, isValidProposalHashFn: isValidProposalHash, isValidSenderFn: nil, isValidCommittedSealFn: nil, @@ -288,14 +297,14 @@ func TestDropMaxFaulty(t *testing.T) { idFn: node.addr, - buildProposalFn: buildValidProposal, + buildProposalFn: buildValidEthereumBlock, buildPrePrepareMessageFn: node.buildPrePrepare, buildPrepareMessageFn: node.buildPrepare, buildCommitMessageFn: node.buildCommit, buildRoundChangeMessageFn: node.buildRoundChange, - insertBlockFn: nil, - hasQuorumFn: c.hasQuorumFn, + insertProposalFn: nil, + hasQuorumFn: c.hasQuorumFn, }, &mockTransport{multicastFn: c.gossip}, diff --git a/core/helpers_test.go b/core/helpers_test.go index d854276..6ed2d67 100644 --- a/core/helpers_test.go +++ b/core/helpers_test.go @@ -14,24 +14,21 @@ import ( /* HELPERS */ var ( - validProposal = []byte("valid proposal") + validEthereumBlock = []byte("valid ethereum block") validProposalHash = []byte("valid proposal hash") validCommittedSeal = []byte("valid committed seal") ) func isValidProposal(newProposal []byte) bool { - return bytes.Equal(newProposal, validProposal) + return bytes.Equal(newProposal, validEthereumBlock) } -func buildValidProposal(_ *proto.View) []byte { - return validProposal +func buildValidEthereumBlock(_ uint64) []byte { + return validEthereumBlock } -func isValidProposalHash(proposal, proposalHash []byte) bool { +func isValidProposalHash(proposal *proto.Proposal, proposalHash []byte) bool { return bytes.Equal( - proposal, - validProposal, - ) && bytes.Equal( proposalHash, validProposalHash, ) @@ -50,12 +47,12 @@ func (n *node) addr() []byte { } func (n *node) buildPrePrepare( - proposal []byte, + rawProposal []byte, certificate *proto.RoundChangeCertificate, view *proto.View, ) *proto.Message { return buildBasicPreprepareMessage( - proposal, + rawProposal, validProposalHash, certificate, n.address, @@ -87,7 +84,7 @@ func (n *node) buildCommit( } func (n *node) buildRoundChange( - proposal []byte, + proposal *proto.Proposal, certificate *proto.PreparedCertificate, view *proto.View, ) *proto.Message { @@ -133,9 +130,7 @@ func newCluster(num uint64, init func(*cluster)) *cluster { return c } -func (c *cluster) runGradualSequence(height uint64, timeout time.Duration) { - ctx, _ := context.WithTimeout(context.Background(), timeout) - +func (c *cluster) runGradualSequence(ctx context.Context, height uint64) { for nodeIndex, n := range c.nodes { c.wg.Add(1) @@ -214,8 +209,8 @@ func (c *cluster) addresses() [][]byte { return addresses } -func (c *cluster) hasQuorumFn(blockNumber uint64, messages []*proto.Message, msgType proto.MessageType) bool { - return commonHasQuorumFn(uint64(len(c.nodes)))(blockNumber, messages, msgType) +func (c *cluster) hasQuorumFn(height uint64, messages []*proto.Message, msgType proto.MessageType) bool { + return commonHasQuorumFn(uint64(len(c.nodes)))(height, messages, msgType) } func (c *cluster) isProposer( diff --git a/core/ibft.go b/core/ibft.go index 3d2a2e8..8e8be25 100644 --- a/core/ibft.go +++ b/core/ibft.go @@ -445,7 +445,7 @@ func (i *IBFT) handleRoundChangeMessage(view *proto.View) *proto.RoundChangeCert ) isValidMsgFn := func(msg *proto.Message) bool { - proposal := messages.ExtractLastPreparedProposedBlock(msg) + proposal := messages.ExtractLastPreparedProposal(msg) certificate := messages.ExtractLatestPC(msg) // Check if the prepared certificate is valid @@ -485,7 +485,7 @@ func (i *IBFT) handleRoundChangeMessage(view *proto.View) *proto.RoundChangeCert // proposalMatchesCertificate checks a prepared certificate // against a proposal func (i *IBFT) proposalMatchesCertificate( - proposal []byte, + proposal *proto.Proposal, certificate *proto.PreparedCertificate, ) bool { // Both the certificate and proposal need to be set @@ -612,6 +612,11 @@ func (i *IBFT) validateProposalCommon(msg *proto.Message, view *proto.View) bool proposalHash = messages.ExtractProposalHash(msg) ) + // round matches + if proposal.Round != view.Round { + return false + } + // is proposer if !i.backend.IsProposer(msg.From, height, round) { return false @@ -622,8 +627,8 @@ func (i *IBFT) validateProposalCommon(msg *proto.Message, view *proto.View) bool return false } - // is valid block - return i.backend.IsValidBlock(proposal) + // is valid proposal + return i.backend.IsValidProposal(proposal.GetRawProposal()) } // validateProposal0 validates the proposal for round 0 @@ -939,8 +944,11 @@ func (i *IBFT) runFin() { // Insert the block to the node's underlying // blockchain layer - i.backend.InsertBlock( - i.state.getProposal(), + i.backend.InsertProposal( + &proto.Proposal{ + RawProposal: i.state.getRawDataFromProposal(), + Round: i.state.getRound(), + }, i.state.getCommittedSeals(), ) @@ -967,10 +975,10 @@ func (i *IBFT) buildProposal(ctx context.Context, view *proto.View) *proto.Messa ) if round == 0 { - proposal := i.backend.BuildProposal(view) + rawProposal := i.backend.BuildProposal(height) return i.backend.BuildPrePrepareMessage( - proposal, + rawProposal, nil, &proto.View{ Height: height, @@ -1005,20 +1013,20 @@ func (i *IBFT) buildProposal(ctx context.Context, view *proto.View) *proto.Messa continue } - lastPB := messages.ExtractLastPreparedProposedBlock(msg) + lastPB := messages.ExtractLastPreparedProposal(msg) if lastPB == nil { continue } if msgRound > maxRound { - previousProposal = lastPB + previousProposal = lastPB.RawProposal maxRound = msgRound } } if previousProposal == nil { // build new proposal - proposal := i.backend.BuildProposal(view) + proposal := i.backend.BuildProposal(height) return i.backend.BuildPrePrepareMessage( proposal, @@ -1197,7 +1205,7 @@ func (i *IBFT) sendPreprepareMessage(message *proto.Message) { func (i *IBFT) sendRoundChangeMessage(height, newRound uint64) { i.transport.Multicast( i.backend.BuildRoundChangeMessage( - i.state.getLatestPreparedProposedBlock(), + i.state.getLatestPreparedProposal(), i.state.getLatestPC(), &proto.View{ Height: height, diff --git a/core/ibft_test.go b/core/ibft_test.go index 775f029..3c2ca6c 100644 --- a/core/ibft_test.go +++ b/core/ibft_test.go @@ -15,15 +15,18 @@ import ( "github.com/0xPolygon/go-ibft/messages/proto" ) -func proposalMatches(proposal []byte, message *proto.Message) bool { +func proposalMatches(proposal *proto.Proposal, message *proto.Message) bool { if message == nil || message.Type != proto.MessageType_PREPREPARE { return false } - preprepareData, _ := message.Payload.(*proto.Message_PreprepareData) - extractedProposal := preprepareData.PreprepareData.Proposal + extractedProposal := messages.ExtractProposal(message) + if extractedProposal == nil { + return false + } - return bytes.Equal(proposal, extractedProposal) + return proposal.Round == extractedProposal.Round && + bytes.Equal(proposal.RawProposal, extractedProposal.RawProposal) } func prepareHashMatches(prepareHash []byte, message *proto.Message) bool { @@ -153,7 +156,7 @@ func filterMessages(messages []*proto.Message, isValid func(message *proto.Messa func generateFilledRCMessages( quorum uint64, - proposal, + proposal *proto.Proposal, proposalHash []byte) []*proto.Message { // Generate random RC messages roundChangeMessages := generateMessagesWithUniqueSender(quorum, proto.MessageType_ROUND_CHANGE) @@ -196,7 +199,7 @@ func generateFilledRCMessages( for _, message := range roundChangeMessages { message.Payload = &proto.Message_RoundChangeData{ RoundChangeData: &proto.RoundChangeMessage{ - LastPreparedProposedBlock: proposal, + LastPreparedProposal: proposal, LatestPreparedCertificate: lastPreparedCertificate, }, } @@ -228,7 +231,7 @@ func TestRunNewRound_Proposer(t *testing.T) { ctx, cancelFn := context.WithCancel(context.Background()) var ( - newProposal = []byte("new block") + newRawProposal = []byte("new block") multicastedProposal *proto.Message = nil log = mockLogger{} @@ -242,11 +245,11 @@ func TestRunNewRound_Proposer(t *testing.T) { isProposerFn: func(_ []byte, _ uint64, _ uint64) bool { return true }, - buildProposalFn: func(_ *proto.View) []byte { - return newProposal + buildProposalFn: func(_ uint64) []byte { + return newRawProposal }, buildPrePrepareMessageFn: func( - proposal []byte, + rawProposal []byte, certificate *proto.RoundChangeCertificate, view *proto.View, ) *proto.Message { @@ -255,7 +258,10 @@ func TestRunNewRound_Proposer(t *testing.T) { Type: proto.MessageType_PREPREPARE, Payload: &proto.Message_PreprepareData{ PreprepareData: &proto.PrePrepareMessage{ - Proposal: proposal, + Proposal: &proto.Proposal{ + RawProposal: rawProposal, + Round: 0, + }, Certificate: certificate, }, }, @@ -289,7 +295,14 @@ func TestRunNewRound_Proposer(t *testing.T) { assert.Equal(t, multicastedProposal, i.state.proposalMessage) // Make sure the accepted proposal matches what was built - assert.True(t, proposalMatches(newProposal, multicastedProposal)) + assert.True( + t, + proposalMatches(&proto.Proposal{ + RawProposal: newRawProposal, + Round: 0, + }, multicastedProposal, + ), + ) }, ) @@ -325,8 +338,8 @@ func TestRunNewRound_Proposer(t *testing.T) { return true }, hasQuorumFn: defaultHasQuorumFn(quorum), - buildProposalFn: func(_ *proto.View) []byte { - return correctRoundMessage.proposal + buildProposalFn: func(_ uint64) []byte { + return correctRoundMessage.proposal.GetRawProposal() }, buildPrepareMessageFn: func(_ []byte, view *proto.View) *proto.Message { return &proto.Message{ @@ -422,7 +435,10 @@ func TestRunNewRound_Proposer(t *testing.T) { func(t *testing.T) { t.Parallel() - lastPreparedProposedBlock := []byte("last prepared block") + lastPreparedProposedProposal := &proto.Proposal{ + RawProposal: []byte("dummy block"), + Round: 0, + } quorum := uint64(4) ctx, cancelFn := context.WithCancel(context.Background()) @@ -446,7 +462,7 @@ func TestRunNewRound_Proposer(t *testing.T) { payload, _ := roundChangeMessages[1].Payload.(*proto.Message_RoundChangeData) rcData := payload.RoundChangeData - rcData.LastPreparedProposedBlock = lastPreparedProposedBlock + rcData.LastPreparedProposal = lastPreparedProposedProposal rcData.LatestPreparedCertificate = &proto.PreparedCertificate{ ProposalMessage: &proto.Message{ View: &proto.View{ @@ -457,7 +473,7 @@ func TestRunNewRound_Proposer(t *testing.T) { Type: proto.MessageType_PREPREPARE, Payload: &proto.Message_PreprepareData{ PreprepareData: &proto.PrePrepareMessage{ - Proposal: lastPreparedProposedBlock, + Proposal: lastPreparedProposedProposal, ProposalHash: correctRoundMessage.hash, Certificate: nil, }, @@ -489,7 +505,7 @@ func TestRunNewRound_Proposer(t *testing.T) { return bytes.Equal(proposerID, proposer) }, hasQuorumFn: defaultHasQuorumFn(quorum), - buildProposalFn: func(_ *proto.View) []byte { + buildProposalFn: func(_ uint64) []byte { return proposal }, buildPrepareMessageFn: func(_ []byte, view *proto.View) *proto.Message { @@ -504,7 +520,7 @@ func TestRunNewRound_Proposer(t *testing.T) { } }, buildPrePrepareMessageFn: func( - proposal []byte, + rawProposal []byte, certificate *proto.RoundChangeCertificate, view *proto.View, ) *proto.Message { @@ -513,7 +529,10 @@ func TestRunNewRound_Proposer(t *testing.T) { Type: proto.MessageType_PREPREPARE, Payload: &proto.Message_PreprepareData{ PreprepareData: &proto.PrePrepareMessage{ - Proposal: proposal, + Proposal: &proto.Proposal{ + RawProposal: rawProposal, + Round: 0, + }, ProposalHash: correctRoundMessage.hash, Certificate: certificate, }, @@ -575,7 +594,7 @@ func TestRunNewRound_Proposer(t *testing.T) { assert.Equal(t, multicastedPreprepare, i.state.proposalMessage) // Make sure the correct proposal was multicasted - assert.True(t, proposalMatches(lastPreparedProposedBlock, multicastedPreprepare)) + assert.True(t, proposalMatches(lastPreparedProposedProposal, multicastedPreprepare)) // Make sure the prepare message was not multicasted assert.Nil(t, multicastedPrepare) @@ -624,7 +643,7 @@ func TestRunNewRound_Validator_Zero(t *testing.T) { isProposerFn: func(from []byte, _, _ uint64) bool { return bytes.Equal(from, proposer) }, - isValidBlockFn: func(_ []byte) bool { + isValidProposalFn: func(_ []byte) bool { return true }, } @@ -690,15 +709,18 @@ func TestRunNewRound_Validator_NonZero(t *testing.T) { quorum := uint64(4) proposer := []byte("proposer") + round := uint64(1) + + correctRoundMessage := newCorrectRoundMessage(round) generateProposalWithNoPrevious := func() *proto.Message { roundChangeMessages := generateMessagesWithUniqueSender(quorum, proto.MessageType_ROUND_CHANGE) - setRoundForMessages(roundChangeMessages, 1) + setRoundForMessages(roundChangeMessages, round) return &proto.Message{ View: &proto.View{ Height: 0, - Round: 1, + Round: round, }, From: proposer, Type: proto.MessageType_PREPREPARE, @@ -794,7 +816,7 @@ func TestRunNewRound_Validator_NonZero(t *testing.T) { isProposerFn: func(from []byte, _, _ uint64) bool { return bytes.Equal(from, proposer) }, - isValidBlockFn: func(_ []byte) bool { + isValidProposalFn: func(_ []byte) bool { return true }, } @@ -887,7 +909,7 @@ func TestRunPrepare(t *testing.T) { hasQuorumFn: func(_ uint64, messages []*proto.Message, _ proto.MessageType) bool { return len(messages) >= 1 }, - isValidProposalHashFn: func(_ []byte, hash []byte) bool { + isValidProposalHashFn: func(_ *proto.Proposal, hash []byte) bool { return bytes.Equal(correctRoundMessage.hash, hash) }, } @@ -985,14 +1007,14 @@ func TestRunCommit(t *testing.T) { log = mockLogger{} transport = mockTransport{} backend = mockBackend{ - insertBlockFn: func(proposal []byte, committedSeals []*messages.CommittedSeal) { - insertedProposal = proposal + insertProposalFn: func(proposal *proto.Proposal, committedSeals []*messages.CommittedSeal) { + insertedProposal = proposal.RawProposal insertedCommittedSeals = committedSeals }, hasQuorumFn: func(_ uint64, messages []*proto.Message, _ proto.MessageType) bool { return len(messages) >= 1 }, - isValidProposalHashFn: func(_ []byte, hash []byte) bool { + isValidProposalHashFn: func(_ *proto.Proposal, hash []byte) bool { return bytes.Equal(correctRoundMessage.hash, hash) }, } @@ -1071,7 +1093,7 @@ func TestRunCommit(t *testing.T) { assert.Equal(t, fin, i.state.name) // Make sure the inserted proposal was the one present - assert.Equal(t, insertedProposal, correctRoundMessage.proposal) + assert.Equal(t, insertedProposal, correctRoundMessage.proposal.RawProposal) // Make sure the inserted committed seals were correct assert.Equal(t, insertedCommittedSeals, committedSeals) @@ -1296,7 +1318,7 @@ func TestIBFT_FutureProposal(t *testing.T) { for _, message := range roundChangeMessages { message.Payload = &proto.Message_RoundChangeData{ RoundChangeData: &proto.RoundChangeMessage{ - LastPreparedProposedBlock: nil, + LastPreparedProposal: nil, LatestPreparedCertificate: nil, }, } @@ -1307,6 +1329,28 @@ func TestIBFT_FutureProposal(t *testing.T) { return roundChangeMessages } + generateValidProposal := func( + view *proto.View, + roundChangeMessages []*proto.Message, + ) *proto.Message { + correctRoundMessage := newCorrectRoundMessage(view.Round) + + return &proto.Message{ + View: view, + From: proposer, + Type: proto.MessageType_PREPREPARE, + Payload: &proto.Message_PreprepareData{ + PreprepareData: &proto.PrePrepareMessage{ + Proposal: correctRoundMessage.proposal, + ProposalHash: correctRoundMessage.hash, + Certificate: &proto.RoundChangeCertificate{ + RoundChangeMessages: roundChangeMessages, + }, + }, + }, + } + } + generateFilledRCMessagesWithRound := func(quorum, round uint64) []*proto.Message { messages := generateFilledRCMessages(quorum, correctRoundMessage.proposal, correctRoundMessage.hash) setRoundForMessages(messages, round) @@ -1347,21 +1391,10 @@ func TestIBFT_FutureProposal(t *testing.T) { t.Parallel() ctx, cancelFn := context.WithCancel(context.Background()) - - validProposal := &proto.Message{ - View: testCase.proposalView, - From: proposer, - Type: proto.MessageType_PREPREPARE, - Payload: &proto.Message_PreprepareData{ - PreprepareData: &proto.PrePrepareMessage{ - Proposal: correctRoundMessage.proposal, - ProposalHash: correctRoundMessage.hash, - Certificate: &proto.RoundChangeCertificate{ - RoundChangeMessages: testCase.roundChangeMessages, - }, - }, - }, - } + validProposal := generateValidProposal( + testCase.proposalView, + testCase.roundChangeMessages, + ) var ( wg sync.WaitGroup @@ -1376,9 +1409,12 @@ func TestIBFT_FutureProposal(t *testing.T) { idFn: func() []byte { return nodeID }, - isValidProposalHashFn: func(p []byte, hash []byte) bool { - return bytes.Equal(hash, correctRoundMessage.hash) && - bytes.Equal(p, correctRoundMessage.proposal) + isValidProposalHashFn: func(p *proto.Proposal, hash []byte) bool { + if bytes.Equal(p.RawProposal, correctRoundMessage.proposal.RawProposal) { + return bytes.Equal(hash, correctRoundMessage.hash) + } + + return false }, hasQuorumFn: defaultHasQuorumFn(quorum), } @@ -1436,7 +1472,11 @@ func TestIBFT_FutureProposal(t *testing.T) { } assert.Equal(t, testCase.notifyRound, receivedProposalEvent.round) - assert.Equal(t, correctRoundMessage.proposal, messages.ExtractProposal(receivedProposalEvent.proposalMessage)) + assert.Equal( + t, + messages.ExtractProposal(validProposal), + messages.ExtractProposal(receivedProposalEvent.proposalMessage), + ) }) } } @@ -1975,7 +2015,11 @@ func TestIBFT_ValidateProposal(t *testing.T) { View: baseView, Type: proto.MessageType_PREPREPARE, Payload: &proto.Message_PreprepareData{ - PreprepareData: &proto.PrePrepareMessage{}, + PreprepareData: &proto.PrePrepareMessage{ + Proposal: &proto.Proposal{ + Round: baseView.Round, + }, + }, }, } @@ -1991,7 +2035,7 @@ func TestIBFT_ValidateProposal(t *testing.T) { isProposerFn: func(_ []byte, _ uint64, _ uint64) bool { return true }, - isValidBlockFn: func(_ []byte) bool { + isValidProposalFn: func(_ []byte) bool { return false }, } @@ -2008,7 +2052,11 @@ func TestIBFT_ValidateProposal(t *testing.T) { View: baseView, Type: proto.MessageType_PREPREPARE, Payload: &proto.Message_PreprepareData{ - PreprepareData: &proto.PrePrepareMessage{}, + PreprepareData: &proto.PrePrepareMessage{ + Proposal: &proto.Proposal{ + Round: 0, + }, + }, }, } @@ -2021,7 +2069,7 @@ func TestIBFT_ValidateProposal(t *testing.T) { var ( log = mockLogger{} backend = mockBackend{ - isValidProposalHashFn: func(_ []byte, _ []byte) bool { + isValidProposalHashFn: func(_ *proto.Proposal, _ []byte) bool { return false }, isProposerFn: func(_ []byte, _ uint64, _ uint64) bool { @@ -2041,7 +2089,11 @@ func TestIBFT_ValidateProposal(t *testing.T) { View: baseView, Type: proto.MessageType_PREPREPARE, Payload: &proto.Message_PreprepareData{ - PreprepareData: &proto.PrePrepareMessage{}, + PreprepareData: &proto.PrePrepareMessage{ + Proposal: &proto.Proposal{ + Round: baseView.Round, + }, + }, }, } @@ -2073,6 +2125,9 @@ func TestIBFT_ValidateProposal(t *testing.T) { Payload: &proto.Message_PreprepareData{ PreprepareData: &proto.PrePrepareMessage{ Certificate: nil, + Proposal: &proto.Proposal{ + Round: 0, + }, }, }, } @@ -2120,6 +2175,9 @@ func TestIBFT_ValidateProposal(t *testing.T) { Certificate: &proto.RoundChangeCertificate{ RoundChangeMessages: messages, }, + Proposal: &proto.Proposal{ + Round: baseView.Round, + }, }, }, } @@ -2157,6 +2215,9 @@ func TestIBFT_ValidateProposal(t *testing.T) { Certificate: &proto.RoundChangeCertificate{ RoundChangeMessages: generateMessages(quorum-1, proto.MessageType_ROUND_CHANGE), }, + Proposal: &proto.Proposal{ + Round: 0, + }, }, }, } @@ -2203,6 +2264,9 @@ func TestIBFT_ValidateProposal(t *testing.T) { Certificate: &proto.RoundChangeCertificate{ RoundChangeMessages: generateMessages(quorum, proto.MessageType_ROUND_CHANGE), }, + Proposal: &proto.Proposal{ + Round: 0, + }, }, }, } @@ -2238,11 +2302,64 @@ func TestIBFT_ValidateProposal(t *testing.T) { proposal := &proto.Message{ View: baseView, Type: proto.MessageType_PREPREPARE, + Payload: &proto.Message_PreprepareData{ + PreprepareData: &proto.PrePrepareMessage{ + Proposal: &proto.Proposal{ + Round: baseView.Round, + }, + Certificate: &proto.RoundChangeCertificate{ + RoundChangeMessages: generateMessages(quorum, proto.MessageType_ROUND_CHANGE), + }, + }, + }, + } + + assert.False(t, i.validateProposal(proposal, baseView)) + }) + + t.Run("round is not correct", func(t *testing.T) { + t.Parallel() + + var ( + quorum = uint64(4) + round = uint64(1) + id = []byte("node id") + uniqueNode = []byte("unique node") + + log = mockLogger{} + backend = mockBackend{ + idFn: func() []byte { + return id + }, + isProposerFn: func(proposer []byte, _ uint64, _ uint64) bool { + if bytes.Equal(proposer, uniqueNode) { + return true + } + + return bytes.Equal(proposer, id) + }, + } + transport = mockTransport{} + ) + + i := NewIBFT(log, backend, transport) + + baseView := &proto.View{ + Height: 0, + Round: round, + } + proposal := &proto.Message{ + View: baseView, + From: uniqueNode, + Type: proto.MessageType_PREPREPARE, Payload: &proto.Message_PreprepareData{ PreprepareData: &proto.PrePrepareMessage{ Certificate: &proto.RoundChangeCertificate{ RoundChangeMessages: generateMessages(quorum, proto.MessageType_ROUND_CHANGE), }, + Proposal: &proto.Proposal{ + Round: 0, + }, }, }, } @@ -2382,7 +2499,7 @@ func TestIBFT_RunSequence_NewProposal(t *testing.T) { defer cancelFn() var ( - proposal = []byte("proposal") + proposal = &proto.Proposal{} round = uint64(10) height = uint64(1) quorum = uint64(4) diff --git a/core/mock_test.go b/core/mock_test.go index 4a6bafd..6900429 100644 --- a/core/mock_test.go +++ b/core/mock_test.go @@ -16,25 +16,35 @@ const ( ) var ( - correctRoundMessage = roundMessage{ - proposal: []byte("proposal"), - hash: []byte("proposal hash"), - seal: []byte("seal"), - } + correctRoundMessage = newCorrectRoundMessage(0) badRoundMessage = roundMessage{ - proposal: []byte("bad proposal"), - hash: []byte("bad proposal hash"), - seal: []byte("bad seal"), + proposal: &proto.Proposal{ + RawProposal: []byte("bad"), + Round: 100, + }, + hash: []byte("bad proposal hash"), + seal: []byte("bad seal"), } ) +func newCorrectRoundMessage(round uint64) roundMessage { + return roundMessage{ + proposal: &proto.Proposal{ + RawProposal: validEthereumBlock, + Round: round, + }, + hash: []byte("proposal hash"), + seal: []byte("seal"), + } +} + // Define delegation methods type isValidBlockDelegate func([]byte) bool type isValidSenderDelegate func(*proto.Message) bool type isProposerDelegate func([]byte, uint64, uint64) bool -type buildProposalDelegate func(*proto.View) []byte -type isValidProposalHashDelegate func([]byte, []byte) bool +type buildEthereumBlockDelegate func(uint64) []byte +type isValidProposalHashDelegate func(*proto.Proposal, []byte) bool type isValidCommittedSealDelegate func([]byte, *messages.CommittedSeal) bool type buildPrePrepareMessageDelegate func( @@ -45,21 +55,21 @@ type buildPrePrepareMessageDelegate func( type buildPrepareMessageDelegate func([]byte, *proto.View) *proto.Message type buildCommitMessageDelegate func([]byte, *proto.View) *proto.Message type buildRoundChangeMessageDelegate func( - []byte, + *proto.Proposal, *proto.PreparedCertificate, *proto.View, ) *proto.Message -type insertBlockDelegate func([]byte, []*messages.CommittedSeal) +type insertProposalDelegate func(*proto.Proposal, []*messages.CommittedSeal) type idDelegate func() []byte type hasQuorumDelegate func(uint64, []*proto.Message, proto.MessageType) bool // mockBackend is the mock backend structure that is configurable type mockBackend struct { - isValidBlockFn isValidBlockDelegate + isValidProposalFn isValidBlockDelegate isValidSenderFn isValidSenderDelegate isProposerFn isProposerDelegate - buildProposalFn buildProposalDelegate + buildProposalFn buildEthereumBlockDelegate isValidProposalHashFn isValidProposalHashDelegate isValidCommittedSealFn isValidCommittedSealDelegate @@ -67,7 +77,7 @@ type mockBackend struct { buildPrepareMessageFn buildPrepareMessageDelegate buildCommitMessageFn buildCommitMessageDelegate buildRoundChangeMessageFn buildRoundChangeMessageDelegate - insertBlockFn insertBlockDelegate + insertProposalFn insertProposalDelegate idFn idDelegate hasQuorumFn hasQuorumDelegate } @@ -80,15 +90,15 @@ func (m mockBackend) ID() []byte { return nil } -func (m mockBackend) InsertBlock(proposal []byte, committedSeals []*messages.CommittedSeal) { - if m.insertBlockFn != nil { - m.insertBlockFn(proposal, committedSeals) +func (m mockBackend) InsertProposal(proposal *proto.Proposal, committedSeals []*messages.CommittedSeal) { + if m.insertProposalFn != nil { + m.insertProposalFn(proposal, committedSeals) } } -func (m mockBackend) IsValidBlock(block []byte) bool { - if m.isValidBlockFn != nil { - return m.isValidBlockFn(block) +func (m mockBackend) IsValidProposal(proposal []byte) bool { + if m.isValidProposalFn != nil { + return m.isValidProposalFn(proposal) } return true @@ -110,15 +120,15 @@ func (m mockBackend) IsProposer(id []byte, sequence, round uint64) bool { return false } -func (m mockBackend) BuildProposal(view *proto.View) []byte { +func (m mockBackend) BuildProposal(height uint64) []byte { if m.buildProposalFn != nil { - return m.buildProposalFn(view) + return m.buildProposalFn(height) } return nil } -func (m mockBackend) IsValidProposalHash(proposal, hash []byte) bool { +func (m mockBackend) IsValidProposalHash(proposal *proto.Proposal, hash []byte) bool { if m.isValidProposalHashFn != nil { return m.isValidProposalHashFn(proposal, hash) } @@ -135,12 +145,12 @@ func (m mockBackend) IsValidCommittedSeal(proposal []byte, committedSeal *messag } func (m mockBackend) BuildPrePrepareMessage( - proposal []byte, + rawProposal []byte, certificate *proto.RoundChangeCertificate, view *proto.View, ) *proto.Message { if m.buildPrePrepareMessageFn != nil { - return m.buildPrePrepareMessageFn(proposal, certificate, view) + return m.buildPrePrepareMessageFn(rawProposal, certificate, view) } return nil @@ -163,7 +173,7 @@ func (m mockBackend) BuildCommitMessage(proposalHash []byte, view *proto.View) * } func (m mockBackend) BuildRoundChangeMessage( - proposal []byte, + proposal *proto.Proposal, certificate *proto.PreparedCertificate, view *proto.View, ) *proto.Message { @@ -181,9 +191,9 @@ func (m mockBackend) BuildRoundChangeMessage( } } -func (m mockBackend) HasQuorum(blockNumber uint64, messages []*proto.Message, msgType proto.MessageType) bool { +func (m mockBackend) HasQuorum(height uint64, messages []*proto.Message, msgType proto.MessageType) bool { if m.hasQuorumFn != nil { - return m.hasQuorumFn(blockNumber, messages, msgType) + return m.hasQuorumFn(height, messages, msgType) } return true diff --git a/core/rapid_test.go b/core/rapid_test.go index 6adb2e0..c635369 100644 --- a/core/rapid_test.go +++ b/core/rapid_test.go @@ -16,7 +16,7 @@ import ( // roundMessage contains message data within consensus round type roundMessage struct { - proposal []byte + proposal *proto.Proposal seal []byte hash []byte } @@ -252,17 +252,18 @@ func TestProperty(t *testing.T) { } // Make sure the proposal is valid if it matches what node 0 proposed - backend.isValidBlockFn = func(newProposal []byte) bool { + backend.isValidProposalFn = func(rawProposal []byte) bool { message := setup.getEvent(nodeIndex).getMessage(nodeIndex) - return bytes.Equal(newProposal, message.proposal) + return bytes.Equal(rawProposal, message.proposal.RawProposal) } // Make sure the proposal hash matches - backend.isValidProposalHashFn = func(p []byte, ph []byte) bool { + backend.isValidProposalHashFn = func(proposal *proto.Proposal, hash []byte) bool { message := setup.getEvent(nodeIndex).getMessage(nodeIndex) - return bytes.Equal(p, message.proposal) && bytes.Equal(ph, message.hash) + return bytes.Equal(proposal.RawProposal, message.proposal.RawProposal) && + bytes.Equal(hash, message.hash) } // Make sure the preprepare message is built correctly @@ -298,7 +299,7 @@ func TestProperty(t *testing.T) { // Make sure the round change message is built correctly backend.buildRoundChangeMessageFn = func( - proposal []byte, + proposal *proto.Proposal, certificate *proto.PreparedCertificate, view *proto.View, ) *proto.Message { @@ -306,15 +307,15 @@ func TestProperty(t *testing.T) { } // Make sure the inserted proposal is noted - backend.insertBlockFn = func(proposal []byte, _ []*messages.CommittedSeal) { - insertedProposals.insertProposal(nodeIndex, proposal) + backend.insertProposalFn = func(proposal *proto.Proposal, _ []*messages.CommittedSeal) { + insertedProposals.insertProposal(nodeIndex, proposal.RawProposal) } // Make sure the proposal can be built - backend.buildProposalFn = func(view *proto.View) []byte { + backend.buildProposalFn = func(_ uint64) []byte { message := setup.getEvent(nodeIndex).getMessage(nodeIndex) - return message.proposal + return message.proposal.GetRawProposal() } } @@ -366,7 +367,7 @@ func TestProperty(t *testing.T) { // Make sure inserted block value is correct for _, val := range proposalMap { - assert.Equal(t, correctRoundMessage.proposal, val) + assert.Equal(t, correctRoundMessage.proposal.RawProposal, val) } } else { // There should not be inserted blocks in bad nodes diff --git a/core/state.go b/core/state.go index 2c773dd..eebb18f 100644 --- a/core/state.go +++ b/core/state.go @@ -16,19 +16,19 @@ const ( fin ) -func (s stateType) String() (str string) { +func (s stateType) String() string { switch s { case newRound: - str = "new round" + return "new round" case prepare: - str = "prepare" + return "prepare" case commit: - str = "commit" + return "commit" case fin: - str = "fin" + return "fin" } - return + return "" } type state struct { @@ -40,11 +40,11 @@ type state struct { // latestPC is the latest prepared certificate latestPC *proto.PreparedCertificate - // latestPreparedProposedBlock is the block + // latestPreparedProposal is the proposal // for which Q(N)-1 PREPARE messages were received - latestPreparedProposedBlock []byte + latestPreparedProposal *proto.Proposal - // accepted block proposal for current round + // accepted proposal for current round proposalMessage *proto.Message // validated commit seals @@ -75,7 +75,7 @@ func (s *state) clear(height uint64) { s.name = newRound s.proposalMessage = nil s.latestPC = nil - s.latestPreparedProposedBlock = nil + s.latestPreparedProposal = nil s.view = &proto.View{ Height: height, @@ -90,11 +90,11 @@ func (s *state) getLatestPC() *proto.PreparedCertificate { return s.latestPC } -func (s *state) getLatestPreparedProposedBlock() []byte { +func (s *state) getLatestPreparedProposal() *proto.Proposal { s.RLock() defer s.RUnlock() - return s.latestPreparedProposedBlock + return s.latestPreparedProposal } func (s *state) getProposalMessage() *proto.Message { @@ -132,7 +132,7 @@ func (s *state) getHeight() uint64 { return s.view.Height } -func (s *state) getProposal() []byte { +func (s *state) getProposal() *proto.Proposal { s.RLock() defer s.RUnlock() @@ -143,6 +143,16 @@ func (s *state) getProposal() []byte { return nil } +func (s *state) getRawDataFromProposal() []byte { + proposal := s.getProposal() + + if proposal != nil { + return proposal.RawProposal + } + + return nil +} + func (s *state) getCommittedSeals() []*messages.CommittedSeal { s.RLock() defer s.RUnlock() @@ -198,13 +208,13 @@ func (s *state) newRound() { func (s *state) finalizePrepare( certificate *proto.PreparedCertificate, - latestPPB []byte, + latestPPB *proto.Proposal, ) { s.Lock() defer s.Unlock() s.latestPC = certificate - s.latestPreparedProposedBlock = latestPPB + s.latestPreparedProposal = latestPPB // Move to the commit state s.name = commit diff --git a/go.mod b/go.mod index d608f63..b140f91 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/0xPolygon/go-ibft go 1.19 require ( + 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 9565209..a7c362c 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,7 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= diff --git a/messages/event_manager.go b/messages/event_manager.go index 9edba60..11d1636 100644 --- a/messages/event_manager.go +++ b/messages/event_manager.go @@ -1,11 +1,13 @@ +// Package messages defines a sub-module to handle IBFT messages package messages import ( "sync" "sync/atomic" - "github.com/0xPolygon/go-ibft/messages/proto" "github.com/google/uuid" + + "github.com/0xPolygon/go-ibft/messages/proto" ) type eventManager struct { @@ -21,6 +23,7 @@ func newEventManager() *eventManager { } } +// SubscriptionID is a unique number to identify Subscription type SubscriptionID int32 // Subscription is the subscription @@ -54,7 +57,7 @@ type SubscriptionDetails struct { HasMinRound bool // HasQuorumFn is the function used to check for quorum existence - HasQuorumFn func(blockNumber uint64, messages []*proto.Message, msgType proto.MessageType) bool + HasQuorumFn func(height uint64, messages []*proto.Message, msgType proto.MessageType) bool } // subscribe registers a new listener for message events diff --git a/messages/helpers.go b/messages/helpers.go index 2b5e6e3..e1683f3 100644 --- a/messages/helpers.go +++ b/messages/helpers.go @@ -12,7 +12,7 @@ var ( ErrWrongCommitMessageType = errors.New("wrong type message is included in COMMIT messages") ) -// CommittedSeal Validator proof of signing a committed block +// CommittedSeal Validator proof of signing a committed proposal type CommittedSeal struct { Signer []byte Signature []byte @@ -55,8 +55,8 @@ func ExtractCommitHash(commitMessage *proto.Message) []byte { return commitData.CommitData.ProposalHash } -// ExtractProposal extracts the proposal from the passed in message -func ExtractProposal(proposalMessage *proto.Message) []byte { +// ExtractProposal extracts the (rawData,r) proposal from the passed in message +func ExtractProposal(proposalMessage *proto.Message) *proto.Proposal { if proposalMessage.Type != proto.MessageType_PREPREPARE { return nil } @@ -110,15 +110,15 @@ func ExtractLatestPC(roundChangeMessage *proto.Message) *proto.PreparedCertifica return rcData.RoundChangeData.LatestPreparedCertificate } -// ExtractLastPreparedProposedBlock extracts the latest prepared proposed block from the passed in message -func ExtractLastPreparedProposedBlock(roundChangeMessage *proto.Message) []byte { +// ExtractLastPreparedProposal extracts the latest prepared proposal from the passed in message +func ExtractLastPreparedProposal(roundChangeMessage *proto.Message) *proto.Proposal { if roundChangeMessage.Type != proto.MessageType_ROUND_CHANGE { return nil } rcData, _ := roundChangeMessage.Payload.(*proto.Message_RoundChangeData) - return rcData.RoundChangeData.LastPreparedProposedBlock + return rcData.RoundChangeData.LastPreparedProposal } // HasUniqueSenders checks if the messages have unique senders diff --git a/messages/helpers_test.go b/messages/helpers_test.go index 7dac979..f8490ef 100644 --- a/messages/helpers_test.go +++ b/messages/helpers_test.go @@ -132,11 +132,11 @@ func TestMessages_ExtractCommitHash(t *testing.T) { func TestMessages_ExtractProposal(t *testing.T) { t.Parallel() - proposal := []byte("proposal") + proposal := &proto.Proposal{} testTable := []struct { name string - expectedProposal []byte + expectedProposal *proto.Proposal message *proto.Message }{ { @@ -367,21 +367,21 @@ func TestMessages_ExtractLatestPC(t *testing.T) { func TestMessages_ExtractLPPB(t *testing.T) { t.Parallel() - latestPPB := []byte("latest block") + lastPreparedProposal := &proto.Proposal{} testTable := []struct { name string - expectedLPPB []byte + expectedLPPB *proto.Proposal message *proto.Message }{ { "valid message", - latestPPB, + lastPreparedProposal, &proto.Message{ Type: proto.MessageType_ROUND_CHANGE, Payload: &proto.Message_RoundChangeData{ RoundChangeData: &proto.RoundChangeMessage{ - LastPreparedProposedBlock: latestPPB, + LastPreparedProposal: lastPreparedProposal, }, }, }, @@ -404,7 +404,7 @@ func TestMessages_ExtractLPPB(t *testing.T) { assert.Equal( t, testCase.expectedLPPB, - ExtractLastPreparedProposedBlock(testCase.message), + ExtractLastPreparedProposal(testCase.message), ) }) } diff --git a/messages/proto/messages.pb.go b/messages/proto/messages.pb.go index 46caf21..9bbe6c5 100644 --- a/messages/proto/messages.pb.go +++ b/messages/proto/messages.pb.go @@ -1,12 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 -// protoc v3.21.2 -// source: messages.proto +// protoc-gen-go v1.25.0 +// protoc v3.21.9 +// source: messages/proto/messages.proto package proto import ( + proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -20,6 +21,10 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + // MessageType defines the types of messages // circulating in the system type MessageType int32 @@ -58,11 +63,11 @@ func (x MessageType) String() string { } func (MessageType) Descriptor() protoreflect.EnumDescriptor { - return file_messages_proto_enumTypes[0].Descriptor() + return file_messages_proto_messages_proto_enumTypes[0].Descriptor() } func (MessageType) Type() protoreflect.EnumType { - return &file_messages_proto_enumTypes[0] + return &file_messages_proto_messages_proto_enumTypes[0] } func (x MessageType) Number() protoreflect.EnumNumber { @@ -71,7 +76,7 @@ func (x MessageType) Number() protoreflect.EnumNumber { // Deprecated: Use MessageType.Descriptor instead. func (MessageType) EnumDescriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{0} + return file_messages_proto_messages_proto_rawDescGZIP(), []int{0} } // View defines the current status @@ -89,7 +94,7 @@ type View struct { func (x *View) Reset() { *x = View{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[0] + mi := &file_messages_proto_messages_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -102,7 +107,7 @@ func (x *View) String() string { func (*View) ProtoMessage() {} func (x *View) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[0] + mi := &file_messages_proto_messages_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -115,7 +120,7 @@ func (x *View) ProtoReflect() protoreflect.Message { // Deprecated: Use View.ProtoReflect.Descriptor instead. func (*View) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{0} + return file_messages_proto_messages_proto_rawDescGZIP(), []int{0} } func (x *View) GetHeight() uint64 { @@ -159,7 +164,7 @@ type Message struct { func (x *Message) Reset() { *x = Message{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[1] + mi := &file_messages_proto_messages_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -172,7 +177,7 @@ func (x *Message) String() string { func (*Message) ProtoMessage() {} func (x *Message) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[1] + mi := &file_messages_proto_messages_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -185,7 +190,7 @@ func (x *Message) ProtoReflect() protoreflect.Message { // Deprecated: Use Message.ProtoReflect.Descriptor instead. func (*Message) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{1} + return file_messages_proto_messages_proto_rawDescGZIP(), []int{1} } func (x *Message) GetView() *View { @@ -286,7 +291,7 @@ type PrePrepareMessage struct { unknownFields protoimpl.UnknownFields // proposal is the actual data being proposed for consensus - Proposal []byte `protobuf:"bytes,1,opt,name=proposal,proto3" json:"proposal,omitempty"` + Proposal *Proposal `protobuf:"bytes,1,opt,name=proposal,proto3" json:"proposal,omitempty"` // proposalHash is the Keccak hash of the proposal ProposalHash []byte `protobuf:"bytes,2,opt,name=proposalHash,proto3" json:"proposalHash,omitempty"` // certificate is the RCC that can accompany @@ -297,7 +302,7 @@ type PrePrepareMessage struct { func (x *PrePrepareMessage) Reset() { *x = PrePrepareMessage{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[2] + mi := &file_messages_proto_messages_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -310,7 +315,7 @@ func (x *PrePrepareMessage) String() string { func (*PrePrepareMessage) ProtoMessage() {} func (x *PrePrepareMessage) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[2] + mi := &file_messages_proto_messages_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -323,10 +328,10 @@ func (x *PrePrepareMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use PrePrepareMessage.ProtoReflect.Descriptor instead. func (*PrePrepareMessage) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{2} + return file_messages_proto_messages_proto_rawDescGZIP(), []int{2} } -func (x *PrePrepareMessage) GetProposal() []byte { +func (x *PrePrepareMessage) GetProposal() *Proposal { if x != nil { return x.Proposal } @@ -360,7 +365,7 @@ type PrepareMessage struct { func (x *PrepareMessage) Reset() { *x = PrepareMessage{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[3] + mi := &file_messages_proto_messages_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -373,7 +378,7 @@ func (x *PrepareMessage) String() string { func (*PrepareMessage) ProtoMessage() {} func (x *PrepareMessage) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[3] + mi := &file_messages_proto_messages_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -386,7 +391,7 @@ func (x *PrepareMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use PrepareMessage.ProtoReflect.Descriptor instead. func (*PrepareMessage) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{3} + return file_messages_proto_messages_proto_rawDescGZIP(), []int{3} } func (x *PrepareMessage) GetProposalHash() []byte { @@ -411,7 +416,7 @@ type CommitMessage struct { func (x *CommitMessage) Reset() { *x = CommitMessage{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[4] + mi := &file_messages_proto_messages_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -424,7 +429,7 @@ func (x *CommitMessage) String() string { func (*CommitMessage) ProtoMessage() {} func (x *CommitMessage) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[4] + mi := &file_messages_proto_messages_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -437,7 +442,7 @@ func (x *CommitMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitMessage.ProtoReflect.Descriptor instead. func (*CommitMessage) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{4} + return file_messages_proto_messages_proto_rawDescGZIP(), []int{4} } func (x *CommitMessage) GetProposalHash() []byte { @@ -460,9 +465,9 @@ type RoundChangeMessage struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // lastPreparedProposedBlock is the last block + // lastProposal is the last proposal // to reach Q(N) - 1 PREPARE messages - LastPreparedProposedBlock []byte `protobuf:"bytes,1,opt,name=lastPreparedProposedBlock,proto3" json:"lastPreparedProposedBlock,omitempty"` + LastPreparedProposal *Proposal `protobuf:"bytes,1,opt,name=lastPreparedProposal,proto3" json:"lastPreparedProposal,omitempty"` // latestPreparedCertificate is the PC that accompanies // the last proposal LatestPreparedCertificate *PreparedCertificate `protobuf:"bytes,2,opt,name=latestPreparedCertificate,proto3" json:"latestPreparedCertificate,omitempty"` @@ -471,7 +476,7 @@ type RoundChangeMessage struct { func (x *RoundChangeMessage) Reset() { *x = RoundChangeMessage{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[5] + mi := &file_messages_proto_messages_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -484,7 +489,7 @@ func (x *RoundChangeMessage) String() string { func (*RoundChangeMessage) ProtoMessage() {} func (x *RoundChangeMessage) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[5] + mi := &file_messages_proto_messages_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -497,12 +502,12 @@ func (x *RoundChangeMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use RoundChangeMessage.ProtoReflect.Descriptor instead. func (*RoundChangeMessage) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{5} + return file_messages_proto_messages_proto_rawDescGZIP(), []int{5} } -func (x *RoundChangeMessage) GetLastPreparedProposedBlock() []byte { +func (x *RoundChangeMessage) GetLastPreparedProposal() *Proposal { if x != nil { - return x.LastPreparedProposedBlock + return x.LastPreparedProposal } return nil } @@ -531,7 +536,7 @@ type PreparedCertificate struct { func (x *PreparedCertificate) Reset() { *x = PreparedCertificate{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[6] + mi := &file_messages_proto_messages_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -544,7 +549,7 @@ func (x *PreparedCertificate) String() string { func (*PreparedCertificate) ProtoMessage() {} func (x *PreparedCertificate) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[6] + mi := &file_messages_proto_messages_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -557,7 +562,7 @@ func (x *PreparedCertificate) ProtoReflect() protoreflect.Message { // Deprecated: Use PreparedCertificate.ProtoReflect.Descriptor instead. func (*PreparedCertificate) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{6} + return file_messages_proto_messages_proto_rawDescGZIP(), []int{6} } func (x *PreparedCertificate) GetProposalMessage() *Message { @@ -588,7 +593,7 @@ type RoundChangeCertificate struct { func (x *RoundChangeCertificate) Reset() { *x = RoundChangeCertificate{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[7] + mi := &file_messages_proto_messages_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -601,7 +606,7 @@ func (x *RoundChangeCertificate) String() string { func (*RoundChangeCertificate) ProtoMessage() {} func (x *RoundChangeCertificate) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[7] + mi := &file_messages_proto_messages_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -614,7 +619,7 @@ func (x *RoundChangeCertificate) ProtoReflect() protoreflect.Message { // Deprecated: Use RoundChangeCertificate.ProtoReflect.Descriptor instead. func (*RoundChangeCertificate) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{7} + return file_messages_proto_messages_proto_rawDescGZIP(), []int{7} } func (x *RoundChangeCertificate) GetRoundChangeMessages() []*Message { @@ -624,102 +629,166 @@ func (x *RoundChangeCertificate) GetRoundChangeMessages() []*Message { return nil } -var File_messages_proto protoreflect.FileDescriptor - -var file_messages_proto_rawDesc = []byte{ - 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x34, 0x0a, 0x04, 0x56, 0x69, 0x65, 0x77, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0xe9, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x19, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x05, 0x2e, 0x56, 0x69, 0x65, 0x77, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x12, 0x12, 0x0a, - 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, - 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, - 0x20, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x70, 0x72, 0x65, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x44, - 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x50, 0x72, 0x65, 0x50, - 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, - 0x0e, 0x70, 0x72, 0x65, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, - 0x33, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x44, 0x61, 0x74, 0x61, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, - 0x44, 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x61, - 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x0f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x22, 0x8e, 0x01, 0x0a, 0x11, 0x50, 0x72, 0x65, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, - 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, - 0x6f, 0x73, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, - 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, - 0x48, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x70, - 0x6f, 0x73, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x12, 0x39, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x22, 0x34, 0x0a, 0x0e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, - 0x6c, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, 0x6f, - 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x22, 0x59, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, - 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x12, 0x24, - 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x53, 0x65, 0x61, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, - 0x53, 0x65, 0x61, 0x6c, 0x22, 0xa6, 0x01, 0x0a, 0x12, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3c, 0x0a, 0x19, 0x6c, - 0x61, 0x73, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70, 0x6f, - 0x73, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x19, +// Proposal is the tuple (raw_proposal, round) +type Proposal struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // rawProposal is an original proposal like block + RawProposal []byte `protobuf:"bytes,1,opt,name=rawProposal,proto3" json:"rawProposal,omitempty"` + // round is the round for which the proposal is created + Round uint64 `protobuf:"varint,2,opt,name=round,proto3" json:"round,omitempty"` +} + +func (x *Proposal) Reset() { + *x = Proposal{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_proto_messages_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Proposal) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Proposal) ProtoMessage() {} + +func (x *Proposal) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_messages_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Proposal.ProtoReflect.Descriptor instead. +func (*Proposal) Descriptor() ([]byte, []int) { + return file_messages_proto_messages_proto_rawDescGZIP(), []int{8} +} + +func (x *Proposal) GetRawProposal() []byte { + if x != nil { + return x.RawProposal + } + return nil +} + +func (x *Proposal) GetRound() uint64 { + if x != nil { + return x.Round + } + return 0 +} + +var File_messages_proto_messages_proto protoreflect.FileDescriptor + +var file_messages_proto_messages_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x34, 0x0a, 0x04, 0x56, 0x69, 0x65, 0x77, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0xe9, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x19, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x05, 0x2e, 0x56, 0x69, 0x65, 0x77, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x12, 0x12, 0x0a, 0x04, + 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, + 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x20, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x3c, 0x0a, 0x0e, 0x70, 0x72, 0x65, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x44, 0x61, + 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x50, 0x72, 0x65, 0x50, 0x72, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0e, + 0x70, 0x72, 0x65, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x33, + 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x44, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x44, + 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x61, 0x74, + 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x0f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x22, 0x99, 0x01, 0x0a, 0x11, 0x50, 0x72, 0x65, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, + 0x73, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x50, 0x72, 0x6f, 0x70, + 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x22, + 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x48, 0x61, + 0x73, 0x68, 0x12, 0x39, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x34, 0x0a, + 0x0e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x48, + 0x61, 0x73, 0x68, 0x22, 0x59, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, + 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x70, + 0x6f, 0x73, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x74, 0x65, 0x64, 0x53, 0x65, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x53, 0x65, 0x61, 0x6c, 0x22, 0xa7, + 0x01, 0x0a, 0x12, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x65, + 0x70, 0x61, 0x72, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x52, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x70, - 0x6f, 0x73, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x52, 0x0a, 0x19, 0x6c, 0x61, 0x74, - 0x65, 0x73, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x50, - 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x52, 0x19, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, - 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x7d, 0x0a, - 0x13, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, - 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x32, 0x0a, 0x0f, 0x70, 0x72, 0x65, 0x70, - 0x61, 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x08, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x70, 0x72, 0x65, - 0x70, 0x61, 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x54, 0x0a, 0x16, - 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x13, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x13, 0x72, - 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x2a, 0x48, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x45, 0x50, 0x52, 0x45, 0x50, 0x41, 0x52, 0x45, 0x10, - 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x45, 0x50, 0x41, 0x52, 0x45, 0x10, 0x01, 0x12, 0x0a, - 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x4f, - 0x55, 0x4e, 0x44, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x03, 0x42, 0x11, 0x5a, 0x0f, - 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x52, 0x0a, 0x19, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x50, 0x72, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, + 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x19, 0x6c, + 0x61, 0x74, 0x65, 0x73, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x7d, 0x0a, 0x13, 0x50, 0x72, 0x65, 0x70, + 0x61, 0x72, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, + 0x32, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x32, 0x0a, 0x0f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x54, 0x0a, 0x16, 0x52, 0x6f, 0x75, 0x6e, 0x64, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x12, 0x3a, 0x0a, 0x13, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, + 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x13, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x42, 0x0a, + 0x08, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x61, 0x77, + 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, + 0x72, 0x61, 0x77, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2a, 0x48, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x45, 0x50, 0x52, 0x45, 0x50, 0x41, 0x52, 0x45, 0x10, 0x00, + 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x45, 0x50, 0x41, 0x52, 0x45, 0x10, 0x01, 0x12, 0x0a, 0x0a, + 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x4f, 0x55, + 0x4e, 0x44, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x03, 0x42, 0x11, 0x5a, 0x0f, 0x2f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_messages_proto_rawDescOnce sync.Once - file_messages_proto_rawDescData = file_messages_proto_rawDesc + file_messages_proto_messages_proto_rawDescOnce sync.Once + file_messages_proto_messages_proto_rawDescData = file_messages_proto_messages_proto_rawDesc ) -func file_messages_proto_rawDescGZIP() []byte { - file_messages_proto_rawDescOnce.Do(func() { - file_messages_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_proto_rawDescData) +func file_messages_proto_messages_proto_rawDescGZIP() []byte { + file_messages_proto_messages_proto_rawDescOnce.Do(func() { + file_messages_proto_messages_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_proto_messages_proto_rawDescData) }) - return file_messages_proto_rawDescData + return file_messages_proto_messages_proto_rawDescData } -var file_messages_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_messages_proto_goTypes = []interface{}{ +var file_messages_proto_messages_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_messages_proto_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_messages_proto_messages_proto_goTypes = []interface{}{ (MessageType)(0), // 0: MessageType (*View)(nil), // 1: View (*Message)(nil), // 2: Message @@ -729,33 +798,36 @@ var file_messages_proto_goTypes = []interface{}{ (*RoundChangeMessage)(nil), // 6: RoundChangeMessage (*PreparedCertificate)(nil), // 7: PreparedCertificate (*RoundChangeCertificate)(nil), // 8: RoundChangeCertificate + (*Proposal)(nil), // 9: Proposal } -var file_messages_proto_depIdxs = []int32{ +var file_messages_proto_messages_proto_depIdxs = []int32{ 1, // 0: Message.view:type_name -> View 0, // 1: Message.type:type_name -> MessageType 3, // 2: Message.preprepareData:type_name -> PrePrepareMessage 4, // 3: Message.prepareData:type_name -> PrepareMessage 5, // 4: Message.commitData:type_name -> CommitMessage 6, // 5: Message.roundChangeData:type_name -> RoundChangeMessage - 8, // 6: PrePrepareMessage.certificate:type_name -> RoundChangeCertificate - 7, // 7: RoundChangeMessage.latestPreparedCertificate:type_name -> PreparedCertificate - 2, // 8: PreparedCertificate.proposalMessage:type_name -> Message - 2, // 9: PreparedCertificate.prepareMessages:type_name -> Message - 2, // 10: RoundChangeCertificate.roundChangeMessages:type_name -> Message - 11, // [11:11] is the sub-list for method output_type - 11, // [11:11] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name -} - -func init() { file_messages_proto_init() } -func file_messages_proto_init() { - if File_messages_proto != nil { + 9, // 6: PrePrepareMessage.proposal:type_name -> Proposal + 8, // 7: PrePrepareMessage.certificate:type_name -> RoundChangeCertificate + 9, // 8: RoundChangeMessage.lastPreparedProposal:type_name -> Proposal + 7, // 9: RoundChangeMessage.latestPreparedCertificate:type_name -> PreparedCertificate + 2, // 10: PreparedCertificate.proposalMessage:type_name -> Message + 2, // 11: PreparedCertificate.prepareMessages:type_name -> Message + 2, // 12: RoundChangeCertificate.roundChangeMessages:type_name -> Message + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name +} + +func init() { file_messages_proto_messages_proto_init() } +func file_messages_proto_messages_proto_init() { + if File_messages_proto_messages_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_messages_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_messages_proto_messages_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*View); i { case 0: return &v.state @@ -767,7 +839,7 @@ func file_messages_proto_init() { return nil } } - file_messages_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_messages_proto_messages_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Message); i { case 0: return &v.state @@ -779,7 +851,7 @@ func file_messages_proto_init() { return nil } } - file_messages_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_messages_proto_messages_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PrePrepareMessage); i { case 0: return &v.state @@ -791,7 +863,7 @@ func file_messages_proto_init() { return nil } } - file_messages_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_messages_proto_messages_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PrepareMessage); i { case 0: return &v.state @@ -803,7 +875,7 @@ func file_messages_proto_init() { return nil } } - file_messages_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_messages_proto_messages_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CommitMessage); i { case 0: return &v.state @@ -815,7 +887,7 @@ func file_messages_proto_init() { return nil } } - file_messages_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_messages_proto_messages_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RoundChangeMessage); i { case 0: return &v.state @@ -827,7 +899,7 @@ func file_messages_proto_init() { return nil } } - file_messages_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_messages_proto_messages_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PreparedCertificate); i { case 0: return &v.state @@ -839,7 +911,7 @@ func file_messages_proto_init() { return nil } } - file_messages_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_messages_proto_messages_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RoundChangeCertificate); i { case 0: return &v.state @@ -851,8 +923,20 @@ func file_messages_proto_init() { return nil } } + file_messages_proto_messages_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Proposal); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } - file_messages_proto_msgTypes[1].OneofWrappers = []interface{}{ + file_messages_proto_messages_proto_msgTypes[1].OneofWrappers = []interface{}{ (*Message_PreprepareData)(nil), (*Message_PrepareData)(nil), (*Message_CommitData)(nil), @@ -862,19 +946,19 @@ func file_messages_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_messages_proto_rawDesc, + RawDescriptor: file_messages_proto_messages_proto_rawDesc, NumEnums: 1, - NumMessages: 8, + NumMessages: 9, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_messages_proto_goTypes, - DependencyIndexes: file_messages_proto_depIdxs, - EnumInfos: file_messages_proto_enumTypes, - MessageInfos: file_messages_proto_msgTypes, + GoTypes: file_messages_proto_messages_proto_goTypes, + DependencyIndexes: file_messages_proto_messages_proto_depIdxs, + EnumInfos: file_messages_proto_messages_proto_enumTypes, + MessageInfos: file_messages_proto_messages_proto_msgTypes, }.Build() - File_messages_proto = out.File - file_messages_proto_rawDesc = nil - file_messages_proto_goTypes = nil - file_messages_proto_depIdxs = nil + File_messages_proto_messages_proto = out.File + file_messages_proto_messages_proto_rawDesc = nil + file_messages_proto_messages_proto_goTypes = nil + file_messages_proto_messages_proto_depIdxs = nil } diff --git a/messages/proto/messages.proto b/messages/proto/messages.proto index 21ac854..3115c9d 100644 --- a/messages/proto/messages.proto +++ b/messages/proto/messages.proto @@ -46,7 +46,7 @@ message Message { // PrePrepareMessage is the message for the PREPREPARE phase message PrePrepareMessage { // proposal is the actual data being proposed for consensus - bytes proposal = 1; + Proposal proposal = 1; // proposalHash is the Keccak hash of the proposal bytes proposalHash = 2; @@ -73,9 +73,9 @@ message CommitMessage { // RoundChangeMessage is the message for the ROUND CHANGE phase message RoundChangeMessage { - // lastPreparedProposedBlock is the last block + // lastProposal is the last proposal // to reach Q(N) - 1 PREPARE messages - bytes lastPreparedProposedBlock = 1; + Proposal lastPreparedProposal = 1; // latestPreparedCertificate is the PC that accompanies // the last proposal @@ -98,4 +98,13 @@ message PreparedCertificate { message RoundChangeCertificate { // roundChangeMessages are the ROUND CHANGE messages repeated Message roundChangeMessages = 1; -} \ No newline at end of file +} + +// Proposal is the tuple (raw_proposal, round) +message Proposal { + // rawProposal is an original proposal like block + bytes rawProposal = 1; + + // round is the round for which the proposal is created + uint64 round = 2; +}