diff --git a/go.mod b/go.mod index 84f8d3782..00f218b41 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/holiman/uint256 v1.2.4 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/mr-tron/base58 v1.2.0 - github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c + github.com/nspcc-dev/dbft v0.1.1-0.20240321205542-332ff86ba4c6 github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2 github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240322141543-1840c057bdd7 github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.11 @@ -55,7 +55,6 @@ require ( github.com/nspcc-dev/neofs-api-go/v2 v2.14.0 // indirect github.com/nspcc-dev/neofs-crypto v0.4.0 // indirect github.com/nspcc-dev/tzhash v1.7.0 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect diff --git a/go.sum b/go.sum index e3f168b05..2aeac5f66 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqky github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c h1:uyK5aLbAhrnZtnvobJLN24gGUrlxIJAAFqiWl+liZuo= -github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c/go.mod h1:kjBC9F8L25GR+kIHy/1KgG/KfcoGnVwIiyovgq1uszk= +github.com/nspcc-dev/dbft v0.1.1-0.20240321205542-332ff86ba4c6 h1:6rpKY0AvXQpL2ZpLTxGDJAM54ak6ziXghi4uLGUrSdg= +github.com/nspcc-dev/dbft v0.1.1-0.20240321205542-332ff86ba4c6/go.mod h1:oFE6paSC/yfFh9mcNU6MheMGOYXK9+sPiRk3YMoz49o= github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2 h1:mD9hU3v+zJcnHAVmHnZKt3I++tvn30gBj2rP2PocZMk= github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2/go.mod h1:U5VfmPNM88P4RORFb6KSUVBdJBDhlqggJZYGXGPxOcc= github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y= @@ -119,7 +119,6 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/pkg/consensus/block.go b/pkg/consensus/block.go index e52e7ef62..989ec1109 100644 --- a/pkg/consensus/block.go +++ b/pkg/consensus/block.go @@ -3,8 +3,7 @@ package consensus import ( "errors" - "github.com/nspcc-dev/dbft/block" - "github.com/nspcc-dev/dbft/crypto" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/config/netmode" coreb "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/transaction" @@ -20,10 +19,10 @@ type neoBlock struct { signature []byte } -var _ block.Block = (*neoBlock)(nil) +var _ dbft.Block[util.Uint256] = (*neoBlock)(nil) // Sign implements the block.Block interface. -func (n *neoBlock) Sign(key crypto.PrivateKey) error { +func (n *neoBlock) Sign(key dbft.PrivateKey) error { k := key.(*privateKey) sig := k.PrivateKey.SignHashable(uint32(n.network), &n.Block) n.signature = sig @@ -31,7 +30,7 @@ func (n *neoBlock) Sign(key crypto.PrivateKey) error { } // Verify implements the block.Block interface. -func (n *neoBlock) Verify(key crypto.PublicKey, sign []byte) error { +func (n *neoBlock) Verify(key dbft.PublicKey, sign []byte) error { k := key.(*publicKey) if k.PublicKey.VerifyHashable(sign, uint32(n.network), &n.Block) { return nil @@ -40,8 +39,8 @@ func (n *neoBlock) Verify(key crypto.PublicKey, sign []byte) error { } // Transactions implements the block.Block interface. -func (n *neoBlock) Transactions() []block.Transaction { - txes := make([]block.Transaction, len(n.Block.Transactions)) +func (n *neoBlock) Transactions() []dbft.Transaction[util.Uint256] { + txes := make([]dbft.Transaction[util.Uint256], len(n.Block.Transactions)) for i, tx := range n.Block.Transactions { txes[i] = tx } @@ -50,16 +49,13 @@ func (n *neoBlock) Transactions() []block.Transaction { } // SetTransactions implements the block.Block interface. -func (n *neoBlock) SetTransactions(txes []block.Transaction) { +func (n *neoBlock) SetTransactions(txes []dbft.Transaction[util.Uint256]) { n.Block.Transactions = make([]*transaction.Transaction, len(txes)) for i, tx := range txes { n.Block.Transactions[i] = tx.(*transaction.Transaction) } } -// Version implements the block.Block interface. -func (n *neoBlock) Version() uint32 { return n.Block.Version } - // PrevHash implements the block.Block interface. func (n *neoBlock) PrevHash() util.Uint256 { return n.Block.PrevHash } @@ -72,11 +68,5 @@ func (n *neoBlock) Timestamp() uint64 { return n.Block.Timestamp * nsInMs } // Index implements the block.Block interface. func (n *neoBlock) Index() uint32 { return n.Block.Index } -// ConsensusData implements the block.Block interface. -func (n *neoBlock) ConsensusData() uint64 { return n.Block.Nonce } - -// NextConsensus implements the block.Block interface. -func (n *neoBlock) NextConsensus() util.Uint160 { return n.Block.NextConsensus } - // Signature implements the block.Block interface. func (n *neoBlock) Signature() []byte { return n.signature } diff --git a/pkg/consensus/block_test.go b/pkg/consensus/block_test.go index afa94a711..f1e206da9 100644 --- a/pkg/consensus/block_test.go +++ b/pkg/consensus/block_test.go @@ -3,7 +3,7 @@ package consensus import ( "testing" - "github.com/nspcc-dev/dbft/block" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/util" @@ -22,9 +22,6 @@ func TestNeoBlock_Sign(t *testing.T) { func TestNeoBlock_Setters(t *testing.T) { b := new(neoBlock) - b.Block.Version = 1 - require.EqualValues(t, 1, b.Version()) - b.Block.Index = 12 require.EqualValues(t, 12, b.Index()) @@ -35,13 +32,10 @@ func TestNeoBlock_Setters(t *testing.T) { b.Block.MerkleRoot = util.Uint256{1, 2, 3, 4} require.Equal(t, util.Uint256{1, 2, 3, 4}, b.MerkleRoot()) - b.Block.NextConsensus = util.Uint160{9, 2} - require.Equal(t, util.Uint160{9, 2}, b.NextConsensus()) - b.Block.PrevHash = util.Uint256{9, 8, 7} require.Equal(t, util.Uint256{9, 8, 7}, b.PrevHash()) - txx := []block.Transaction{transaction.New([]byte{byte(opcode.PUSH1)}, 1)} + txx := []dbft.Transaction[util.Uint256]{transaction.New([]byte{byte(opcode.PUSH1)}, 1)} b.SetTransactions(txx) require.Equal(t, txx, b.Transactions()) } diff --git a/pkg/consensus/cache_test.go b/pkg/consensus/cache_test.go index d54ed9cf1..c7796fe71 100644 --- a/pkg/consensus/cache_test.go +++ b/pkg/consensus/cache_test.go @@ -3,7 +3,6 @@ package consensus import ( "testing" - "github.com/nspcc-dev/dbft/payload" "github.com/nspcc-dev/neo-go/internal/random" "github.com/stretchr/testify/require" ) @@ -52,8 +51,8 @@ func getDifferentPayloads(t *testing.T, n int) (payloads []Payload) { var sign [signatureSize]byte random.Fill(sign[:]) - payloads[i].SetValidatorIndex(uint16(i)) - payloads[i].SetType(payload.MessageType(commitType)) + payloads[i].message.ValidatorIndex = byte(i) + payloads[i].message.Type = commitType payloads[i].payload = &commit{ signature: sign, } diff --git a/pkg/consensus/change_view.go b/pkg/consensus/change_view.go index df796699a..d406d8cd3 100644 --- a/pkg/consensus/change_view.go +++ b/pkg/consensus/change_view.go @@ -1,7 +1,7 @@ package consensus import ( - "github.com/nspcc-dev/dbft/payload" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/io" ) @@ -9,10 +9,10 @@ import ( type changeView struct { newViewNumber byte timestamp uint64 - reason payload.ChangeViewReason + reason dbft.ChangeViewReason } -var _ payload.ChangeView = (*changeView)(nil) +var _ dbft.ChangeView = (*changeView)(nil) // EncodeBinary implements the io.Serializable interface. func (c *changeView) EncodeBinary(w *io.BinWriter) { @@ -23,23 +23,11 @@ func (c *changeView) EncodeBinary(w *io.BinWriter) { // DecodeBinary implements the io.Serializable interface. func (c *changeView) DecodeBinary(r *io.BinReader) { c.timestamp = r.ReadU64LE() - c.reason = payload.ChangeViewReason(r.ReadB()) + c.reason = dbft.ChangeViewReason(r.ReadB()) } // NewViewNumber implements the payload.ChangeView interface. func (c changeView) NewViewNumber() byte { return c.newViewNumber } -// SetNewViewNumber implements the payload.ChangeView interface. -func (c *changeView) SetNewViewNumber(view byte) { c.newViewNumber = view } - -// Timestamp implements the payload.ChangeView interface. -func (c changeView) Timestamp() uint64 { return c.timestamp * nsInMs } - -// SetTimestamp implements the payload.ChangeView interface. -func (c *changeView) SetTimestamp(ts uint64) { c.timestamp = ts / nsInMs } - // Reason implements the payload.ChangeView interface. -func (c changeView) Reason() payload.ChangeViewReason { return c.reason } - -// SetReason implements the payload.ChangeView interface. -func (c *changeView) SetReason(reason payload.ChangeViewReason) { c.reason = reason } +func (c changeView) Reason() dbft.ChangeViewReason { return c.reason } diff --git a/pkg/consensus/change_view_test.go b/pkg/consensus/change_view_test.go index eaad6b2db..afd11c9ab 100644 --- a/pkg/consensus/change_view_test.go +++ b/pkg/consensus/change_view_test.go @@ -3,15 +3,16 @@ package consensus import ( "testing" + "github.com/nspcc-dev/dbft" "github.com/stretchr/testify/require" ) -func TestChangeView_Setters(t *testing.T) { - var c changeView +func TestChangeView_Getters(t *testing.T) { + var c = &changeView{ + newViewNumber: 2, + reason: dbft.CVTimeout, + } - c.SetTimestamp(123 * nsInMs) - require.EqualValues(t, 123*nsInMs, c.Timestamp()) - - c.SetNewViewNumber(2) require.EqualValues(t, 2, c.NewViewNumber()) + require.EqualValues(t, dbft.CVTimeout, c.Reason()) } diff --git a/pkg/consensus/commit.go b/pkg/consensus/commit.go index a59a81183..c21aa378e 100644 --- a/pkg/consensus/commit.go +++ b/pkg/consensus/commit.go @@ -1,7 +1,7 @@ package consensus import ( - "github.com/nspcc-dev/dbft/payload" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/io" ) @@ -14,7 +14,7 @@ type commit struct { // without a leading byte (0x04, uncompressed). const signatureSize = 64 -var _ payload.Commit = (*commit)(nil) +var _ dbft.Commit = (*commit)(nil) // EncodeBinary implements the io.Serializable interface. func (c *commit) EncodeBinary(w *io.BinWriter) { @@ -28,8 +28,3 @@ func (c *commit) DecodeBinary(r *io.BinReader) { // Signature implements the payload.Commit interface. func (c commit) Signature() []byte { return c.signature[:] } - -// SetSignature implements the payload.Commit interface. -func (c *commit) SetSignature(signature []byte) { - copy(c.signature[:], signature) -} diff --git a/pkg/consensus/commit_test.go b/pkg/consensus/commit_test.go index 8616894ec..21b21cbce 100644 --- a/pkg/consensus/commit_test.go +++ b/pkg/consensus/commit_test.go @@ -7,11 +7,12 @@ import ( "github.com/stretchr/testify/require" ) -func TestCommit_Setters(t *testing.T) { +func TestCommit_Getters(t *testing.T) { var sign [signatureSize]byte random.Fill(sign[:]) - var c commit - c.SetSignature(sign[:]) + var c = &commit{ + signature: sign, + } require.Equal(t, sign[:], c.Signature()) } diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 2eb9d6e15..f77778ed4 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -8,9 +8,7 @@ import ( "time" "github.com/nspcc-dev/dbft" - "github.com/nspcc-dev/dbft/block" - "github.com/nspcc-dev/dbft/crypto" - "github.com/nspcc-dev/dbft/payload" + "github.com/nspcc-dev/dbft/timer" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config/netmode" coreb "github.com/nspcc-dev/neo-go/pkg/core/block" @@ -88,7 +86,7 @@ type service struct { log *zap.Logger // txx is a fifo cache which stores miner transactions. txx *relayCache - dbft *dbft.DBFT + dbft *dbft.DBFT[util.Uint256] // messages and transactions are channels needed to process // everything in single thread. messages chan Payload @@ -181,48 +179,46 @@ func NewService(cfg Config) (Service, error) { } } - srv.dbft = dbft.New( - dbft.WithLogger(srv.log), - dbft.WithSecondsPerBlock(cfg.TimePerBlock), - dbft.WithGetKeyPair(srv.getKeyPair), + srv.dbft, err = dbft.New[util.Uint256]( + dbft.WithTimer[util.Uint256](timer.New()), + dbft.WithLogger[util.Uint256](srv.log), + dbft.WithSecondsPerBlock[util.Uint256](cfg.TimePerBlock), + dbft.WithGetKeyPair[util.Uint256](srv.getKeyPair), dbft.WithRequestTx(cfg.RequestTx), - dbft.WithStopTxFlow(cfg.StopTxFlow), - dbft.WithGetTx(srv.getTx), - dbft.WithGetVerified(srv.getVerifiedTx), - dbft.WithBroadcast(srv.broadcast), - dbft.WithProcessBlock(srv.processBlock), - dbft.WithVerifyBlock(srv.verifyBlock), - dbft.WithGetBlock(srv.getBlock), - dbft.WithWatchOnly(func() bool { return false }), - dbft.WithNewBlockFromContext(srv.newBlockFromContext), - dbft.WithCurrentHeight(cfg.Chain.BlockHeight), + dbft.WithStopTxFlow[util.Uint256](cfg.StopTxFlow), + dbft.WithGetTx[util.Uint256](srv.getTx), + dbft.WithGetVerified[util.Uint256](srv.getVerifiedTx), + dbft.WithBroadcast[util.Uint256](srv.broadcast), + dbft.WithProcessBlock[util.Uint256](srv.processBlock), + dbft.WithVerifyBlock[util.Uint256](srv.verifyBlock), + dbft.WithGetBlock[util.Uint256](srv.getBlock), + dbft.WithWatchOnly[util.Uint256](func() bool { return false }), + dbft.WithNewBlockFromContext[util.Uint256](srv.newBlockFromContext), + dbft.WithCurrentHeight[util.Uint256](cfg.Chain.BlockHeight), dbft.WithCurrentBlockHash(cfg.Chain.CurrentBlockHash), - dbft.WithGetValidators(srv.getValidators), - dbft.WithGetConsensusAddress(srv.getConsensusAddress), + dbft.WithGetValidators[util.Uint256](srv.getValidators), - dbft.WithNewConsensusPayload(srv.newPayload), - dbft.WithNewPrepareRequest(srv.newPrepareRequest), - dbft.WithNewPrepareResponse(func() payload.PrepareResponse { return new(prepareResponse) }), - dbft.WithNewChangeView(func() payload.ChangeView { return new(changeView) }), - dbft.WithNewCommit(func() payload.Commit { return new(commit) }), - dbft.WithNewRecoveryRequest(func() payload.RecoveryRequest { return new(recoveryRequest) }), - dbft.WithNewRecoveryMessage(func() payload.RecoveryMessage { - return &recoveryMessage{stateRootEnabled: srv.ProtocolConfiguration.StateRootInHeader} - }), - dbft.WithVerifyPrepareRequest(srv.verifyRequest), - dbft.WithVerifyPrepareResponse(func(_ payload.ConsensusPayload) error { return nil }), + dbft.WithNewConsensusPayload[util.Uint256](srv.newPayload), + dbft.WithNewPrepareRequest[util.Uint256](srv.newPrepareRequest), + dbft.WithNewPrepareResponse[util.Uint256](srv.newPrepareResponse), + dbft.WithNewChangeView[util.Uint256](srv.newChangeView), + dbft.WithNewCommit[util.Uint256](srv.newCommit), + dbft.WithNewRecoveryRequest[util.Uint256](srv.newRecoveryRequest), + dbft.WithNewRecoveryMessage[util.Uint256](srv.newRecoveryMessage), + dbft.WithVerifyPrepareRequest[util.Uint256](srv.verifyRequest), + dbft.WithVerifyPrepareResponse[util.Uint256](srv.verifyResponse), ) - if srv.dbft == nil { - return nil, errors.New("can't initialize dBFT") + if err != nil { + return nil, fmt.Errorf("can't initialize dBFT: %w", err) } return srv, nil } var ( - _ block.Transaction = (*transaction.Transaction)(nil) - _ block.Block = (*neoBlock)(nil) + _ dbft.Transaction[util.Uint256] = (*transaction.Transaction)(nil) + _ dbft.Block[util.Uint256] = (*neoBlock)(nil) ) // NewPayload creates a new consensus payload for the provided network. @@ -238,17 +234,17 @@ func NewPayload(m netmode.Magic, stateRootEnabled bool) *Payload { } } -func (s *service) newPayload(c *dbft.Context, t payload.MessageType, msg any) payload.ConsensusPayload { +func (s *service) newPayload(c *dbft.Context[util.Uint256], t dbft.MessageType, msg any) dbft.ConsensusPayload[util.Uint256] { cp := NewPayload(s.ProtocolConfiguration.Magic, s.ProtocolConfiguration.StateRootInHeader) - cp.SetHeight(c.BlockIndex) - cp.SetValidatorIndex(uint16(c.MyIndex)) - cp.SetViewNumber(c.ViewNumber) - cp.SetType(t) + cp.BlockIndex = c.BlockIndex + cp.message.ValidatorIndex = byte(c.MyIndex) + cp.message.ViewNumber = c.ViewNumber + cp.message.Type = messageType(t) if pr, ok := msg.(*prepareRequest); ok { - pr.SetPrevHash(s.dbft.PrevHash) - pr.SetVersion(s.dbft.Version) + pr.prevHash = s.dbft.PrevHash + pr.version = coreb.VersionInitial } - cp.SetPayload(msg) + cp.payload = msg.(io.Serializable) cp.Extensible.ValidBlockStart = 0 cp.Extensible.ValidBlockEnd = c.BlockIndex @@ -257,8 +253,12 @@ func (s *service) newPayload(c *dbft.Context, t payload.MessageType, msg any) pa return cp } -func (s *service) newPrepareRequest() payload.PrepareRequest { - r := new(prepareRequest) +func (s *service) newPrepareRequest(ts uint64, nonce uint64, transactionsHashes []util.Uint256) dbft.PrepareRequest[util.Uint256] { + r := &prepareRequest{ + timestamp: ts / nsInMs, + nonce: nonce, + transactionHashes: transactionsHashes, + } if s.ProtocolConfiguration.StateRootInHeader { r.stateRootEnabled = true if sr, err := s.Chain.GetStateRoot(s.dbft.BlockIndex - 1); err == nil { @@ -270,6 +270,38 @@ func (s *service) newPrepareRequest() payload.PrepareRequest { return r } +func (s *service) newPrepareResponse(preparationHash util.Uint256) dbft.PrepareResponse[util.Uint256] { + return &prepareResponse{ + preparationHash: preparationHash, + } +} + +func (s *service) newChangeView(newViewNumber byte, reason dbft.ChangeViewReason, ts uint64) dbft.ChangeView { + return &changeView{ + newViewNumber: newViewNumber, + timestamp: ts / nsInMs, + reason: reason, + } +} + +func (s *service) newCommit(signature []byte) dbft.Commit { + c := new(commit) + copy(c.signature[:], signature) + return c +} + +func (s *service) newRecoveryRequest(ts uint64) dbft.RecoveryRequest { + return &recoveryRequest{ + timestamp: ts / nsInMs, + } +} + +func (s *service) newRecoveryMessage() dbft.RecoveryMessage[util.Uint256] { + return &recoveryMessage{ + stateRootEnabled: s.ProtocolConfiguration.StateRootInHeader, + } +} + // Name returns service name. func (s *service) Name() string { return "consensus" @@ -315,18 +347,18 @@ events: s.Chain.UnsubscribeFromBlocks(s.blockEvents) break events case <-s.dbft.Timer.C(): - hv := s.dbft.Timer.HV() + h, v := s.dbft.Timer.Height(), s.dbft.Timer.View() s.log.Debug("timer fired", - zap.Uint32("height", hv.Height), - zap.Uint("view", uint(hv.View))) - s.dbft.OnTimeout(hv) + zap.Uint32("height", h), + zap.Uint("view", uint(v))) + s.dbft.OnTimeout(h, v) case msg := <-s.messages: fields := []zap.Field{ zap.Uint8("from", msg.message.ValidatorIndex), zap.Stringer("type", msg.Type()), } - if msg.Type() == payload.RecoveryMessageType { + if msg.Type() == dbft.RecoveryMessageType { rec := msg.GetRecoveryMessage().(*recoveryMessage) if rec.preparationHash == nil { req := rec.GetPrepareRequest(&msg, s.dbft.Validators, uint16(s.dbft.PrimaryIndex)) @@ -389,7 +421,7 @@ func (s *service) handleChainBlock(b *coreb.Block) { zap.Uint32("dbft index", s.dbft.BlockIndex), zap.Uint32("chain index", s.Chain.BlockHeight())) s.postBlock(b) - s.dbft.InitializeConsensus(0, b.Timestamp*nsInMs) + s.dbft.Reset(b.Timestamp * nsInMs) } } @@ -404,7 +436,7 @@ func (s *service) validatePayload(p *Payload) bool { return p.Sender == h } -func (s *service) getKeyPair(pubs []crypto.PublicKey) (int, crypto.PrivateKey, crypto.PublicKey) { +func (s *service) getKeyPair(pubs []dbft.PublicKey) (int, dbft.PrivateKey, dbft.PublicKey) { if s.wallet != nil { for i := range pubs { sh := pubs[i].(*publicKey).GetScriptHash() @@ -466,7 +498,7 @@ func (s *service) OnTransaction(tx *transaction.Transaction) { } } -func (s *service) broadcast(p payload.ConsensusPayload) { +func (s *service) broadcast(p dbft.ConsensusPayload[util.Uint256]) { if err := p.(*Payload).Sign(s.dbft.Priv.(*privateKey)); err != nil { s.log.Warn("can't sign consensus payload", zap.Error(err)) } @@ -475,7 +507,7 @@ func (s *service) broadcast(p payload.ConsensusPayload) { s.Config.Broadcast(ep) } -func (s *service) getTx(h util.Uint256) block.Transaction { +func (s *service) getTx(h util.Uint256) dbft.Transaction[util.Uint256] { if tx := s.txx.Get(h); tx != nil { return tx.(*transaction.Transaction) } @@ -491,7 +523,7 @@ func (s *service) getTx(h util.Uint256) block.Transaction { return nil } -func (s *service) verifyBlock(b block.Block) bool { +func (s *service) verifyBlock(b dbft.Block[util.Uint256]) bool { coreb := &b.(*neoBlock).Block if s.Chain.BlockHeight() >= coreb.Index { @@ -558,12 +590,12 @@ var ( errInvalidTransactionsCount = errors.New("invalid transactions count") ) -func (s *service) verifyRequest(p payload.ConsensusPayload) error { +func (s *service) verifyRequest(p dbft.ConsensusPayload[util.Uint256]) error { req := p.GetPrepareRequest().(*prepareRequest) if req.prevHash != s.dbft.PrevHash { return errInvalidPrevHash } - if req.version != s.dbft.Version { + if req.version != coreb.VersionInitial { return errInvalidVersion } if s.ProtocolConfiguration.StateRootInHeader { @@ -583,7 +615,11 @@ func (s *service) verifyRequest(p payload.ConsensusPayload) error { return nil } -func (s *service) processBlock(b block.Block) { +func (s *service) verifyResponse(p dbft.ConsensusPayload[util.Uint256]) error { + return nil +} + +func (s *service) processBlock(b dbft.Block[util.Uint256]) { bb := &b.(*neoBlock).Block bb.Script = *(s.getBlockWitness(bb)) @@ -638,7 +674,7 @@ func (s *service) getBlockWitness(b *coreb.Block) *transaction.Witness { } } -func (s *service) getBlock(h util.Uint256) block.Block { +func (s *service) getBlock(h util.Uint256) dbft.Block[util.Uint256] { b, err := s.Chain.GetBlock(h) if err != nil { return nil @@ -647,7 +683,7 @@ func (s *service) getBlock(h util.Uint256) block.Block { return &neoBlock{network: s.ProtocolConfiguration.Magic, Block: *b} } -func (s *service) getVerifiedTx() []block.Transaction { +func (s *service) getVerifiedTx() []dbft.Transaction[util.Uint256] { pool := s.Config.Chain.GetMemPool() var txx []*transaction.Transaction @@ -671,7 +707,7 @@ func (s *service) getVerifiedTx() []block.Transaction { txx = s.Config.Chain.ApplyPolicyToTxSet(txx) } - res := make([]block.Transaction, len(txx)) + res := make([]dbft.Transaction[util.Uint256], len(txx)) for i := range txx { res[i] = txx[i] } @@ -679,7 +715,7 @@ func (s *service) getVerifiedTx() []block.Transaction { return res } -func (s *service) getValidators(txes ...block.Transaction) []crypto.PublicKey { +func (s *service) getValidators(txes ...dbft.Transaction[util.Uint256]) []dbft.PublicKey { var ( pKeys []*keys.PublicKey err error @@ -699,7 +735,7 @@ func (s *service) getValidators(txes ...block.Transaction) []crypto.PublicKey { s.log.Error("error while trying to get validators", zap.Error(err)) } - pubs := make([]crypto.PublicKey, len(pKeys)) + pubs := make([]dbft.PublicKey, len(pKeys)) for i := range pKeys { pubs[i] = &publicKey{PublicKey: pKeys[i]} } @@ -707,11 +743,7 @@ func (s *service) getValidators(txes ...block.Transaction) []crypto.PublicKey { return pubs } -func (s *service) getConsensusAddress(validators ...crypto.PublicKey) util.Uint160 { - return util.Uint160{} -} - -func convertKeys(validators []crypto.PublicKey) (pubs []*keys.PublicKey) { +func convertKeys(validators []dbft.PublicKey) (pubs []*keys.PublicKey) { pubs = make([]*keys.PublicKey, len(validators)) for i, k := range validators { pubs[i] = k.(*publicKey).PublicKey @@ -720,7 +752,7 @@ func convertKeys(validators []crypto.PublicKey) (pubs []*keys.PublicKey) { return } -func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block { +func (s *service) newBlockFromContext(ctx *dbft.Context[util.Uint256]) dbft.Block[util.Uint256] { block := &neoBlock{network: s.ProtocolConfiguration.Magic} block.Block.Timestamp = ctx.Timestamp / nsInMs @@ -750,9 +782,9 @@ func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block { if err != nil { s.log.Fatal(fmt.Sprintf("failed to create multisignature script: %s", err.Error())) } - block.Block.NextConsensus = crypto.Hash160(script) + block.Block.NextConsensus = hash.Hash160(script) block.Block.PrevHash = ctx.PrevHash - block.Block.Version = ctx.Version + block.Block.Version = coreb.VersionInitial primaryIndex := byte(ctx.PrimaryIndex) block.Block.PrimaryIndex = primaryIndex diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index c095e8e3e..72242cc8f 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -4,9 +4,7 @@ import ( "testing" "time" - "github.com/nspcc-dev/dbft/block" - "github.com/nspcc-dev/dbft/payload" - "github.com/nspcc-dev/dbft/timer" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/internal/random" "github.com/nspcc-dev/neo-go/internal/testchain" "github.com/nspcc-dev/neo-go/pkg/config" @@ -38,7 +36,7 @@ func TestNewService(t *testing.T) { signTx(t, srv.Chain, tx) require.NoError(t, srv.Chain.PoolTx(tx)) - var txx []block.Transaction + var txx []dbft.Transaction[util.Uint256] require.NotPanics(t, func() { txx = srv.getVerifiedTx() }) require.Len(t, txx, 1) require.Equal(t, tx, txx[0]) @@ -65,10 +63,10 @@ func TestNewWatchingService(t *testing.T) { func collectBlock(t *testing.T, bc *core.Blockchain, srv *service) { h := bc.BlockHeight() - srv.dbft.OnTimeout(timer.HV{Height: srv.dbft.Context.BlockIndex}) // Collect and add block to the chain. + srv.dbft.OnTimeout(srv.dbft.Context.BlockIndex, 0) // Collect and add block to the chain. header, err := bc.GetHeader(bc.GetHeaderHash(h + 1)) require.NoError(t, err) - srv.dbft.InitializeConsensus(0, header.Timestamp*nsInMs) // Init consensus manually at the next height, as we don't run the consensus service. + srv.dbft.Reset(header.Timestamp * nsInMs) // Init consensus manually at the next height, as we don't run the consensus service. } func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint32) (*service, *wallet.Account) { @@ -102,7 +100,7 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3 srv.dbft.Start(0) header, err := bc.GetHeader(bc.GetHeaderHash(h + 1)) require.NoError(t, err) - srv.dbft.InitializeConsensus(0, header.Timestamp*nsInMs) // Init consensus manually at the next height, as we don't run the consensus service. + srv.dbft.Reset(header.Timestamp * nsInMs) // Init consensus manually at the next height, as we don't run the consensus service. // Register new candidate. b.Reset() @@ -214,14 +212,14 @@ func TestService_GetVerified(t *testing.T) { p := new(Payload) // One PrepareRequest and three ChangeViews. if i == 1 { - p.SetType(payload.PrepareRequestType) - p.SetPayload(&prepareRequest{prevHash: srv.Chain.CurrentBlockHash(), transactionHashes: hashes}) + p.message.Type = messageType(dbft.PrepareRequestType) + p.payload = &prepareRequest{prevHash: srv.Chain.CurrentBlockHash(), transactionHashes: hashes} } else { - p.SetType(payload.ChangeViewType) - p.SetPayload(&changeView{newViewNumber: 1, timestamp: uint64(time.Now().UnixNano() / nsInMs)}) + p.message.Type = messageType(dbft.ChangeViewType) + p.payload = &changeView{newViewNumber: 1, timestamp: uint64(time.Now().UnixNano() / nsInMs)} } - p.SetHeight(1) - p.SetValidatorIndex(uint16(i)) + p.BlockIndex = 1 + p.message.ValidatorIndex = byte(i) priv, _ := getTestValidator(i) require.NoError(t, p.Sign(priv)) @@ -255,10 +253,10 @@ func TestService_ValidatePayload(t *testing.T) { priv, _ := getTestValidator(1) p := new(Payload) p.Sender = priv.GetScriptHash() - p.SetPayload(&prepareRequest{}) + p.payload = &prepareRequest{} t.Run("invalid validator index", func(t *testing.T) { - p.SetValidatorIndex(11) + p.message.ValidatorIndex = 11 require.NoError(t, p.Sign(priv)) var ok bool @@ -267,20 +265,20 @@ func TestService_ValidatePayload(t *testing.T) { }) t.Run("wrong validator index", func(t *testing.T) { - p.SetValidatorIndex(2) + p.message.ValidatorIndex = 2 require.NoError(t, p.Sign(priv)) require.False(t, srv.validatePayload(p)) }) t.Run("invalid sender", func(t *testing.T) { - p.SetValidatorIndex(1) + p.message.ValidatorIndex = 1 p.Sender = util.Uint160{} require.NoError(t, p.Sign(priv)) require.False(t, srv.validatePayload(p)) }) t.Run("normal case", func(t *testing.T) { - p.SetValidatorIndex(1) + p.message.ValidatorIndex = 1 p.Sender = priv.GetScriptHash() require.NoError(t, p.Sign(priv)) require.True(t, srv.validatePayload(p)) @@ -330,12 +328,12 @@ func TestService_PrepareRequest(t *testing.T) { priv, _ := getTestValidator(1) p := new(Payload) - p.SetValidatorIndex(1) + p.message.ValidatorIndex = 1 prevHash := srv.Chain.CurrentBlockHash() checkRequest := func(t *testing.T, expectedErr error, req *prepareRequest) { - p.SetPayload(req) + p.payload = req require.NoError(t, p.Sign(priv)) err := srv.verifyRequest(p) if expectedErr == nil { @@ -377,8 +375,8 @@ func TestService_OnPayload(t *testing.T) { priv, _ := getTestValidator(1) p := new(Payload) - p.SetValidatorIndex(1) - p.SetPayload(&prepareRequest{}) + p.message.ValidatorIndex = 1 + p.payload = &prepareRequest{} p.encodeData() // sender is invalid @@ -386,9 +384,9 @@ func TestService_OnPayload(t *testing.T) { shouldNotReceive(t, srv.messages) p = new(Payload) - p.SetValidatorIndex(1) + p.message.ValidatorIndex = 1 p.Sender = priv.GetScriptHash() - p.SetPayload(&prepareRequest{}) + p.payload = &prepareRequest{} require.NoError(t, p.Sign(priv)) require.NoError(t, srv.OnPayload(&p.Extensible)) shouldReceive(t, srv.messages) diff --git a/pkg/consensus/crypto.go b/pkg/consensus/crypto.go index 702930f10..e2382bc94 100644 --- a/pkg/consensus/crypto.go +++ b/pkg/consensus/crypto.go @@ -4,6 +4,7 @@ import ( "crypto/sha256" "errors" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" ) @@ -13,6 +14,8 @@ type privateKey struct { *keys.PrivateKey } +var _ dbft.PrivateKey = &privateKey{} + // Sign implements the dbft's crypto.PrivateKey interface. func (p *privateKey) Sign(data []byte) ([]byte, error) { return p.PrivateKey.Sign(data), nil @@ -24,6 +27,8 @@ type publicKey struct { *keys.PublicKey } +var _ dbft.PublicKey = &publicKey{} + // MarshalBinary implements the encoding.BinaryMarshaler interface. func (p publicKey) MarshalBinary() (data []byte, err error) { return p.PublicKey.Bytes(), nil diff --git a/pkg/consensus/payload.go b/pkg/consensus/payload.go index aa100cf8c..9ed6ca880 100644 --- a/pkg/consensus/payload.go +++ b/pkg/consensus/payload.go @@ -3,7 +3,7 @@ package consensus import ( "fmt" - "github.com/nspcc-dev/dbft/payload" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/io" npayload "github.com/nspcc-dev/neo-go/pkg/network/payload" @@ -44,6 +44,8 @@ const ( payloadGasLimit = 2000000 // 0.02 GAS ) +var _ dbft.ConsensusPayload[util.Uint256] = &Payload{} + // ViewNumber implements the payload.ConsensusPayload interface. func (p Payload) ViewNumber() byte { return p.message.ViewNumber @@ -55,13 +57,8 @@ func (p *Payload) SetViewNumber(view byte) { } // Type implements the payload.ConsensusPayload interface. -func (p Payload) Type() payload.MessageType { - return payload.MessageType(p.message.Type) -} - -// SetType implements the payload.ConsensusPayload interface. -func (p *Payload) SetType(t payload.MessageType) { - p.message.Type = messageType(t) +func (p Payload) Type() dbft.MessageType { + return dbft.MessageType(p.message.Type) } // Payload implements the payload.ConsensusPayload interface. @@ -69,35 +66,30 @@ func (p Payload) Payload() any { return p.payload } -// SetPayload implements the payload.ConsensusPayload interface. -func (p *Payload) SetPayload(pl any) { - p.payload = pl.(io.Serializable) -} - // GetChangeView implements the payload.ConsensusPayload interface. -func (p Payload) GetChangeView() payload.ChangeView { return p.payload.(payload.ChangeView) } +func (p Payload) GetChangeView() dbft.ChangeView { return p.payload.(dbft.ChangeView) } // GetPrepareRequest implements the payload.ConsensusPayload interface. -func (p Payload) GetPrepareRequest() payload.PrepareRequest { - return p.payload.(payload.PrepareRequest) +func (p Payload) GetPrepareRequest() dbft.PrepareRequest[util.Uint256] { + return p.payload.(dbft.PrepareRequest[util.Uint256]) } // GetPrepareResponse implements the payload.ConsensusPayload interface. -func (p Payload) GetPrepareResponse() payload.PrepareResponse { - return p.payload.(payload.PrepareResponse) +func (p Payload) GetPrepareResponse() dbft.PrepareResponse[util.Uint256] { + return p.payload.(dbft.PrepareResponse[util.Uint256]) } // GetCommit implements the payload.ConsensusPayload interface. -func (p Payload) GetCommit() payload.Commit { return p.payload.(payload.Commit) } +func (p Payload) GetCommit() dbft.Commit { return p.payload.(dbft.Commit) } // GetRecoveryRequest implements the payload.ConsensusPayload interface. -func (p Payload) GetRecoveryRequest() payload.RecoveryRequest { - return p.payload.(payload.RecoveryRequest) +func (p Payload) GetRecoveryRequest() dbft.RecoveryRequest { + return p.payload.(dbft.RecoveryRequest) } // GetRecoveryMessage implements the payload.ConsensusPayload interface. -func (p Payload) GetRecoveryMessage() payload.RecoveryMessage { - return p.payload.(payload.RecoveryMessage) +func (p Payload) GetRecoveryMessage() dbft.RecoveryMessage[util.Uint256] { + return p.payload.(dbft.RecoveryMessage[util.Uint256]) } // ValidatorIndex implements the payload.ConsensusPayload interface. @@ -115,11 +107,6 @@ func (p Payload) Height() uint32 { return p.message.BlockIndex } -// SetHeight implements the payload.ConsensusPayload interface. -func (p *Payload) SetHeight(h uint32) { - p.message.BlockIndex = h -} - // EncodeBinary implements the io.Serializable interface. func (p *Payload) EncodeBinary(w *io.BinWriter) { p.encodeData() diff --git a/pkg/consensus/payload_test.go b/pkg/consensus/payload_test.go index 1eddab699..0e7253967 100644 --- a/pkg/consensus/payload_test.go +++ b/pkg/consensus/payload_test.go @@ -6,7 +6,7 @@ import ( "math/rand" "testing" - "github.com/nspcc-dev/dbft/payload" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/internal/random" "github.com/nspcc-dev/neo-go/internal/testserdes" "github.com/nspcc-dev/neo-go/pkg/config/netmode" @@ -29,50 +29,45 @@ var messageTypes = []messageType{ recoveryMessageType, } -func TestConsensusPayload_Setters(t *testing.T) { - var p Payload +func TestConsensusPayload_Getters(t *testing.T) { + var p = &Payload{ + Extensible: npayload.Extensible{}, + message: message{ + Type: prepareRequestType, + BlockIndex: 11, + ValidatorIndex: 4, + ViewNumber: 2, + }, + } - //p.SetVersion(1) - //assert.EqualValues(t, 1, p.Version()) - - //p.SetPrevHash(util.Uint256{1, 2, 3}) - //assert.Equal(t, util.Uint256{1, 2, 3}, p.PrevHash()) - - p.SetValidatorIndex(4) assert.EqualValues(t, 4, p.ValidatorIndex()) - - p.SetHeight(11) assert.EqualValues(t, 11, p.Height()) - - p.SetViewNumber(2) assert.EqualValues(t, 2, p.ViewNumber()) - - p.SetType(payload.PrepareRequestType) - assert.Equal(t, payload.PrepareRequestType, p.Type()) + assert.Equal(t, dbft.PrepareRequestType, p.Type()) pl := randomMessage(t, prepareRequestType) - p.SetPayload(pl) + p.payload = pl require.Equal(t, pl, p.Payload()) require.Equal(t, pl, p.GetPrepareRequest()) pl = randomMessage(t, prepareResponseType) - p.SetPayload(pl) + p.payload = pl require.Equal(t, pl, p.GetPrepareResponse()) pl = randomMessage(t, commitType) - p.SetPayload(pl) + p.payload = pl require.Equal(t, pl, p.GetCommit()) pl = randomMessage(t, changeViewType) - p.SetPayload(pl) + p.payload = pl require.Equal(t, pl, p.GetChangeView()) pl = randomMessage(t, recoveryRequestType) - p.SetPayload(pl) + p.payload = pl require.Equal(t, pl, p.GetRecoveryRequest()) pl = randomMessage(t, recoveryMessageType) - p.SetPayload(pl) + p.payload = pl require.Equal(t, pl, p.GetRecoveryMessage()) } @@ -290,7 +285,7 @@ func TestPayload_DecodeFromPrivnet(t *testing.T) { p := NewPayload(netmode.PrivNet, false) p.DecodeBinary(buf) require.NoError(t, buf.Err) - require.Equal(t, payload.CommitType, p.Type()) + require.Equal(t, dbft.CommitType, p.Type()) require.Equal(t, uint32(2), p.Height()) require.Equal(t, uint16(3), p.ValidatorIndex()) require.Equal(t, byte(0), p.ViewNumber()) diff --git a/pkg/consensus/prepare_request.go b/pkg/consensus/prepare_request.go index 1c21348f3..0d5ecebd7 100644 --- a/pkg/consensus/prepare_request.go +++ b/pkg/consensus/prepare_request.go @@ -1,7 +1,7 @@ package consensus import ( - "github.com/nspcc-dev/dbft/payload" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/util" @@ -18,7 +18,7 @@ type prepareRequest struct { stateRoot util.Uint256 } -var _ payload.PrepareRequest = (*prepareRequest)(nil) +var _ dbft.PrepareRequest[util.Uint256] = (*prepareRequest)(nil) // EncodeBinary implements the io.Serializable interface. func (p *prepareRequest) EncodeBinary(w *io.BinWriter) { @@ -47,46 +47,11 @@ func (p *prepareRequest) DecodeBinary(r *io.BinReader) { } } -// Version implements the payload.PrepareRequest interface. -func (p prepareRequest) Version() uint32 { - return p.version -} - -// SetVersion implements the payload.PrepareRequest interface. -func (p *prepareRequest) SetVersion(v uint32) { - p.version = v -} - -// PrevHash implements the payload.PrepareRequest interface. -func (p prepareRequest) PrevHash() util.Uint256 { - return p.prevHash -} - -// SetPrevHash implements the payload.PrepareRequest interface. -func (p *prepareRequest) SetPrevHash(h util.Uint256) { - p.prevHash = h -} - // Timestamp implements the payload.PrepareRequest interface. func (p *prepareRequest) Timestamp() uint64 { return p.timestamp * nsInMs } -// SetTimestamp implements the payload.PrepareRequest interface. -func (p *prepareRequest) SetTimestamp(ts uint64) { p.timestamp = ts / nsInMs } - // Nonce implements the payload.PrepareRequest interface. func (p *prepareRequest) Nonce() uint64 { return p.nonce } -// SetNonce implements the payload.PrepareRequest interface. -func (p *prepareRequest) SetNonce(nonce uint64) { p.nonce = nonce } - // TransactionHashes implements the payload.PrepareRequest interface. func (p *prepareRequest) TransactionHashes() []util.Uint256 { return p.transactionHashes } - -// SetTransactionHashes implements the payload.PrepareRequest interface. -func (p *prepareRequest) SetTransactionHashes(hs []util.Uint256) { p.transactionHashes = hs } - -// NextConsensus implements the payload.PrepareRequest interface. -func (p *prepareRequest) NextConsensus() util.Uint160 { return util.Uint160{} } - -// SetNextConsensus implements the payload.PrepareRequest interface. -func (p *prepareRequest) SetNextConsensus(_ util.Uint160) {} diff --git a/pkg/consensus/prepare_request_test.go b/pkg/consensus/prepare_request_test.go index 8a8a4e218..bd1fb0e97 100644 --- a/pkg/consensus/prepare_request_test.go +++ b/pkg/consensus/prepare_request_test.go @@ -10,24 +10,17 @@ import ( "github.com/stretchr/testify/require" ) -func TestPrepareRequest_Setters(t *testing.T) { - var p prepareRequest +func TestPrepareRequest_Getters(t *testing.T) { + hashes := []util.Uint256{random.Uint256(), random.Uint256()} + var p = &prepareRequest{ + version: 123, + prevHash: util.Uint256{1, 2, 3}, + timestamp: 123, + transactionHashes: hashes, + } - p.SetTimestamp(123) - // 123ns -> 0ms -> 0ns - require.EqualValues(t, 0, p.Timestamp()) - - p.SetTimestamp(1230000) - // 1230000ns -> 1ms -> 1000000ns - require.EqualValues(t, 1000000, p.Timestamp()) - - p.SetNextConsensus(util.Uint160{5, 6, 7}) - require.Equal(t, util.Uint160{}, p.NextConsensus()) - - hashes := [2]util.Uint256{random.Uint256(), random.Uint256()} - - p.SetTransactionHashes(hashes[:]) - require.Equal(t, hashes[:], p.TransactionHashes()) + require.EqualValues(t, 123000000, p.Timestamp()) + require.Equal(t, hashes, p.TransactionHashes()) } func TestPrepareRequest_EncodeDecodeBinary(t *testing.T) { diff --git a/pkg/consensus/prepare_response.go b/pkg/consensus/prepare_response.go index 0fa93ab2d..1b2f064fb 100644 --- a/pkg/consensus/prepare_response.go +++ b/pkg/consensus/prepare_response.go @@ -1,7 +1,7 @@ package consensus import ( - "github.com/nspcc-dev/dbft/payload" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/util" ) @@ -11,7 +11,7 @@ type prepareResponse struct { preparationHash util.Uint256 } -var _ payload.PrepareResponse = (*prepareResponse)(nil) +var _ dbft.PrepareResponse[util.Uint256] = (*prepareResponse)(nil) // EncodeBinary implements the io.Serializable interface. func (p *prepareResponse) EncodeBinary(w *io.BinWriter) { @@ -25,6 +25,3 @@ func (p *prepareResponse) DecodeBinary(r *io.BinReader) { // PreparationHash implements the payload.PrepareResponse interface. func (p *prepareResponse) PreparationHash() util.Uint256 { return p.preparationHash } - -// SetPreparationHash implements the payload.PrepareResponse interface. -func (p *prepareResponse) SetPreparationHash(h util.Uint256) { p.preparationHash = h } diff --git a/pkg/consensus/prepare_response_test.go b/pkg/consensus/prepare_response_test.go index 6139848be..67fa7ee80 100644 --- a/pkg/consensus/prepare_response_test.go +++ b/pkg/consensus/prepare_response_test.go @@ -8,8 +8,9 @@ import ( ) func TestPrepareResponse_Setters(t *testing.T) { - var p prepareResponse + var p = prepareResponse{ + preparationHash: util.Uint256{1, 2, 3}, + } - p.SetPreparationHash(util.Uint256{1, 2, 3}) require.Equal(t, util.Uint256{1, 2, 3}, p.PreparationHash()) } diff --git a/pkg/consensus/recovery_message.go b/pkg/consensus/recovery_message.go index a7fa9c435..7d3ad3a12 100644 --- a/pkg/consensus/recovery_message.go +++ b/pkg/consensus/recovery_message.go @@ -3,8 +3,7 @@ package consensus import ( "errors" - "github.com/nspcc-dev/dbft/crypto" - "github.com/nspcc-dev/dbft/payload" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/io" npayload "github.com/nspcc-dev/neo-go/pkg/network/payload" "github.com/nspcc-dev/neo-go/pkg/util" @@ -41,7 +40,7 @@ type ( } ) -var _ payload.RecoveryMessage = (*recoveryMessage)(nil) +var _ dbft.RecoveryMessage[util.Uint256] = (*recoveryMessage)(nil) // DecodeBinary implements the io.Serializable interface. func (m *recoveryMessage) DecodeBinary(r *io.BinReader) { @@ -139,11 +138,11 @@ func (p *preparationCompact) EncodeBinary(w *io.BinWriter) { } // AddPayload implements the payload.RecoveryMessage interface. -func (m *recoveryMessage) AddPayload(p payload.ConsensusPayload) { +func (m *recoveryMessage) AddPayload(p dbft.ConsensusPayload[util.Uint256]) { validator := uint8(p.ValidatorIndex()) switch p.Type() { - case payload.PrepareRequestType: + case dbft.PrepareRequestType: m.prepareRequest = &message{ Type: prepareRequestType, ViewNumber: p.ViewNumber(), @@ -156,24 +155,24 @@ func (m *recoveryMessage) AddPayload(p payload.ConsensusPayload) { ValidatorIndex: validator, InvocationScript: p.(*Payload).Witness.InvocationScript, }) - case payload.PrepareResponseType: + case dbft.PrepareResponseType: m.preparationPayloads = append(m.preparationPayloads, &preparationCompact{ ValidatorIndex: validator, InvocationScript: p.(*Payload).Witness.InvocationScript, }) if m.preparationHash == nil { - h := p.GetPrepareResponse().PreparationHash() + h := p.GetPrepareResponse().(*prepareResponse).preparationHash m.preparationHash = &h } - case payload.ChangeViewType: + case dbft.ChangeViewType: m.changeViewPayloads = append(m.changeViewPayloads, &changeViewCompact{ ValidatorIndex: validator, OriginalViewNumber: p.ViewNumber(), - Timestamp: p.GetChangeView().Timestamp() / nsInMs, + Timestamp: p.GetChangeView().(*changeView).timestamp, InvocationScript: p.(*Payload).Witness.InvocationScript, }) - case payload.CommitType: + case dbft.CommitType: m.commitPayloads = append(m.commitPayloads, &commitCompact{ ValidatorIndex: validator, ViewNumber: p.ViewNumber(), @@ -184,7 +183,7 @@ func (m *recoveryMessage) AddPayload(p payload.ConsensusPayload) { } // GetPrepareRequest implements the payload.RecoveryMessage interface. -func (m *recoveryMessage) GetPrepareRequest(p payload.ConsensusPayload, validators []crypto.PublicKey, primary uint16) payload.ConsensusPayload { +func (m *recoveryMessage) GetPrepareRequest(p dbft.ConsensusPayload[util.Uint256], validators []dbft.PublicKey, primary uint16) dbft.ConsensusPayload[util.Uint256] { if m.prepareRequest == nil { return nil } @@ -202,7 +201,7 @@ func (m *recoveryMessage) GetPrepareRequest(p payload.ConsensusPayload, validato } req := fromPayload(prepareRequestType, p.(*Payload), m.prepareRequest.payload) - req.SetValidatorIndex(primary) + req.message.ValidatorIndex = byte(primary) req.Sender = validators[primary].(*publicKey).GetScriptHash() req.Witness.InvocationScript = compact.InvocationScript req.Witness.VerificationScript = getVerificationScript(uint8(primary), validators) @@ -211,18 +210,18 @@ func (m *recoveryMessage) GetPrepareRequest(p payload.ConsensusPayload, validato } // GetPrepareResponses implements the payload.RecoveryMessage interface. -func (m *recoveryMessage) GetPrepareResponses(p payload.ConsensusPayload, validators []crypto.PublicKey) []payload.ConsensusPayload { +func (m *recoveryMessage) GetPrepareResponses(p dbft.ConsensusPayload[util.Uint256], validators []dbft.PublicKey) []dbft.ConsensusPayload[util.Uint256] { if m.preparationHash == nil { return nil } - ps := make([]payload.ConsensusPayload, len(m.preparationPayloads)) + ps := make([]dbft.ConsensusPayload[util.Uint256], len(m.preparationPayloads)) for i, resp := range m.preparationPayloads { r := fromPayload(prepareResponseType, p.(*Payload), &prepareResponse{ preparationHash: *m.preparationHash, }) - r.SetValidatorIndex(uint16(resp.ValidatorIndex)) + r.message.ValidatorIndex = resp.ValidatorIndex r.Sender = validators[resp.ValidatorIndex].(*publicKey).GetScriptHash() r.Witness.InvocationScript = resp.InvocationScript r.Witness.VerificationScript = getVerificationScript(resp.ValidatorIndex, validators) @@ -234,8 +233,8 @@ func (m *recoveryMessage) GetPrepareResponses(p payload.ConsensusPayload, valida } // GetChangeViews implements the payload.RecoveryMessage interface. -func (m *recoveryMessage) GetChangeViews(p payload.ConsensusPayload, validators []crypto.PublicKey) []payload.ConsensusPayload { - ps := make([]payload.ConsensusPayload, len(m.changeViewPayloads)) +func (m *recoveryMessage) GetChangeViews(p dbft.ConsensusPayload[util.Uint256], validators []dbft.PublicKey) []dbft.ConsensusPayload[util.Uint256] { + ps := make([]dbft.ConsensusPayload[util.Uint256], len(m.changeViewPayloads)) for i, cv := range m.changeViewPayloads { c := fromPayload(changeViewType, p.(*Payload), &changeView{ @@ -243,7 +242,7 @@ func (m *recoveryMessage) GetChangeViews(p payload.ConsensusPayload, validators timestamp: cv.Timestamp, }) c.message.ViewNumber = cv.OriginalViewNumber - c.SetValidatorIndex(uint16(cv.ValidatorIndex)) + c.message.ValidatorIndex = cv.ValidatorIndex c.Sender = validators[cv.ValidatorIndex].(*publicKey).GetScriptHash() c.Witness.InvocationScript = cv.InvocationScript c.Witness.VerificationScript = getVerificationScript(cv.ValidatorIndex, validators) @@ -255,12 +254,12 @@ func (m *recoveryMessage) GetChangeViews(p payload.ConsensusPayload, validators } // GetCommits implements the payload.RecoveryMessage interface. -func (m *recoveryMessage) GetCommits(p payload.ConsensusPayload, validators []crypto.PublicKey) []payload.ConsensusPayload { - ps := make([]payload.ConsensusPayload, len(m.commitPayloads)) +func (m *recoveryMessage) GetCommits(p dbft.ConsensusPayload[util.Uint256], validators []dbft.PublicKey) []dbft.ConsensusPayload[util.Uint256] { + ps := make([]dbft.ConsensusPayload[util.Uint256], len(m.commitPayloads)) for i, c := range m.commitPayloads { cc := fromPayload(commitType, p.(*Payload), &commit{signature: c.Signature}) - cc.SetValidatorIndex(uint16(c.ValidatorIndex)) + cc.message.ValidatorIndex = c.ValidatorIndex cc.Sender = validators[c.ValidatorIndex].(*publicKey).GetScriptHash() cc.Witness.InvocationScript = c.InvocationScript cc.Witness.VerificationScript = getVerificationScript(c.ValidatorIndex, validators) @@ -276,12 +275,7 @@ func (m *recoveryMessage) PreparationHash() *util.Uint256 { return m.preparationHash } -// SetPreparationHash implements the payload.RecoveryMessage interface. -func (m *recoveryMessage) SetPreparationHash(h *util.Uint256) { - m.preparationHash = h -} - -func getVerificationScript(i uint8, validators []crypto.PublicKey) []byte { +func getVerificationScript(i uint8, validators []dbft.PublicKey) []byte { if int(i) >= len(validators) { return nil } diff --git a/pkg/consensus/recovery_message_test.go b/pkg/consensus/recovery_message_test.go index 9fe19e263..50ee54c2f 100644 --- a/pkg/consensus/recovery_message_test.go +++ b/pkg/consensus/recovery_message_test.go @@ -3,8 +3,7 @@ package consensus import ( "testing" - "github.com/nspcc-dev/dbft/crypto" - "github.com/nspcc-dev/dbft/payload" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/internal/testchain" "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/util" @@ -23,7 +22,7 @@ func TestRecoveryMessageSetters(t *testing.T) { func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) { srv := newTestServiceWithState(t, enableStateRoot) privs := make([]*privateKey, testchain.Size()) - pubs := make([]crypto.PublicKey, testchain.Size()) + pubs := make([]dbft.PublicKey, testchain.Size()) for i := 0; i < testchain.Size(); i++ { privs[i], pubs[i] = getTestValidator(i) } @@ -32,9 +31,9 @@ func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) { r := &recoveryMessage{stateRootEnabled: enableStateRoot} p := NewPayload(netmode.UnitTestNet, enableStateRoot) - p.SetType(payload.RecoveryMessageType) - p.SetHeight(msgHeight) - p.SetPayload(r) + p.message.Type = messageType(dbft.RecoveryMessageType) + p.BlockIndex = msgHeight + p.payload = r // sign payload to have verification script require.NoError(t, p.Sign(privs[0])) @@ -44,21 +43,21 @@ func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) { stateRootEnabled: enableStateRoot, } p1 := NewPayload(netmode.UnitTestNet, enableStateRoot) - p1.SetType(payload.PrepareRequestType) - p1.SetHeight(msgHeight) - p1.SetPayload(req) - p1.SetValidatorIndex(0) + p1.message.Type = messageType(dbft.PrepareRequestType) + p1.BlockIndex = msgHeight + p1.payload = req + p1.message.ValidatorIndex = 0 p1.Sender = privs[0].GetScriptHash() require.NoError(t, p1.Sign(privs[0])) t.Run("prepare response is added", func(t *testing.T) { p2 := NewPayload(netmode.UnitTestNet, enableStateRoot) - p2.SetType(payload.PrepareResponseType) - p2.SetHeight(msgHeight) - p2.SetPayload(&prepareResponse{ + p2.message.Type = messageType(dbft.PrepareResponseType) + p2.BlockIndex = msgHeight + p2.payload = &prepareResponse{ preparationHash: p1.Hash(), - }) - p2.SetValidatorIndex(1) + } + p2.message.ValidatorIndex = 1 p2.Sender = privs[1].GetScriptHash() require.NoError(t, p2.Sign(privs[1])) @@ -91,13 +90,13 @@ func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) { t.Run("change view is added", func(t *testing.T) { p3 := NewPayload(netmode.UnitTestNet, enableStateRoot) - p3.SetType(payload.ChangeViewType) - p3.SetHeight(msgHeight) - p3.SetPayload(&changeView{ + p3.message.Type = messageType(dbft.ChangeViewType) + p3.BlockIndex = msgHeight + p3.payload = &changeView{ newViewNumber: 1, timestamp: 12345, - }) - p3.SetValidatorIndex(3) + } + p3.message.ValidatorIndex = 3 p3.Sender = privs[3].GetScriptHash() require.NoError(t, p3.Sign(privs[3])) @@ -115,10 +114,10 @@ func testRecoveryMessageSetters(t *testing.T, enableStateRoot bool) { t.Run("commit is added", func(t *testing.T) { p4 := NewPayload(netmode.UnitTestNet, enableStateRoot) - p4.SetType(payload.CommitType) - p4.SetHeight(msgHeight) - p4.SetPayload(randomMessage(t, commitType)) - p4.SetValidatorIndex(3) + p4.message.Type = messageType(dbft.CommitType) + p4.BlockIndex = msgHeight + p4.payload = randomMessage(t, commitType) + p4.message.ValidatorIndex = 3 p4.Sender = privs[3].GetScriptHash() require.NoError(t, p4.Sign(privs[3])) diff --git a/pkg/consensus/recovery_request.go b/pkg/consensus/recovery_request.go index 6add949a5..897f0b72f 100644 --- a/pkg/consensus/recovery_request.go +++ b/pkg/consensus/recovery_request.go @@ -1,7 +1,7 @@ package consensus import ( - "github.com/nspcc-dev/dbft/payload" + "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/io" ) @@ -10,7 +10,7 @@ type recoveryRequest struct { timestamp uint64 } -var _ payload.RecoveryRequest = (*recoveryRequest)(nil) +var _ dbft.RecoveryRequest = (*recoveryRequest)(nil) // DecodeBinary implements the io.Serializable interface. func (m *recoveryRequest) DecodeBinary(r *io.BinReader) { @@ -24,6 +24,3 @@ func (m *recoveryRequest) EncodeBinary(w *io.BinWriter) { // Timestamp implements the payload.RecoveryRequest interface. func (m *recoveryRequest) Timestamp() uint64 { return m.timestamp * nsInMs } - -// SetTimestamp implements the payload.RecoveryRequest interface. -func (m *recoveryRequest) SetTimestamp(ts uint64) { m.timestamp = ts / nsInMs } diff --git a/pkg/consensus/recovery_request_test.go b/pkg/consensus/recovery_request_test.go index adfc57c51..3ce19aa65 100644 --- a/pkg/consensus/recovery_request_test.go +++ b/pkg/consensus/recovery_request_test.go @@ -6,9 +6,10 @@ import ( "github.com/stretchr/testify/require" ) -func TestRecoveryRequest_Setters(t *testing.T) { - var r recoveryRequest +func TestRecoveryRequest_Getters(t *testing.T) { + var r = &recoveryRequest{ + timestamp: 123, + } - r.SetTimestamp(123 * nsInMs) require.EqualValues(t, 123*nsInMs, r.Timestamp()) } diff --git a/pkg/core/block/header.go b/pkg/core/block/header.go index ba37658e9..b56e1cbba 100644 --- a/pkg/core/block/header.go +++ b/pkg/core/block/header.go @@ -13,6 +13,9 @@ import ( "github.com/nspcc-dev/neo-go/pkg/util" ) +// VersionInitial is the default Neo block version. +const VersionInitial uint32 = 0 + // Header holds the base info of a block. type Header struct { // Version of the block.