forked from TrueCloudLab/frostfs-contract
[#174] subnet: Add NodeAllowed
method
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
4b47bfadcd
commit
b5db977e62
2 changed files with 47 additions and 6 deletions
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/native/management"
|
"github.com/nspcc-dev/neo-go/pkg/interop/native/management"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
"github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/util"
|
|
||||||
"github.com/nspcc-dev/neofs-contract/common"
|
"github.com/nspcc-dev/neofs-contract/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,6 +17,8 @@ const (
|
||||||
ErrInvalidOwner = "invalid owner"
|
ErrInvalidOwner = "invalid owner"
|
||||||
// ErrInvalidAdmin is thrown when admin has invalid format.
|
// ErrInvalidAdmin is thrown when admin has invalid format.
|
||||||
ErrInvalidAdmin = "invalid administrator"
|
ErrInvalidAdmin = "invalid administrator"
|
||||||
|
// ErrInvalidNode is thrown when node has invalid format.
|
||||||
|
ErrInvalidNode = "invalid node key"
|
||||||
// ErrAlreadyExists is thrown when id already exists.
|
// ErrAlreadyExists is thrown when id already exists.
|
||||||
ErrAlreadyExists = "subnet id already exists"
|
ErrAlreadyExists = "subnet id already exists"
|
||||||
// ErrSubNotExist is thrown when id doesn't exist.
|
// ErrSubNotExist is thrown when id doesn't exist.
|
||||||
|
@ -214,7 +215,7 @@ func RemoveNodeAdmin(subnetID []byte, adminKey interop.PublicKey) {
|
||||||
// only.
|
// only.
|
||||||
func AddNode(subnetID []byte, node interop.PublicKey) {
|
func AddNode(subnetID []byte, node interop.PublicKey) {
|
||||||
if len(node) != interop.PublicKeyCompressedLen {
|
if len(node) != interop.PublicKeyCompressedLen {
|
||||||
panic("addNode: " + ErrInvalidAdmin)
|
panic("addNode: " + ErrInvalidNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := storage.GetContext()
|
ctx := storage.GetContext()
|
||||||
|
@ -261,7 +262,7 @@ func AddNode(subnetID []byte, node interop.PublicKey) {
|
||||||
// only.
|
// only.
|
||||||
func RemoveNode(subnetID []byte, node interop.PublicKey) {
|
func RemoveNode(subnetID []byte, node interop.PublicKey) {
|
||||||
if len(node) != interop.PublicKeyCompressedLen {
|
if len(node) != interop.PublicKeyCompressedLen {
|
||||||
panic("removeNode: " + ErrInvalidAdmin)
|
panic("removeNode: " + ErrInvalidNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := storage.GetContext()
|
ctx := storage.GetContext()
|
||||||
|
@ -305,6 +306,27 @@ func RemoveNode(subnetID []byte, node interop.PublicKey) {
|
||||||
runtime.Notify("NodeRemove", subnetID, node)
|
runtime.Notify("NodeRemove", subnetID, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NodeAllowed checks if node is included in the
|
||||||
|
// specified subnet or not.
|
||||||
|
func NodeAllowed(subnetID []byte, node interop.PublicKey) bool {
|
||||||
|
if len(node) != interop.PublicKeyCompressedLen {
|
||||||
|
panic("nodeAllowed: " + ErrInvalidNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := storage.GetReadOnlyContext()
|
||||||
|
|
||||||
|
stKey := append([]byte{ownerPrefix}, subnetID...)
|
||||||
|
|
||||||
|
rawOwner := storage.Get(ctx, stKey)
|
||||||
|
if rawOwner == nil {
|
||||||
|
panic("nodeAllowed: " + ErrSubNotExist)
|
||||||
|
}
|
||||||
|
|
||||||
|
stKey[0] = nodePrefix
|
||||||
|
|
||||||
|
return storage.Get(ctx, append(stKey, node...)) != nil
|
||||||
|
}
|
||||||
|
|
||||||
// Version returns version of the contract.
|
// Version returns version of the contract.
|
||||||
func Version() int {
|
func Version() int {
|
||||||
return common.Version
|
return common.Version
|
||||||
|
@ -316,7 +338,7 @@ func keyInList(ctx storage.Context, searchedKey interop.PublicKey, prefix []byte
|
||||||
iter := storage.Find(ctx, prefix, storage.KeysOnly)
|
iter := storage.Find(ctx, prefix, storage.KeysOnly)
|
||||||
for iterator.Next(iter) {
|
for iterator.Next(iter) {
|
||||||
key := iterator.Value(iter).([]byte)
|
key := iterator.Value(iter).([]byte)
|
||||||
if util.Equals(string(key[prefixLen:]), string(searchedKey)) {
|
if common.BytesEqual(key[prefixLen:], searchedKey) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ func TestSubnet_AddNode(t *testing.T) {
|
||||||
const method = "addNode"
|
const method = "addNode"
|
||||||
|
|
||||||
cOwn := e.WithSigners(owner)
|
cOwn := e.WithSigners(owner)
|
||||||
cOwn.InvokeFail(t, method+errSeparator+subnet.ErrInvalidAdmin, method, id, nodePub[1:])
|
cOwn.InvokeFail(t, method+errSeparator+subnet.ErrInvalidNode, method, id, nodePub[1:])
|
||||||
|
|
||||||
cOwn.Invoke(t, stackitem.Null{}, method, id, nodePub)
|
cOwn.Invoke(t, stackitem.Null{}, method, id, nodePub)
|
||||||
cOwn.InvokeFail(t, method+errSeparator+"node has already been added", method, id, nodePub)
|
cOwn.InvokeFail(t, method+errSeparator+"node has already been added", method, id, nodePub)
|
||||||
|
@ -158,7 +158,7 @@ func TestSubnet_RemoveNode(t *testing.T) {
|
||||||
const method = "removeNode"
|
const method = "removeNode"
|
||||||
|
|
||||||
cOwn := e.WithSigners(owner)
|
cOwn := e.WithSigners(owner)
|
||||||
cOwn.InvokeFail(t, method+errSeparator+subnet.ErrInvalidAdmin, method, id, nodePub[1:])
|
cOwn.InvokeFail(t, method+errSeparator+subnet.ErrInvalidNode, method, id, nodePub[1:])
|
||||||
cOwn.InvokeFail(t, method+errSeparator+subnet.ErrNodeNotExist, method, id, nodePub)
|
cOwn.InvokeFail(t, method+errSeparator+subnet.ErrNodeNotExist, method, id, nodePub)
|
||||||
|
|
||||||
cOwn.Invoke(t, stackitem.Null{}, "addNode", id, nodePub)
|
cOwn.Invoke(t, stackitem.Null{}, "addNode", id, nodePub)
|
||||||
|
@ -170,6 +170,25 @@ func TestSubnet_RemoveNode(t *testing.T) {
|
||||||
cAdm.InvokeFail(t, method+errSeparator+subnet.ErrNodeNotExist, method, id, nodePub)
|
cAdm.InvokeFail(t, method+errSeparator+subnet.ErrNodeNotExist, method, id, nodePub)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSubnet_NodeAllowed(t *testing.T) {
|
||||||
|
e := newSubnetInvoker(t)
|
||||||
|
|
||||||
|
id, owner := createSubnet(t, e)
|
||||||
|
|
||||||
|
node := e.NewAccount(t)
|
||||||
|
nodePub, ok := vm.ParseSignatureContract(node.Script())
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
const method = "nodeAllowed"
|
||||||
|
|
||||||
|
cOwn := e.WithSigners(owner)
|
||||||
|
cOwn.InvokeFail(t, method+errSeparator+subnet.ErrInvalidNode, method, id, nodePub[1:])
|
||||||
|
cOwn.Invoke(t, stackitem.NewBool(false), method, id, nodePub)
|
||||||
|
|
||||||
|
cOwn.Invoke(t, stackitem.Null{}, "addNode", id, nodePub)
|
||||||
|
cOwn.Invoke(t, stackitem.NewBool(true), method, id, nodePub)
|
||||||
|
}
|
||||||
|
|
||||||
func createSubnet(t *testing.T, e *neotest.ContractInvoker) (id []byte, owner neotest.Signer) {
|
func createSubnet(t *testing.T, e *neotest.ContractInvoker) (id []byte, owner neotest.Signer) {
|
||||||
var (
|
var (
|
||||||
ok bool
|
ok bool
|
||||||
|
|
Loading…
Reference in a new issue