forked from TrueCloudLab/frostfs-node
[#755] morph: Drop FrostFSID contract usage
Unused. Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>rpc_not_defined
parent
d5c9dd3c83
commit
1cd2bfe51a
|
@ -20,7 +20,6 @@ import (
|
|||
balanceClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/balance"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||
frostfsClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
||||
nmClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
control "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
||||
|
@ -250,9 +249,7 @@ func (s *Server) initAlphabetProcessor(cfg *viper.Viper) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (s *Server) initContainerProcessor(cfg *viper.Viper, cnrClient *container.Client,
|
||||
frostfsIDClient *frostfsid.Client,
|
||||
) error {
|
||||
func (s *Server) initContainerProcessor(cfg *viper.Viper, cnrClient *container.Client) error {
|
||||
// container processor
|
||||
containerProcessor, err := cont.New(&cont.Params{
|
||||
Log: s.log,
|
||||
|
@ -261,7 +258,6 @@ func (s *Server) initContainerProcessor(cfg *viper.Viper, cnrClient *container.C
|
|||
AlphabetState: s,
|
||||
ContainerClient: cnrClient,
|
||||
MorphClient: cnrClient.Morph(),
|
||||
FrostFSIDClient: frostfsIDClient,
|
||||
NetworkState: s.netmapClient,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -289,7 +285,7 @@ func (s *Server) initBalanceProcessor(cfg *viper.Viper, frostfsCli *frostfsClien
|
|||
return bindMorphProcessor(balanceProcessor, s)
|
||||
}
|
||||
|
||||
func (s *Server) initFrostFSMainnetProcessor(cfg *viper.Viper, frostfsIDClient *frostfsid.Client) error {
|
||||
func (s *Server) initFrostFSMainnetProcessor(cfg *viper.Viper) error {
|
||||
if s.withoutMainNet {
|
||||
return nil
|
||||
}
|
||||
|
@ -299,7 +295,6 @@ func (s *Server) initFrostFSMainnetProcessor(cfg *viper.Viper, frostfsIDClient *
|
|||
Metrics: s.irMetrics,
|
||||
PoolSize: cfg.GetInt("workers.frostfs"),
|
||||
FrostFSContract: s.contracts.frostfs,
|
||||
FrostFSIDClient: frostfsIDClient,
|
||||
BalanceClient: s.balanceClient,
|
||||
NetmapClient: s.netmapClient,
|
||||
MorphClient: s.morphClient,
|
||||
|
@ -369,9 +364,8 @@ func (s *Server) initGRPCServer(cfg *viper.Viper) error {
|
|||
}
|
||||
|
||||
type serverMorphClients struct {
|
||||
CnrClient *container.Client
|
||||
FrostFSIDClient *frostfsid.Client
|
||||
FrostFSClient *frostfsClient.Client
|
||||
CnrClient *container.Client
|
||||
FrostFSClient *frostfsClient.Client
|
||||
}
|
||||
|
||||
func (s *Server) initClientsFromMorph() (*serverMorphClients, error) {
|
||||
|
@ -403,11 +397,6 @@ func (s *Server) initClientsFromMorph() (*serverMorphClients, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
result.FrostFSIDClient, err = frostfsid.NewFromMorph(s.morphClient, s.contracts.frostfsID, fee, frostfsid.TryNotary(), frostfsid.AsAlphabet())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result.FrostFSClient, err = frostfsClient.NewFromMorph(s.mainnetClient, s.contracts.frostfs,
|
||||
s.feeConfig.MainChainFee(), frostfsClient.TryNotary(), frostfsClient.AsAlphabet())
|
||||
if err != nil {
|
||||
|
@ -437,7 +426,7 @@ func (s *Server) initProcessors(cfg *viper.Viper, morphClients *serverMorphClien
|
|||
return err
|
||||
}
|
||||
|
||||
err = s.initContainerProcessor(cfg, morphClients.CnrClient, morphClients.FrostFSIDClient)
|
||||
err = s.initContainerProcessor(cfg, morphClients.CnrClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -447,7 +436,7 @@ func (s *Server) initProcessors(cfg *viper.Viper, morphClients *serverMorphClien
|
|||
return err
|
||||
}
|
||||
|
||||
err = s.initFrostFSMainnetProcessor(cfg, morphClients.FrostFSIDClient)
|
||||
err = s.initFrostFSMainnetProcessor(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
|
@ -73,20 +72,6 @@ func (cp *Processor) verifySignature(v signatureVerificationData) error {
|
|||
|
||||
return errors.New("invalid signature calculated by container owner's key")
|
||||
}
|
||||
} else {
|
||||
var prm frostfsid.AccountKeysPrm
|
||||
prm.SetID(v.ownerContainer)
|
||||
|
||||
ownerKeys, err := cp.idClient.AccountKeys(prm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("receive owner keys %s: %w", v.ownerContainer, err)
|
||||
}
|
||||
|
||||
for i := range ownerKeys {
|
||||
if (*frostfsecdsa.PublicKeyRFC6979)(ownerKeys[i]).Verify(v.signedData, v.signature) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errors.New("signature is invalid or calculated with the key not bound to the container owner")
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
|
||||
containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
||||
containerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
|
@ -40,7 +39,6 @@ func TestPutEvent(t *testing.T) {
|
|||
Log: test.NewLogger(t, true),
|
||||
PoolSize: 2,
|
||||
AlphabetState: &testAlphabetState{isAlphabet: true},
|
||||
FrostFSIDClient: &testIDClient{},
|
||||
NetworkState: nst,
|
||||
ContainerClient: &testContainerClient{},
|
||||
MorphClient: mc,
|
||||
|
@ -95,18 +93,12 @@ func TestDeleteEvent(t *testing.T) {
|
|||
p, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
idc := &testIDClient{
|
||||
publicKeys: []*keys.PublicKey{
|
||||
p.PublicKey(),
|
||||
},
|
||||
}
|
||||
mc := &testMorphClient{}
|
||||
|
||||
proc, err := New(&Params{
|
||||
Log: test.NewLogger(t, true),
|
||||
PoolSize: 2,
|
||||
AlphabetState: &testAlphabetState{isAlphabet: true},
|
||||
FrostFSIDClient: idc,
|
||||
NetworkState: nst,
|
||||
ContainerClient: cc,
|
||||
MorphClient: mc,
|
||||
|
@ -139,6 +131,7 @@ func TestDeleteEvent(t *testing.T) {
|
|||
ContainerIDValue: cidBin,
|
||||
SignatureValue: p.Sign(cidBin),
|
||||
NotaryRequestValue: nr,
|
||||
PublicKeyValue: p.PublicKey().Bytes(),
|
||||
}
|
||||
|
||||
var signature frostfscrypto.Signature
|
||||
|
@ -177,7 +170,6 @@ func TestSetEACLEvent(t *testing.T) {
|
|||
Log: test.NewLogger(t, true),
|
||||
PoolSize: 2,
|
||||
AlphabetState: &testAlphabetState{isAlphabet: true},
|
||||
FrostFSIDClient: &testIDClient{},
|
||||
NetworkState: nst,
|
||||
ContainerClient: cc,
|
||||
MorphClient: mc,
|
||||
|
@ -285,14 +277,6 @@ func (c *testContainerClient) Get(cid []byte) (*containercore.Container, error)
|
|||
return nil, new(apistatus.ContainerNotFound)
|
||||
}
|
||||
|
||||
type testIDClient struct {
|
||||
publicKeys keys.PublicKeys
|
||||
}
|
||||
|
||||
func (c *testIDClient) AccountKeys(p frostfsid.AccountKeysPrm) (keys.PublicKeys, error) {
|
||||
return c.publicKeys, nil
|
||||
}
|
||||
|
||||
var _ putEvent = &testPutEvent{}
|
||||
|
||||
type testPutEvent struct {
|
||||
|
|
|
@ -7,13 +7,11 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/metrics"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
containerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/mempoolevent"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/panjf2000/ants/v2"
|
||||
"go.uber.org/zap"
|
||||
|
@ -34,10 +32,6 @@ type (
|
|||
NotarySignAndInvokeTX(mainTx *transaction.Transaction) error
|
||||
}
|
||||
|
||||
IDClient interface {
|
||||
AccountKeys(p frostfsid.AccountKeysPrm) (keys.PublicKeys, error)
|
||||
}
|
||||
|
||||
// Processor of events produced by container contract in the sidechain.
|
||||
Processor struct {
|
||||
log *logger.Logger
|
||||
|
@ -46,7 +40,6 @@ type (
|
|||
alphabetState AlphabetState
|
||||
cnrClient ContClient // notary must be enabled
|
||||
morphClient MorphClient
|
||||
idClient IDClient
|
||||
netState NetworkState
|
||||
}
|
||||
|
||||
|
@ -58,7 +51,6 @@ type (
|
|||
AlphabetState AlphabetState
|
||||
ContainerClient ContClient
|
||||
MorphClient MorphClient
|
||||
FrostFSIDClient IDClient
|
||||
NetworkState NetworkState
|
||||
}
|
||||
)
|
||||
|
@ -92,8 +84,6 @@ func New(p *Params) (*Processor, error) {
|
|||
return nil, errors.New("ir/container: Container client is not set")
|
||||
case p.MorphClient == nil:
|
||||
return nil, errors.New("ir/container: Morph client is not set")
|
||||
case p.FrostFSIDClient == nil:
|
||||
return nil, errors.New("ir/container: FrostFS ID client is not set")
|
||||
case p.NetworkState == nil:
|
||||
return nil, errors.New("ir/container: network state is not set")
|
||||
}
|
||||
|
@ -116,7 +106,6 @@ func New(p *Params) (*Processor, error) {
|
|||
pool: pool,
|
||||
alphabetState: p.AlphabetState,
|
||||
cnrClient: p.ContainerClient,
|
||||
idClient: p.FrostFSIDClient,
|
||||
netState: p.NetworkState,
|
||||
morphClient: p.MorphClient,
|
||||
}, nil
|
||||
|
|
|
@ -88,39 +88,3 @@ func (np *Processor) handleConfig(ev event.Event) {
|
|||
zap.Int("capacity", np.pool.Cap()))
|
||||
}
|
||||
}
|
||||
|
||||
func (np *Processor) handleBind(ev event.Event) {
|
||||
e := ev.(frostfsEvent.Bind)
|
||||
np.log.Info(logs.Notification,
|
||||
zap.String("type", "bind"),
|
||||
)
|
||||
|
||||
// send event to the worker pool
|
||||
|
||||
err := processors.SubmitEvent(np.pool, np.metrics, "frostfs_bind", func() bool {
|
||||
return np.processBind(e, true)
|
||||
})
|
||||
if err != nil {
|
||||
// there system can be moved into controlled degradation stage
|
||||
np.log.Warn(logs.FrostFSFrostfsProcessorWorkerPoolDrained,
|
||||
zap.Int("capacity", np.pool.Cap()))
|
||||
}
|
||||
}
|
||||
|
||||
func (np *Processor) handleUnbind(ev event.Event) {
|
||||
e := ev.(frostfsEvent.Unbind)
|
||||
np.log.Info(logs.Notification,
|
||||
zap.String("type", "unbind"),
|
||||
)
|
||||
|
||||
// send event to the worker pool
|
||||
|
||||
err := processors.SubmitEvent(np.pool, np.metrics, "frostfs_unbind", func() bool {
|
||||
return np.processBind(e, false)
|
||||
})
|
||||
if err != nil {
|
||||
// there system can be moved into controlled degradation stage
|
||||
np.log.Warn(logs.FrostFSFrostfsProcessorWorkerPoolDrained,
|
||||
zap.Int("capacity", np.pool.Cap()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,9 @@ import (
|
|||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/balance"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
||||
nmClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
||||
frostfsEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/frostfs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -194,80 +191,11 @@ func TestHandleConfig(t *testing.T) {
|
|||
require.EqualValues(t, []nmClient.SetConfigPrm{expConfig}, nm.config, "invalid config value")
|
||||
}
|
||||
|
||||
func TestHandleUnbind(t *testing.T) {
|
||||
t.Parallel()
|
||||
es := &testEpochState{
|
||||
epochCounter: 100,
|
||||
}
|
||||
m := &testMorphClient{
|
||||
balance: 150,
|
||||
}
|
||||
id := &testIDClient{}
|
||||
proc, err := newTestProc(t, func(p *Params) {
|
||||
p.EpochState = es
|
||||
p.MorphClient = m
|
||||
p.FrostFSIDClient = id
|
||||
})
|
||||
require.NoError(t, err, "failed to create processor")
|
||||
|
||||
p, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
evUnbind := frostfsEvent.Unbind{
|
||||
BindCommon: frostfsEvent.BindCommon{
|
||||
UserValue: util.Uint160{49}.BytesBE(),
|
||||
KeysValue: [][]byte{
|
||||
p.PublicKey().Bytes(),
|
||||
},
|
||||
TxHashValue: util.Uint256{100},
|
||||
},
|
||||
}
|
||||
|
||||
proc.handleUnbind(evUnbind)
|
||||
|
||||
for proc.pool.Running() > 0 {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
|
||||
var userID user.ID
|
||||
userID.SetScriptHash(util.Uint160{49})
|
||||
|
||||
var expBind frostfsid.CommonBindPrm
|
||||
expBind.SetOwnerID(userID.WalletBytes())
|
||||
expBind.SetKeys(evUnbind.BindCommon.KeysValue)
|
||||
expBind.SetHash(evUnbind.BindCommon.TxHashValue)
|
||||
|
||||
var expNilSlice []frostfsid.CommonBindPrm
|
||||
|
||||
require.EqualValues(t, []frostfsid.CommonBindPrm{expBind}, id.remove, "invalid remove keys value")
|
||||
require.EqualValues(t, expNilSlice, id.add, "invalid add keys value")
|
||||
|
||||
evBind := frostfsEvent.Bind{
|
||||
BindCommon: frostfsEvent.BindCommon{
|
||||
UserValue: util.Uint160{49}.BytesBE(),
|
||||
KeysValue: [][]byte{
|
||||
p.PublicKey().Bytes(),
|
||||
},
|
||||
TxHashValue: util.Uint256{100},
|
||||
},
|
||||
}
|
||||
|
||||
proc.handleBind(evBind)
|
||||
|
||||
for proc.pool.Running() > 0 {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
|
||||
require.EqualValues(t, []frostfsid.CommonBindPrm{expBind}, id.remove, "invalid remove keys value")
|
||||
require.EqualValues(t, []frostfsid.CommonBindPrm{expBind}, id.add, "invalid add keys value")
|
||||
}
|
||||
|
||||
func newTestProc(t *testing.T, nonDefault func(p *Params)) (*Processor, error) {
|
||||
p := &Params{
|
||||
Log: test.NewLogger(t, true),
|
||||
PoolSize: 1,
|
||||
FrostFSContract: util.Uint160{0},
|
||||
FrostFSIDClient: &testIDClient{},
|
||||
BalanceClient: &testBalaceClient{},
|
||||
NetmapClient: &testNetmapClient{},
|
||||
MorphClient: &testMorphClient{},
|
||||
|
@ -358,18 +286,3 @@ func (c *testMorphClient) TransferGas(receiver util.Uint160, amount fixedn.Fixed
|
|||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
type testIDClient struct {
|
||||
add []frostfsid.CommonBindPrm
|
||||
remove []frostfsid.CommonBindPrm
|
||||
}
|
||||
|
||||
func (c *testIDClient) AddKeys(p frostfsid.CommonBindPrm) error {
|
||||
c.add = append(c.add, p)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *testIDClient) RemoveKeys(args frostfsid.CommonBindPrm) error {
|
||||
c.remove = append(c.remove, args)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
package frostfs
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type bindCommon interface {
|
||||
User() []byte
|
||||
Keys() [][]byte
|
||||
TxHash() util.Uint256
|
||||
}
|
||||
|
||||
func (np *Processor) processBind(e bindCommon, bind bool) bool {
|
||||
if !np.alphabetState.IsAlphabet() {
|
||||
np.log.Info(logs.FrostFSNonAlphabetModeIgnoreBind)
|
||||
return true
|
||||
}
|
||||
|
||||
c := &bindCommonContext{
|
||||
bindCommon: e,
|
||||
bind: bind,
|
||||
}
|
||||
|
||||
err := np.checkBindCommon(c)
|
||||
if err != nil {
|
||||
np.log.Error(logs.FrostFSInvalidManageKeyEvent,
|
||||
zap.Bool("bind", c.bind),
|
||||
zap.String("error", err.Error()),
|
||||
)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return np.approveBindCommon(c) == nil
|
||||
}
|
||||
|
||||
type bindCommonContext struct {
|
||||
bindCommon
|
||||
|
||||
bind bool
|
||||
|
||||
scriptHash util.Uint160
|
||||
}
|
||||
|
||||
func (np *Processor) checkBindCommon(e *bindCommonContext) error {
|
||||
var err error
|
||||
|
||||
e.scriptHash, err = util.Uint160DecodeBytesBE(e.User())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
curve := elliptic.P256()
|
||||
|
||||
for _, key := range e.Keys() {
|
||||
_, err = keys.NewPublicKeyFromBytes(key, curve)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (np *Processor) approveBindCommon(e *bindCommonContext) error {
|
||||
// calculate wallet address
|
||||
scriptHash := e.User()
|
||||
|
||||
u160, err := util.Uint160DecodeBytesBE(scriptHash)
|
||||
if err != nil {
|
||||
np.log.Error(logs.FrostFSCouldNotDecodeScriptHashFromBytes,
|
||||
zap.String("error", err.Error()),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
var id user.ID
|
||||
id.SetScriptHash(u160)
|
||||
|
||||
prm := frostfsid.CommonBindPrm{}
|
||||
prm.SetOwnerID(id.WalletBytes())
|
||||
prm.SetKeys(e.Keys())
|
||||
prm.SetHash(e.bindCommon.TxHash())
|
||||
|
||||
var typ string
|
||||
if e.bind {
|
||||
typ = "bind"
|
||||
err = np.frostfsIDClient.AddKeys(prm)
|
||||
} else {
|
||||
typ = "unbind"
|
||||
err = np.frostfsIDClient.RemoveKeys(prm)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
np.log.Error(fmt.Sprintf("could not approve %s", typ),
|
||||
zap.String("error", err.Error()))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
|
@ -8,7 +8,6 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/metrics"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/balance"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
||||
nmClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
frostfsEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/frostfs"
|
||||
|
@ -51,11 +50,6 @@ type (
|
|||
TransferGas(receiver util.Uint160, amount fixedn.Fixed8) error
|
||||
}
|
||||
|
||||
IDClient interface {
|
||||
AddKeys(p frostfsid.CommonBindPrm) error
|
||||
RemoveKeys(args frostfsid.CommonBindPrm) error
|
||||
}
|
||||
|
||||
// Processor of events produced by frostfs contract in main net.
|
||||
Processor struct {
|
||||
log *logger.Logger
|
||||
|
@ -73,7 +67,6 @@ type (
|
|||
mintEmitThreshold uint64
|
||||
mintEmitValue fixedn.Fixed8
|
||||
gasBalanceThreshold int64
|
||||
frostfsIDClient IDClient
|
||||
}
|
||||
|
||||
// Params of the processor constructor.
|
||||
|
@ -82,7 +75,6 @@ type (
|
|||
Metrics metrics.Register
|
||||
PoolSize int
|
||||
FrostFSContract util.Uint160
|
||||
FrostFSIDClient IDClient
|
||||
BalanceClient BalanceClient
|
||||
NetmapClient NetmapClient
|
||||
MorphClient MorphClient
|
||||
|
@ -101,8 +93,6 @@ const (
|
|||
withdrawNotification = "Withdraw"
|
||||
chequeNotification = "Cheque"
|
||||
configNotification = "SetConfig"
|
||||
bindNotification = "Bind"
|
||||
unbindNotification = "Unbind"
|
||||
)
|
||||
|
||||
// New creates frostfs mainnet contract processor instance.
|
||||
|
@ -152,8 +142,6 @@ func New(p *Params) (*Processor, error) {
|
|||
mintEmitThreshold: p.MintEmitThreshold,
|
||||
mintEmitValue: p.MintEmitValue,
|
||||
gasBalanceThreshold: p.GasBalanceThreshold,
|
||||
|
||||
frostfsIDClient: p.FrostFSIDClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -187,16 +175,6 @@ func (np *Processor) ListenerNotificationParsers() []event.NotificationParserInf
|
|||
p.SetParser(frostfsEvent.ParseConfig)
|
||||
parsers = append(parsers, p)
|
||||
|
||||
// bind event
|
||||
p.SetType(event.TypeFromString(bindNotification))
|
||||
p.SetParser(frostfsEvent.ParseBind)
|
||||
parsers = append(parsers, p)
|
||||
|
||||
// unbind event
|
||||
p.SetType(event.TypeFromString(unbindNotification))
|
||||
p.SetParser(frostfsEvent.ParseUnbind)
|
||||
parsers = append(parsers, p)
|
||||
|
||||
return parsers
|
||||
}
|
||||
|
||||
|
@ -230,16 +208,6 @@ func (np *Processor) ListenerNotificationHandlers() []event.NotificationHandlerI
|
|||
h.SetHandler(np.handleConfig)
|
||||
handlers = append(handlers, h)
|
||||
|
||||
// bind handler
|
||||
h.SetType(event.TypeFromString(bindNotification))
|
||||
h.SetHandler(np.handleBind)
|
||||
handlers = append(handlers, h)
|
||||
|
||||
// unbind handler
|
||||
h.SetType(event.TypeFromString(unbindNotification))
|
||||
h.SetHandler(np.handleUnbind)
|
||||
handlers = append(handlers, h)
|
||||
|
||||
return handlers
|
||||
}
|
||||
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
package frostfscontract
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
type commonBindArgs struct {
|
||||
scriptHash []byte // script hash of account identifier
|
||||
|
||||
keys [][]byte // list of serialized public keys
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetOptionalPrm sets optional client parameters.
|
||||
func (x *commonBindArgs) SetOptionalPrm(op client.InvokePrmOptional) {
|
||||
x.InvokePrmOptional = op
|
||||
}
|
||||
|
||||
// SetScriptHash sets script hash of the FrostFS account identifier.
|
||||
func (x *commonBindArgs) SetScriptHash(v []byte) {
|
||||
x.scriptHash = v
|
||||
}
|
||||
|
||||
// SetKeys sets a list of public keys in a binary format.
|
||||
func (x *commonBindArgs) SetKeys(v [][]byte) {
|
||||
x.keys = v
|
||||
}
|
||||
|
||||
// BindKeysPrm groups parameters of BindKeys operation.
|
||||
type BindKeysPrm struct {
|
||||
commonBindArgs
|
||||
}
|
||||
|
||||
// BindKeys binds list of public keys from FrostFS account by script hash.
|
||||
func (x *Client) BindKeys(p BindKeysPrm) error {
|
||||
prm := client.InvokePrm{}
|
||||
prm.SetMethod(bindKeysMethod)
|
||||
prm.SetArgs(p.scriptHash, p.keys)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
_, err := x.client.Invoke(prm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", bindKeysMethod, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnbindKeysPrm groups parameters of UnbindKeys operation.
|
||||
type UnbindKeysPrm struct {
|
||||
commonBindArgs
|
||||
}
|
||||
|
||||
// UnbindKeys invokes the call of key unbinding method
|
||||
// of FrostFS contract.
|
||||
func (x *Client) UnbindKeys(args UnbindKeysPrm) error {
|
||||
prm := client.InvokePrm{}
|
||||
prm.SetMethod(unbindKeysMethod)
|
||||
prm.SetArgs(args.scriptHash, args.keys)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
|
||||
_, err := x.client.Invoke(prm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", unbindKeysMethod, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -21,8 +21,6 @@ type Client struct {
|
|||
}
|
||||
|
||||
const (
|
||||
bindKeysMethod = "bind"
|
||||
unbindKeysMethod = "unbind"
|
||||
alphabetUpdateMethod = "alphabetUpdate"
|
||||
chequeMethod = "cheque"
|
||||
)
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
package frostfsid
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
type CommonBindPrm struct {
|
||||
ownerID []byte // FrostFS account identifier
|
||||
|
||||
keys [][]byte // list of serialized public keys
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
func (x *CommonBindPrm) SetOptionalPrm(prm client.InvokePrmOptional) {
|
||||
x.InvokePrmOptional = prm
|
||||
}
|
||||
|
||||
// SetOwnerID sets FrostFS account identifier.
|
||||
func (x *CommonBindPrm) SetOwnerID(v []byte) {
|
||||
x.ownerID = v
|
||||
}
|
||||
|
||||
// SetKeys sets a list of public keys in a binary format.
|
||||
func (x *CommonBindPrm) SetKeys(v [][]byte) {
|
||||
x.keys = v
|
||||
}
|
||||
|
||||
// AddKeys adds a list of public keys to/from FrostFS account.
|
||||
func (x *Client) AddKeys(p CommonBindPrm) error {
|
||||
prm := client.InvokePrm{}
|
||||
|
||||
prm.SetMethod(addKeysMethod)
|
||||
prm.SetArgs(p.ownerID, p.keys)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
_, err := x.client.Invoke(prm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", addKeysMethod, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveKeys removes a list of public keys to/from FrostFS account.
|
||||
func (x *Client) RemoveKeys(args CommonBindPrm) error {
|
||||
prm := client.InvokePrm{}
|
||||
|
||||
prm.SetMethod(removeKeysMethod)
|
||||
prm.SetArgs(args.ownerID, args.keys)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
|
||||
_, err := x.client.Invoke(prm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", removeKeysMethod, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package frostfsid
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// Client is a wrapper over StaticClient
|
||||
// which makes calls with the names and arguments
|
||||
// of the FrostFS ID contract.
|
||||
//
|
||||
// Working client must be created via constructor New.
|
||||
// Using the Client that has been created with new(Client)
|
||||
// expression (or just declaring a Client variable) is unsafe
|
||||
// and can lead to panic.
|
||||
type Client struct {
|
||||
client *client.StaticClient // static FrostFS ID contract client
|
||||
}
|
||||
|
||||
const (
|
||||
keyListingMethod = "key"
|
||||
addKeysMethod = "addKey"
|
||||
removeKeysMethod = "removeKey"
|
||||
)
|
||||
|
||||
// NewFromMorph wraps client to work with FrostFS ID contract.
|
||||
func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8, opts ...Option) (*Client, error) {
|
||||
o := defaultOpts()
|
||||
|
||||
for i := range opts {
|
||||
opts[i](o)
|
||||
}
|
||||
|
||||
sc, err := client.NewStatic(cli, contract, fee, ([]client.StaticClientOption)(*o)...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create client of FrostFS ID contract: %w", err)
|
||||
}
|
||||
|
||||
return &Client{client: sc}, nil
|
||||
}
|
||||
|
||||
// Option allows to set an optional
|
||||
// parameter of ClientWrapper.
|
||||
type Option func(*opts)
|
||||
|
||||
type opts []client.StaticClientOption
|
||||
|
||||
func defaultOpts() *opts {
|
||||
return new(opts)
|
||||
}
|
||||
|
||||
// TryNotary returns option to enable
|
||||
// notary invocation tries.
|
||||
func TryNotary() Option {
|
||||
return func(o *opts) {
|
||||
*o = append(*o, client.TryNotary())
|
||||
}
|
||||
}
|
||||
|
||||
// AsAlphabet returns option to sign main TX
|
||||
// of notary requests with client's private
|
||||
// key.
|
||||
//
|
||||
// Considered to be used by IR nodes only.
|
||||
func AsAlphabet() Option {
|
||||
return func(o *opts) {
|
||||
*o = append(*o, client.AsAlphabet())
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package frostfsid
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
)
|
||||
|
||||
// AccountKeysPrm groups parameters of AccountKeys operation.
|
||||
type AccountKeysPrm struct {
|
||||
id user.ID
|
||||
}
|
||||
|
||||
// SetID sets owner ID.
|
||||
func (a *AccountKeysPrm) SetID(id user.ID) {
|
||||
a.id = id
|
||||
}
|
||||
|
||||
// AccountKeys requests public keys of FrostFS account from FrostFS ID contract.
|
||||
func (x *Client) AccountKeys(p AccountKeysPrm) (keys.PublicKeys, error) {
|
||||
prm := client.TestInvokePrm{}
|
||||
prm.SetMethod(keyListingMethod)
|
||||
prm.SetArgs(p.id.WalletBytes())
|
||||
|
||||
items, err := x.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w", keyListingMethod, err)
|
||||
} else if ln := len(items); ln != 1 {
|
||||
return nil, fmt.Errorf("unexpected stack item count (%s): %d", keyListingMethod, ln)
|
||||
}
|
||||
|
||||
items, err = client.ArrayFromStackItem(items[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("1st stack item must be an array (%s)", keyListingMethod)
|
||||
}
|
||||
|
||||
pubs := make(keys.PublicKeys, len(items))
|
||||
for i := range items {
|
||||
rawPub, err := client.BytesFromStackItem(items[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid stack item, expected byte array (%s)", keyListingMethod)
|
||||
}
|
||||
|
||||
pubs[i], err = keys.NewPublicKeyFromBytes(rawPub, elliptic.P256())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("received invalid key (%s): %w", keyListingMethod, err)
|
||||
}
|
||||
}
|
||||
|
||||
return pubs, nil
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package frostfs
|
||||
|
||||
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"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
type Bind struct {
|
||||
BindCommon
|
||||
}
|
||||
|
||||
type BindCommon struct {
|
||||
UserValue []byte
|
||||
KeysValue [][]byte
|
||||
|
||||
// TxHashValue is used in notary environmental
|
||||
// for calculating unique but same for
|
||||
// all notification receivers values.
|
||||
TxHashValue util.Uint256
|
||||
}
|
||||
|
||||
// TxHash returns hash of the TX with new epoch
|
||||
// notification.
|
||||
func (b BindCommon) TxHash() util.Uint256 {
|
||||
return b.TxHashValue
|
||||
}
|
||||
|
||||
// MorphEvent implements Neo:Morph Event interface.
|
||||
func (BindCommon) MorphEvent() {}
|
||||
|
||||
func (b BindCommon) Keys() [][]byte { return b.KeysValue }
|
||||
|
||||
func (b BindCommon) User() []byte { return b.UserValue }
|
||||
|
||||
func ParseBind(e *state.ContainedNotificationEvent) (event.Event, error) {
|
||||
var (
|
||||
ev Bind
|
||||
err error
|
||||
)
|
||||
|
||||
params, err := event.ParseStackArray(e)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse stack items from notify event: %w", err)
|
||||
}
|
||||
|
||||
err = parseBind(&ev.BindCommon, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ev.TxHashValue = e.Container
|
||||
|
||||
return ev, nil
|
||||
}
|
||||
|
||||
func parseBind(dst *BindCommon, params []stackitem.Item) error {
|
||||
if ln := len(params); ln != 2 {
|
||||
return event.WrongNumberOfParameters(2, ln)
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
// parse user
|
||||
dst.UserValue, err = client.BytesFromStackItem(params[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get bind user: %w", err)
|
||||
}
|
||||
|
||||
// parse keys
|
||||
bindKeys, err := client.ArrayFromStackItem(params[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get bind keys: %w", err)
|
||||
}
|
||||
|
||||
dst.KeysValue = make([][]byte, 0, len(bindKeys))
|
||||
|
||||
for i := range bindKeys {
|
||||
rawKey, err := client.BytesFromStackItem(bindKeys[i])
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get bind public key: %w", err)
|
||||
}
|
||||
|
||||
dst.KeysValue = append(dst.KeysValue, rawKey)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package frostfs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"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/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParseBind(t *testing.T) {
|
||||
var (
|
||||
user = []byte{0x1, 0x2, 0x3}
|
||||
publicKeys = [][]byte{
|
||||
[]byte("key1"),
|
||||
[]byte("key2"),
|
||||
[]byte("key3"),
|
||||
}
|
||||
)
|
||||
|
||||
t.Run("wrong number of parameters", func(t *testing.T) {
|
||||
prms := []stackitem.Item{
|
||||
stackitem.NewMap(),
|
||||
}
|
||||
|
||||
_, err := ParseBind(createNotifyEventFromItems(prms))
|
||||
require.EqualError(t, err, event.WrongNumberOfParameters(2, len(prms)).Error())
|
||||
})
|
||||
|
||||
t.Run("wrong first parameter", func(t *testing.T) {
|
||||
_, err := ParseBind(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewMap(),
|
||||
}))
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("wrong second parameter", func(t *testing.T) {
|
||||
_, err := ParseBind(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewByteArray(user),
|
||||
stackitem.NewMap(),
|
||||
}))
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("correct", func(t *testing.T) {
|
||||
ev, err := ParseBind(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewByteArray(user),
|
||||
stackitem.NewArray([]stackitem.Item{
|
||||
stackitem.NewByteArray(publicKeys[0]),
|
||||
stackitem.NewByteArray(publicKeys[1]),
|
||||
stackitem.NewByteArray(publicKeys[2]),
|
||||
}),
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
||||
e := ev.(Bind)
|
||||
|
||||
require.Equal(t, user, e.User())
|
||||
require.Equal(t, publicKeys, e.Keys())
|
||||
})
|
||||
}
|
||||
|
||||
func createNotifyEventFromItems(items []stackitem.Item) *state.ContainedNotificationEvent {
|
||||
return &state.ContainedNotificationEvent{
|
||||
NotificationEvent: state.NotificationEvent{
|
||||
Item: stackitem.NewArray(items),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"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"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -84,3 +85,11 @@ func TestParseCheque(t *testing.T) {
|
|||
}, ev)
|
||||
})
|
||||
}
|
||||
|
||||
func createNotifyEventFromItems(items []stackitem.Item) *state.ContainedNotificationEvent {
|
||||
return &state.ContainedNotificationEvent{
|
||||
NotificationEvent: state.NotificationEvent{
|
||||
Item: stackitem.NewArray(items),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
package frostfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
)
|
||||
|
||||
type Unbind struct {
|
||||
BindCommon
|
||||
}
|
||||
|
||||
func ParseUnbind(e *state.ContainedNotificationEvent) (event.Event, error) {
|
||||
var (
|
||||
ev Unbind
|
||||
err error
|
||||
)
|
||||
|
||||
params, err := event.ParseStackArray(e)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse stack items from notify event: %w", err)
|
||||
}
|
||||
|
||||
err = parseBind(&ev.BindCommon, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ev.TxHashValue = e.Container
|
||||
|
||||
return ev, nil
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package frostfs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParseUnbind(t *testing.T) {
|
||||
var (
|
||||
user = []byte{0x1, 0x2, 0x3}
|
||||
publicKeys = [][]byte{
|
||||
[]byte("key1"),
|
||||
[]byte("key2"),
|
||||
[]byte("key3"),
|
||||
}
|
||||
)
|
||||
|
||||
t.Run("wrong number of parameters", func(t *testing.T) {
|
||||
prms := []stackitem.Item{
|
||||
stackitem.NewMap(),
|
||||
}
|
||||
|
||||
_, err := ParseUnbind(createNotifyEventFromItems(prms))
|
||||
require.EqualError(t, err, event.WrongNumberOfParameters(2, len(prms)).Error())
|
||||
})
|
||||
|
||||
t.Run("wrong first parameter", func(t *testing.T) {
|
||||
_, err := ParseUnbind(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewMap(),
|
||||
}))
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("wrong second parameter", func(t *testing.T) {
|
||||
_, err := ParseUnbind(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewByteArray(user),
|
||||
stackitem.NewMap(),
|
||||
}))
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("correct", func(t *testing.T) {
|
||||
ev, err := ParseUnbind(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewByteArray(user),
|
||||
stackitem.NewArray([]stackitem.Item{
|
||||
stackitem.NewByteArray(publicKeys[0]),
|
||||
stackitem.NewByteArray(publicKeys[1]),
|
||||
stackitem.NewByteArray(publicKeys[2]),
|
||||
}),
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
||||
e := ev.(Unbind)
|
||||
|
||||
require.Equal(t, user, e.User())
|
||||
require.Equal(t, publicKeys, e.Keys())
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue