From ca0e3211be75b3b45dd63aa7984e0f9692429646 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 21 May 2021 10:45:15 +0300 Subject: [PATCH] [#496] innerring/invoke: remove function wrappers Use morph.Client directly. Signed-off-by: Evgenii Stratonikov --- pkg/innerring/indexer.go | 28 ++- pkg/innerring/innerring.go | 22 ++- pkg/innerring/invoke/alphabet.go | 31 ---- pkg/innerring/invoke/balance.go | 92 ---------- pkg/innerring/invoke/chain.go | 53 ------ pkg/innerring/invoke/container.go | 52 ------ pkg/innerring/invoke/neofs.go | 54 ------ pkg/innerring/invoke/netmap.go | 159 ------------------ .../processors/alphabet/process_emit.go | 9 +- .../processors/balance/process_assets.go | 15 +- .../processors/container/process_container.go | 24 +-- .../processors/governance/process_update.go | 14 +- .../processors/neofs/process_assets.go | 39 ++--- .../processors/neofs/process_config.go | 12 +- .../processors/netmap/process_cleanup.go | 11 +- .../processors/netmap/process_epoch.go | 10 +- .../processors/netmap/process_peers.go | 13 +- .../processors/netmap/snapshot/netmap.go | 61 +++++++ pkg/innerring/state.go | 5 +- 19 files changed, 181 insertions(+), 523 deletions(-) delete mode 100644 pkg/innerring/invoke/alphabet.go delete mode 100644 pkg/innerring/invoke/balance.go delete mode 100644 pkg/innerring/invoke/container.go delete mode 100644 pkg/innerring/invoke/neofs.go delete mode 100644 pkg/innerring/invoke/netmap.go create mode 100644 pkg/innerring/processors/netmap/snapshot/netmap.go diff --git a/pkg/innerring/indexer.go b/pkg/innerring/indexer.go index fd309dc9a..b05c8b8dd 100644 --- a/pkg/innerring/indexer.go +++ b/pkg/innerring/indexer.go @@ -1,12 +1,14 @@ package innerring import ( + "bytes" "crypto/ecdsa" "fmt" "sync" "time" - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-node/pkg/morph/client" ) @@ -54,16 +56,20 @@ func (s *innerRingIndexer) update() (ind indexes, err error) { return s.ind, nil } - s.ind.innerRingIndex, s.ind.innerRingSize, err = invoke.InnerRingIndex(s.cli, s.key) + innerRing, err := s.cli.NeoFSAlphabetList() if err != nil { return indexes{}, err } - s.ind.alphabetIndex, err = invoke.AlphabetIndex(s.cli, s.key) + s.ind.innerRingIndex = keyPosition(s.key, innerRing) + s.ind.innerRingSize = int32(len(innerRing)) + + alphabet, err := s.cli.Committee() if err != nil { return indexes{}, err } + s.ind.alphabetIndex = keyPosition(s.key, alphabet) s.lastAccess = time.Now() return s.ind, nil @@ -95,3 +101,19 @@ func (s *innerRingIndexer) AlphabetIndex() (int32, error) { return ind.alphabetIndex, nil } + +// keyPosition returns "-1" if key is not found in the list, otherwise returns +// index of the key. +func keyPosition(key *ecdsa.PublicKey, list keys.PublicKeys) (result int32) { + result = -1 + rawBytes := crypto.MarshalPublicKey(key) + + for i := range list { + if bytes.Equal(list[i].Bytes(), rawBytes) { + result = int32(i) + break + } + } + + return result +} diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 1f091d21d..cf176f894 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -121,6 +121,10 @@ const ( notaryExtraBlocks = 300 // amount of tries before notary deposit timeout. notaryDepositTimeout = 100 + + precisionMethod = "decimals" + // netmap + getEpochMethod = "epoch" ) var ( @@ -831,25 +835,35 @@ func parseAlphabetContracts(cfg *viper.Viper) (alphabetContracts, error) { func (s *Server) initConfigFromBlockchain() error { // get current epoch - epoch, err := invoke.Epoch(s.morphClient, s.contracts.netmap) + val, err := s.morphClient.TestInvoke(s.contracts.netmap, getEpochMethod) if err != nil { return fmt.Errorf("can't read epoch: %w", err) } + epoch, err := client.IntFromStackItem(val[0]) + if err != nil { + return fmt.Errorf("can't parse epoch: %w", err) + } + // get balance precision - balancePrecision, err := invoke.BalancePrecision(s.morphClient, s.contracts.balance) + v, err := s.morphClient.TestInvoke(s.contracts.balance, precisionMethod) if err != nil { return fmt.Errorf("can't read balance contract precision: %w", err) } + balancePrecision, err := client.IntFromStackItem(v[0]) + if err != nil { + return fmt.Errorf("can't parse balance contract precision: %w", err) + } + s.epochCounter.Store(uint64(epoch)) - s.precision.SetBalancePrecision(balancePrecision) + s.precision.SetBalancePrecision(uint32(balancePrecision)) s.log.Debug("read config from blockchain", zap.Bool("active", s.IsActive()), zap.Bool("alphabet", s.IsAlphabet()), zap.Int64("epoch", epoch), - zap.Uint32("precision", balancePrecision), + zap.Uint32("precision", uint32(balancePrecision)), ) return nil diff --git a/pkg/innerring/invoke/alphabet.go b/pkg/innerring/invoke/alphabet.go deleted file mode 100644 index 393e5b146..000000000 --- a/pkg/innerring/invoke/alphabet.go +++ /dev/null @@ -1,31 +0,0 @@ -package invoke - -import ( - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neofs-node/pkg/morph/client" -) - -const ( - emitMethod = "emit" - voteMethod = "vote" -) - -// AlphabetEmit invokes emit method on alphabet contract. -func AlphabetEmit(cli *client.Client, con util.Uint160) error { - if cli == nil { - return client.ErrNilClient - } - - // there is no signature collecting, so we don't need extra fee - return cli.Invoke(con, 0, emitMethod) -} - -// AlphabetVote invokes vote method on alphabet contract. -func AlphabetVote(cli *client.Client, con util.Uint160, fee SideFeeProvider, epoch uint64, keys keys.PublicKeys) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), voteMethod, int64(epoch), keys) -} diff --git a/pkg/innerring/invoke/balance.go b/pkg/innerring/invoke/balance.go deleted file mode 100644 index 5da410b87..000000000 --- a/pkg/innerring/invoke/balance.go +++ /dev/null @@ -1,92 +0,0 @@ -package invoke - -import ( - "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neofs-node/pkg/morph/client" -) - -type ( - // LockParams for LockAsset invocation. - LockParams struct { - ID []byte - User util.Uint160 - LockAccount util.Uint160 - Amount int64 // in Fixed16 - Until uint64 // epochs - } - - // MintBurnParams for Mint and Burn invocations. - MintBurnParams struct { - ScriptHash []byte - Amount int64 // in Fixed16 - Comment []byte - } -) - -const ( - transferXMethod = "transferX" - lockMethod = "lock" - mintMethod = "mint" - burnMethod = "burn" - precisionMethod = "decimals" -) - -// Mint assets in contract. -func Mint(cli *client.Client, con util.Uint160, fee SideFeeProvider, p *MintBurnParams) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), mintMethod, - p.ScriptHash, - p.Amount, - p.Comment, - ) -} - -// Burn minted assets. -func Burn(cli *client.Client, con util.Uint160, fee SideFeeProvider, p *MintBurnParams) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), burnMethod, - p.ScriptHash, - p.Amount, - p.Comment, - ) -} - -// LockAsset invokes Lock method. -func LockAsset(cli *client.Client, con util.Uint160, fee SideFeeProvider, p *LockParams) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), lockMethod, - p.ID, - p.User.BytesBE(), - p.LockAccount.BytesBE(), - p.Amount, - int64(p.Until), - ) -} - -// BalancePrecision invokes Decimal method that returns precision of NEP-5 contract. -func BalancePrecision(cli *client.Client, con util.Uint160) (uint32, error) { - if cli == nil { - return 0, client.ErrNilClient - } - - v, err := cli.TestInvoke(con, precisionMethod) - if err != nil { - return 0, err - } - - precision, err := client.IntFromStackItem(v[0]) - if err != nil { - return 0, err - } - - return uint32(precision), nil -} diff --git a/pkg/innerring/invoke/chain.go b/pkg/innerring/invoke/chain.go index f0ff58dd9..d774fff2c 100644 --- a/pkg/innerring/invoke/chain.go +++ b/pkg/innerring/invoke/chain.go @@ -1,13 +1,7 @@ package invoke import ( - "bytes" - "crypto/ecdsa" - - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" - crypto "github.com/nspcc-dev/neofs-crypto" - "github.com/nspcc-dev/neofs-node/pkg/morph/client" ) type ( @@ -23,50 +17,3 @@ type ( MainChainFee() fixedn.Fixed8 } ) - -// InnerRingIndex returns index of the `key` in the inner ring list from sidechain -// along with total size of inner ring list. If key is not in the inner ring list, -// then returns `-1` as index. -func InnerRingIndex(cli *client.Client, key *ecdsa.PublicKey) (int32, int32, error) { - if cli == nil { - return 0, 0, client.ErrNilClient - } - - innerRing, err := cli.NeoFSAlphabetList() - if err != nil { - return 0, 0, err - } - - return keyPosition(key, innerRing), int32(len(innerRing)), nil -} - -// AlphabetIndex returns index of the `key` in the alphabet key list from sidechain -// If key is not in the inner ring list, then returns `-1` as index. -func AlphabetIndex(cli *client.Client, key *ecdsa.PublicKey) (int32, error) { - if cli == nil { - return 0, client.ErrNilClient - } - - alphabet, err := cli.Committee() - if err != nil { - return 0, err - } - - return keyPosition(key, alphabet), nil -} - -// keyPosition returns "-1" if key is not found in the list, otherwise returns -// index of the key. -func keyPosition(key *ecdsa.PublicKey, list keys.PublicKeys) (result int32) { - result = -1 - rawBytes := crypto.MarshalPublicKey(key) - - for i := range list { - if bytes.Equal(list[i].Bytes(), rawBytes) { - result = int32(i) - break - } - } - - return result -} diff --git a/pkg/innerring/invoke/container.go b/pkg/innerring/invoke/container.go deleted file mode 100644 index 3533efc01..000000000 --- a/pkg/innerring/invoke/container.go +++ /dev/null @@ -1,52 +0,0 @@ -package invoke - -import ( - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neofs-node/pkg/morph/client" -) - -type ( - // ContainerParams for container put invocation. - ContainerParams struct { - Key *keys.PublicKey - Container []byte - Signature []byte - } - - // RemoveContainerParams for container delete invocation. - RemoveContainerParams struct { - ContainerID []byte - Signature []byte - } -) - -const ( - putContainerMethod = "put" - deleteContainerMethod = "delete" -) - -// RegisterContainer invokes Put method. -func RegisterContainer(cli *client.Client, con util.Uint160, fee SideFeeProvider, p *ContainerParams) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), putContainerMethod, - p.Container, - p.Signature, - p.Key.Bytes(), - ) -} - -// RemoveContainer invokes Delete method. -func RemoveContainer(cli *client.Client, con util.Uint160, fee SideFeeProvider, p *RemoveContainerParams) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), deleteContainerMethod, - p.ContainerID, - p.Signature, - ) -} diff --git a/pkg/innerring/invoke/neofs.go b/pkg/innerring/invoke/neofs.go deleted file mode 100644 index 66f7fada8..000000000 --- a/pkg/innerring/invoke/neofs.go +++ /dev/null @@ -1,54 +0,0 @@ -package invoke - -import ( - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neofs-node/pkg/morph/client" -) - -type ( - // ChequeParams for CashOutCheque invocation. - ChequeParams struct { - ID []byte - Amount int64 // Fixed8 - User util.Uint160 - LockAccount util.Uint160 - } -) - -const ( - // Extra SysFee for contract invocations. Contracts execute inner ring - // invocations in two steps: collection and execution. At collection - // step contract waits for (2\3*n + 1) invocations, and then in execution - // stage contract actually makes changes in the contract storage. SysFee - // for invocation calculated based on testinvoke which happens at collection - // stage. Therefore client has to provide some extra SysFee to operate at - // execution stage. Otherwise invocation will fail due to gas limit. - extraFee = 2_0000_0000 // 2.0 Fixed8 gas - - chequeMethod = "cheque" - alphabetUpdateMethod = "alphabetUpdate" -) - -// CashOutCheque invokes Cheque method. -func CashOutCheque(cli *client.Client, con util.Uint160, fee MainFeeProvider, p *ChequeParams) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.MainChainFee(), chequeMethod, - p.ID, - p.User.BytesBE(), - p.Amount, - p.LockAccount.BytesBE(), - ) -} - -// AlphabetUpdate invokes alphabetUpdate method. -func AlphabetUpdate(cli *client.Client, con util.Uint160, fee MainFeeProvider, id []byte, list keys.PublicKeys) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.MainChainFee(), alphabetUpdateMethod, id, list) -} diff --git a/pkg/innerring/invoke/netmap.go b/pkg/innerring/invoke/netmap.go deleted file mode 100644 index 9ddaffc92..000000000 --- a/pkg/innerring/invoke/netmap.go +++ /dev/null @@ -1,159 +0,0 @@ -package invoke - -import ( - "errors" - "fmt" - - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" - "github.com/nspcc-dev/neofs-api-go/pkg/netmap" - "github.com/nspcc-dev/neofs-node/pkg/morph/client" -) - -type ( - UpdatePeerArgs struct { - Key *keys.PublicKey - Status netmap.NodeState - } - - SetConfigArgs struct { - ID []byte - Key []byte - Value []byte - } -) - -const ( - getEpochMethod = "epoch" - setNewEpochMethod = "newEpoch" - approvePeerMethod = "addPeer" - updatePeerStateMethod = "updateState" - setConfigMethod = "setConfig" - setInnerRingMethod = "updateInnerRing" - getNetmapSnapshotMethod = "netmap" -) - -// Epoch return epoch value from contract. -func Epoch(cli *client.Client, con util.Uint160) (int64, error) { - if cli == nil { - return 0, client.ErrNilClient - } - - val, err := cli.TestInvoke(con, getEpochMethod) - if err != nil { - return 0, err - } - - epoch, err := client.IntFromStackItem(val[0]) - if err != nil { - return 0, err - } - - return epoch, nil -} - -// SetNewEpoch invokes newEpoch method. -func SetNewEpoch(cli *client.Client, con util.Uint160, fee SideFeeProvider, epoch uint64) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), setNewEpochMethod, int64(epoch)) -} - -// ApprovePeer invokes addPeer method. -func ApprovePeer(cli *client.Client, con util.Uint160, fee SideFeeProvider, peer []byte) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), approvePeerMethod, peer) -} - -// UpdatePeerState invokes addPeer method. -func UpdatePeerState(cli *client.Client, con util.Uint160, fee SideFeeProvider, args *UpdatePeerArgs) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), updatePeerStateMethod, - int64(args.Status.ToV2()), - args.Key.Bytes(), - ) -} - -// SetConfig invokes setConfig method. -func SetConfig(cli *client.Client, con util.Uint160, fee SideFeeProvider, args *SetConfigArgs) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), setConfigMethod, - args.ID, - args.Key, - args.Value, - ) -} - -// SetInnerRing invokes update inner ring method. This should be used only -// without notary support. -func SetInnerRing(cli *client.Client, con util.Uint160, fee SideFeeProvider, list keys.PublicKeys) error { - if cli == nil { - return client.ErrNilClient - } - - return cli.NotaryInvoke(con, fee.SideChainFee(), setInnerRingMethod, list) -} - -// NetmapSnapshot returns current netmap node infos. -// Consider using pkg/morph/client/netmap for this. -func NetmapSnapshot(cli *client.Client, con util.Uint160) (*netmap.Netmap, error) { - if cli == nil { - return nil, client.ErrNilClient - } - - rawNetmapStack, err := cli.TestInvoke(con, getNetmapSnapshotMethod) - if err != nil { - return nil, err - } - - if ln := len(rawNetmapStack); ln != 1 { - return nil, errors.New("invalid RPC response") - } - - rawNodeInfos, err := client.ArrayFromStackItem(rawNetmapStack[0]) - if err != nil { - return nil, err - } - - result := make([]netmap.NodeInfo, 0, len(rawNodeInfos)) - - for i := range rawNodeInfos { - nodeInfo, err := peerInfoFromStackItem(rawNodeInfos[i]) - if err != nil { - return nil, fmt.Errorf("invalid RPC response: %w", err) - } - - result = append(result, *nodeInfo) - } - - return netmap.NewNetmap(netmap.NodesFromInfo(result)) -} - -func peerInfoFromStackItem(prm stackitem.Item) (*netmap.NodeInfo, error) { - node := netmap.NewNodeInfo() - - subItems, err := client.ArrayFromStackItem(prm) - if err != nil { - return nil, err - } else if ln := len(subItems); ln != 1 { - return nil, errors.New("invalid RPC response") - } else if rawNodeInfo, err := client.BytesFromStackItem(subItems[0]); err != nil { - return nil, err - } else if err = node.Unmarshal(rawNodeInfo); err != nil { - return nil, err - } - - return node, nil -} diff --git a/pkg/innerring/processors/alphabet/process_emit.go b/pkg/innerring/processors/alphabet/process_emit.go index 250146a3b..742d97d7f 100644 --- a/pkg/innerring/processors/alphabet/process_emit.go +++ b/pkg/innerring/processors/alphabet/process_emit.go @@ -5,10 +5,12 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" + "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap/snapshot" "go.uber.org/zap" ) +const emitMethod = "emit" + func (np *Processor) processEmit() { index := np.irList.AlphabetIndex() if index < 0 { @@ -25,7 +27,8 @@ func (np *Processor) processEmit() { return } - err := invoke.AlphabetEmit(np.morphClient, contract) + // there is no signature collecting, so we don't need extra fee + err := np.morphClient.Invoke(contract, 0, emitMethod) if err != nil { np.log.Warn("can't invoke alphabet emit method") @@ -38,7 +41,7 @@ func (np *Processor) processEmit() { return } - networkMap, err := invoke.NetmapSnapshot(np.morphClient, np.netmapContract) + networkMap, err := snapshot.Fetch(np.morphClient, np.netmapContract) if err != nil { np.log.Warn("can't get netmap snapshot to emit gas to storage nodes", zap.String("error", err.Error())) diff --git a/pkg/innerring/processors/balance/process_assets.go b/pkg/innerring/processors/balance/process_assets.go index d40649c45..fd940f79e 100644 --- a/pkg/innerring/processors/balance/process_assets.go +++ b/pkg/innerring/processors/balance/process_assets.go @@ -1,11 +1,12 @@ package balance import ( - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" balanceEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/balance" "go.uber.org/zap" ) +const chequeMethod = "cheque" + // Process lock event by invoking Cheque method in main net to send assets // back to the withdraw issuer. func (bp *Processor) processLock(lock *balanceEvent.Lock) { @@ -14,13 +15,11 @@ func (bp *Processor) processLock(lock *balanceEvent.Lock) { return } - err := invoke.CashOutCheque(bp.mainnetClient, bp.neofsContract, bp.feeProvider, - &invoke.ChequeParams{ - ID: lock.ID(), - Amount: bp.converter.ToFixed8(lock.Amount()), - User: lock.User(), - LockAccount: lock.LockAccount(), - }) + err := bp.mainnetClient.NotaryInvoke(bp.neofsContract, bp.feeProvider.MainChainFee(), chequeMethod, + lock.ID(), + lock.User(), + bp.converter.ToFixed8(lock.Amount()), + lock.LockAccount()) if err != nil { bp.log.Error("can't send lock asset tx", zap.Error(err)) } diff --git a/pkg/innerring/processors/container/process_container.go b/pkg/innerring/processors/container/process_container.go index b781986f3..03c7c1b53 100644 --- a/pkg/innerring/processors/container/process_container.go +++ b/pkg/innerring/processors/container/process_container.go @@ -3,11 +3,15 @@ package container import ( containerSDK "github.com/nspcc-dev/neofs-api-go/pkg/container" "github.com/nspcc-dev/neofs-node/pkg/core/container" - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container" "go.uber.org/zap" ) +const ( + deleteContainerMethod = "delete" + putContainerMethod = "put" +) + // Process new container from the user by checking container sanity // and sending approve tx back to morph. func (cp *Processor) processContainerPut(put *containerEvent.Put) { @@ -37,12 +41,10 @@ func (cp *Processor) processContainerPut(put *containerEvent.Put) { return } - err := invoke.RegisterContainer(cp.morphClient, cp.containerContract, cp.feeProvider, - &invoke.ContainerParams{ - Key: put.PublicKey(), - Container: cnrData, - Signature: put.Signature(), - }) + err := cp.morphClient.NotaryInvoke(cp.containerContract, cp.feeProvider.SideChainFee(), putContainerMethod, + cnrData, + put.Signature(), + put.PublicKey().Bytes()) if err != nil { cp.log.Error("can't invoke new container", zap.Error(err)) } @@ -56,11 +58,9 @@ func (cp *Processor) processContainerDelete(delete *containerEvent.Delete) { return } - err := invoke.RemoveContainer(cp.morphClient, cp.containerContract, cp.feeProvider, - &invoke.RemoveContainerParams{ - ContainerID: delete.ContainerID(), - Signature: delete.Signature(), - }) + err := cp.morphClient.NotaryInvoke(cp.containerContract, cp.feeProvider.SideChainFee(), deleteContainerMethod, + delete.ContainerID(), + delete.Signature()) if err != nil { cp.log.Error("can't invoke delete container", zap.Error(err)) } diff --git a/pkg/innerring/processors/governance/process_update.go b/pkg/innerring/processors/governance/process_update.go index 07e7aee89..7b45cf589 100644 --- a/pkg/innerring/processors/governance/process_update.go +++ b/pkg/innerring/processors/governance/process_update.go @@ -4,11 +4,15 @@ import ( "encoding/binary" "sort" - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" "go.uber.org/zap" ) -const alphabetUpdateIDPrefix = "AlphabetUpdate" +const ( + alphabetUpdateIDPrefix = "AlphabetUpdate" + + alphabetUpdateMethod = "alphabetUpdate" + setInnerRingMethod = "updateInnerRing" +) func (gp *Processor) processAlphabetSync() { if !gp.alphabetState.IsAlphabet() { @@ -66,7 +70,8 @@ func (gp *Processor) processAlphabetSync() { sort.Sort(newInnerRing) if gp.notaryDisabled { - err = invoke.SetInnerRing(gp.morphClient, gp.netmapContract, gp.feeProvider, newInnerRing) + err = gp.morphClient.NotaryInvoke(gp.netmapContract, gp.feeProvider.SideChainFee(), setInnerRingMethod, + newInnerRing) } else { err = gp.morphClient.UpdateNeoFSAlphabetList(newInnerRing) } @@ -95,7 +100,8 @@ func (gp *Processor) processAlphabetSync() { id := append([]byte(alphabetUpdateIDPrefix), buf...) - err = invoke.AlphabetUpdate(gp.mainnetClient, gp.neofsContract, gp.feeProvider, id, newAlphabet) + err = gp.mainnetClient.NotaryInvoke(gp.neofsContract, gp.feeProvider.MainChainFee(), alphabetUpdateMethod, + id, newAlphabet) if err != nil { gp.log.Error("can't update list of alphabet nodes in neofs contract", zap.String("error", err.Error())) diff --git a/pkg/innerring/processors/neofs/process_assets.go b/pkg/innerring/processors/neofs/process_assets.go index a4e257153..daeda154a 100644 --- a/pkg/innerring/processors/neofs/process_assets.go +++ b/pkg/innerring/processors/neofs/process_assets.go @@ -2,7 +2,6 @@ package neofs import ( "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" neofsEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/neofs" "go.uber.org/zap" ) @@ -10,6 +9,10 @@ import ( const ( // lockAccountLifeTime defines amount of epochs when lock account is valid. lockAccountLifetime uint64 = 20 + + burnMethod = "burn" + lockMethod = "lock" + mintMethod = "mint" ) // Process deposit event by invoking balance contract and sending native @@ -21,12 +24,10 @@ func (np *Processor) processDeposit(deposit *neofsEvent.Deposit) { } // send transferX to balance contract - err := invoke.Mint(np.morphClient, np.balanceContract, np.feeProvider, - &invoke.MintBurnParams{ - ScriptHash: deposit.To().BytesBE(), - Amount: np.converter.ToBalancePrecision(deposit.Amount()), - Comment: deposit.ID(), - }) + err := np.morphClient.NotaryInvoke(np.balanceContract, np.feeProvider.SideChainFee(), mintMethod, + deposit.To().BytesBE(), + np.converter.ToBalancePrecision(deposit.Amount()), + deposit.ID()) if err != nil { np.log.Error("can't transfer assets to balance contract", zap.Error(err)) } @@ -94,14 +95,12 @@ func (np *Processor) processWithdraw(withdraw *neofsEvent.Withdraw) { curEpoch := np.epochState.EpochCounter() - err = invoke.LockAsset(np.morphClient, np.balanceContract, np.feeProvider, - &invoke.LockParams{ - ID: withdraw.ID(), - User: withdraw.User(), - LockAccount: lock, - Amount: np.converter.ToBalancePrecision(withdraw.Amount()), - Until: curEpoch + lockAccountLifetime, - }) + err = np.morphClient.NotaryInvoke(np.balanceContract, np.feeProvider.SideChainFee(), lockMethod, + withdraw.ID(), + withdraw.User(), + lock, + np.converter.ToBalancePrecision(withdraw.Amount()), + int64(curEpoch+lockAccountLifetime)) if err != nil { np.log.Error("can't lock assets for withdraw", zap.Error(err)) } @@ -115,12 +114,10 @@ func (np *Processor) processCheque(cheque *neofsEvent.Cheque) { return } - err := invoke.Burn(np.morphClient, np.balanceContract, np.feeProvider, - &invoke.MintBurnParams{ - ScriptHash: cheque.LockAccount().BytesBE(), - Amount: np.converter.ToBalancePrecision(cheque.Amount()), - Comment: cheque.ID(), - }) + err := np.morphClient.NotaryInvoke(np.balanceContract, np.feeProvider.SideChainFee(), burnMethod, + cheque.LockAccount().BytesBE(), + np.converter.ToBalancePrecision(cheque.Amount()), + cheque.ID()) if err != nil { np.log.Error("can't transfer assets to fed contract", zap.Error(err)) } diff --git a/pkg/innerring/processors/neofs/process_config.go b/pkg/innerring/processors/neofs/process_config.go index 5d04c9d88..283260b7d 100644 --- a/pkg/innerring/processors/neofs/process_config.go +++ b/pkg/innerring/processors/neofs/process_config.go @@ -1,11 +1,12 @@ package neofs import ( - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" neofsEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/neofs" "go.uber.org/zap" ) +const setConfigMethod = "setConfig" + // Process config event by setting configuration value from main chain in // side chain. func (np *Processor) processConfig(config *neofsEvent.Config) { @@ -14,13 +15,8 @@ func (np *Processor) processConfig(config *neofsEvent.Config) { return } - err := invoke.SetConfig(np.morphClient, np.netmapContract, np.feeProvider, - &invoke.SetConfigArgs{ - ID: config.ID(), - Key: config.Key(), - Value: config.Value(), - }, - ) + err := np.morphClient.NotaryInvoke(np.netmapContract, np.feeProvider.SideChainFee(), setConfigMethod, + config.ID(), config.Key(), config.Value()) if err != nil { np.log.Error("can't relay set config event", zap.Error(err)) } diff --git a/pkg/innerring/processors/netmap/process_cleanup.go b/pkg/innerring/processors/netmap/process_cleanup.go index 1920c1bae..ab51cb327 100644 --- a/pkg/innerring/processors/netmap/process_cleanup.go +++ b/pkg/innerring/processors/netmap/process_cleanup.go @@ -3,10 +3,11 @@ package netmap import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-api-go/pkg/netmap" - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" "go.uber.org/zap" ) +const updatePeerStateMethod = "updateState" + func (np *Processor) processNetmapCleanupTick(epoch uint64) { if !np.alphabetState.IsAlphabet() { np.log.Info("non alphabet mode, ignore new netmap cleanup tick") @@ -25,11 +26,9 @@ func (np *Processor) processNetmapCleanupTick(epoch uint64) { np.log.Info("vote to remove node from netmap", zap.String("key", s)) - err = invoke.UpdatePeerState(np.morphClient, np.netmapContract, np.feeProvider, - &invoke.UpdatePeerArgs{ - Key: key, - Status: netmap.NodeStateOffline, - }) + err = np.morphClient.NotaryInvoke(np.netmapContract, np.feeProvider.SideChainFee(), updatePeerStateMethod, + int64(netmap.NodeStateOffline.ToV2()), + key.Bytes()) if err != nil { np.log.Error("can't invoke netmap.UpdateState", zap.Error(err)) } diff --git a/pkg/innerring/processors/netmap/process_epoch.go b/pkg/innerring/processors/netmap/process_epoch.go index af29593f4..877c8d448 100644 --- a/pkg/innerring/processors/netmap/process_epoch.go +++ b/pkg/innerring/processors/netmap/process_epoch.go @@ -1,13 +1,15 @@ package netmap import ( - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/audit" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/governance" + "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap/snapshot" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement" "go.uber.org/zap" ) +const setNewEpochMethod = "newEpoch" + // Process new epoch notification by setting global epoch value and resetting // local epoch timer. func (np *Processor) processNewEpoch(epoch uint64) { @@ -18,7 +20,7 @@ func (np *Processor) processNewEpoch(epoch uint64) { } // get new netmap snapshot - snapshot, err := invoke.NetmapSnapshot(np.morphClient, np.netmapContract) + networkMap, err := snapshot.Fetch(np.morphClient, np.netmapContract) if err != nil { np.log.Warn("can't get netmap snapshot to perform cleanup", zap.String("error", err.Error())) @@ -40,7 +42,7 @@ func (np *Processor) processNewEpoch(epoch uint64) { } } - np.netmapSnapshot.update(snapshot, epoch) + np.netmapSnapshot.update(networkMap, epoch) np.handleCleanupTick(netmapCleanupTick{epoch: epoch}) np.handleNewAudit(audit.NewAuditStartEvent(epoch)) np.handleAuditSettlements(settlement.NewAuditEvent(epoch)) @@ -57,7 +59,7 @@ func (np *Processor) processNewEpochTick() { nextEpoch := np.epochState.EpochCounter() + 1 np.log.Debug("next epoch", zap.Uint64("value", nextEpoch)) - err := invoke.SetNewEpoch(np.morphClient, np.netmapContract, np.feeProvider, nextEpoch) + err := np.morphClient.NotaryInvoke(np.netmapContract, np.feeProvider.SideChainFee(), setNewEpochMethod, int64(nextEpoch)) if err != nil { np.log.Error("can't invoke netmap.NewEpoch", zap.Error(err)) } diff --git a/pkg/innerring/processors/netmap/process_peers.go b/pkg/innerring/processors/netmap/process_peers.go index e0664c0c6..4f91b59a8 100644 --- a/pkg/innerring/processors/netmap/process_peers.go +++ b/pkg/innerring/processors/netmap/process_peers.go @@ -6,11 +6,12 @@ import ( "strings" "github.com/nspcc-dev/neofs-api-go/pkg/netmap" - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" netmapEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/netmap" "go.uber.org/zap" ) +const approvePeerMethod = "addPeer" + // Process add peer notification by sanity check of new node // local epoch timer. func (np *Processor) processAddPeer(node []byte) { @@ -66,7 +67,7 @@ func (np *Processor) processAddPeer(node []byte) { np.log.Info("approving network map candidate", zap.String("key", keyString)) - err := invoke.ApprovePeer(np.morphClient, np.netmapContract, np.feeProvider, node) + err := np.morphClient.NotaryInvoke(np.netmapContract, np.feeProvider.SideChainFee(), approvePeerMethod, node) if err != nil { np.log.Error("can't invoke netmap.AddPeer", zap.Error(err)) } @@ -93,11 +94,9 @@ func (np *Processor) processUpdatePeer(ev netmapEvent.UpdatePeer) { // again before new epoch will tick np.netmapSnapshot.flag(hex.EncodeToString(ev.PublicKey().Bytes())) - err := invoke.UpdatePeerState(np.morphClient, np.netmapContract, np.feeProvider, - &invoke.UpdatePeerArgs{ - Key: ev.PublicKey(), - Status: ev.Status(), - }) + err := np.morphClient.NotaryInvoke(np.netmapContract, np.feeProvider.SideChainFee(), updatePeerStateMethod, + int64(ev.Status().ToV2()), + ev.PublicKey().Bytes()) if err != nil { np.log.Error("can't invoke netmap.UpdatePeer", zap.Error(err)) } diff --git a/pkg/innerring/processors/netmap/snapshot/netmap.go b/pkg/innerring/processors/netmap/snapshot/netmap.go new file mode 100644 index 000000000..dbba45785 --- /dev/null +++ b/pkg/innerring/processors/netmap/snapshot/netmap.go @@ -0,0 +1,61 @@ +package snapshot + +import ( + "errors" + "fmt" + + "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" + "github.com/nspcc-dev/neofs-api-go/pkg/netmap" + "github.com/nspcc-dev/neofs-node/pkg/morph/client" +) + +const getNetmapSnapshotMethod = "netmap" + +// Fetch returns current netmap node infos. +// Consider using pkg/morph/client/netmap for this. +func Fetch(cli *client.Client, contract util.Uint160) (*netmap.Netmap, error) { + rawNetmapStack, err := cli.TestInvoke(contract, getNetmapSnapshotMethod) + if err != nil { + return nil, err + } + + if ln := len(rawNetmapStack); ln != 1 { + return nil, errors.New("invalid RPC response") + } + + rawNodeInfos, err := client.ArrayFromStackItem(rawNetmapStack[0]) + if err != nil { + return nil, err + } + + result := make([]netmap.NodeInfo, 0, len(rawNodeInfos)) + + for i := range rawNodeInfos { + nodeInfo, err := peerInfoFromStackItem(rawNodeInfos[i]) + if err != nil { + return nil, fmt.Errorf("invalid RPC response: %w", err) + } + + result = append(result, *nodeInfo) + } + + return netmap.NewNetmap(netmap.NodesFromInfo(result)) +} + +func peerInfoFromStackItem(prm stackitem.Item) (*netmap.NodeInfo, error) { + node := netmap.NewNodeInfo() + + subItems, err := client.ArrayFromStackItem(prm) + if err != nil { + return nil, err + } else if ln := len(subItems); ln != 1 { + return nil, errors.New("invalid RPC response") + } else if rawNodeInfo, err := client.BytesFromStackItem(subItems[0]); err != nil { + return nil, err + } else if err = node.Unmarshal(rawNodeInfo); err != nil { + return nil, err + } + + return node, nil +} diff --git a/pkg/innerring/state.go b/pkg/innerring/state.go index 170f1bd52..310f5e01d 100644 --- a/pkg/innerring/state.go +++ b/pkg/innerring/state.go @@ -5,11 +5,12 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" "github.com/nspcc-dev/neofs-node/pkg/services/audit" "go.uber.org/zap" ) +const voteMethod = "vote" + // EpochCounter is a getter for a global epoch counter. func (s *Server) EpochCounter() uint64 { return s.epochCounter.Load() @@ -84,7 +85,7 @@ func (s *Server) voteForSidechainValidator(validators keys.PublicKeys) error { epoch := s.EpochCounter() s.contracts.alphabet.iterate(func(letter glagoliticLetter, contract util.Uint160) { - err := invoke.AlphabetVote(s.morphClient, contract, s.feeConfig, epoch, validators) + err := s.morphClient.NotaryInvoke(contract, s.feeConfig.SideChainFee(), voteMethod, int64(epoch), validators) if err != nil { s.log.Warn("can't invoke vote method in alphabet contract", zap.Int8("alphabet_index", int8(letter)),