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
VerifyBlocks: true
VerifyTransactions: true
P2PSigExtensions: true
ApplicationConfiguration:
# 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{}),
unsubCh: make(chan interface{}),
contracts: *native.NewContracts(),
contracts: *native.NewContracts(cfg.P2PSigExtensions),
}
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
// 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

View file

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

View file

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