core: add P2PNotary designated role

This commit is contained in:
Anna Shaleva 2020-11-18 11:59:34 +03:00
parent 619b6d4132
commit b00eb51c55
5 changed files with 35 additions and 14 deletions

View file

@ -17,6 +17,7 @@ ProtocolConfiguration:
- 127.0.0.1:20336 - 127.0.0.1:20336
VerifyBlocks: true VerifyBlocks: true
VerifyTransactions: true VerifyTransactions: true
P2PSigExtensions: true
ApplicationConfiguration: ApplicationConfiguration:
# LogPath could be set up in case you need stdout logs to some proper file. # LogPath could be set up in case you need stdout logs to some proper file.

View file

@ -171,7 +171,7 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L
subCh: make(chan interface{}), subCh: make(chan interface{}),
unsubCh: make(chan interface{}), unsubCh: make(chan interface{}),
contracts: *native.NewContracts(), contracts: *native.NewContracts(cfg.P2PSigExtensions),
} }
if err := bc.init(); err != nil { if err := bc.init(); err != nil {

View file

@ -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 // NewContracts returns new set of native contracts with new GAS, NEO and Policy
// contracts. // contracts.
func NewContracts() *Contracts { func NewContracts(p2pSigExtensionsEnabled bool) *Contracts {
cs := new(Contracts) cs := new(Contracts)
gas := newGAS() gas := newGAS()
@ -72,7 +72,7 @@ func NewContracts() *Contracts {
cs.Oracle = oracle cs.Oracle = oracle
cs.Contracts = append(cs.Contracts, oracle) cs.Contracts = append(cs.Contracts, oracle)
desig := newDesignate() desig := newDesignate(p2pSigExtensionsEnabled)
desig.NEO = neo desig.NEO = neo
cs.Designate = desig cs.Designate = desig
cs.Oracle.Desig = desig cs.Oracle.Desig = desig

View file

@ -27,6 +27,9 @@ type Designate struct {
rolesChangedFlag atomic.Value rolesChangedFlag atomic.Value
oracles atomic.Value oracles atomic.Value
// p2pSigExtensionsEnabled defines whether the P2P signature extensions logic is relevant.
p2pSigExtensionsEnabled bool
} }
type oraclesData struct { type oraclesData struct {
@ -50,6 +53,7 @@ type Role byte
const ( const (
RoleStateValidator Role = 4 RoleStateValidator Role = 4
RoleOracle Role = 8 RoleOracle Role = 8
RoleP2PNotary Role = 128
) )
// Various errors. // Various errors.
@ -62,13 +66,14 @@ var (
ErrNoBlock = errors.New("no persisting block in the context") ErrNoBlock = errors.New("no persisting block in the context")
) )
func isValidRole(r Role) bool { func (s *Designate) isValidRole(r Role) bool {
return r == RoleOracle || r == RoleStateValidator return r == RoleOracle || r == RoleStateValidator || (s.p2pSigExtensionsEnabled && r == RoleP2PNotary)
} }
func newDesignate() *Designate { func newDesignate(p2pSigExtensionsEnabled bool) *Designate {
s := &Designate{ContractMD: *interop.NewContractMD(designateName)} s := &Designate{ContractMD: *interop.NewContractMD(designateName)}
s.ContractID = designateContractID s.ContractID = designateContractID
s.p2pSigExtensionsEnabled = p2pSigExtensionsEnabled
desc := newDescriptor("getDesignatedByRole", smartcontract.ArrayType, desc := newDescriptor("getDesignatedByRole", smartcontract.ArrayType,
manifest.NewParameter("role", smartcontract.IntegerType), 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 { 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 { if !ok {
panic(ErrInvalidRole) 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) { func (s *Designate) getLastDesignatedHash(d dao.DAO, r Role) (util.Uint160, error) {
if !isValidRole(r) { if !s.isValidRole(r) {
return util.Uint160{}, ErrInvalidRole return util.Uint160{}, ErrInvalidRole
} }
if r == RoleOracle && !s.rolesChanged() { 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. // GetDesignatedByRole returns nodes for role r.
func (s *Designate) GetDesignatedByRole(d dao.DAO, r Role, index uint32) (keys.PublicKeys, uint32, error) { 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 return nil, 0, ErrInvalidRole
} }
if r == RoleOracle && !s.rolesChanged() { 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 { 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 { if !ok {
panic(ErrInvalidRole) panic(ErrInvalidRole)
} }
@ -239,7 +244,7 @@ func (s *Designate) DesignateAsRole(ic *interop.Context, r Role, pubs keys.Publi
if length > maxNodeCount { if length > maxNodeCount {
return ErrLargeNodeList return ErrLargeNodeList
} }
if !isValidRole(r) { if !s.isValidRole(r) {
return ErrInvalidRole return ErrInvalidRole
} }
h := s.NEO.GetCommitteeAddress() 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) 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() bi, err := item.TryInteger()
if err != nil { if err != nil {
return 0, false return 0, false
@ -272,5 +277,5 @@ func getRole(item stackitem.Item) (Role, bool) {
return 0, false return 0, false
} }
u := bi.Uint64() u := bi.Uint64()
return Role(u), u <= math.MaxUint8 && isValidRole(Role(u)) return Role(u), u <= math.MaxUint8 && s.isValidRole(Role(u))
} }

View file

@ -163,7 +163,7 @@ func TestDesignate_DesignateAsRole(t *testing.T) {
require.Equal(t, 0, len(pubs)) require.Equal(t, 0, len(pubs))
require.Equal(t, uint32(0), index) require.Equal(t, uint32(0), index)
// Set another role. // Set StateValidator role.
_, err = keys.NewPrivateKey() _, err = keys.NewPrivateKey()
require.NoError(t, err) require.NoError(t, err)
pub1 := priv.PublicKey() pub1 := priv.PublicKey()
@ -180,4 +180,19 @@ func TestDesignate_DesignateAsRole(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, keys.PublicKeys{pub1}, pubs) require.Equal(t, keys.PublicKeys{pub1}, pubs)
require.Equal(t, bl.Index+1, index) 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)
} }