From 2dc51d60314d63e66bc0133040cac91173d14e31 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Wed, 6 Mar 2024 12:39:21 +0300 Subject: [PATCH] *: remove NextConsensus mentions from dBFT API NextConsensus API is not used by the users of dBFT. NextConsensus handling (proposal, verification and agrreement) is moved to the upper level of dBFT users. Starting from this commit NextConsensus verification should be performed by dBFT user manually in WithVerifyPrepareRequest callback. A part of #84. Signed-off-by: Anna Shaleva --- block.go | 2 -- config.go | 15 ++------------- consensus_message.go | 2 +- context.go | 5 ----- dbft.go | 6 ------ dbft_test.go | 18 +++--------------- helpers_test.go | 2 +- internal/block/block.go | 9 +-------- internal/block/block_test.go | 3 --- internal/payload/consensus_message.go | 4 ++-- internal/payload/constructors.go | 3 +-- internal/payload/prepare_request.go | 11 +---------- internal/payload/recovery_message.go | 3 +-- internal/simulation/main.go | 3 +-- prepare_request.go | 5 +---- send.go | 2 +- 16 files changed, 16 insertions(+), 77 deletions(-) diff --git a/block.go b/block.go index c849fc89..617303f9 100644 --- a/block.go +++ b/block.go @@ -16,8 +16,6 @@ type Block[H Hash, A Address] interface { Index() uint32 // ConsensusData is a random nonce. ConsensusData() uint64 - // NextConsensus returns hash of the validators of the next block. - NextConsensus() A // Signature returns block's signature. Signature() []byte diff --git a/config.go b/config.go index d0b3f316..cb9cdf79 100644 --- a/config.go +++ b/config.go @@ -57,12 +57,10 @@ type Config[H Hash, A Address] struct { // list of the validators of the next block. // If this function ever returns 0-length slice, dbft will panic. GetValidators func(...Transaction[H]) []PublicKey - // GetConsensusAddress returns hash of the validator list. - GetConsensusAddress func(...PublicKey) A // NewConsensusPayload is a constructor for payload.ConsensusPayload. NewConsensusPayload func(*Context[H, A], MessageType, any) ConsensusPayload[H, A] // NewPrepareRequest is a constructor for payload.PrepareRequest. - NewPrepareRequest func(ts uint64, nonce uint64, nextConsensus A, transactionHashes []H) PrepareRequest[H, A] + NewPrepareRequest func(ts uint64, nonce uint64, transactionHashes []H) PrepareRequest[H] // NewPrepareResponse is a constructor for payload.PrepareResponse. NewPrepareResponse func(preparationHash H) PrepareResponse[H] // NewChangeView is a constructor for payload.ChangeView. @@ -120,8 +118,6 @@ func checkConfig[H Hash, A Address](cfg *Config[H, A]) error { return errors.New("GetValidators is nil") } else if cfg.NewBlockFromContext == nil { return errors.New("NewBlockFromContext is nil") - } else if cfg.GetConsensusAddress == nil { - return errors.New("GetConsensusAddress is nil") } else if cfg.NewConsensusPayload == nil { return errors.New("NewConsensusPayload is nil") } else if cfg.NewPrepareRequest == nil { @@ -291,13 +287,6 @@ func WithGetValidators[H Hash, A Address](f func(...Transaction[H]) []PublicKey) } } -// WithGetConsensusAddress sets GetConsensusAddress. -func WithGetConsensusAddress[H Hash, A Address](f func(keys ...PublicKey) A) func(config *Config[H, A]) { - return func(cfg *Config[H, A]) { - cfg.GetConsensusAddress = f - } -} - // WithNewConsensusPayload sets NewConsensusPayload. func WithNewConsensusPayload[H Hash, A Address](f func(*Context[H, A], MessageType, any) ConsensusPayload[H, A]) func(config *Config[H, A]) { return func(cfg *Config[H, A]) { @@ -306,7 +295,7 @@ func WithNewConsensusPayload[H Hash, A Address](f func(*Context[H, A], MessageTy } // WithNewPrepareRequest sets NewPrepareRequest. -func WithNewPrepareRequest[H Hash, A Address](f func(ts uint64, nonce uint64, nextConsensus A, transactionsHashes []H) PrepareRequest[H, A]) func(config *Config[H, A]) { +func WithNewPrepareRequest[H Hash, A Address](f func(ts uint64, nonce uint64, transactionsHashes []H) PrepareRequest[H]) func(config *Config[H, A]) { return func(cfg *Config[H, A]) { cfg.NewPrepareRequest = f } diff --git a/consensus_message.go b/consensus_message.go index 7e72029f..5d435a5b 100644 --- a/consensus_message.go +++ b/consensus_message.go @@ -12,7 +12,7 @@ type ConsensusMessage[H Hash, A Address] interface { // GetChangeView returns payload as if it was ChangeView. GetChangeView() ChangeView // GetPrepareRequest returns payload as if it was PrepareRequest. - GetPrepareRequest() PrepareRequest[H, A] + GetPrepareRequest() PrepareRequest[H] // GetPrepareResponse returns payload as if it was PrepareResponse. GetPrepareResponse() PrepareResponse[H] // GetCommit returns payload as if it was Commit. diff --git a/context.go b/context.go index a6725649..1c1c5d52 100644 --- a/context.go +++ b/context.go @@ -40,8 +40,6 @@ type Context[H Hash, A Address] struct { PrimaryIndex uint Version uint32 - // NextConsensus is a hash of the validators which will be accepting the next block. - NextConsensus A // PrevHash is a hash of the previous block. PrevHash H @@ -261,9 +259,6 @@ func (c *Context[H, A]) Fill() { c.Transactions[h] = txx[i] } - validators := c.Config.GetValidators(txx...) - c.NextConsensus = c.Config.GetConsensusAddress(validators...) - c.Timestamp = c.lastBlockTimestamp + c.Config.TimestampIncrement if now := c.getTimestamp(); now > c.Timestamp { c.Timestamp = now diff --git a/dbft.go b/dbft.go index 2fec0cd8..c4e5cb8a 100644 --- a/dbft.go +++ b/dbft.go @@ -327,7 +327,6 @@ func (d *DBFT[H, A]) onPrepareRequest(msg ConsensusPayload[H, A]) { d.Timestamp = p.Timestamp() d.Nonce = p.Nonce() - d.NextConsensus = p.NextConsensus() d.TransactionHashes = p.TransactionHashes() d.Logger.Info("received PrepareRequest", zap.Uint16("validator", msg.ValidatorIndex()), zap.Int("tx", len(d.TransactionHashes))) @@ -374,11 +373,6 @@ func (d *DBFT[H, A]) createAndCheckBlock() bool { for _, h := range d.TransactionHashes { txx = append(txx, d.Transactions[h]) } - if d.NextConsensus != d.GetConsensusAddress(d.GetValidators(txx...)...) { - d.Logger.Error("invalid nextConsensus in proposed block") - d.sendChangeView(CVBlockRejectedByPolicy) - return false - } if b := d.Context.CreateBlock(); !d.VerifyBlock(b) { d.Logger.Warn("proposed block fails verification") d.sendChangeView(CVTxInvalid) diff --git a/dbft_test.go b/dbft_test.go index abd7a056..923a5d6d 100644 --- a/dbft_test.go +++ b/dbft_test.go @@ -443,13 +443,6 @@ func TestDBFT_Invalid(t *testing.T) { opts = append(opts, dbft.WithNewBlockFromContext[crypto.Uint256, crypto.Uint160](func(_ *dbft.Context[crypto.Uint256, crypto.Uint160]) dbft.Block[crypto.Uint256, crypto.Uint160] { return nil })) - t.Run("without GetConsensusAddress", func(t *testing.T) { - require.Nil(t, dbft.New(opts...)) - }) - - opts = append(opts, dbft.WithGetConsensusAddress[crypto.Uint256, crypto.Uint160](func(_ ...dbft.PublicKey) crypto.Uint160 { - return crypto.Uint160{} - })) t.Run("without NewConsensusPayload", func(t *testing.T) { require.Nil(t, dbft.New(opts...)) }) @@ -461,7 +454,7 @@ func TestDBFT_Invalid(t *testing.T) { require.Nil(t, dbft.New(opts...)) }) - opts = append(opts, dbft.WithNewPrepareRequest[crypto.Uint256, crypto.Uint160](func(uint64, uint64, crypto.Uint160, []crypto.Uint256) dbft.PrepareRequest[crypto.Uint256, crypto.Uint160] { + opts = append(opts, dbft.WithNewPrepareRequest[crypto.Uint256, crypto.Uint160](func(uint64, uint64, []crypto.Uint256) dbft.PrepareRequest[crypto.Uint256] { return nil })) t.Run("without NewPrepareResponse", func(t *testing.T) { @@ -760,7 +753,7 @@ func (s testState) getPrepareRequest(from uint16, hashes ...crypto.Uint256) Payl } func (s testState) getPrepareRequestWithHeight(from uint16, height uint32, hashes ...crypto.Uint256) Payload { - req := payload.NewPrepareRequest(0, 0, s.nextConsensus(), hashes) + req := payload.NewPrepareRequest(0, 0, hashes) p := payload.NewConsensusPayload(dbft.PrepareRequestType, height, from, 0, req) return p @@ -812,10 +805,6 @@ func (s testState) copyWithIndex(myIndex int) *testState { } } -func (s testState) nextConsensus(...dbft.PublicKey) crypto.Uint160 { - return crypto.Uint160{1} -} - func (s *testState) getOptions() []func(*dbft.Config[crypto.Uint256, crypto.Uint160]) { opts := []func(*dbft.Config[crypto.Uint256, crypto.Uint160]){ dbft.WithCurrentHeight[crypto.Uint256, crypto.Uint160](func() uint32 { return s.currHeight }), @@ -825,7 +814,6 @@ func (s *testState) getOptions() []func(*dbft.Config[crypto.Uint256, crypto.Uint dbft.WithBroadcast[crypto.Uint256, crypto.Uint160](func(p Payload) { s.ch = append(s.ch, p) }), dbft.WithGetTx[crypto.Uint256, crypto.Uint160](s.pool.Get), dbft.WithProcessBlock[crypto.Uint256, crypto.Uint160](func(b dbft.Block[crypto.Uint256, crypto.Uint160]) { s.blocks = append(s.blocks, b) }), - dbft.WithGetConsensusAddress[crypto.Uint256, crypto.Uint160](s.nextConsensus), dbft.WithWatchOnly[crypto.Uint256, crypto.Uint160](func() bool { return false }), dbft.WithGetBlock[crypto.Uint256, crypto.Uint160](func(crypto.Uint256) dbft.Block[crypto.Uint256, crypto.Uint160] { return nil }), dbft.WithTimer[crypto.Uint256, crypto.Uint160](timer.New()), @@ -867,7 +855,7 @@ func newBlockFromContext(ctx *dbft.Context[crypto.Uint256, crypto.Uint160]) dbft if ctx.TransactionHashes == nil { return nil } - block := block.NewBlock(ctx.Timestamp, ctx.BlockIndex, ctx.NextConsensus, ctx.PrevHash, ctx.Version, ctx.Nonce, ctx.TransactionHashes) + block := block.NewBlock(ctx.Timestamp, ctx.BlockIndex, ctx.PrevHash, ctx.Version, ctx.Nonce, ctx.TransactionHashes) return block } diff --git a/helpers_test.go b/helpers_test.go index a24f86db..12d09243 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -47,7 +47,7 @@ func (p payloadStub) SetPayload(any) { func (p payloadStub) GetChangeView() ChangeView { panic("TODO") } -func (p payloadStub) GetPrepareRequest() PrepareRequest[hash, address] { +func (p payloadStub) GetPrepareRequest() PrepareRequest[hash] { panic("TODO") } func (p payloadStub) GetPrepareResponse() PrepareResponse[hash] { diff --git a/internal/block/block.go b/internal/block/block.go index 19940e7d..91dfcd0b 100644 --- a/internal/block/block.go +++ b/internal/block/block.go @@ -19,7 +19,6 @@ type ( Version uint32 MerkleRoot crypto.Uint256 PrevHash crypto.Uint256 - NextConsensus crypto.Uint160 } neoBlock struct { @@ -52,11 +51,6 @@ func (b *neoBlock) Index() uint32 { return b.base.Index } -// NextConsensus implements Block interface. -func (b *neoBlock) NextConsensus() crypto.Uint160 { - return b.base.NextConsensus -} - // MerkleRoot implements Block interface. func (b *neoBlock) MerkleRoot() crypto.Uint256 { return b.base.MerkleRoot @@ -78,11 +72,10 @@ func (b *neoBlock) SetTransactions(txx []dbft.Transaction[crypto.Uint256]) { } // NewBlock returns new block. -func NewBlock(timestamp uint64, index uint32, nextConsensus crypto.Uint160, prevHash crypto.Uint256, version uint32, nonce uint64, txHashes []crypto.Uint256) dbft.Block[crypto.Uint256, crypto.Uint160] { +func NewBlock(timestamp uint64, index uint32, prevHash crypto.Uint256, version uint32, nonce uint64, txHashes []crypto.Uint256) dbft.Block[crypto.Uint256, crypto.Uint160] { block := new(neoBlock) block.base.Timestamp = uint32(timestamp / 1000000000) block.base.Index = index - block.base.NextConsensus = nextConsensus block.base.PrevHash = prevHash block.base.Version = version block.base.ConsensusData = nonce diff --git a/internal/block/block_test.go b/internal/block/block_test.go index 25e27e86..96f98035 100644 --- a/internal/block/block_test.go +++ b/internal/block/block_test.go @@ -29,9 +29,6 @@ func TestNeoBlock_Setters(t *testing.T) { b.base.Version = 42 assert.EqualValues(t, 42, b.Version()) - b.base.NextConsensus = crypto.Uint160{1} - assert.Equal(t, crypto.Uint160{1}, b.NextConsensus()) - b.base.PrevHash = crypto.Uint256{3, 7} assert.Equal(t, crypto.Uint256{3, 7}, b.PrevHash()) diff --git a/internal/payload/consensus_message.go b/internal/payload/consensus_message.go index dd0e2436..8b43208c 100644 --- a/internal/payload/consensus_message.go +++ b/internal/payload/consensus_message.go @@ -81,8 +81,8 @@ func (m *message) DecodeBinary(r *gob.Decoder) error { } func (m message) GetChangeView() dbft.ChangeView { return m.payload.(dbft.ChangeView) } -func (m message) GetPrepareRequest() dbft.PrepareRequest[crypto.Uint256, crypto.Uint160] { - return m.payload.(dbft.PrepareRequest[crypto.Uint256, crypto.Uint160]) +func (m message) GetPrepareRequest() dbft.PrepareRequest[crypto.Uint256] { + return m.payload.(dbft.PrepareRequest[crypto.Uint256]) } func (m message) GetPrepareResponse() dbft.PrepareResponse[crypto.Uint256] { return m.payload.(dbft.PrepareResponse[crypto.Uint256]) diff --git a/internal/payload/constructors.go b/internal/payload/constructors.go index 68f19fe7..08019254 100644 --- a/internal/payload/constructors.go +++ b/internal/payload/constructors.go @@ -19,12 +19,11 @@ func NewConsensusPayload(t dbft.MessageType, height uint32, validatorIndex uint1 } // NewPrepareRequest returns minimal prepareRequest implementation. -func NewPrepareRequest(ts uint64, nonce uint64, nextConsensus crypto.Uint160, transactionsHashes []crypto.Uint256) dbft.PrepareRequest[crypto.Uint256, crypto.Uint160] { +func NewPrepareRequest(ts uint64, nonce uint64, transactionsHashes []crypto.Uint256) dbft.PrepareRequest[crypto.Uint256] { return &prepareRequest{ transactionHashes: transactionsHashes, nonce: nonce, timestamp: nanoSecToSec(ts), - nextConsensus: nextConsensus, } } diff --git a/internal/payload/prepare_request.go b/internal/payload/prepare_request.go index 1fffb097..2c67f670 100644 --- a/internal/payload/prepare_request.go +++ b/internal/payload/prepare_request.go @@ -12,18 +12,16 @@ type ( transactionHashes []crypto.Uint256 nonce uint64 timestamp uint32 - nextConsensus crypto.Uint160 } // prepareRequestAux is an auxiliary structure for prepareRequest encoding. prepareRequestAux struct { TransactionHashes []crypto.Uint256 Nonce uint64 Timestamp uint32 - NextConsensus crypto.Uint160 } ) -var _ dbft.PrepareRequest[crypto.Uint256, crypto.Uint160] = (*prepareRequest)(nil) +var _ dbft.PrepareRequest[crypto.Uint256] = (*prepareRequest)(nil) // EncodeBinary implements Serializable interface. func (p prepareRequest) EncodeBinary(w *gob.Encoder) error { @@ -31,7 +29,6 @@ func (p prepareRequest) EncodeBinary(w *gob.Encoder) error { TransactionHashes: p.transactionHashes, Nonce: p.nonce, Timestamp: p.timestamp, - NextConsensus: p.nextConsensus, }) } @@ -44,7 +41,6 @@ func (p *prepareRequest) DecodeBinary(r *gob.Decoder) error { p.timestamp = aux.Timestamp p.nonce = aux.Nonce - p.nextConsensus = aux.NextConsensus p.transactionHashes = aux.TransactionHashes return nil } @@ -63,8 +59,3 @@ func (p prepareRequest) Nonce() uint64 { func (p prepareRequest) TransactionHashes() []crypto.Uint256 { return p.transactionHashes } - -// NextConsensus implements PrepareRequest interface. -func (p prepareRequest) NextConsensus() crypto.Uint160 { - return p.nextConsensus -} diff --git a/internal/payload/recovery_message.go b/internal/payload/recovery_message.go index f98647f3..776e3c23 100644 --- a/internal/payload/recovery_message.go +++ b/internal/payload/recovery_message.go @@ -14,7 +14,7 @@ type ( preparationPayloads []preparationCompact commitPayloads []commitCompact changeViewPayloads []changeViewCompact - prepareRequest dbft.PrepareRequest[crypto.Uint256, crypto.Uint160] + prepareRequest dbft.PrepareRequest[crypto.Uint256] } // recoveryMessageAux is an auxiliary structure for recoveryMessage encoding. recoveryMessageAux struct { @@ -80,7 +80,6 @@ func (m *recoveryMessage) GetPrepareRequest(p dbft.ConsensusPayload[crypto.Uint2 timestamp: nanoSecToSec(m.prepareRequest.Timestamp()), nonce: m.prepareRequest.Nonce(), transactionHashes: m.prepareRequest.TransactionHashes(), - nextConsensus: m.prepareRequest.NextConsensus(), }) req.SetValidatorIndex(ind) diff --git a/internal/simulation/main.go b/internal/simulation/main.go index 8cc655db..00e4d282 100644 --- a/internal/simulation/main.go +++ b/internal/simulation/main.go @@ -114,7 +114,7 @@ func newBlockFromContext(ctx *dbft.Context[crypto.Uint256, crypto.Uint160]) dbft if ctx.TransactionHashes == nil { return nil } - block := block.NewBlock(ctx.Timestamp, ctx.BlockIndex, ctx.NextConsensus, ctx.PrevHash, ctx.Version, ctx.Nonce, ctx.TransactionHashes) + block := block.NewBlock(ctx.Timestamp, ctx.BlockIndex, ctx.PrevHash, ctx.Version, ctx.Nonce, ctx.TransactionHashes) return block } @@ -151,7 +151,6 @@ func initSimNode(nodes []*simNode, i int, log *zap.Logger) error { dbft.WithVerifyPrepareResponse[crypto.Uint256, crypto.Uint160](nodes[i].VerifyPayload), dbft.WithNewBlockFromContext[crypto.Uint256, crypto.Uint160](newBlockFromContext), - dbft.WithGetConsensusAddress[crypto.Uint256, crypto.Uint160](func(...dbft.PublicKey) crypto.Uint160 { return crypto.Uint160{} }), dbft.WithNewConsensusPayload[crypto.Uint256, crypto.Uint160](defaultNewConsensusPayload), dbft.WithNewPrepareRequest[crypto.Uint256, crypto.Uint160](payload.NewPrepareRequest), dbft.WithNewPrepareResponse[crypto.Uint256, crypto.Uint160](payload.NewPrepareResponse), diff --git a/prepare_request.go b/prepare_request.go index c27a2318..3ba594c9 100644 --- a/prepare_request.go +++ b/prepare_request.go @@ -1,14 +1,11 @@ package dbft // PrepareRequest represents dBFT PrepareRequest message. -type PrepareRequest[H Hash, A Address] interface { +type PrepareRequest[H Hash] interface { // Timestamp returns this message's timestamp. Timestamp() uint64 // Nonce is a random nonce. Nonce() uint64 // TransactionHashes returns hashes of all transaction in a proposed block. TransactionHashes() []H - // NextConsensus returns hash which is based on which validators will - // try to agree on a block in the current epoch. - NextConsensus() A } diff --git a/send.go b/send.go index 4e32149a..7578dabf 100644 --- a/send.go +++ b/send.go @@ -17,7 +17,7 @@ func (d *DBFT[H, A]) broadcast(msg ConsensusPayload[H, A]) { func (c *Context[H, A]) makePrepareRequest() ConsensusPayload[H, A] { c.Fill() - req := c.Config.NewPrepareRequest(c.Timestamp, c.Nonce, c.NextConsensus, c.TransactionHashes) + req := c.Config.NewPrepareRequest(c.Timestamp, c.Nonce, c.TransactionHashes) return c.Config.NewConsensusPayload(c, PrepareRequestType, req) }