Skip to content

Commit

Permalink
Merge pull request #98 from nspcc-dev/94-use-neofs-contract-wrappers
Browse files Browse the repository at this point in the history
Use neofs contract wrappers
  • Loading branch information
roman-khimov authored Oct 19, 2023
2 parents 4c0e2a1 + 70329d7 commit fc0b6c1
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 234 deletions.
9 changes: 1 addition & 8 deletions cmd/neofs-net-monitor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ const (
delimiter = "."

// contracts scripthash
cfgNetmapContract = "contracts.netmap"
cfgProxyContract = "contracts.proxy"
cfgBalanceContract = "contracts.balance"
cfgNeoFSContract = "contracts.neofs"
cfgContainerContract = "contracts.container"
cfgNeoFSContract = "contracts.neofs"

// neo rpc node related config values
mainPrefix = "mainnet"
Expand All @@ -38,9 +34,6 @@ const (
)

func DefaultConfiguration(cfg *viper.Viper) {
cfg.SetDefault(cfgNetmapContract, "")
cfg.SetDefault(cfgProxyContract, "")

cfg.SetDefault(sidePrefix+delimiter+cfgNeoRPCEndpoint, "")
cfg.SetDefault(sidePrefix+delimiter+cfgNeoRPCDialTimeout, 5*time.Second)

Expand Down
63 changes: 5 additions & 58 deletions cmd/neofs-net-monitor/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ package main

import (
"context"
"errors"
"fmt"

"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/nspcc-dev/neofs-contract/nns"
rpcnns "github.com/nspcc-dev/neofs-contract/rpc/nns"
"github.com/nspcc-dev/neofs-net-monitor/pkg/locode"
"github.com/nspcc-dev/neofs-net-monitor/pkg/monitor"
"github.com/nspcc-dev/neofs-net-monitor/pkg/morphchain"
Expand Down Expand Up @@ -52,12 +49,12 @@ func New(ctx context.Context, cfg *viper.Viper) (*monitor.Monitor, error) {
return nil, fmt.Errorf("can't create main chain neo-go client: %w", err)
}

netmapContract, err := getScriptHash(cfg, sideNeogoClient, "netmap.neofs", cfgNetmapContract)
netmapContract, err := sideNeogoClient.ResolveContract(rpcnns.NameNetmap)
if err != nil {
return nil, fmt.Errorf("can't read netmap scripthash: %w", err)
}

containerContract, err := getScriptHash(cfg, sideNeogoClient, "container.neofs", cfgContainerContract)
containerContract, err := sideNeogoClient.ResolveContract(rpcnns.NameContainer)
if err != nil {
return nil, fmt.Errorf("can't read container scripthash: %w", err)
}
Expand Down Expand Up @@ -104,12 +101,12 @@ func New(ctx context.Context, cfg *viper.Viper) (*monitor.Monitor, error) {
neofs *util.Uint160
)

balance, err = getScriptHash(cfg, sideNeogoClient, "balance.neofs", cfgBalanceContract)
balance, err = sideNeogoClient.ResolveContract(rpcnns.NameBalance)
if err != nil {
return nil, fmt.Errorf("balance contract is not available: %w", err)
}

proxyContract, err := getScriptHash(cfg, sideNeogoClient, "proxy.neofs", cfgProxyContract)
proxyContract, err := sideNeogoClient.ResolveContract(rpcnns.NameProxy)
if err != nil {
logger.Info("proxy disabled")
} else {
Expand Down Expand Up @@ -149,53 +146,3 @@ func New(ctx context.Context, cfg *viper.Viper) (*monitor.Monitor, error) {
CnrFetcher: cnrFetcher,
}), nil
}

const nnsContractID = 1

func getScriptHash(cfg *viper.Viper, cli *pool.Pool, nnsKey, configKey string) (sh util.Uint160, err error) {
cs, err := cli.GetContractStateByID(nnsContractID)
if err != nil {
return sh, fmt.Errorf("NNS contract state: %w", err)
}

hash := cfg.GetString(configKey)
if len(hash) == 0 {
sh, err = nnsResolve(cli, cs.Hash, nnsKey)
if err != nil {
return sh, fmt.Errorf("NNS.resolve: %w", err)
}
} else {
sh, err = util.Uint160DecodeStringLE(hash)
if err != nil {
return sh, fmt.Errorf("NNS u160 decode: %w", err)
}
}

return sh, nil
}

func nnsResolve(c *pool.Pool, nnsHash util.Uint160, domain string) (util.Uint160, error) {
item, err := unwrap.Item(c.Call(nnsHash, "resolve", domain, int64(nns.TXT)))
if err != nil {
return util.Uint160{}, fmt.Errorf("contract invocation: %w", err)
}

if _, ok := item.(stackitem.Null); ok {
return util.Uint160{}, errors.New("NNS record is missing")
}

// Parse the result of resolving NNS record.
// It works with multiple formats (corresponding to multiple NNS versions).
// If array of hashes is provided, it returns only the first one.
if arr, ok := item.Value().([]stackitem.Item); ok {
if len(arr) == 0 {
return util.Uint160{}, errors.New("NNS record is missing")
}
item = arr[0]
}
bs, err := item.TryBytes()
if err != nil {
return util.Uint160{}, fmt.Errorf("malformed response: %w", err)
}
return util.Uint160DecodeStringLE(string(bs))
}
30 changes: 21 additions & 9 deletions pkg/morphchain/balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/gas"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/notary"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neofs-net-monitor/pkg/pool"
)

type (
BalanceFetcher struct {
cli *pool.Pool
gas util.Uint160
notary util.Uint160
cli *pool.Pool
}

BalanceFetcherArgs struct {
Expand All @@ -23,9 +22,7 @@ type (

func NewBalanceFetcher(p BalanceFetcherArgs) (*BalanceFetcher, error) {
return &BalanceFetcher{
cli: p.Cli,
gas: gas.Hash,
notary: notary.Hash,
cli: p.Cli,
}, nil
}

Expand All @@ -42,13 +39,28 @@ func (b BalanceFetcher) FetchNotary(key keys.PublicKey) (int64, error) {
}

func (b BalanceFetcher) FetchGASByScriptHash(sh util.Uint160) (int64, error) {
return b.cli.NEP17BalanceOf(b.gas, sh)
res, err := gas.NewReader(b.cli).BalanceOf(sh)
if err != nil {
return 0, err
}

return res.Int64(), nil
}

func (b BalanceFetcher) FetchNotaryByScriptHash(sh util.Uint160) (int64, error) {
return b.cli.NEP17BalanceOf(b.notary, sh)
res, err := notary.NewReader(b.cli).BalanceOf(sh)
if err != nil {
return 0, err
}

return res.Int64(), nil
}

func (b BalanceFetcher) FetchNEP17TotalSupply(tokenHash util.Uint160) (int64, error) {
return b.cli.NEP17TotalSupply(tokenHash)
res, err := nep17.NewReader(b.cli, tokenHash).TotalSupply()
if err != nil {
return 0, err
}

return res.Int64(), nil
}
21 changes: 11 additions & 10 deletions pkg/morphchain/contracts/container.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
package contracts

import (
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"fmt"

"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neofs-contract/rpc/container"
"github.com/nspcc-dev/neofs-net-monitor/pkg/pool"
)

type Container struct {
pool *pool.Pool
contractHash util.Uint160
contractReader *container.ContractReader
}

const (
count = "count"
)

// NewContainer creates Container to interact with 'container' contract in morph chain.
func NewContainer(p *pool.Pool, contractHash util.Uint160) (*Container, error) {
return &Container{
pool: p,
contractHash: contractHash,
contractReader: container.NewReader(p, contractHash),
}, nil
}

func (c *Container) Total() (int64, error) {
return unwrap.Int64(c.pool.Call(c.contractHash, count))
amount, err := c.contractReader.Count()
if err != nil {
return 0, fmt.Errorf("count: %w", err)
}

return amount.Int64(), nil
}
65 changes: 20 additions & 45 deletions pkg/morphchain/contracts/netmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import (
"github.com/nspcc-dev/hrw"
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
rpcnetmap "github.com/nspcc-dev/neofs-contract/rpc/netmap"
"github.com/nspcc-dev/neofs-net-monitor/pkg/monitor"
"github.com/nspcc-dev/neofs-net-monitor/pkg/pool"
"github.com/nspcc-dev/neofs-sdk-go/netmap"
Expand All @@ -23,9 +23,10 @@ import (
type (
Netmap struct {
pool *pool.Pool
contractHash util.Uint160
logger *zap.Logger
notaryDisabled bool

contractReader *rpcnetmap.ContractReader
}

NetmapArgs struct {
Expand All @@ -35,19 +36,12 @@ type (
}
)

const (
epochMethod = "epoch"
netmapMethod = "netmap"
netmapCandidatesMethod = "netmapCandidates"
innerRingListMethod = "innerRingList"
)

// NewNetmap creates Netmap to interact with 'netmap' contract in morph chain.
func NewNetmap(p NetmapArgs) (*Netmap, error) {
return &Netmap{
pool: p.Pool,
contractHash: p.NetmapContract,
logger: p.Logger,
pool: p.Pool,
logger: p.Logger,
contractReader: rpcnetmap.NewReader(p.Pool, p.NetmapContract),
}, nil
}

Expand Down Expand Up @@ -122,53 +116,34 @@ func (c *Netmap) FetchInnerRingKeys() (keys.PublicKeys, error) {
}

func (c *Netmap) Epoch() (int64, error) {
return unwrap.Int64(c.pool.Call(c.contractHash, epochMethod))
e, err := c.contractReader.Epoch()
if err != nil {
return 0, fmt.Errorf("epoch: %w", err)
}

return e.Int64(), nil
}

func (c *Netmap) Netmap() ([]*netmap.NodeInfo, error) {
return c.getNodesInfo(netmapMethod)
return c.parsedNodes((*rpcnetmap.ContractReader).Netmap)
}

func (c *Netmap) NetmapCandidates() ([]*netmap.NodeInfo, error) {
return c.getNodesInfo(netmapCandidatesMethod)
return c.parsedNodes((*rpcnetmap.ContractReader).NetmapCandidates)
}

func (c *Netmap) getNodesInfo(method string) ([]*netmap.NodeInfo, error) {
arr, err := unwrap.Array(c.pool.Call(c.contractHash, method))
func (c *Netmap) parsedNodes(f func(reader *rpcnetmap.ContractReader) ([]*rpcnetmap.NetmapNode, error)) ([]*netmap.NodeInfo, error) {
data, err := f(c.contractReader)
if err != nil {
return nil, err
}

nodes := make([]*netmap.NodeInfo, 0, len(arr))
for _, item := range arr {
nodeInfo, err := parseNodeInfo(item)
if err != nil {
return nil, err
}

nodes = append(nodes, nodeInfo)
return nil, fmt.Errorf("contract reader: %w", err)
}

return nodes, nil
}

func (c *Netmap) InnerRingList() (keys.PublicKeys, error) {
arr, err := unwrap.Array(c.pool.Call(c.contractHash, innerRingListMethod))
nodes, err := parseContractNodes(data)
if err != nil {
return nil, err
}

irKeys := make(keys.PublicKeys, 0, len(arr))

for _, item := range arr {
irKey, err := parseIRNode(item)
if err != nil {
return nil, err
}
irKeys = append(irKeys, irKey)
return nil, fmt.Errorf("parseContractNodes: %w", err)
}

return irKeys, nil
return nodes, nil
}

func processNode(logger *zap.Logger, node *netmap.NodeInfo) (*monitor.Node, error) {
Expand Down
Loading

0 comments on commit fc0b6c1

Please sign in to comment.