[#496] innerring/invoke: remove function wrappers

Use morph.Client directly.

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2021-05-21 10:45:15 +03:00 committed by Alex Vanin
parent b5cda8cd41
commit ca0e3211be
19 changed files with 181 additions and 523 deletions

View file

@ -1,12 +1,14 @@
package innerring package innerring
import ( import (
"bytes"
"crypto/ecdsa" "crypto/ecdsa"
"fmt" "fmt"
"sync" "sync"
"time" "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" "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 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 { if err != nil {
return indexes{}, err 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 { if err != nil {
return indexes{}, err return indexes{}, err
} }
s.ind.alphabetIndex = keyPosition(s.key, alphabet)
s.lastAccess = time.Now() s.lastAccess = time.Now()
return s.ind, nil return s.ind, nil
@ -95,3 +101,19 @@ func (s *innerRingIndexer) AlphabetIndex() (int32, error) {
return ind.alphabetIndex, nil 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
}

View file

@ -121,6 +121,10 @@ const (
notaryExtraBlocks = 300 notaryExtraBlocks = 300
// amount of tries before notary deposit timeout. // amount of tries before notary deposit timeout.
notaryDepositTimeout = 100 notaryDepositTimeout = 100
precisionMethod = "decimals"
// netmap
getEpochMethod = "epoch"
) )
var ( var (
@ -831,25 +835,35 @@ func parseAlphabetContracts(cfg *viper.Viper) (alphabetContracts, error) {
func (s *Server) initConfigFromBlockchain() error { func (s *Server) initConfigFromBlockchain() error {
// get current epoch // get current epoch
epoch, err := invoke.Epoch(s.morphClient, s.contracts.netmap) val, err := s.morphClient.TestInvoke(s.contracts.netmap, getEpochMethod)
if err != nil { if err != nil {
return fmt.Errorf("can't read epoch: %w", err) 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 // get balance precision
balancePrecision, err := invoke.BalancePrecision(s.morphClient, s.contracts.balance) v, err := s.morphClient.TestInvoke(s.contracts.balance, precisionMethod)
if err != nil { if err != nil {
return fmt.Errorf("can't read balance contract precision: %w", err) 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.epochCounter.Store(uint64(epoch))
s.precision.SetBalancePrecision(balancePrecision) s.precision.SetBalancePrecision(uint32(balancePrecision))
s.log.Debug("read config from blockchain", s.log.Debug("read config from blockchain",
zap.Bool("active", s.IsActive()), zap.Bool("active", s.IsActive()),
zap.Bool("alphabet", s.IsAlphabet()), zap.Bool("alphabet", s.IsAlphabet()),
zap.Int64("epoch", epoch), zap.Int64("epoch", epoch),
zap.Uint32("precision", balancePrecision), zap.Uint32("precision", uint32(balancePrecision)),
) )
return nil return nil

View file

@ -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)
}

View file

@ -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
}

View file

@ -1,13 +1,7 @@
package invoke package invoke
import ( import (
"bytes"
"crypto/ecdsa"
"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/encoding/fixedn"
crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
) )
type ( type (
@ -23,50 +17,3 @@ type (
MainChainFee() fixedn.Fixed8 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
}

View file

@ -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,
)
}

View file

@ -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)
}

View file

@ -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
}

View file

@ -5,10 +5,12 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "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/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" "go.uber.org/zap"
) )
const emitMethod = "emit"
func (np *Processor) processEmit() { func (np *Processor) processEmit() {
index := np.irList.AlphabetIndex() index := np.irList.AlphabetIndex()
if index < 0 { if index < 0 {
@ -25,7 +27,8 @@ func (np *Processor) processEmit() {
return 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 { if err != nil {
np.log.Warn("can't invoke alphabet emit method") np.log.Warn("can't invoke alphabet emit method")
@ -38,7 +41,7 @@ func (np *Processor) processEmit() {
return return
} }
networkMap, err := invoke.NetmapSnapshot(np.morphClient, np.netmapContract) networkMap, err := snapshot.Fetch(np.morphClient, np.netmapContract)
if err != nil { if err != nil {
np.log.Warn("can't get netmap snapshot to emit gas to storage nodes", np.log.Warn("can't get netmap snapshot to emit gas to storage nodes",
zap.String("error", err.Error())) zap.String("error", err.Error()))

View file

@ -1,11 +1,12 @@
package balance package balance
import ( import (
"github.com/nspcc-dev/neofs-node/pkg/innerring/invoke"
balanceEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/balance" balanceEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/balance"
"go.uber.org/zap" "go.uber.org/zap"
) )
const chequeMethod = "cheque"
// Process lock event by invoking Cheque method in main net to send assets // Process lock event by invoking Cheque method in main net to send assets
// back to the withdraw issuer. // back to the withdraw issuer.
func (bp *Processor) processLock(lock *balanceEvent.Lock) { func (bp *Processor) processLock(lock *balanceEvent.Lock) {
@ -14,13 +15,11 @@ func (bp *Processor) processLock(lock *balanceEvent.Lock) {
return return
} }
err := invoke.CashOutCheque(bp.mainnetClient, bp.neofsContract, bp.feeProvider, err := bp.mainnetClient.NotaryInvoke(bp.neofsContract, bp.feeProvider.MainChainFee(), chequeMethod,
&invoke.ChequeParams{ lock.ID(),
ID: lock.ID(), lock.User(),
Amount: bp.converter.ToFixed8(lock.Amount()), bp.converter.ToFixed8(lock.Amount()),
User: lock.User(), lock.LockAccount())
LockAccount: lock.LockAccount(),
})
if err != nil { if err != nil {
bp.log.Error("can't send lock asset tx", zap.Error(err)) bp.log.Error("can't send lock asset tx", zap.Error(err))
} }

View file

@ -3,11 +3,15 @@ package container
import ( import (
containerSDK "github.com/nspcc-dev/neofs-api-go/pkg/container" 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/core/container"
"github.com/nspcc-dev/neofs-node/pkg/innerring/invoke"
containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container" containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container"
"go.uber.org/zap" "go.uber.org/zap"
) )
const (
deleteContainerMethod = "delete"
putContainerMethod = "put"
)
// Process new container from the user by checking container sanity // Process new container from the user by checking container sanity
// and sending approve tx back to morph. // and sending approve tx back to morph.
func (cp *Processor) processContainerPut(put *containerEvent.Put) { func (cp *Processor) processContainerPut(put *containerEvent.Put) {
@ -37,12 +41,10 @@ func (cp *Processor) processContainerPut(put *containerEvent.Put) {
return return
} }
err := invoke.RegisterContainer(cp.morphClient, cp.containerContract, cp.feeProvider, err := cp.morphClient.NotaryInvoke(cp.containerContract, cp.feeProvider.SideChainFee(), putContainerMethod,
&invoke.ContainerParams{ cnrData,
Key: put.PublicKey(), put.Signature(),
Container: cnrData, put.PublicKey().Bytes())
Signature: put.Signature(),
})
if err != nil { if err != nil {
cp.log.Error("can't invoke new container", zap.Error(err)) cp.log.Error("can't invoke new container", zap.Error(err))
} }
@ -56,11 +58,9 @@ func (cp *Processor) processContainerDelete(delete *containerEvent.Delete) {
return return
} }
err := invoke.RemoveContainer(cp.morphClient, cp.containerContract, cp.feeProvider, err := cp.morphClient.NotaryInvoke(cp.containerContract, cp.feeProvider.SideChainFee(), deleteContainerMethod,
&invoke.RemoveContainerParams{ delete.ContainerID(),
ContainerID: delete.ContainerID(), delete.Signature())
Signature: delete.Signature(),
})
if err != nil { if err != nil {
cp.log.Error("can't invoke delete container", zap.Error(err)) cp.log.Error("can't invoke delete container", zap.Error(err))
} }

View file

@ -4,11 +4,15 @@ import (
"encoding/binary" "encoding/binary"
"sort" "sort"
"github.com/nspcc-dev/neofs-node/pkg/innerring/invoke"
"go.uber.org/zap" "go.uber.org/zap"
) )
const alphabetUpdateIDPrefix = "AlphabetUpdate" const (
alphabetUpdateIDPrefix = "AlphabetUpdate"
alphabetUpdateMethod = "alphabetUpdate"
setInnerRingMethod = "updateInnerRing"
)
func (gp *Processor) processAlphabetSync() { func (gp *Processor) processAlphabetSync() {
if !gp.alphabetState.IsAlphabet() { if !gp.alphabetState.IsAlphabet() {
@ -66,7 +70,8 @@ func (gp *Processor) processAlphabetSync() {
sort.Sort(newInnerRing) sort.Sort(newInnerRing)
if gp.notaryDisabled { 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 { } else {
err = gp.morphClient.UpdateNeoFSAlphabetList(newInnerRing) err = gp.morphClient.UpdateNeoFSAlphabetList(newInnerRing)
} }
@ -95,7 +100,8 @@ func (gp *Processor) processAlphabetSync() {
id := append([]byte(alphabetUpdateIDPrefix), buf...) 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 { if err != nil {
gp.log.Error("can't update list of alphabet nodes in neofs contract", gp.log.Error("can't update list of alphabet nodes in neofs contract",
zap.String("error", err.Error())) zap.String("error", err.Error()))

View file

@ -2,7 +2,6 @@ package neofs
import ( import (
"github.com/nspcc-dev/neo-go/pkg/util" "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" neofsEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/neofs"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -10,6 +9,10 @@ import (
const ( const (
// lockAccountLifeTime defines amount of epochs when lock account is valid. // lockAccountLifeTime defines amount of epochs when lock account is valid.
lockAccountLifetime uint64 = 20 lockAccountLifetime uint64 = 20
burnMethod = "burn"
lockMethod = "lock"
mintMethod = "mint"
) )
// Process deposit event by invoking balance contract and sending native // 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 // send transferX to balance contract
err := invoke.Mint(np.morphClient, np.balanceContract, np.feeProvider, err := np.morphClient.NotaryInvoke(np.balanceContract, np.feeProvider.SideChainFee(), mintMethod,
&invoke.MintBurnParams{ deposit.To().BytesBE(),
ScriptHash: deposit.To().BytesBE(), np.converter.ToBalancePrecision(deposit.Amount()),
Amount: np.converter.ToBalancePrecision(deposit.Amount()), deposit.ID())
Comment: deposit.ID(),
})
if err != nil { if err != nil {
np.log.Error("can't transfer assets to balance contract", zap.Error(err)) 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() curEpoch := np.epochState.EpochCounter()
err = invoke.LockAsset(np.morphClient, np.balanceContract, np.feeProvider, err = np.morphClient.NotaryInvoke(np.balanceContract, np.feeProvider.SideChainFee(), lockMethod,
&invoke.LockParams{ withdraw.ID(),
ID: withdraw.ID(), withdraw.User(),
User: withdraw.User(), lock,
LockAccount: lock, np.converter.ToBalancePrecision(withdraw.Amount()),
Amount: np.converter.ToBalancePrecision(withdraw.Amount()), int64(curEpoch+lockAccountLifetime))
Until: curEpoch + lockAccountLifetime,
})
if err != nil { if err != nil {
np.log.Error("can't lock assets for withdraw", zap.Error(err)) np.log.Error("can't lock assets for withdraw", zap.Error(err))
} }
@ -115,12 +114,10 @@ func (np *Processor) processCheque(cheque *neofsEvent.Cheque) {
return return
} }
err := invoke.Burn(np.morphClient, np.balanceContract, np.feeProvider, err := np.morphClient.NotaryInvoke(np.balanceContract, np.feeProvider.SideChainFee(), burnMethod,
&invoke.MintBurnParams{ cheque.LockAccount().BytesBE(),
ScriptHash: cheque.LockAccount().BytesBE(), np.converter.ToBalancePrecision(cheque.Amount()),
Amount: np.converter.ToBalancePrecision(cheque.Amount()), cheque.ID())
Comment: cheque.ID(),
})
if err != nil { if err != nil {
np.log.Error("can't transfer assets to fed contract", zap.Error(err)) np.log.Error("can't transfer assets to fed contract", zap.Error(err))
} }

View file

@ -1,11 +1,12 @@
package neofs package neofs
import ( import (
"github.com/nspcc-dev/neofs-node/pkg/innerring/invoke"
neofsEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/neofs" neofsEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/neofs"
"go.uber.org/zap" "go.uber.org/zap"
) )
const setConfigMethod = "setConfig"
// Process config event by setting configuration value from main chain in // Process config event by setting configuration value from main chain in
// side chain. // side chain.
func (np *Processor) processConfig(config *neofsEvent.Config) { func (np *Processor) processConfig(config *neofsEvent.Config) {
@ -14,13 +15,8 @@ func (np *Processor) processConfig(config *neofsEvent.Config) {
return return
} }
err := invoke.SetConfig(np.morphClient, np.netmapContract, np.feeProvider, err := np.morphClient.NotaryInvoke(np.netmapContract, np.feeProvider.SideChainFee(), setConfigMethod,
&invoke.SetConfigArgs{ config.ID(), config.Key(), config.Value())
ID: config.ID(),
Key: config.Key(),
Value: config.Value(),
},
)
if err != nil { if err != nil {
np.log.Error("can't relay set config event", zap.Error(err)) np.log.Error("can't relay set config event", zap.Error(err))
} }

View file

@ -3,10 +3,11 @@ package netmap
import ( import (
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neofs-api-go/pkg/netmap" "github.com/nspcc-dev/neofs-api-go/pkg/netmap"
"github.com/nspcc-dev/neofs-node/pkg/innerring/invoke"
"go.uber.org/zap" "go.uber.org/zap"
) )
const updatePeerStateMethod = "updateState"
func (np *Processor) processNetmapCleanupTick(epoch uint64) { func (np *Processor) processNetmapCleanupTick(epoch uint64) {
if !np.alphabetState.IsAlphabet() { if !np.alphabetState.IsAlphabet() {
np.log.Info("non alphabet mode, ignore new netmap cleanup tick") 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)) np.log.Info("vote to remove node from netmap", zap.String("key", s))
err = invoke.UpdatePeerState(np.morphClient, np.netmapContract, np.feeProvider, err = np.morphClient.NotaryInvoke(np.netmapContract, np.feeProvider.SideChainFee(), updatePeerStateMethod,
&invoke.UpdatePeerArgs{ int64(netmap.NodeStateOffline.ToV2()),
Key: key, key.Bytes())
Status: netmap.NodeStateOffline,
})
if err != nil { if err != nil {
np.log.Error("can't invoke netmap.UpdateState", zap.Error(err)) np.log.Error("can't invoke netmap.UpdateState", zap.Error(err))
} }

View file

@ -1,13 +1,15 @@
package netmap package netmap
import ( 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/audit"
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/governance" "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" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement"
"go.uber.org/zap" "go.uber.org/zap"
) )
const setNewEpochMethod = "newEpoch"
// Process new epoch notification by setting global epoch value and resetting // Process new epoch notification by setting global epoch value and resetting
// local epoch timer. // local epoch timer.
func (np *Processor) processNewEpoch(epoch uint64) { func (np *Processor) processNewEpoch(epoch uint64) {
@ -18,7 +20,7 @@ func (np *Processor) processNewEpoch(epoch uint64) {
} }
// get new netmap snapshot // get new netmap snapshot
snapshot, err := invoke.NetmapSnapshot(np.morphClient, np.netmapContract) networkMap, err := snapshot.Fetch(np.morphClient, np.netmapContract)
if err != nil { if err != nil {
np.log.Warn("can't get netmap snapshot to perform cleanup", np.log.Warn("can't get netmap snapshot to perform cleanup",
zap.String("error", err.Error())) 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.handleCleanupTick(netmapCleanupTick{epoch: epoch})
np.handleNewAudit(audit.NewAuditStartEvent(epoch)) np.handleNewAudit(audit.NewAuditStartEvent(epoch))
np.handleAuditSettlements(settlement.NewAuditEvent(epoch)) np.handleAuditSettlements(settlement.NewAuditEvent(epoch))
@ -57,7 +59,7 @@ func (np *Processor) processNewEpochTick() {
nextEpoch := np.epochState.EpochCounter() + 1 nextEpoch := np.epochState.EpochCounter() + 1
np.log.Debug("next epoch", zap.Uint64("value", nextEpoch)) 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 { if err != nil {
np.log.Error("can't invoke netmap.NewEpoch", zap.Error(err)) np.log.Error("can't invoke netmap.NewEpoch", zap.Error(err))
} }

View file

@ -6,11 +6,12 @@ import (
"strings" "strings"
"github.com/nspcc-dev/neofs-api-go/pkg/netmap" "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" netmapEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/netmap"
"go.uber.org/zap" "go.uber.org/zap"
) )
const approvePeerMethod = "addPeer"
// Process add peer notification by sanity check of new node // Process add peer notification by sanity check of new node
// local epoch timer. // local epoch timer.
func (np *Processor) processAddPeer(node []byte) { func (np *Processor) processAddPeer(node []byte) {
@ -66,7 +67,7 @@ func (np *Processor) processAddPeer(node []byte) {
np.log.Info("approving network map candidate", np.log.Info("approving network map candidate",
zap.String("key", keyString)) 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 { if err != nil {
np.log.Error("can't invoke netmap.AddPeer", zap.Error(err)) 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 // again before new epoch will tick
np.netmapSnapshot.flag(hex.EncodeToString(ev.PublicKey().Bytes())) np.netmapSnapshot.flag(hex.EncodeToString(ev.PublicKey().Bytes()))
err := invoke.UpdatePeerState(np.morphClient, np.netmapContract, np.feeProvider, err := np.morphClient.NotaryInvoke(np.netmapContract, np.feeProvider.SideChainFee(), updatePeerStateMethod,
&invoke.UpdatePeerArgs{ int64(ev.Status().ToV2()),
Key: ev.PublicKey(), ev.PublicKey().Bytes())
Status: ev.Status(),
})
if err != nil { if err != nil {
np.log.Error("can't invoke netmap.UpdatePeer", zap.Error(err)) np.log.Error("can't invoke netmap.UpdatePeer", zap.Error(err))
} }

View file

@ -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
}

View file

@ -5,11 +5,12 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/util" "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" "github.com/nspcc-dev/neofs-node/pkg/services/audit"
"go.uber.org/zap" "go.uber.org/zap"
) )
const voteMethod = "vote"
// EpochCounter is a getter for a global epoch counter. // EpochCounter is a getter for a global epoch counter.
func (s *Server) EpochCounter() uint64 { func (s *Server) EpochCounter() uint64 {
return s.epochCounter.Load() return s.epochCounter.Load()
@ -84,7 +85,7 @@ func (s *Server) voteForSidechainValidator(validators keys.PublicKeys) error {
epoch := s.EpochCounter() epoch := s.EpochCounter()
s.contracts.alphabet.iterate(func(letter glagoliticLetter, contract util.Uint160) { 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 { if err != nil {
s.log.Warn("can't invoke vote method in alphabet contract", s.log.Warn("can't invoke vote method in alphabet contract",
zap.Int8("alphabet_index", int8(letter)), zap.Int8("alphabet_index", int8(letter)),