From ee0d92c6d22875ee9fef4695d6630ad3a1cbf2bf Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 1 Aug 2024 13:06:02 +0300 Subject: [PATCH] dbft: update to AMEV-enabled version Signed-off-by: Roman Khimov --- go.mod | 2 +- go.sum | 4 ++-- pkg/consensus/block.go | 5 +++-- pkg/consensus/block_test.go | 2 +- pkg/consensus/consensus.go | 12 ++++++------ pkg/consensus/consensus_test.go | 4 ++-- pkg/consensus/crypto.go | 31 ------------------------------- pkg/consensus/crypto_test.go | 20 ++++++-------------- pkg/consensus/payload.go | 4 ++++ pkg/consensus/recovery_message.go | 17 ++++++++++++----- 10 files changed, 37 insertions(+), 64 deletions(-) diff --git a/go.mod b/go.mod index 5d56c6e55..73d095310 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.2.0 + github.com/nspcc-dev/dbft v0.3.0 github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2 github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.12 diff --git a/go.sum b/go.sum index 39cb1229a..e7ff71e45 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,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.2.0 h1:sDwsQES600OSIMncV176t2SX5OvB14lzeOAyKFOkbMI= -github.com/nspcc-dev/dbft v0.2.0/go.mod h1:oFE6paSC/yfFh9mcNU6MheMGOYXK9+sPiRk3YMoz49o= +github.com/nspcc-dev/dbft v0.3.0 h1:P9dFQje43sabA6w89l1OqGe1BvnO7DdHcu27w6mfnOE= +github.com/nspcc-dev/dbft v0.3.0/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/v2 v2.0.1 h1:CxYUkBeJvNfMEn2lHhrV6FjY8pZPceSxXUtMVq0BUOU= diff --git a/pkg/consensus/block.go b/pkg/consensus/block.go index 989ec1109..cabb0c684 100644 --- a/pkg/consensus/block.go +++ b/pkg/consensus/block.go @@ -7,6 +7,7 @@ import ( "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" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/util" ) @@ -31,8 +32,8 @@ func (n *neoBlock) Sign(key dbft.PrivateKey) error { // Verify implements the block.Block interface. func (n *neoBlock) Verify(key dbft.PublicKey, sign []byte) error { - k := key.(*publicKey) - if k.PublicKey.VerifyHashable(sign, uint32(n.network), &n.Block) { + k := key.(*keys.PublicKey) + if k.VerifyHashable(sign, uint32(n.network), &n.Block) { return nil } return errors.New("verification failed") diff --git a/pkg/consensus/block_test.go b/pkg/consensus/block_test.go index f1e206da9..67a9e2488 100644 --- a/pkg/consensus/block_test.go +++ b/pkg/consensus/block_test.go @@ -16,7 +16,7 @@ func TestNeoBlock_Sign(t *testing.T) { priv, _ := keys.NewPrivateKey() require.NoError(t, b.Sign(&privateKey{PrivateKey: priv})) - require.NoError(t, b.Verify(&publicKey{PublicKey: priv.PublicKey()}, b.Signature())) + require.NoError(t, b.Verify(priv.PublicKey(), b.Signature())) } func TestNeoBlock_Setters(t *testing.T) { diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index f77778ed4..6472d46da 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -248,7 +248,7 @@ func (s *service) newPayload(c *dbft.Context[util.Uint256], t dbft.MessageType, cp.Extensible.ValidBlockStart = 0 cp.Extensible.ValidBlockEnd = c.BlockIndex - cp.Extensible.Sender = c.Validators[c.MyIndex].(*publicKey).GetScriptHash() + cp.Extensible.Sender = c.Validators[c.MyIndex].(*keys.PublicKey).GetScriptHash() return cp } @@ -432,14 +432,14 @@ func (s *service) validatePayload(p *Payload) bool { } pub := validators[p.message.ValidatorIndex] - h := pub.(*publicKey).GetScriptHash() + h := pub.(*keys.PublicKey).GetScriptHash() return p.Sender == h } 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() + sh := pubs[i].(*keys.PublicKey).GetScriptHash() acc := s.wallet.GetAccount(sh) if acc == nil { continue @@ -453,7 +453,7 @@ func (s *service) getKeyPair(pubs []dbft.PublicKey) (int, dbft.PrivateKey, dbft. } } - return i, &privateKey{PrivateKey: acc.PrivateKey()}, &publicKey{PublicKey: acc.PublicKey()} + return i, &privateKey{PrivateKey: acc.PrivateKey()}, acc.PublicKey() } } return -1, nil, nil @@ -737,7 +737,7 @@ func (s *service) getValidators(txes ...dbft.Transaction[util.Uint256]) []dbft.P pubs := make([]dbft.PublicKey, len(pKeys)) for i := range pKeys { - pubs[i] = &publicKey{PublicKey: pKeys[i]} + pubs[i] = pKeys[i] } return pubs @@ -746,7 +746,7 @@ func (s *service) getValidators(txes ...dbft.Transaction[util.Uint256]) []dbft.P func convertKeys(validators []dbft.PublicKey) (pubs []*keys.PublicKey) { pubs = make([]*keys.PublicKey, len(validators)) for i, k := range validators { - pubs[i] = k.(*publicKey).PublicKey + pubs[i] = k.(*keys.PublicKey) } return diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index 72242cc8f..df1dd8a86 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -532,9 +532,9 @@ func (bq testBlockQueuer) PutBlock(b *coreb.Block) error { return bq.bc.AddBlock(b) } -func getTestValidator(i int) (*privateKey, *publicKey) { +func getTestValidator(i int) (*privateKey, *keys.PublicKey) { key := testchain.PrivateKey(i) - return &privateKey{PrivateKey: key}, &publicKey{PublicKey: key.PublicKey()} + return &privateKey{PrivateKey: key}, key.PublicKey() } func newSingleTestChain(t *testing.T) *core.Blockchain { diff --git a/pkg/consensus/crypto.go b/pkg/consensus/crypto.go index e2382bc94..647282426 100644 --- a/pkg/consensus/crypto.go +++ b/pkg/consensus/crypto.go @@ -1,9 +1,6 @@ package consensus import ( - "crypto/sha256" - "errors" - "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" ) @@ -20,31 +17,3 @@ var _ dbft.PrivateKey = &privateKey{} func (p *privateKey) Sign(data []byte) ([]byte, error) { return p.PrivateKey.Sign(data), nil } - -// publicKey is a wrapper around keys.PublicKey -// which implements the crypto.PublicKey interface. -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 -} - -// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. -func (p *publicKey) UnmarshalBinary(data []byte) error { - return p.PublicKey.DecodeBytes(data) -} - -// Verify implements the crypto.PublicKey interface. -func (p publicKey) Verify(msg, sig []byte) error { - hash := sha256.Sum256(msg) - if p.PublicKey.Verify(sig, hash[:]) { - return nil - } - - return errors.New("error") -} diff --git a/pkg/consensus/crypto_test.go b/pkg/consensus/crypto_test.go index f21fe5df9..8ba0b9c95 100644 --- a/pkg/consensus/crypto_test.go +++ b/pkg/consensus/crypto_test.go @@ -1,6 +1,7 @@ package consensus import ( + "crypto/sha256" "testing" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -13,24 +14,15 @@ func TestCrypt(t *testing.T) { priv := privateKey{key} - key1, err := keys.NewPrivateKey() - require.NoError(t, err) + pub := key.PublicKey() - pub := publicKey{key.PublicKey()} - data, err := pub.MarshalBinary() - require.NoError(t, err) - - pub1 := publicKey{key1.PublicKey()} - require.NotEqual(t, pub, pub1) - require.NoError(t, pub1.UnmarshalBinary(data)) - require.Equal(t, pub, pub1) - - data = []byte{1, 2, 3, 4} + data := []byte{1, 2, 3, 4} + hash := sha256.Sum256(data) sign, err := priv.Sign(data) require.NoError(t, err) - require.NoError(t, pub.Verify(data, sign)) + require.True(t, pub.Verify(sign, hash[:])) sign[0] = ^sign[0] - require.Error(t, pub.Verify(data, sign)) + require.False(t, pub.Verify(sign, hash[:])) } diff --git a/pkg/consensus/payload.go b/pkg/consensus/payload.go index 9ed6ca880..4f2ba0671 100644 --- a/pkg/consensus/payload.go +++ b/pkg/consensus/payload.go @@ -79,6 +79,10 @@ func (p Payload) GetPrepareResponse() dbft.PrepareResponse[util.Uint256] { return p.payload.(dbft.PrepareResponse[util.Uint256]) } +// GetPreCommit implements the payload.ConsensusPayload interface. +// It's a stub since PreCommits are never used on N3. +func (p Payload) GetPreCommit() dbft.PreCommit { return nil } + // GetCommit implements the payload.ConsensusPayload interface. func (p Payload) GetCommit() dbft.Commit { return p.payload.(dbft.Commit) } diff --git a/pkg/consensus/recovery_message.go b/pkg/consensus/recovery_message.go index 7d3ad3a12..3f805f5a9 100644 --- a/pkg/consensus/recovery_message.go +++ b/pkg/consensus/recovery_message.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/nspcc-dev/dbft" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "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" @@ -202,7 +203,7 @@ func (m *recoveryMessage) GetPrepareRequest(p dbft.ConsensusPayload[util.Uint256 req := fromPayload(prepareRequestType, p.(*Payload), m.prepareRequest.payload) req.message.ValidatorIndex = byte(primary) - req.Sender = validators[primary].(*publicKey).GetScriptHash() + req.Sender = validators[primary].(*keys.PublicKey).GetScriptHash() req.Witness.InvocationScript = compact.InvocationScript req.Witness.VerificationScript = getVerificationScript(uint8(primary), validators) @@ -222,7 +223,7 @@ func (m *recoveryMessage) GetPrepareResponses(p dbft.ConsensusPayload[util.Uint2 preparationHash: *m.preparationHash, }) r.message.ValidatorIndex = resp.ValidatorIndex - r.Sender = validators[resp.ValidatorIndex].(*publicKey).GetScriptHash() + r.Sender = validators[resp.ValidatorIndex].(*keys.PublicKey).GetScriptHash() r.Witness.InvocationScript = resp.InvocationScript r.Witness.VerificationScript = getVerificationScript(resp.ValidatorIndex, validators) @@ -243,7 +244,7 @@ func (m *recoveryMessage) GetChangeViews(p dbft.ConsensusPayload[util.Uint256], }) c.message.ViewNumber = cv.OriginalViewNumber c.message.ValidatorIndex = cv.ValidatorIndex - c.Sender = validators[cv.ValidatorIndex].(*publicKey).GetScriptHash() + c.Sender = validators[cv.ValidatorIndex].(*keys.PublicKey).GetScriptHash() c.Witness.InvocationScript = cv.InvocationScript c.Witness.VerificationScript = getVerificationScript(cv.ValidatorIndex, validators) @@ -253,6 +254,12 @@ func (m *recoveryMessage) GetChangeViews(p dbft.ConsensusPayload[util.Uint256], return ps } +// GetPreCommits implements the payload.RecoveryMessage interface. It's a stub +// since N3 doesn't use extension enabling them. +func (m *recoveryMessage) GetPreCommits(p dbft.ConsensusPayload[util.Uint256], validators []dbft.PublicKey) []dbft.ConsensusPayload[util.Uint256] { + return nil +} + // GetCommits implements the payload.RecoveryMessage interface. 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)) @@ -260,7 +267,7 @@ func (m *recoveryMessage) GetCommits(p dbft.ConsensusPayload[util.Uint256], vali for i, c := range m.commitPayloads { cc := fromPayload(commitType, p.(*Payload), &commit{signature: c.Signature}) cc.message.ValidatorIndex = c.ValidatorIndex - cc.Sender = validators[c.ValidatorIndex].(*publicKey).GetScriptHash() + cc.Sender = validators[c.ValidatorIndex].(*keys.PublicKey).GetScriptHash() cc.Witness.InvocationScript = c.InvocationScript cc.Witness.VerificationScript = getVerificationScript(c.ValidatorIndex, validators) @@ -280,7 +287,7 @@ func getVerificationScript(i uint8, validators []dbft.PublicKey) []byte { return nil } - pub, ok := validators[i].(*publicKey) + pub, ok := validators[i].(*keys.PublicKey) if !ok { return nil }