Merge pull request #3541 from nspcc-dev/up-dbft

dbft: update to AMEV-enabled version
This commit is contained in:
Anna Shaleva 2024-08-06 15:44:56 +03:00 committed by GitHub
commit 7e8fda6b6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 37 additions and 64 deletions

2
go.mod
View file

@ -14,7 +14,7 @@ require (
github.com/holiman/uint256 v1.2.4 github.com/holiman/uint256 v1.2.4
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/mr-tron/base58 v1.2.0 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/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/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.12 github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.12

4
go.sum
View file

@ -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/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 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= 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.3.0 h1:P9dFQje43sabA6w89l1OqGe1BvnO7DdHcu27w6mfnOE=
github.com/nspcc-dev/dbft v0.2.0/go.mod h1:oFE6paSC/yfFh9mcNU6MheMGOYXK9+sPiRk3YMoz49o= 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 h1:mD9hU3v+zJcnHAVmHnZKt3I++tvn30gBj2rP2PocZMk=
github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2/go.mod h1:U5VfmPNM88P4RORFb6KSUVBdJBDhlqggJZYGXGPxOcc= 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= github.com/nspcc-dev/hrw/v2 v2.0.1 h1:CxYUkBeJvNfMEn2lHhrV6FjY8pZPceSxXUtMVq0BUOU=

View file

@ -7,6 +7,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/config/netmode"
coreb "github.com/nspcc-dev/neo-go/pkg/core/block" 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/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/util" "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. // Verify implements the block.Block interface.
func (n *neoBlock) Verify(key dbft.PublicKey, sign []byte) error { func (n *neoBlock) Verify(key dbft.PublicKey, sign []byte) error {
k := key.(*publicKey) k := key.(*keys.PublicKey)
if k.PublicKey.VerifyHashable(sign, uint32(n.network), &n.Block) { if k.VerifyHashable(sign, uint32(n.network), &n.Block) {
return nil return nil
} }
return errors.New("verification failed") return errors.New("verification failed")

View file

@ -16,7 +16,7 @@ func TestNeoBlock_Sign(t *testing.T) {
priv, _ := keys.NewPrivateKey() priv, _ := keys.NewPrivateKey()
require.NoError(t, b.Sign(&privateKey{PrivateKey: priv})) 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) { func TestNeoBlock_Setters(t *testing.T) {

View file

@ -248,7 +248,7 @@ func (s *service) newPayload(c *dbft.Context[util.Uint256], t dbft.MessageType,
cp.Extensible.ValidBlockStart = 0 cp.Extensible.ValidBlockStart = 0
cp.Extensible.ValidBlockEnd = c.BlockIndex 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 return cp
} }
@ -432,14 +432,14 @@ func (s *service) validatePayload(p *Payload) bool {
} }
pub := validators[p.message.ValidatorIndex] pub := validators[p.message.ValidatorIndex]
h := pub.(*publicKey).GetScriptHash() h := pub.(*keys.PublicKey).GetScriptHash()
return p.Sender == h return p.Sender == h
} }
func (s *service) getKeyPair(pubs []dbft.PublicKey) (int, dbft.PrivateKey, dbft.PublicKey) { func (s *service) getKeyPair(pubs []dbft.PublicKey) (int, dbft.PrivateKey, dbft.PublicKey) {
if s.wallet != nil { if s.wallet != nil {
for i := range pubs { for i := range pubs {
sh := pubs[i].(*publicKey).GetScriptHash() sh := pubs[i].(*keys.PublicKey).GetScriptHash()
acc := s.wallet.GetAccount(sh) acc := s.wallet.GetAccount(sh)
if acc == nil { if acc == nil {
continue 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 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)) pubs := make([]dbft.PublicKey, len(pKeys))
for i := range pKeys { for i := range pKeys {
pubs[i] = &publicKey{PublicKey: pKeys[i]} pubs[i] = pKeys[i]
} }
return pubs 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) { func convertKeys(validators []dbft.PublicKey) (pubs []*keys.PublicKey) {
pubs = make([]*keys.PublicKey, len(validators)) pubs = make([]*keys.PublicKey, len(validators))
for i, k := range validators { for i, k := range validators {
pubs[i] = k.(*publicKey).PublicKey pubs[i] = k.(*keys.PublicKey)
} }
return return

View file

@ -532,9 +532,9 @@ func (bq testBlockQueuer) PutBlock(b *coreb.Block) error {
return bq.bc.AddBlock(b) return bq.bc.AddBlock(b)
} }
func getTestValidator(i int) (*privateKey, *publicKey) { func getTestValidator(i int) (*privateKey, *keys.PublicKey) {
key := testchain.PrivateKey(i) 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 { func newSingleTestChain(t *testing.T) *core.Blockchain {

View file

@ -1,9 +1,6 @@
package consensus package consensus
import ( import (
"crypto/sha256"
"errors"
"github.com/nspcc-dev/dbft" "github.com/nspcc-dev/dbft"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "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) { func (p *privateKey) Sign(data []byte) ([]byte, error) {
return p.PrivateKey.Sign(data), nil 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")
}

View file

@ -1,6 +1,7 @@
package consensus package consensus
import ( import (
"crypto/sha256"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@ -13,24 +14,15 @@ func TestCrypt(t *testing.T) {
priv := privateKey{key} priv := privateKey{key}
key1, err := keys.NewPrivateKey() pub := key.PublicKey()
require.NoError(t, err)
pub := publicKey{key.PublicKey()} data := []byte{1, 2, 3, 4}
data, err := pub.MarshalBinary() hash := sha256.Sum256(data)
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}
sign, err := priv.Sign(data) sign, err := priv.Sign(data)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, pub.Verify(data, sign)) require.True(t, pub.Verify(sign, hash[:]))
sign[0] = ^sign[0] sign[0] = ^sign[0]
require.Error(t, pub.Verify(data, sign)) require.False(t, pub.Verify(sign, hash[:]))
} }

View file

@ -79,6 +79,10 @@ func (p Payload) GetPrepareResponse() dbft.PrepareResponse[util.Uint256] {
return p.payload.(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. // GetCommit implements the payload.ConsensusPayload interface.
func (p Payload) GetCommit() dbft.Commit { return p.payload.(dbft.Commit) } func (p Payload) GetCommit() dbft.Commit { return p.payload.(dbft.Commit) }

View file

@ -4,6 +4,7 @@ import (
"errors" "errors"
"github.com/nspcc-dev/dbft" "github.com/nspcc-dev/dbft"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
npayload "github.com/nspcc-dev/neo-go/pkg/network/payload" npayload "github.com/nspcc-dev/neo-go/pkg/network/payload"
"github.com/nspcc-dev/neo-go/pkg/util" "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 := fromPayload(prepareRequestType, p.(*Payload), m.prepareRequest.payload)
req.message.ValidatorIndex = byte(primary) 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.InvocationScript = compact.InvocationScript
req.Witness.VerificationScript = getVerificationScript(uint8(primary), validators) req.Witness.VerificationScript = getVerificationScript(uint8(primary), validators)
@ -222,7 +223,7 @@ func (m *recoveryMessage) GetPrepareResponses(p dbft.ConsensusPayload[util.Uint2
preparationHash: *m.preparationHash, preparationHash: *m.preparationHash,
}) })
r.message.ValidatorIndex = resp.ValidatorIndex 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.InvocationScript = resp.InvocationScript
r.Witness.VerificationScript = getVerificationScript(resp.ValidatorIndex, validators) 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.ViewNumber = cv.OriginalViewNumber
c.message.ValidatorIndex = cv.ValidatorIndex 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.InvocationScript = cv.InvocationScript
c.Witness.VerificationScript = getVerificationScript(cv.ValidatorIndex, validators) c.Witness.VerificationScript = getVerificationScript(cv.ValidatorIndex, validators)
@ -253,6 +254,12 @@ func (m *recoveryMessage) GetChangeViews(p dbft.ConsensusPayload[util.Uint256],
return ps 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. // GetCommits implements the payload.RecoveryMessage interface.
func (m *recoveryMessage) GetCommits(p dbft.ConsensusPayload[util.Uint256], validators []dbft.PublicKey) []dbft.ConsensusPayload[util.Uint256] { 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)) 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 { for i, c := range m.commitPayloads {
cc := fromPayload(commitType, p.(*Payload), &commit{signature: c.Signature}) cc := fromPayload(commitType, p.(*Payload), &commit{signature: c.Signature})
cc.message.ValidatorIndex = c.ValidatorIndex 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.InvocationScript = c.InvocationScript
cc.Witness.VerificationScript = getVerificationScript(c.ValidatorIndex, validators) cc.Witness.VerificationScript = getVerificationScript(c.ValidatorIndex, validators)
@ -280,7 +287,7 @@ func getVerificationScript(i uint8, validators []dbft.PublicKey) []byte {
return nil return nil
} }
pub, ok := validators[i].(*publicKey) pub, ok := validators[i].(*keys.PublicKey)
if !ok { if !ok {
return nil return nil
} }