From b00eb51c55d196741a60a2d682861fea76d0b3e6 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Wed, 18 Nov 2020 11:59:34 +0300 Subject: [PATCH] core: add P2PNotary designated role --- config/protocol.unit_testnet.yml | 1 + pkg/core/blockchain.go | 2 +- pkg/core/native/contract.go | 4 ++-- pkg/core/native/designate.go | 25 +++++++++++++++---------- pkg/core/native_designate_test.go | 17 ++++++++++++++++- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/config/protocol.unit_testnet.yml b/config/protocol.unit_testnet.yml index c74b4168a..e63b288ee 100644 --- a/config/protocol.unit_testnet.yml +++ b/config/protocol.unit_testnet.yml @@ -17,6 +17,7 @@ ProtocolConfiguration: - 127.0.0.1:20336 VerifyBlocks: true VerifyTransactions: true + P2PSigExtensions: true ApplicationConfiguration: # LogPath could be set up in case you need stdout logs to some proper file. diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 878261691..d8a53a2e4 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -171,7 +171,7 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L subCh: make(chan interface{}), unsubCh: make(chan interface{}), - contracts: *native.NewContracts(), + contracts: *native.NewContracts(cfg.P2PSigExtensions), } if err := bc.init(); err != nil { diff --git a/pkg/core/native/contract.go b/pkg/core/native/contract.go index a32dbc827..b34c2578c 100644 --- a/pkg/core/native/contract.go +++ b/pkg/core/native/contract.go @@ -49,7 +49,7 @@ func (cs *Contracts) ByName(name string) interop.Contract { // NewContracts returns new set of native contracts with new GAS, NEO and Policy // contracts. -func NewContracts() *Contracts { +func NewContracts(p2pSigExtensionsEnabled bool) *Contracts { cs := new(Contracts) gas := newGAS() @@ -72,7 +72,7 @@ func NewContracts() *Contracts { cs.Oracle = oracle cs.Contracts = append(cs.Contracts, oracle) - desig := newDesignate() + desig := newDesignate(p2pSigExtensionsEnabled) desig.NEO = neo cs.Designate = desig cs.Oracle.Desig = desig diff --git a/pkg/core/native/designate.go b/pkg/core/native/designate.go index 7440d8213..1f426ec5c 100644 --- a/pkg/core/native/designate.go +++ b/pkg/core/native/designate.go @@ -27,6 +27,9 @@ type Designate struct { rolesChangedFlag atomic.Value oracles atomic.Value + + // p2pSigExtensionsEnabled defines whether the P2P signature extensions logic is relevant. + p2pSigExtensionsEnabled bool } type oraclesData struct { @@ -50,6 +53,7 @@ type Role byte const ( RoleStateValidator Role = 4 RoleOracle Role = 8 + RoleP2PNotary Role = 128 ) // Various errors. @@ -62,13 +66,14 @@ var ( ErrNoBlock = errors.New("no persisting block in the context") ) -func isValidRole(r Role) bool { - return r == RoleOracle || r == RoleStateValidator +func (s *Designate) isValidRole(r Role) bool { + return r == RoleOracle || r == RoleStateValidator || (s.p2pSigExtensionsEnabled && r == RoleP2PNotary) } -func newDesignate() *Designate { +func newDesignate(p2pSigExtensionsEnabled bool) *Designate { s := &Designate{ContractMD: *interop.NewContractMD(designateName)} s.ContractID = designateContractID + s.p2pSigExtensionsEnabled = p2pSigExtensionsEnabled desc := newDescriptor("getDesignatedByRole", smartcontract.ArrayType, manifest.NewParameter("role", smartcontract.IntegerType), @@ -121,7 +126,7 @@ func (s *Designate) Metadata() *interop.ContractMD { } func (s *Designate) getDesignatedByRole(ic *interop.Context, args []stackitem.Item) stackitem.Item { - r, ok := getRole(args[0]) + r, ok := s.getRole(args[0]) if !ok { panic(ErrInvalidRole) } @@ -154,7 +159,7 @@ func oracleHashFromNodes(nodes keys.PublicKeys) util.Uint160 { } func (s *Designate) getLastDesignatedHash(d dao.DAO, r Role) (util.Uint160, error) { - if !isValidRole(r) { + if !s.isValidRole(r) { return util.Uint160{}, ErrInvalidRole } if r == RoleOracle && !s.rolesChanged() { @@ -174,7 +179,7 @@ func (s *Designate) getLastDesignatedHash(d dao.DAO, r Role) (util.Uint160, erro // GetDesignatedByRole returns nodes for role r. func (s *Designate) GetDesignatedByRole(d dao.DAO, r Role, index uint32) (keys.PublicKeys, uint32, error) { - if !isValidRole(r) { + if !s.isValidRole(r) { return nil, 0, ErrInvalidRole } if r == RoleOracle && !s.rolesChanged() { @@ -214,7 +219,7 @@ func (s *Designate) GetDesignatedByRole(d dao.DAO, r Role, index uint32) (keys.P } func (s *Designate) designateAsRole(ic *interop.Context, args []stackitem.Item) stackitem.Item { - r, ok := getRole(args[0]) + r, ok := s.getRole(args[0]) if !ok { panic(ErrInvalidRole) } @@ -239,7 +244,7 @@ func (s *Designate) DesignateAsRole(ic *interop.Context, r Role, pubs keys.Publi if length > maxNodeCount { return ErrLargeNodeList } - if !isValidRole(r) { + if !s.isValidRole(r) { return ErrInvalidRole } h := s.NEO.GetCommitteeAddress() @@ -263,7 +268,7 @@ func (s *Designate) DesignateAsRole(ic *interop.Context, r Role, pubs keys.Publi return ic.DAO.PutStorageItem(s.ContractID, key, si) } -func getRole(item stackitem.Item) (Role, bool) { +func (s *Designate) getRole(item stackitem.Item) (Role, bool) { bi, err := item.TryInteger() if err != nil { return 0, false @@ -272,5 +277,5 @@ func getRole(item stackitem.Item) (Role, bool) { return 0, false } u := bi.Uint64() - return Role(u), u <= math.MaxUint8 && isValidRole(Role(u)) + return Role(u), u <= math.MaxUint8 && s.isValidRole(Role(u)) } diff --git a/pkg/core/native_designate_test.go b/pkg/core/native_designate_test.go index 4c4e78779..697821f00 100644 --- a/pkg/core/native_designate_test.go +++ b/pkg/core/native_designate_test.go @@ -163,7 +163,7 @@ func TestDesignate_DesignateAsRole(t *testing.T) { require.Equal(t, 0, len(pubs)) require.Equal(t, uint32(0), index) - // Set another role. + // Set StateValidator role. _, err = keys.NewPrivateKey() require.NoError(t, err) pub1 := priv.PublicKey() @@ -180,4 +180,19 @@ func TestDesignate_DesignateAsRole(t *testing.T) { require.NoError(t, err) require.Equal(t, keys.PublicKeys{pub1}, pubs) require.Equal(t, bl.Index+1, index) + + // Set P2PNotary role. + pubs, index, err = des.GetDesignatedByRole(ic.DAO, native.RoleP2PNotary, 255) + require.NoError(t, err) + require.Equal(t, 0, len(pubs)) + require.Equal(t, uint32(0), index) + + err = des.DesignateAsRole(ic, native.RoleP2PNotary, keys.PublicKeys{pub1}) + require.NoError(t, err) + require.NoError(t, des.OnPersistEnd(ic.DAO)) + + pubs, index, err = des.GetDesignatedByRole(ic.DAO, native.RoleP2PNotary, 255) + require.NoError(t, err) + require.Equal(t, keys.PublicKeys{pub1}, pubs) + require.Equal(t, bl.Index+1, index) }