dbft: update to AMEV-enabled version

Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
Roman Khimov 2024-08-01 13:06:02 +03:00
parent d8e3e57f88
commit ee0d92c6d2
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/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

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/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=

View file

@ -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")

View file

@ -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) {

View file

@ -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

View file

@ -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 {

View file

@ -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")
}

View file

@ -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[:]))
}

View file

@ -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) }

View file

@ -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
}