forked from TrueCloudLab/frostfs-node
[#249] node: Drop subnet from IR and morph
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
d757d881d0
commit
f07d4158f5
41 changed files with 55 additions and 1935 deletions
|
@ -32,8 +32,6 @@ const (
|
|||
NNSNetmapContractName = "netmap.frostfs"
|
||||
// NNSProxyContractName is a name of the proxy contract in NNS.
|
||||
NNSProxyContractName = "proxy.frostfs"
|
||||
// NNSSubnetworkContractName is a name of the subnet contract in NNS.
|
||||
NNSSubnetworkContractName = "subnet.frostfs"
|
||||
// NNSGroupKeyName is a name for the FrostFS group key record in NNS.
|
||||
NNSGroupKeyName = "group.frostfs"
|
||||
)
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
package morphsubnet
|
||||
|
||||
import "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
|
||||
// ManageAdminsPrm groups parameters of administer methods of Subnet contract.
|
||||
//
|
||||
// Zero value adds node admin. Subnet, key and group must be specified via setters.
|
||||
type ManageAdminsPrm struct {
|
||||
// remove or add admin
|
||||
rm bool
|
||||
|
||||
// client or node admin
|
||||
client bool
|
||||
|
||||
subnet []byte
|
||||
|
||||
admin []byte
|
||||
|
||||
group []byte
|
||||
}
|
||||
|
||||
// SetRemove marks admin to be removed. By default, admin is added.
|
||||
func (x *ManageAdminsPrm) SetRemove() {
|
||||
x.rm = true
|
||||
}
|
||||
|
||||
// SetClient switches to client admin. By default, node admin is modified.
|
||||
func (x *ManageAdminsPrm) SetClient() {
|
||||
x.client = true
|
||||
}
|
||||
|
||||
// SetSubnet sets identifier of the subnet in a binary FrostFS API protocol format.
|
||||
func (x *ManageAdminsPrm) SetSubnet(id []byte) {
|
||||
x.subnet = id
|
||||
}
|
||||
|
||||
// SetAdmin sets admin's public key in a binary format.
|
||||
func (x *ManageAdminsPrm) SetAdmin(key []byte) {
|
||||
x.admin = key
|
||||
}
|
||||
|
||||
// SetGroup sets identifier of the client group in a binary FrostFS API protocol format.
|
||||
// Makes sense only for client admins (see ManageAdminsPrm.SetClient).
|
||||
func (x *ManageAdminsPrm) SetGroup(id []byte) {
|
||||
x.group = id
|
||||
}
|
||||
|
||||
// ManageAdminsRes groups the resulting values of node administer methods of Subnet contract.
|
||||
type ManageAdminsRes struct{}
|
||||
|
||||
// ManageAdmins manages admin list of the FrostFS subnet through Subnet contract calls.
|
||||
func (x Client) ManageAdmins(prm ManageAdminsPrm) (*ManageAdminsPrm, error) {
|
||||
var method string
|
||||
|
||||
args := make([]any, 1, 3)
|
||||
args[0] = prm.subnet
|
||||
|
||||
if prm.client {
|
||||
args = append(args, prm.group, prm.admin)
|
||||
|
||||
if prm.rm {
|
||||
method = removeClientAdminMethod
|
||||
} else {
|
||||
method = addClientAdminMethod
|
||||
}
|
||||
} else {
|
||||
args = append(args, prm.admin)
|
||||
|
||||
if prm.rm {
|
||||
method = removeNodeAdminMethod
|
||||
} else {
|
||||
method = addNodeAdminMethod
|
||||
}
|
||||
}
|
||||
|
||||
var prmInvoke client.InvokePrm
|
||||
|
||||
prmInvoke.SetMethod(method)
|
||||
prmInvoke.SetArgs(args...)
|
||||
|
||||
err := x.client.Invoke(prmInvoke)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return new(ManageAdminsPrm), nil
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
package morphsubnet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// Client represents Subnet contract client.
|
||||
//
|
||||
// Client should be preliminary initialized (see Init method).
|
||||
type Client struct {
|
||||
client *client.StaticClient
|
||||
}
|
||||
|
||||
// InitPrm groups parameters of Client's initialization.
|
||||
type InitPrm struct {
|
||||
base *client.Client
|
||||
|
||||
addr util.Uint160
|
||||
|
||||
modeSet bool
|
||||
mode Mode
|
||||
}
|
||||
|
||||
const (
|
||||
deleteMethod = "delete"
|
||||
getMethod = "get"
|
||||
putMethod = "put"
|
||||
|
||||
removeClientAdminMethod = "removeClientAdmin"
|
||||
addClientAdminMethod = "addClientAdmin"
|
||||
|
||||
userAllowedMethod = "userAllowed"
|
||||
removeUserMethod = "removeUser"
|
||||
addUserMethod = "addUser"
|
||||
|
||||
removeNodeAdminMethod = "removeNodeAdmin"
|
||||
addNodeAdminMethod = "addNodeAdmin"
|
||||
nodeAllowedMethod = "nodeAllowed"
|
||||
removeNodeMethod = "removeNode"
|
||||
addNodeMethod = "addNode"
|
||||
)
|
||||
|
||||
// SetBaseClient sets basic morph client.
|
||||
func (x *InitPrm) SetBaseClient(base *client.Client) {
|
||||
x.base = base
|
||||
}
|
||||
|
||||
// SetContractAddress sets address of Subnet contract in FrostFS sidechain.
|
||||
func (x *InitPrm) SetContractAddress(addr util.Uint160) {
|
||||
x.addr = addr
|
||||
}
|
||||
|
||||
// Mode regulates client work mode.
|
||||
type Mode uint8
|
||||
|
||||
const (
|
||||
_ Mode = iota
|
||||
|
||||
// NonNotary makes client to work in non-notary environment.
|
||||
NonNotary
|
||||
|
||||
// NotaryAlphabet makes client to use its internal key for signing the notary requests.
|
||||
NotaryAlphabet
|
||||
|
||||
// NotaryNonAlphabet makes client to not use its internal key for signing the notary requests.
|
||||
NotaryNonAlphabet
|
||||
)
|
||||
|
||||
// SetMode makes client to work with non-notary sidechain.
|
||||
// By default, NonNotary is used.
|
||||
func (x *InitPrm) SetMode(mode Mode) {
|
||||
x.modeSet = true
|
||||
x.mode = mode
|
||||
}
|
||||
|
||||
// Init initializes client with specified parameters.
|
||||
//
|
||||
// Base client must be set.
|
||||
func (x *Client) Init(prm InitPrm) error {
|
||||
if prm.base == nil {
|
||||
panic("missing base morph client")
|
||||
}
|
||||
|
||||
if !prm.modeSet {
|
||||
prm.mode = NonNotary
|
||||
}
|
||||
|
||||
var opts []client.StaticClientOption
|
||||
|
||||
switch prm.mode {
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid work mode %d", prm.mode))
|
||||
case NonNotary:
|
||||
case NotaryNonAlphabet:
|
||||
opts = []client.StaticClientOption{client.TryNotary()}
|
||||
case NotaryAlphabet:
|
||||
opts = []client.StaticClientOption{client.TryNotary(), client.AsAlphabet()}
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
x.client, err = client.NewStatic(prm.base, prm.addr, 0, opts...)
|
||||
|
||||
return err
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
package morphsubnet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
// UserAllowedPrm groups parameters of UserAllowed method of Subnet contract.
|
||||
type UserAllowedPrm struct {
|
||||
args [2]any
|
||||
}
|
||||
|
||||
// SetID sets identifier of the subnet in a binary FrostFS API protocol format.
|
||||
func (x *UserAllowedPrm) SetID(id []byte) {
|
||||
x.args[0] = id
|
||||
}
|
||||
|
||||
// SetClient sets owner ID of the client that is being checked in a binary FrostFS API protocol format.
|
||||
func (x *UserAllowedPrm) SetClient(id []byte) {
|
||||
x.args[1] = id
|
||||
}
|
||||
|
||||
// UserAllowedRes groups the resulting values of UserAllowed method of Subnet contract.
|
||||
type UserAllowedRes struct {
|
||||
result bool
|
||||
}
|
||||
|
||||
// Allowed returns true iff the client is allowed to create containers in the subnet.
|
||||
func (x UserAllowedRes) Allowed() bool {
|
||||
return x.result
|
||||
}
|
||||
|
||||
// UserAllowed checks if the user has access to the subnetwork.
|
||||
func (x *Client) UserAllowed(prm UserAllowedPrm) (*UserAllowedRes, error) {
|
||||
args := client.TestInvokePrm{}
|
||||
|
||||
args.SetMethod(userAllowedMethod)
|
||||
args.SetArgs(prm.args[:]...)
|
||||
|
||||
res, err := x.client.TestInvoke(args)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not make test invoke: %w", err)
|
||||
}
|
||||
|
||||
if len(res) == 0 {
|
||||
return nil, errEmptyResponse
|
||||
}
|
||||
|
||||
result, err := client.BoolFromStackItem(res[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &UserAllowedRes{
|
||||
result: result,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ManageClientsPrm groups parameters of client management in Subnet contract.
|
||||
//
|
||||
// Zero value adds subnet client. Subnet, group and client ID must be specified via setters.
|
||||
type ManageClientsPrm struct {
|
||||
// remove or add client
|
||||
rm bool
|
||||
|
||||
args [3]any
|
||||
}
|
||||
|
||||
// SetRemove marks client to be removed. By default, client is added.
|
||||
func (x *ManageClientsPrm) SetRemove() {
|
||||
x.rm = true
|
||||
}
|
||||
|
||||
// SetSubnet sets identifier of the subnet in a binary FrostFS API protocol format.
|
||||
func (x *ManageClientsPrm) SetSubnet(id []byte) {
|
||||
x.args[0] = id
|
||||
}
|
||||
|
||||
// SetGroup sets identifier of the client group in a binary FrostFS API protocol format.
|
||||
func (x *ManageClientsPrm) SetGroup(id []byte) {
|
||||
x.args[1] = id
|
||||
}
|
||||
|
||||
// SetClient sets client's user ID in a binary FrostFS API protocol format.
|
||||
func (x *ManageClientsPrm) SetClient(id []byte) {
|
||||
x.args[2] = id
|
||||
}
|
||||
|
||||
// ManageClientsRes groups the resulting values of client management methods of Subnet contract.
|
||||
type ManageClientsRes struct{}
|
||||
|
||||
// ManageClients manages client list of the FrostFS subnet through Subnet contract calls.
|
||||
func (x Client) ManageClients(prm ManageClientsPrm) (*ManageClientsRes, error) {
|
||||
var method string
|
||||
|
||||
if prm.rm {
|
||||
method = removeUserMethod
|
||||
} else {
|
||||
method = addUserMethod
|
||||
}
|
||||
|
||||
var prmInvoke client.InvokePrm
|
||||
|
||||
prmInvoke.SetMethod(method)
|
||||
prmInvoke.SetArgs(prm.args[:]...)
|
||||
|
||||
err := x.client.Invoke(prmInvoke)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return new(ManageClientsRes), nil
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package morphsubnet
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// DeletePrm groups parameters of Delete method of Subnet contract.
|
||||
type DeletePrm struct {
|
||||
cliPrm client.InvokePrm
|
||||
|
||||
args [1]any
|
||||
}
|
||||
|
||||
// SetTxHash sets hash of the transaction which spawned the notification.
|
||||
// Ignore this parameter for new requests.
|
||||
func (x *DeletePrm) SetTxHash(hash util.Uint256) {
|
||||
x.cliPrm.SetHash(hash)
|
||||
}
|
||||
|
||||
// SetID sets identifier of the subnet to be removed in a binary FrostFS API protocol format.
|
||||
func (x *DeletePrm) SetID(id []byte) {
|
||||
x.args[0] = id
|
||||
}
|
||||
|
||||
// DeleteRes groups the resulting values of Delete method of Subnet contract.
|
||||
type DeleteRes struct{}
|
||||
|
||||
// Delete removes subnet though the call of the corresponding method of the Subnet contract.
|
||||
func (x Client) Delete(prm DeletePrm) (*DeleteRes, error) {
|
||||
prm.cliPrm.SetMethod(deleteMethod)
|
||||
prm.cliPrm.SetArgs(prm.args[:]...)
|
||||
|
||||
err := x.client.Invoke(prm.cliPrm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return new(DeleteRes), nil
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
package morphsubnet
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
// GetPrm groups parameters of Get method of Subnet contract.
|
||||
type GetPrm struct {
|
||||
args [1]any
|
||||
}
|
||||
|
||||
// SetID sets identifier of the subnet to be read in a binary FrostFS API protocol format.
|
||||
func (x *GetPrm) SetID(id []byte) {
|
||||
x.args[0] = id
|
||||
}
|
||||
|
||||
// GetRes groups the resulting values of Get method of Subnet contract.
|
||||
type GetRes struct {
|
||||
info []byte
|
||||
}
|
||||
|
||||
// Info returns information about the subnet in a binary format of FrostFS API protocol.
|
||||
func (x GetRes) Info() []byte {
|
||||
return x.info
|
||||
}
|
||||
|
||||
var errEmptyResponse = errors.New("empty response")
|
||||
|
||||
// Get reads the subnet through the call of the corresponding method of the Subnet contract.
|
||||
func (x *Client) Get(prm GetPrm) (*GetRes, error) {
|
||||
var prmGet client.TestInvokePrm
|
||||
|
||||
prmGet.SetMethod(getMethod)
|
||||
prmGet.SetArgs(prm.args[:]...)
|
||||
|
||||
res, err := x.client.TestInvoke(prmGet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(res) == 0 {
|
||||
return nil, errEmptyResponse
|
||||
}
|
||||
|
||||
data, err := client.BytesFromStackItem(res[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &GetRes{
|
||||
info: data,
|
||||
}, nil
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package morphsubnet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
// NodeAllowedPrm groups parameters of NodeAllowed method of Subnet contract.
|
||||
type NodeAllowedPrm struct {
|
||||
cliPrm client.TestInvokePrm
|
||||
|
||||
args [2]any
|
||||
}
|
||||
|
||||
// SetID sets identifier of the subnet of the node in a binary FrostFS API protocol format.
|
||||
func (x *NodeAllowedPrm) SetID(id []byte) {
|
||||
x.args[0] = id
|
||||
}
|
||||
|
||||
// SetNode sets public key of the node that is being checked.
|
||||
func (x *NodeAllowedPrm) SetNode(id []byte) {
|
||||
x.args[1] = id
|
||||
}
|
||||
|
||||
// NodeAllowedRes groups the resulting values of NodeAllowed method of Subnet contract.
|
||||
type NodeAllowedRes struct {
|
||||
result bool
|
||||
}
|
||||
|
||||
// Allowed returns true iff the node is allowed to enter the subnet.
|
||||
func (x NodeAllowedRes) Allowed() bool {
|
||||
return x.result
|
||||
}
|
||||
|
||||
// NodeAllowed checks if the node is included in the subnetwork.
|
||||
func (x *Client) NodeAllowed(prm NodeAllowedPrm) (*NodeAllowedRes, error) {
|
||||
prm.cliPrm.SetMethod(nodeAllowedMethod)
|
||||
prm.cliPrm.SetArgs(prm.args[:]...)
|
||||
|
||||
res, err := x.client.TestInvoke(prm.cliPrm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not make test invoke: %w", err)
|
||||
}
|
||||
|
||||
if len(res) == 0 {
|
||||
return nil, errEmptyResponse
|
||||
}
|
||||
|
||||
result, err := client.BoolFromStackItem(res[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &NodeAllowedRes{
|
||||
result: result,
|
||||
}, nil
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package morphsubnet
|
||||
|
||||
import "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
|
||||
// ManageNodesPrm groups parameters of node management in Subnet contract.
|
||||
//
|
||||
// Zero value adds node to subnet. Subnet and node IDs must be specified via setters.
|
||||
type ManageNodesPrm struct {
|
||||
// remove or add node
|
||||
rm bool
|
||||
|
||||
args [2]any
|
||||
}
|
||||
|
||||
// SetRemove marks node to be removed. By default, node is added.
|
||||
func (x *ManageNodesPrm) SetRemove() {
|
||||
x.rm = true
|
||||
}
|
||||
|
||||
// SetSubnet sets identifier of the subnet in a binary NeoFS API protocol format.
|
||||
func (x *ManageNodesPrm) SetSubnet(id []byte) {
|
||||
x.args[0] = id
|
||||
}
|
||||
|
||||
// SetNode sets node's public key in a binary format.
|
||||
func (x *ManageNodesPrm) SetNode(id []byte) {
|
||||
x.args[1] = id
|
||||
}
|
||||
|
||||
// ManageNodesRes groups the resulting values of node management methods of Subnet contract.
|
||||
type ManageNodesRes struct{}
|
||||
|
||||
// ManageNodes manages node list of the NeoFS subnet through Subnet contract calls.
|
||||
func (x Client) ManageNodes(prm ManageNodesPrm) (*ManageNodesRes, error) {
|
||||
var method string
|
||||
|
||||
if prm.rm {
|
||||
method = removeNodeMethod
|
||||
} else {
|
||||
method = addNodeMethod
|
||||
}
|
||||
|
||||
var prmInvoke client.InvokePrm
|
||||
|
||||
prmInvoke.SetMethod(method)
|
||||
prmInvoke.SetArgs(prm.args[:]...)
|
||||
|
||||
err := x.client.Invoke(prmInvoke)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return new(ManageNodesRes), nil
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package morphsubnet
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// PutPrm groups parameters of Put method of Subnet contract.
|
||||
type PutPrm struct {
|
||||
cliPrm client.InvokePrm
|
||||
|
||||
args [3]any
|
||||
}
|
||||
|
||||
// SetTxHash sets hash of the transaction which spawned the notification.
|
||||
// Ignore this parameter for new requests.
|
||||
func (x *PutPrm) SetTxHash(hash util.Uint256) {
|
||||
x.cliPrm.SetHash(hash)
|
||||
}
|
||||
|
||||
// SetID sets identifier of the created subnet in a binary FrostFS API protocol format.
|
||||
func (x *PutPrm) SetID(id []byte) {
|
||||
x.args[0] = id
|
||||
}
|
||||
|
||||
// SetOwner sets identifier of the subnet owner in a binary FrostFS API protocol format.
|
||||
func (x *PutPrm) SetOwner(id []byte) {
|
||||
x.args[1] = id
|
||||
}
|
||||
|
||||
// SetInfo sets information about the created subnet in a binary FrostFS API protocol format.
|
||||
func (x *PutPrm) SetInfo(id []byte) {
|
||||
x.args[2] = id
|
||||
}
|
||||
|
||||
// PutRes groups the resulting values of Put method of Subnet contract.
|
||||
type PutRes struct{}
|
||||
|
||||
// Put creates subnet though the call of the corresponding method of the Subnet contract.
|
||||
func (x Client) Put(prm PutPrm) (*PutRes, error) {
|
||||
prm.cliPrm.SetMethod(putMethod)
|
||||
prm.cliPrm.SetArgs(prm.args[:]...)
|
||||
|
||||
err := x.client.Invoke(prm.cliPrm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return new(PutRes), nil
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package subnetevents
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// Delete structures information about the notification generated by Delete method of Subnet contract.
|
||||
type Delete struct {
|
||||
txHash util.Uint256
|
||||
|
||||
id []byte
|
||||
}
|
||||
|
||||
// MorphEvent implements Neo:Morph Event interface.
|
||||
func (Delete) MorphEvent() {}
|
||||
|
||||
// ID returns identifier of the removed subnet in a binary format of NeoFS API protocol.
|
||||
func (x Delete) ID() []byte {
|
||||
return x.id
|
||||
}
|
||||
|
||||
// TxHash returns hash of the transaction which thrown the notification event.
|
||||
// Makes sense only in notary environments.
|
||||
func (x Delete) TxHash() util.Uint256 {
|
||||
return x.txHash
|
||||
}
|
||||
|
||||
// ParseDelete parses the notification about the removal of a subnet which has been thrown
|
||||
// by the appropriate method of the Subnet contract.
|
||||
//
|
||||
// Resulting event is of Delete type.
|
||||
func ParseDelete(e *state.ContainedNotificationEvent) (event.Event, error) {
|
||||
var (
|
||||
ev Delete
|
||||
err error
|
||||
)
|
||||
|
||||
items, err := event.ParseStackArray(e)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse stack array: %w", err)
|
||||
}
|
||||
|
||||
const itemNumDelete = 1
|
||||
|
||||
if ln := len(items); ln != itemNumDelete {
|
||||
return nil, event.WrongNumberOfParameters(itemNumDelete, ln)
|
||||
}
|
||||
|
||||
// parse ID
|
||||
ev.id, err = client.BytesFromStackItem(items[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("id item: %w", err)
|
||||
}
|
||||
|
||||
ev.txHash = e.Container
|
||||
|
||||
return ev, nil
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package subnetevents_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
subnetevents "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/subnet"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParseDelete(t *testing.T) {
|
||||
id := []byte("id")
|
||||
|
||||
t.Run("wrong number of items", func(t *testing.T) {
|
||||
prms := []stackitem.Item{
|
||||
stackitem.NewByteArray(nil),
|
||||
stackitem.NewByteArray(nil),
|
||||
}
|
||||
|
||||
_, err := subnetevents.ParseDelete(createNotifyEventFromItems(prms))
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("wrong id item", func(t *testing.T) {
|
||||
_, err := subnetevents.ParseDelete(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewMap(),
|
||||
}))
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("correct behavior", func(t *testing.T) {
|
||||
ev, err := subnetevents.ParseDelete(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewByteArray(id),
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
||||
v := ev.(subnetevents.Delete)
|
||||
|
||||
require.Equal(t, id, v.ID())
|
||||
})
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
package subnetevents
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// Put structures information about the notification generated by Put method of Subnet contract.
|
||||
type Put struct {
|
||||
notaryRequest *payload.P2PNotaryRequest
|
||||
|
||||
txHash util.Uint256
|
||||
|
||||
id []byte
|
||||
|
||||
owner []byte
|
||||
|
||||
info []byte
|
||||
}
|
||||
|
||||
// MorphEvent implements Neo:Morph Event interface.
|
||||
func (Put) MorphEvent() {}
|
||||
|
||||
// ID returns identifier of the creating subnet in a binary format of FrostFS API protocol.
|
||||
func (x Put) ID() []byte {
|
||||
return x.id
|
||||
}
|
||||
|
||||
// Owner returns subnet owner's public key in a binary format.
|
||||
func (x Put) Owner() []byte {
|
||||
return x.owner
|
||||
}
|
||||
|
||||
// Info returns information about the subnet in a binary format of FrostFS API protocol.
|
||||
func (x Put) Info() []byte {
|
||||
return x.info
|
||||
}
|
||||
|
||||
// TxHash returns hash of the transaction which thrown the notification event.
|
||||
// Makes sense only in notary environments.
|
||||
func (x Put) TxHash() util.Uint256 {
|
||||
return x.txHash
|
||||
}
|
||||
|
||||
// NotaryMainTx returns main transaction of the request in the Notary service.
|
||||
// Returns nil in non-notary environments.
|
||||
func (x Put) NotaryMainTx() *transaction.Transaction {
|
||||
if x.notaryRequest != nil {
|
||||
return x.notaryRequest.MainTransaction
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// number of items in notification about subnet creation.
|
||||
const itemNumPut = 3
|
||||
|
||||
// ParsePut parses the notification about the creation of a subnet which has been thrown
|
||||
// by the appropriate method of the subnet contract.
|
||||
//
|
||||
// Resulting event is of Put type.
|
||||
func ParsePut(e *state.ContainedNotificationEvent) (event.Event, error) {
|
||||
var (
|
||||
put Put
|
||||
err error
|
||||
)
|
||||
|
||||
items, err := event.ParseStackArray(e)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse stack array: %w", err)
|
||||
}
|
||||
|
||||
if ln := len(items); ln != itemNumPut {
|
||||
return nil, event.WrongNumberOfParameters(itemNumPut, ln)
|
||||
}
|
||||
|
||||
// parse ID
|
||||
put.id, err = client.BytesFromStackItem(items[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("id item: %w", err)
|
||||
}
|
||||
|
||||
// parse owner
|
||||
put.owner, err = client.BytesFromStackItem(items[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("owner item: %w", err)
|
||||
}
|
||||
|
||||
// parse info about subnet
|
||||
put.info, err = client.BytesFromStackItem(items[2])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("info item: %w", err)
|
||||
}
|
||||
|
||||
put.txHash = e.Container
|
||||
|
||||
return put, nil
|
||||
}
|
||||
|
||||
// ParseNotaryPut parses the notary notification about the creation of a subnet which has been
|
||||
// thrown by the appropriate method of the subnet contract.
|
||||
//
|
||||
// Resulting event is of Put type.
|
||||
func ParseNotaryPut(e event.NotaryEvent) (event.Event, error) {
|
||||
var put Put
|
||||
|
||||
put.notaryRequest = e.Raw()
|
||||
if put.notaryRequest == nil {
|
||||
panic(fmt.Sprintf("nil %T in notary environment", put.notaryRequest))
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
|
||||
prms = e.Params()
|
||||
)
|
||||
|
||||
if ln := len(prms); ln != itemNumPut {
|
||||
return nil, event.WrongNumberOfParameters(itemNumPut, ln)
|
||||
}
|
||||
|
||||
// parse info about subnet
|
||||
put.info, err = event.BytesFromOpcode(prms[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("info param: %w", err)
|
||||
}
|
||||
|
||||
// parse owner
|
||||
put.owner, err = event.BytesFromOpcode(prms[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creator param: %w", err)
|
||||
}
|
||||
|
||||
// parse ID
|
||||
put.id, err = event.BytesFromOpcode(prms[2])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("id param: %w", err)
|
||||
}
|
||||
|
||||
return put, nil
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package subnetevents_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
subnetevents "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/subnet"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParsePut(t *testing.T) {
|
||||
var (
|
||||
id = []byte("id")
|
||||
owner = []byte("owner")
|
||||
info = []byte("info")
|
||||
)
|
||||
|
||||
t.Run("wrong number of items", func(t *testing.T) {
|
||||
prms := []stackitem.Item{
|
||||
stackitem.NewByteArray(nil),
|
||||
stackitem.NewByteArray(nil),
|
||||
}
|
||||
|
||||
_, err := subnetevents.ParsePut(createNotifyEventFromItems(prms))
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("wrong id item", func(t *testing.T) {
|
||||
_, err := subnetevents.ParsePut(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewMap(),
|
||||
}))
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("wrong owner item", func(t *testing.T) {
|
||||
_, err := subnetevents.ParsePut(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewByteArray(id),
|
||||
stackitem.NewMap(),
|
||||
}))
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("wrong info item", func(t *testing.T) {
|
||||
_, err := subnetevents.ParsePut(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewByteArray(id),
|
||||
stackitem.NewByteArray(owner),
|
||||
stackitem.NewMap(),
|
||||
}))
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("correct behavior", func(t *testing.T) {
|
||||
ev, err := subnetevents.ParsePut(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewByteArray(id),
|
||||
stackitem.NewByteArray(owner),
|
||||
stackitem.NewByteArray(info),
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
||||
v := ev.(subnetevents.Put)
|
||||
|
||||
require.Equal(t, id, v.ID())
|
||||
require.Equal(t, owner, v.Owner())
|
||||
require.Equal(t, info, v.Info())
|
||||
})
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package subnetevents
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// RemoveNode structure of subnet.RemoveNode notification from morph chain.
|
||||
type RemoveNode struct {
|
||||
subnetID []byte
|
||||
nodeKey []byte
|
||||
|
||||
// txHash is used in notary environmental
|
||||
// for calculating unique but same for
|
||||
// all notification receivers values.
|
||||
txHash util.Uint256
|
||||
}
|
||||
|
||||
// MorphEvent implements Neo:Morph Event interface.
|
||||
func (RemoveNode) MorphEvent() {}
|
||||
|
||||
// SubnetworkID returns a marshalled subnetID structure, defined in API.
|
||||
func (rn RemoveNode) SubnetworkID() []byte { return rn.subnetID }
|
||||
|
||||
// Node is public key of the nodeKey that is being deleted.
|
||||
func (rn RemoveNode) Node() []byte { return rn.nodeKey }
|
||||
|
||||
// TxHash returns hash of the TX with RemoveNode
|
||||
// notification.
|
||||
func (rn RemoveNode) TxHash() util.Uint256 { return rn.txHash }
|
||||
|
||||
const expectedItemNumRemoveNode = 2
|
||||
|
||||
// ParseRemoveNode parses notification into subnet event structure.
|
||||
//
|
||||
// Expects 2 stack items.
|
||||
func ParseRemoveNode(e *state.ContainedNotificationEvent) (event.Event, error) {
|
||||
var (
|
||||
ev RemoveNode
|
||||
err error
|
||||
)
|
||||
|
||||
params, err := event.ParseStackArray(e)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse stack items from notify event: %w", err)
|
||||
}
|
||||
|
||||
if ln := len(params); ln != expectedItemNumRemoveNode {
|
||||
return nil, event.WrongNumberOfParameters(expectedItemNumRemoveNode, ln)
|
||||
}
|
||||
|
||||
ev.subnetID, err = client.BytesFromStackItem(params[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get raw subnetID: %w", err)
|
||||
}
|
||||
|
||||
ev.nodeKey, err = client.BytesFromStackItem(params[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get raw public key of the node: %w", err)
|
||||
}
|
||||
|
||||
ev.txHash = e.Container
|
||||
|
||||
return ev, nil
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package subnetevents_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/subnet"
|
||||
subnetid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/subnet/id"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParseRemoveNode(t *testing.T) {
|
||||
t.Run("wrong number of arguments", func(t *testing.T) {
|
||||
_, err := ParseRemoveNode(createNotifyEventFromItems([]stackitem.Item{}))
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("invalid item type", func(t *testing.T) {
|
||||
args := []stackitem.Item{stackitem.NewMap(), stackitem.Make(123)}
|
||||
_, err := ParseRemoveNode(createNotifyEventFromItems(args))
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
subnetID := subnetid.ID{}
|
||||
subnetID.SetNumeric(123)
|
||||
|
||||
rawSubnetID := subnetID.Marshal()
|
||||
|
||||
priv, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
pub := priv.PublicKey()
|
||||
|
||||
t.Run("good", func(t *testing.T) {
|
||||
args := []stackitem.Item{stackitem.NewByteArray(rawSubnetID), stackitem.Make(pub.Bytes())}
|
||||
|
||||
e, err := ParseRemoveNode(createNotifyEventFromItems(args))
|
||||
require.NoError(t, err)
|
||||
|
||||
gotRaw := e.(RemoveNode).SubnetworkID()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, rawSubnetID, gotRaw)
|
||||
require.Equal(t, pub.Bytes(), e.(RemoveNode).Node())
|
||||
})
|
||||
}
|
||||
|
||||
func createNotifyEventFromItems(items []stackitem.Item) *state.ContainedNotificationEvent {
|
||||
return &state.ContainedNotificationEvent{
|
||||
NotificationEvent: state.NotificationEvent{
|
||||
Item: stackitem.NewArray(items),
|
||||
},
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue