From d9c1b950c28d045cc77f6aa01359626def20b12d Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Wed, 6 Mar 2024 14:49:47 +0300 Subject: [PATCH] internal: split simulation from consensus service implementation All dBFT payloads implementations should be kept in the same package or have exported fields. It's inevitable since dBFT user have to refer to payload fields via converting dBFT interfaces to user-defined local structures. dBFT test (`dbft_test` package) imports custom payloads implementations from `internal`. Since all payloads will be moved to the same package, we need to split this package from `main` package of simulation. A consequence of #84. Signed-off-by: Anna Shaleva --- internal/consensus/consensus.go | 61 +++++++++++++++++++++++++++++++++ internal/simulation/main.go | 49 +++++--------------------- 2 files changed, 70 insertions(+), 40 deletions(-) create mode 100644 internal/consensus/consensus.go diff --git a/internal/consensus/consensus.go b/internal/consensus/consensus.go new file mode 100644 index 00000000..f493d683 --- /dev/null +++ b/internal/consensus/consensus.go @@ -0,0 +1,61 @@ +package consensus + +import ( + "time" + + "github.com/nspcc-dev/dbft" + "github.com/nspcc-dev/dbft/internal/block" + "github.com/nspcc-dev/dbft/internal/crypto" + "github.com/nspcc-dev/dbft/internal/payload" + "go.uber.org/zap" +) + +func New(logger *zap.Logger, key dbft.PrivateKey, pub dbft.PublicKey, + getTx func(uint256 crypto.Uint256) dbft.Transaction[crypto.Uint256], + getVerified func() []dbft.Transaction[crypto.Uint256], + broadcast func(dbft.ConsensusPayload[crypto.Uint256, crypto.Uint160]), + processBlock func(dbft.Block[crypto.Uint256, crypto.Uint160]), + currentHeight func() uint32, + currentBlockHash func() crypto.Uint256, + getValidators func(...dbft.Transaction[crypto.Uint256]) []dbft.PublicKey, + verifyPayload func(consensusPayload dbft.ConsensusPayload[crypto.Uint256, crypto.Uint160]) error) *dbft.DBFT[crypto.Uint256, crypto.Uint160] { + return dbft.New[crypto.Uint256, crypto.Uint160]( + dbft.WithLogger[crypto.Uint256, crypto.Uint160](logger), + dbft.WithSecondsPerBlock[crypto.Uint256, crypto.Uint160](time.Second*5), + dbft.WithKeyPair[crypto.Uint256, crypto.Uint160](key, pub), + dbft.WithGetTx[crypto.Uint256, crypto.Uint160](getTx), + dbft.WithGetVerified[crypto.Uint256, crypto.Uint160](getVerified), + dbft.WithBroadcast[crypto.Uint256, crypto.Uint160](broadcast), + dbft.WithProcessBlock[crypto.Uint256, crypto.Uint160](processBlock), + dbft.WithCurrentHeight[crypto.Uint256, crypto.Uint160](currentHeight), + dbft.WithCurrentBlockHash[crypto.Uint256, crypto.Uint160](currentBlockHash), + dbft.WithGetValidators[crypto.Uint256, crypto.Uint160](getValidators), + dbft.WithVerifyPrepareRequest[crypto.Uint256, crypto.Uint160](verifyPayload), + dbft.WithVerifyPrepareResponse[crypto.Uint256, crypto.Uint160](verifyPayload), + + dbft.WithNewBlockFromContext[crypto.Uint256, crypto.Uint160](newBlockFromContext), + dbft.WithNewConsensusPayload[crypto.Uint256, crypto.Uint160](defaultNewConsensusPayload), + dbft.WithNewPrepareRequest[crypto.Uint256, crypto.Uint160](payload.NewPrepareRequest), + dbft.WithNewPrepareResponse[crypto.Uint256, crypto.Uint160](payload.NewPrepareResponse), + dbft.WithNewChangeView[crypto.Uint256, crypto.Uint160](payload.NewChangeView), + dbft.WithNewCommit[crypto.Uint256, crypto.Uint160](payload.NewCommit), + dbft.WithNewRecoveryMessage[crypto.Uint256, crypto.Uint160](func() dbft.RecoveryMessage[crypto.Uint256, crypto.Uint160] { + return payload.NewRecoveryMessage(nil) + }), + dbft.WithNewRecoveryRequest[crypto.Uint256, crypto.Uint160](payload.NewRecoveryRequest), + ) +} + +func newBlockFromContext(ctx *dbft.Context[crypto.Uint256, crypto.Uint160]) dbft.Block[crypto.Uint256, crypto.Uint160] { + if ctx.TransactionHashes == nil { + return nil + } + block := block.NewBlock(ctx.Timestamp, ctx.BlockIndex, ctx.PrevHash, ctx.Nonce, ctx.TransactionHashes) + return block +} + +// defaultNewConsensusPayload is default function for creating +// consensus payload of specific type. +func defaultNewConsensusPayload(c *dbft.Context[crypto.Uint256, crypto.Uint160], t dbft.MessageType, msg any) dbft.ConsensusPayload[crypto.Uint256, crypto.Uint160] { + return payload.NewConsensusPayload(t, c.BlockIndex, uint16(c.MyIndex), c.ViewNumber, msg) +} diff --git a/internal/simulation/main.go b/internal/simulation/main.go index 2f700387..85ba0037 100644 --- a/internal/simulation/main.go +++ b/internal/simulation/main.go @@ -17,9 +17,8 @@ import ( "time" "github.com/nspcc-dev/dbft" - "github.com/nspcc-dev/dbft/internal/block" + "github.com/nspcc-dev/dbft/internal/consensus" "github.com/nspcc-dev/dbft/internal/crypto" - "github.com/nspcc-dev/dbft/internal/payload" "github.com/twmb/murmur3" "go.uber.org/zap" ) @@ -110,20 +109,6 @@ func initNodes(nodes []*simNode, log *zap.Logger) { } } -func newBlockFromContext(ctx *dbft.Context[crypto.Uint256, crypto.Uint160]) dbft.Block[crypto.Uint256, crypto.Uint160] { - if ctx.TransactionHashes == nil { - return nil - } - block := block.NewBlock(ctx.Timestamp, ctx.BlockIndex, ctx.PrevHash, ctx.Nonce, ctx.TransactionHashes) - return block -} - -// defaultNewConsensusPayload is default function for creating -// consensus payload of specific type. -func defaultNewConsensusPayload(c *dbft.Context[crypto.Uint256, crypto.Uint160], t dbft.MessageType, msg any) dbft.ConsensusPayload[crypto.Uint256, crypto.Uint160] { - return payload.NewConsensusPayload(t, c.BlockIndex, uint16(c.MyIndex), c.ViewNumber, msg) -} - func initSimNode(nodes []*simNode, i int, log *zap.Logger) error { key, pub := crypto.Generate(rand.Reader) nodes[i] = &simNode{ @@ -136,30 +121,14 @@ func initSimNode(nodes []*simNode, i int, log *zap.Logger) error { cluster: nodes, } - nodes[i].d = dbft.New[crypto.Uint256, crypto.Uint160]( - dbft.WithLogger[crypto.Uint256, crypto.Uint160](nodes[i].log), - dbft.WithSecondsPerBlock[crypto.Uint256, crypto.Uint160](time.Second*5), - dbft.WithKeyPair[crypto.Uint256, crypto.Uint160](key, pub), - dbft.WithGetTx[crypto.Uint256, crypto.Uint160](nodes[i].pool.Get), - dbft.WithGetVerified[crypto.Uint256, crypto.Uint160](nodes[i].pool.GetVerified), - dbft.WithBroadcast[crypto.Uint256, crypto.Uint160](nodes[i].Broadcast), - dbft.WithProcessBlock[crypto.Uint256, crypto.Uint160](nodes[i].ProcessBlock), - dbft.WithCurrentHeight[crypto.Uint256, crypto.Uint160](nodes[i].CurrentHeight), - dbft.WithCurrentBlockHash[crypto.Uint256, crypto.Uint160](nodes[i].CurrentBlockHash), - dbft.WithGetValidators[crypto.Uint256, crypto.Uint160](nodes[i].GetValidators), - dbft.WithVerifyPrepareRequest[crypto.Uint256, crypto.Uint160](nodes[i].VerifyPayload), - dbft.WithVerifyPrepareResponse[crypto.Uint256, crypto.Uint160](nodes[i].VerifyPayload), - - dbft.WithNewBlockFromContext[crypto.Uint256, crypto.Uint160](newBlockFromContext), - dbft.WithNewConsensusPayload[crypto.Uint256, crypto.Uint160](defaultNewConsensusPayload), - dbft.WithNewPrepareRequest[crypto.Uint256, crypto.Uint160](payload.NewPrepareRequest), - dbft.WithNewPrepareResponse[crypto.Uint256, crypto.Uint160](payload.NewPrepareResponse), - dbft.WithNewChangeView[crypto.Uint256, crypto.Uint160](payload.NewChangeView), - dbft.WithNewCommit[crypto.Uint256, crypto.Uint160](payload.NewCommit), - dbft.WithNewRecoveryMessage[crypto.Uint256, crypto.Uint160](func() dbft.RecoveryMessage[crypto.Uint256, crypto.Uint160] { - return payload.NewRecoveryMessage(nil) - }), - dbft.WithNewRecoveryRequest[crypto.Uint256, crypto.Uint160](payload.NewRecoveryRequest), + nodes[i].d = consensus.New(nodes[i].log, key, pub, nodes[i].pool.Get, + nodes[i].pool.GetVerified, + nodes[i].Broadcast, + nodes[i].ProcessBlock, + nodes[i].CurrentHeight, + nodes[i].CurrentBlockHash, + nodes[i].GetValidators, + nodes[i].VerifyPayload, ) if nodes[i].d == nil {