core: add P2PNotary designated role
This commit is contained in:
parent
619b6d4132
commit
b00eb51c55
5 changed files with 35 additions and 14 deletions
|
@ -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.
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue