[#1711] amd: Cache committee actor in the init context

Also simplify the code using `invoker.Invoker`.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2022-09-05 15:45:38 +03:00 committed by fyrchik
parent 60aa53651b
commit 8e6e89aca3
16 changed files with 172 additions and 244 deletions

View file

@ -13,6 +13,8 @@ import (
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
@ -55,6 +57,8 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
return err return err
} }
inv := invoker.New(c, nil)
ns, err := getNativeHashes(c) ns, err := getNativeHashes(c)
if err != nil { if err != nil {
return fmt.Errorf("can't fetch the list of native contracts: %w", err) return fmt.Errorf("can't fetch the list of native contracts: %w", err)
@ -76,7 +80,7 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("can't get NNS contract info: %w", err) return fmt.Errorf("can't get NNS contract info: %w", err)
} }
nmHash, err = nnsResolveHash(c, nnsCs.Hash, netmapContract+".neofs") nmHash, err = nnsResolveHash(inv, nnsCs.Hash, netmapContract+".neofs")
if err != nil { if err != nil {
return fmt.Errorf("can't get netmap contract hash: %w", err) return fmt.Errorf("can't get netmap contract hash: %w", err)
} }
@ -87,18 +91,14 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
return err return err
} }
if err := fetchBalances(c, gasHash, irList); err != nil { if err := fetchBalances(inv, gasHash, irList); err != nil {
return err return err
} }
printBalances(cmd, "Inner ring nodes balances:", irList) printBalances(cmd, "Inner ring nodes balances:", irList)
if dumpStorage { if dumpStorage {
res, err := invokeFunction(c, nmHash, "netmap", []interface{}{}, nil) arr, err := unwrap.Array(inv.Call(nmHash, "netmap"))
if err != nil || res.State != vmstate.Halt.String() || len(res.Stack) == 0 { if err != nil {
return errors.New("can't fetch the list of storage nodes")
}
arr, ok := res.Stack[0].Value().([]stackitem.Item)
if !ok {
return errors.New("can't fetch the list of storage nodes") return errors.New("can't fetch the list of storage nodes")
} }
@ -123,20 +123,20 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
snList[i].scriptHash = pub.GetScriptHash() snList[i].scriptHash = pub.GetScriptHash()
} }
if err := fetchBalances(c, gasHash, snList); err != nil { if err := fetchBalances(inv, gasHash, snList); err != nil {
return err return err
} }
printBalances(cmd, "\nStorage node balances:", snList) printBalances(cmd, "\nStorage node balances:", snList)
} }
if dumpProxy { if dumpProxy {
h, err := nnsResolveHash(c, nnsCs.Hash, proxyContract+".neofs") h, err := nnsResolveHash(inv, nnsCs.Hash, proxyContract+".neofs")
if err != nil { if err != nil {
return fmt.Errorf("can't get hash of the proxy contract: %w", err) return fmt.Errorf("can't get hash of the proxy contract: %w", err)
} }
proxyList := []accBalancePair{{scriptHash: h}} proxyList := []accBalancePair{{scriptHash: h}}
if err := fetchBalances(c, gasHash, proxyList); err != nil { if err := fetchBalances(inv, gasHash, proxyList); err != nil {
return err return err
} }
printBalances(cmd, "\nProxy contract balance:", proxyList) printBalances(cmd, "\nProxy contract balance:", proxyList)
@ -168,7 +168,7 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
alphaList[i].scriptHash = h alphaList[i].scriptHash = h
} }
if err := fetchBalances(c, gasHash, alphaList); err != nil { if err := fetchBalances(inv, gasHash, alphaList); err != nil {
return err return err
} }
printBalances(cmd, "\nAlphabet contracts balances:", alphaList) printBalances(cmd, "\nAlphabet contracts balances:", alphaList)
@ -180,13 +180,15 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
func fetchIRNodes(c Client, nmHash, desigHash util.Uint160) ([]accBalancePair, error) { func fetchIRNodes(c Client, nmHash, desigHash util.Uint160) ([]accBalancePair, error) {
var irList []accBalancePair var irList []accBalancePair
inv := invoker.New(c, nil)
if notaryEnabled { if notaryEnabled {
height, err := c.GetBlockCount() height, err := c.GetBlockCount()
if err != nil { if err != nil {
return nil, fmt.Errorf("can't get block height: %w", err) return nil, fmt.Errorf("can't get block height: %w", err)
} }
arr, err := getDesignatedByRole(c, desigHash, noderoles.NeoFSAlphabet, height) arr, err := getDesignatedByRole(inv, desigHash, noderoles.NeoFSAlphabet, height)
if err != nil { if err != nil {
return nil, errors.New("can't fetch list of IR nodes from the netmap contract") return nil, errors.New("can't fetch list of IR nodes from the netmap contract")
} }
@ -196,27 +198,14 @@ func fetchIRNodes(c Client, nmHash, desigHash util.Uint160) ([]accBalancePair, e
irList[i].scriptHash = arr[i].GetScriptHash() irList[i].scriptHash = arr[i].GetScriptHash()
} }
} else { } else {
res, err := invokeFunction(c, nmHash, "innerRingList", []interface{}{}, nil) arr, err := unwrap.ArrayOfBytes(inv.Call(nmHash, "innerRingList"))
if err != nil || res.State != vmstate.Halt.String() || len(res.Stack) == 0 { if err != nil {
return nil, errors.New("can't fetch list of IR nodes from the netmap contract") return nil, errors.New("can't fetch list of IR nodes from the netmap contract")
} }
arr, ok := res.Stack[0].Value().([]stackitem.Item)
if !ok || len(arr) == 0 {
return nil, errors.New("can't fetch list of IR nodes: invalid response")
}
irList = make([]accBalancePair, len(arr)) irList = make([]accBalancePair, len(arr))
for i := range arr { for i := range arr {
node, ok := arr[i].Value().([]stackitem.Item) pub, err := keys.NewPublicKeyFromBytes(arr[i], elliptic.P256())
if !ok || len(arr) == 0 {
return nil, errors.New("can't fetch list of IR nodes: invalid response")
}
bs, err := node[0].TryBytes()
if err != nil {
return nil, fmt.Errorf("can't fetch list of IR nodes: %w", err)
}
pub, err := keys.NewPublicKeyFromBytes(bs, elliptic.P256())
if err != nil { if err != nil {
return nil, fmt.Errorf("can't parse IR node public key: %w", err) return nil, fmt.Errorf("can't parse IR node public key: %w", err)
} }
@ -241,7 +230,7 @@ func printBalances(cmd *cobra.Command, prefix string, accounts []accBalancePair)
} }
} }
func fetchBalances(c Client, gasHash util.Uint160, accounts []accBalancePair) error { func fetchBalances(c *invoker.Invoker, gasHash util.Uint160, accounts []accBalancePair) error {
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
for i := range accounts { for i := range accounts {
emit.AppCall(w.BinWriter, gasHash, "balanceOf", callflag.ReadStates, accounts[i].scriptHash) emit.AppCall(w.BinWriter, gasHash, "balanceOf", callflag.ReadStates, accounts[i].scriptHash)
@ -250,7 +239,7 @@ func fetchBalances(c Client, gasHash util.Uint160, accounts []accBalancePair) er
panic(w.Err) panic(w.Err)
} }
res, err := c.InvokeScript(w.Bytes(), nil) res, err := c.Run(w.Bytes())
if err != nil || res.State != vmstate.Halt.String() || len(res.Stack) != len(accounts) { if err != nil || res.State != vmstate.Halt.String() || len(res.Stack) != len(accounts) {
return errors.New("can't fetch account balances") return errors.New("can't fetch account balances")
} }

View file

@ -11,10 +11,11 @@ import (
"text/tabwriter" "text/tabwriter"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -27,26 +28,23 @@ func dumpNetworkConfig(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("can't create N3 client: %w", err) return fmt.Errorf("can't create N3 client: %w", err)
} }
inv := invoker.New(c, nil)
cs, err := c.GetContractStateByID(1) cs, err := c.GetContractStateByID(1)
if err != nil { if err != nil {
return fmt.Errorf("can't get NNS contract info: %w", err) return fmt.Errorf("can't get NNS contract info: %w", err)
} }
nmHash, err := nnsResolveHash(c, cs.Hash, netmapContract+".neofs") nmHash, err := nnsResolveHash(inv, cs.Hash, netmapContract+".neofs")
if err != nil { if err != nil {
return fmt.Errorf("can't get netmap contract hash: %w", err) return fmt.Errorf("can't get netmap contract hash: %w", err)
} }
res, err := invokeFunction(c, nmHash, "listConfig", nil, nil) arr, err := unwrap.Array(inv.Call(nmHash, "listConfig"))
if err != nil || res.State != vmstate.Halt.String() || len(res.Stack) == 0 { if err != nil {
return errors.New("can't fetch list of network config keys from the netmap contract") return errors.New("can't fetch list of network config keys from the netmap contract")
} }
arr, ok := res.Stack[0].Value().([]stackitem.Item)
if !ok {
return errors.New("invalid ListConfig response from netmap contract")
}
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
tw := tabwriter.NewWriter(buf, 0, 2, 2, ' ', 0) tw := tabwriter.NewWriter(buf, 0, 2, 2, ' ', 0)
@ -111,7 +109,7 @@ func setConfigCmd(cmd *cobra.Command, args []string) error {
return fmt.Errorf("can't get NNS contract info: %w", err) return fmt.Errorf("can't get NNS contract info: %w", err)
} }
nmHash, err := nnsResolveHash(wCtx.Client, cs.Hash, netmapContract+".neofs") nmHash, err := nnsResolveHash(wCtx.ReadOnlyInvoker, cs.Hash, netmapContract+".neofs")
if err != nil { if err != nil {
return fmt.Errorf("can't get netmap contract hash: %w", err) return fmt.Errorf("can't get netmap contract hash: %w", err)
} }

View file

@ -9,6 +9,8 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
@ -31,6 +33,8 @@ func dumpContainers(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("can't create N3 client: %w", err) return fmt.Errorf("can't create N3 client: %w", err)
} }
inv := invoker.New(c, nil)
nnsCs, err := c.GetContractStateByID(1) nnsCs, err := c.GetContractStateByID(1)
if err != nil { if err != nil {
return fmt.Errorf("can't get NNS contract state: %w", err) return fmt.Errorf("can't get NNS contract state: %w", err)
@ -42,30 +46,17 @@ func dumpContainers(cmd *cobra.Command, _ []string) error {
ch, err = util.Uint160DecodeStringLE(s) ch, err = util.Uint160DecodeStringLE(s)
} }
if err != nil { if err != nil {
ch, err = nnsResolveHash(c, nnsCs.Hash, containerContract+".neofs") ch, err = nnsResolveHash(inv, nnsCs.Hash, containerContract+".neofs")
if err != nil { if err != nil {
return err return err
} }
} }
res, err := invokeFunction(c, ch, "list", []interface{}{""}, nil) cids, err := unwrap.ArrayOfBytes(inv.Call(ch, "list", ""))
if err != nil { if err != nil {
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err) return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
} }
var cids [][]byte
arr, ok := res.Stack[0].Value().([]stackitem.Item)
if !ok {
return fmt.Errorf("%w: not a struct", errInvalidContainerResponse)
}
for _, item := range arr {
id, err := item.TryBytes()
if err != nil {
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
}
cids = append(cids, id)
}
isOK, err := getCIDFilterFunc(cmd) isOK, err := getCIDFilterFunc(cmd)
if err != nil { if err != nil {
return err return err
@ -80,7 +71,7 @@ func dumpContainers(cmd *cobra.Command, _ []string) error {
bw.Reset() bw.Reset()
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, id) emit.AppCall(bw.BinWriter, ch, "get", callflag.All, id)
emit.AppCall(bw.BinWriter, ch, "eACL", callflag.All, id) emit.AppCall(bw.BinWriter, ch, "eACL", callflag.All, id)
res, err := c.InvokeScript(bw.Bytes(), nil) res, err := inv.Run(bw.Bytes())
if err != nil { if err != nil {
return fmt.Errorf("can't get container info: %w", err) return fmt.Errorf("can't get container info: %w", err)
} }
@ -129,7 +120,7 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("can't get NNS contract state: %w", err) return fmt.Errorf("can't get NNS contract state: %w", err)
} }
ch, err := nnsResolveHash(wCtx.Client, nnsCs.Hash, containerContract+".neofs") ch, err := nnsResolveHash(wCtx.ReadOnlyInvoker, nnsCs.Hash, containerContract+".neofs")
if err != nil { if err != nil {
return fmt.Errorf("can't fetch container contract hash: %w", err) return fmt.Errorf("can't fetch container contract hash: %w", err)
} }

View file

@ -87,7 +87,7 @@ func deployContractCmd(cmd *cobra.Command, args []string) error {
domain := ctrName + "." + zone domain := ctrName + "." + zone
isUpdate, _ := cmd.Flags().GetBool(updateFlag) isUpdate, _ := cmd.Flags().GetBool(updateFlag)
if isUpdate { if isUpdate {
cs.Hash, err = nnsResolveHash(c.Client, nnsCs.Hash, domain) cs.Hash, err = nnsResolveHash(c.ReadOnlyInvoker, nnsCs.Hash, domain)
if err != nil { if err != nil {
return fmt.Errorf("can't fetch contract hash from NNS: %w", err) return fmt.Errorf("can't fetch contract hash from NNS: %w", err)
} }

View file

@ -6,10 +6,8 @@ import (
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
@ -17,7 +15,6 @@ import (
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate" "github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
"github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/nspcc-dev/neofs-contract/nns" "github.com/nspcc-dev/neofs-contract/nns"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -110,25 +107,9 @@ func dumpContractHashes(cmd *cobra.Command, _ []string) error {
func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string, c Client) error { func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string, c Client) error {
const nnsMaxTokens = 100 const nnsMaxTokens = 100
inv := invoker.New(c, nil)
// The actual signer is not important here. arr, err := unwrap.Array(inv.CallAndExpandIterator(nnsHash, "tokens", nnsMaxTokens))
account, err := wallet.NewAccount()
if err != nil {
return fmt.Errorf("can't create a temporary account: %w", err)
}
signers := []actor.SignerAccount{{
Signer: transaction.Signer{
Account: account.PrivateKey().GetScriptHash(),
},
Account: account,
}}
a, err := actor.New(c.(*rpcclient.Client), signers)
if err != nil {
return fmt.Errorf("can't get a list of NNS domains: %w", err)
}
arr, err := unwrap.Array(a.CallAndExpandIterator(nnsHash, "tokens", nnsMaxTokens))
if err != nil { if err != nil {
return fmt.Errorf("can't get a list of NNS domains: %w", err) return fmt.Errorf("can't get a list of NNS domains: %w", err)
} }
@ -148,7 +129,7 @@ func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string,
continue continue
} }
h, err := nnsResolveHash(c, nnsHash, string(bs)) h, err := nnsResolveHash(inv, nnsHash, string(bs))
if err != nil { if err != nil {
continue continue
} }

View file

@ -5,10 +5,10 @@ import (
"fmt" "fmt"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -24,7 +24,7 @@ func forceNewEpochCmd(cmd *cobra.Command, args []string) error {
return fmt.Errorf("can't get NNS contract info: %w", err) return fmt.Errorf("can't get NNS contract info: %w", err)
} }
nmHash, err := nnsResolveHash(wCtx.Client, cs.Hash, netmapContract+".neofs") nmHash, err := nnsResolveHash(wCtx.ReadOnlyInvoker, cs.Hash, netmapContract+".neofs")
if err != nil { if err != nil {
return fmt.Errorf("can't get netmap contract hash: %w", err) return fmt.Errorf("can't get netmap contract hash: %w", err)
} }
@ -42,18 +42,13 @@ func forceNewEpochCmd(cmd *cobra.Command, args []string) error {
} }
func emitNewEpochCall(bw *io.BufBinWriter, wCtx *initializeContext, nmHash util.Uint160) error { func emitNewEpochCall(bw *io.BufBinWriter, wCtx *initializeContext, nmHash util.Uint160) error {
res, err := invokeFunction(wCtx.Client, nmHash, "epoch", nil, nil) curr, err := unwrap.Int64(wCtx.ReadOnlyInvoker.Call(nmHash, "epoch"))
if err != nil || res.State != vmstate.Halt.String() || len(res.Stack) == 0 { if err != nil {
return errors.New("can't fetch current epoch from the netmap contract") return errors.New("can't fetch current epoch from the netmap contract")
} }
bi, err := res.Stack[0].TryInteger() newEpoch := curr + 1
if err != nil { wCtx.Command.Printf("Current epoch: %d, increase to %d.\n", curr, newEpoch)
return fmt.Errorf("can't parse current epoch: %w", err)
}
newEpoch := bi.Int64() + 1
wCtx.Command.Printf("Current epoch: %s, increase to %d.\n", bi, newEpoch)
// In NeoFS this is done via Notary contract. Here, however, we can form the // In NeoFS this is done via Notary contract. Here, however, we can form the
// transaction locally. // transaction locally.

View file

@ -183,8 +183,13 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
accounts[i] = acc accounts[i] = acc
} }
cliCtx, err := defaultClientContext(c, committeeAcc)
if err != nil {
return nil, fmt.Errorf("client context: %w", err)
}
initCtx := &initializeContext{ initCtx := &initializeContext{
clientContext: *defaultClientContext(c), clientContext: *cliCtx,
ConsensusAcc: consensusAcc, ConsensusAcc: consensusAcc,
CommitteeAcc: committeeAcc, CommitteeAcc: committeeAcc,
ContractWallet: w, ContractWallet: w,
@ -299,7 +304,7 @@ func (c *initializeContext) getSigner(tryGroup bool) transaction.Signer {
return signer return signer
} }
groupKey, err := nnsResolveKey(c.Client, nnsCs.Hash, morphClient.NNSGroupKeyName) groupKey, err := nnsResolveKey(c.ReadOnlyInvoker, nnsCs.Hash, morphClient.NNSGroupKeyName)
if err == nil { if err == nil {
c.groupKey = groupKey c.groupKey = groupKey
@ -320,12 +325,24 @@ func (c *clientContext) awaitTx(cmd *cobra.Command) error {
} }
} }
err := awaitTx(cmd, c.Client, c.Hashes)
c.Hashes = c.Hashes[:0]
return err
}
func awaitTx(cmd *cobra.Command, c Client, hashes []util.Uint256) error {
cmd.Println("Waiting for transactions to persist...") cmd.Println("Waiting for transactions to persist...")
tick := time.NewTicker(c.PollInterval) // improve TX awaiting process:
// https://github.com/nspcc-dev/neofs-node/issues/1741
const pollInterval = time.Second
const waitDuration = 30 * time.Second
tick := time.NewTicker(pollInterval)
defer tick.Stop() defer tick.Stop()
timer := time.NewTimer(c.WaitDuration) timer := time.NewTimer(waitDuration)
defer timer.Stop() defer timer.Stop()
at := trigger.Application at := trigger.Application
@ -333,8 +350,8 @@ func (c *clientContext) awaitTx(cmd *cobra.Command) error {
var retErr error var retErr error
loop: loop:
for i := range c.Hashes { for i := range hashes {
res, err := c.Client.GetApplicationLog(c.Hashes[i], &at) res, err := c.GetApplicationLog(hashes[i], &at)
if err == nil { if err == nil {
if retErr == nil && len(res.Executions) > 0 && res.Executions[0].VMState != vmstate.Halt { if retErr == nil && len(res.Executions) > 0 && res.Executions[0].VMState != vmstate.Halt {
retErr = fmt.Errorf("tx %d persisted in %s state: %s", retErr = fmt.Errorf("tx %d persisted in %s state: %s",
@ -345,7 +362,7 @@ loop:
for { for {
select { select {
case <-tick.C: case <-tick.C:
res, err := c.Client.GetApplicationLog(c.Hashes[i], &at) res, err := c.GetApplicationLog(hashes[i], &at)
if err == nil { if err == nil {
if retErr == nil && len(res.Executions) > 0 && res.Executions[0].VMState != vmstate.Halt { if retErr == nil && len(res.Executions) > 0 && res.Executions[0].VMState != vmstate.Halt {
retErr = fmt.Errorf("tx %d persisted in %s state: %s", retErr = fmt.Errorf("tx %d persisted in %s state: %s",
@ -359,50 +376,34 @@ loop:
} }
} }
c.Hashes = c.Hashes[:0]
return retErr return retErr
} }
// sendCommitteeTx creates transaction from script and sends it to RPC. // sendCommitteeTx creates transaction from script and sends it to RPC.
// Test invocation will be performed and the result will be checked. If tryGroup // If tryGroup is false, global scope is used for the signer (useful when
// is false, global scope is used for the signer (useful when working with native // working with native contracts).
// contracts).
func (c *initializeContext) sendCommitteeTx(script []byte, tryGroup bool) error { func (c *initializeContext) sendCommitteeTx(script []byte, tryGroup bool) error {
sigCount := len(c.CommitteeAcc.Contract.Parameters) var act *actor.Actor
var err error
signers := make([]actor.SignerAccount, 0, sigCount) if tryGroup {
signer := c.getSigner(tryGroup) act, err = actor.New(c.Client, []actor.SignerAccount{{
Signer: c.getSigner(tryGroup),
for i, w := range c.Wallets { Account: c.CommitteeAcc,
if i == sigCount { }})
break } else {
act, err = c.CommitteeAct, nil
} }
acc, err := getWalletAccount(w, committeeAccountName)
if err != nil {
return fmt.Errorf("could not get %s account for %d wallet: %w",
committeeAccountName, i, err)
}
signers = append(signers, actor.SignerAccount{
Signer: signer,
Account: acc,
})
}
act, err := actor.New(c.Client, signers)
if err != nil { if err != nil {
return fmt.Errorf("could not create actor: %w", err) return fmt.Errorf("could not create actor: %w", err)
} }
txHash, _, err := act.SendTunedRun(script, []transaction.Attribute{{Type: transaction.HighPriority}}, nil) tx, err := act.MakeUnsignedRun(script, []transaction.Attribute{{Type: transaction.HighPriority}})
if err != nil { if err != nil {
return fmt.Errorf("cound not send transaction: %w", err) return fmt.Errorf("could not perform test invocation: %w", err)
} }
c.Hashes = append(c.Hashes, txHash) return c.multiSignAndSend(tx, committeeAccountName)
return nil
} }
func getWalletAccount(w *wallet.Wallet, typ string) (*wallet.Account, error) { func getWalletAccount(w *wallet.Wallet, typ string) (*wallet.Account, error) {

View file

@ -181,7 +181,7 @@ func (c *initializeContext) updateContracts() error {
// alphabet contracts should be deployed by individual nodes to get different hashes. // alphabet contracts should be deployed by individual nodes to get different hashes.
for i, acc := range c.Accounts { for i, acc := range c.Accounts {
ctrHash, err := nnsResolveHash(c.Client, nnsHash, getAlphabetNNSDomain(i)) ctrHash, err := nnsResolveHash(c.ReadOnlyInvoker, nnsHash, getAlphabetNNSDomain(i))
if err != nil { if err != nil {
return fmt.Errorf("can't resolve hash for contract update: %w", err) return fmt.Errorf("can't resolve hash for contract update: %w", err)
} }
@ -219,7 +219,7 @@ func (c *initializeContext) updateContracts() error {
cs := c.getContract(ctrName) cs := c.getContract(ctrName)
method := updateMethodName method := updateMethodName
ctrHash, err := nnsResolveHash(c.Client, nnsHash, ctrName+".neofs") ctrHash, err := nnsResolveHash(c.ReadOnlyInvoker, nnsHash, ctrName+".neofs")
if err != nil { if err != nil {
if errors.Is(err, errMissingNNSRecord) { if errors.Is(err, errMissingNNSRecord) {
// if contract not found we deploy it instead of update // if contract not found we deploy it instead of update
@ -240,17 +240,9 @@ func (c *initializeContext) updateContracts() error {
} }
params := getContractDeployParameters(cs, c.getContractDeployData(ctrName, keysParam)) params := getContractDeployParameters(cs, c.getContractDeployData(ctrName, keysParam))
signer := transaction.Signer{ res, err := c.CommitteeAct.MakeCall(invokeHash, method, params)
Account: c.CommitteeAcc.Contract.ScriptHash(),
Scopes: transaction.Global,
}
res, err := invokeFunction(c.Client, invokeHash, method, params, []transaction.Signer{signer})
if err != nil { if err != nil {
return fmt.Errorf("can't deploy %s contract: %w", ctrName, err) return fmt.Errorf("deploy contract: %w", err)
}
if res.State != vmstate.Halt.String() {
return fmt.Errorf("can't deploy %s contract: %s", ctrName, res.FaultException)
} }
w.WriteBytes(res.Script) w.WriteBytes(res.Script)
@ -343,18 +335,10 @@ func (c *initializeContext) deployContracts() error {
} }
params := getContractDeployParameters(cs, c.getContractDeployData(ctrName, keysParam)) params := getContractDeployParameters(cs, c.getContractDeployData(ctrName, keysParam))
signer := transaction.Signer{ res, err := c.CommitteeAct.MakeCall(mgmtHash, deployMethodName, params...)
Account: c.CommitteeAcc.Contract.ScriptHash(),
Scopes: transaction.Global,
}
res, err := invokeFunction(c.Client, mgmtHash, deployMethodName, params, []transaction.Signer{signer})
if err != nil { if err != nil {
return fmt.Errorf("can't deploy %s contract: %w", ctrName, err) return fmt.Errorf("can't deploy %s contract: %w", ctrName, err)
} }
if res.State != vmstate.Halt.String() {
return fmt.Errorf("can't deploy %s contract: %s", ctrName, res.FaultException)
}
if err := c.sendCommitteeTx(res.Script, false); err != nil { if err := c.sendCommitteeTx(res.Script, false); err != nil {
return err return err

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
@ -13,6 +12,8 @@ import (
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
@ -107,7 +108,7 @@ func (c *initializeContext) emitUpdateNNSGroupScript(bw *io.BufBinWriter, nnsHas
} }
if !isAvail { if !isAvail {
currentPub, err := nnsResolveKey(c.Client, nnsHash, morphClient.NNSGroupKeyName) currentPub, err := nnsResolveKey(c.ReadOnlyInvoker, nnsHash, morphClient.NNSGroupKeyName)
if err != nil { if err != nil {
return false, false, err return false, false, err
} }
@ -177,7 +178,7 @@ func (c *initializeContext) nnsRegisterDomainScript(nnsHash, expectedHash util.U
return bw.Bytes(), false, nil return bw.Bytes(), false, nil
} }
s, err := nnsResolveHash(c.Client, nnsHash, domain) s, err := nnsResolveHash(c.ReadOnlyInvoker, nnsHash, domain)
if err != nil { if err != nil {
return nil, false, err return nil, false, err
} }
@ -203,52 +204,39 @@ func (c *initializeContext) nnsRegisterDomain(nnsHash, expectedHash util.Uint160
} }
func (c *initializeContext) nnsRootRegistered(nnsHash util.Uint160, zone string) (bool, error) { func (c *initializeContext) nnsRootRegistered(nnsHash util.Uint160, zone string) (bool, error) {
params := []interface{}{"name." + zone} res, err := c.CommitteeAct.Call(nnsHash, "isAvailable", "name."+zone)
res, err := invokeFunction(c.Client, nnsHash, "isAvailable", params, nil)
if err != nil { if err != nil {
return false, err return false, err
} }
return res.State == vmstate.Halt.String(), nil return res.State == vmstate.Halt.String(), nil
} }
var errMissingNNSRecord = errors.New("missing NNS record") var errMissingNNSRecord = errors.New("missing NNS record")
// Returns errMissingNNSRecord if invocation fault exception contains "token not found". // Returns errMissingNNSRecord if invocation fault exception contains "token not found".
func nnsResolveHash(c Client, nnsHash util.Uint160, domain string) (util.Uint160, error) { func nnsResolveHash(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (util.Uint160, error) {
item, err := nnsResolve(c, nnsHash, domain) item, err := nnsResolve(inv, nnsHash, domain)
if err != nil { if err != nil {
return util.Uint160{}, err return util.Uint160{}, err
} }
return parseNNSResolveResult(item) return parseNNSResolveResult(item)
} }
func nnsResolve(c Client, nnsHash util.Uint160, domain string) (stackitem.Item, error) { func nnsResolve(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (stackitem.Item, error) {
result, err := invokeFunction(c, nnsHash, "resolve", []interface{}{domain, int64(nns.TXT)}, nil) return unwrap.Item(inv.Call(nnsHash, "resolve", domain, int64(nns.TXT)))
if err != nil {
return nil, fmt.Errorf("`resolve`: %w", err)
}
if result.State != vmstate.Halt.String() {
if strings.Contains(result.FaultException, "token not found") {
return nil, errMissingNNSRecord
}
return nil, fmt.Errorf("invocation failed: %s", result.FaultException)
}
if len(result.Stack) == 0 {
return nil, errors.New("result stack is empty")
}
return result.Stack[len(result.Stack)-1], nil
} }
func nnsResolveKey(c Client, nnsHash util.Uint160, domain string) (*keys.PublicKey, error) { func nnsResolveKey(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (*keys.PublicKey, error) {
item, err := nnsResolve(c, nnsHash, domain) item, err := nnsResolve(inv, nnsHash, domain)
if err != nil { if err != nil {
return nil, err return nil, err
} }
arr, ok := item.Value().([]stackitem.Item) v, ok := item.Value().(stackitem.Null)
if !ok || len(arr) == 0 { if ok {
return nil, errors.New("NNS record is missing") return nil, errors.New("NNS record is missing")
} }
bs, err := arr[0].TryBytes() bs, err := v.TryBytes()
if err != nil { if err != nil {
return nil, errors.New("malformed response") return nil, errors.New("malformed response")
} }
@ -286,24 +274,16 @@ func parseNNSResolveResult(res stackitem.Item) (util.Uint160, error) {
return util.Uint160{}, errors.New("no valid hashes are found") return util.Uint160{}, errors.New("no valid hashes are found")
} }
var errNNSIsAvailableInvalid = errors.New("`isAvailable`: invalid response")
func nnsIsAvailable(c Client, nnsHash util.Uint160, name string) (bool, error) { func nnsIsAvailable(c Client, nnsHash util.Uint160, name string) (bool, error) {
switch ct := c.(type) { switch ct := c.(type) {
case *rpcclient.Client: case *rpcclient.Client:
return ct.NNSIsAvailable(nnsHash, name) return ct.NNSIsAvailable(nnsHash, name)
default: default:
res, err := invokeFunction(c, nnsHash, "isAvailable", []interface{}{name}, nil) b, err := unwrap.Bool(invokeFunction(c, nnsHash, "isAvailable", []interface{}{name}, nil))
if err != nil { if err != nil {
return false, err return false, fmt.Errorf("`isAvailable`: invalid response: %w", err)
}
if len(res.Stack) == 0 {
return false, errNNSIsAvailableInvalid
}
b, err := res.Stack[0].TryBool()
if err != nil {
return b, errNNSIsAvailableInvalid
} }
return b, nil return b, nil
} }
} }

View file

@ -10,12 +10,11 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
) )
// initialAlphabetNEOAmount represents the total amount of GAS distributed between alphabet nodes. // initialAlphabetNEOAmount represents the total amount of GAS distributed between alphabet nodes.
@ -24,17 +23,15 @@ const initialAlphabetNEOAmount = native.NEOTotalSupply
func (c *initializeContext) registerCandidates() error { func (c *initializeContext) registerCandidates() error {
neoHash := c.nativeHash(nativenames.Neo) neoHash := c.nativeHash(nativenames.Neo)
res, err := invokeFunction(c.Client, neoHash, "getCandidates", nil, nil) cc, err := unwrap.Array(c.ReadOnlyInvoker.Call(neoHash, "getCandidates"))
if err != nil { if err != nil {
return err return fmt.Errorf("`getCandidates`: %w", err)
} }
if res.State == vmstate.Halt.String() && len(res.Stack) > 0 {
arr, ok := res.Stack[0].Value().([]stackitem.Item) if len(cc) > 0 {
if ok && len(arr) > 0 {
c.Command.Println("Candidates are already registered.") c.Command.Println("Candidates are already registered.")
return nil return nil
} }
}
regPrice, err := c.getCandidateRegisterPrice() regPrice, err := c.getCandidateRegisterPrice()
if err != nil { if err != nil {
@ -75,7 +72,7 @@ func (c *initializeContext) registerCandidates() error {
return fmt.Errorf("can't sign a transaction: %w", err) return fmt.Errorf("can't sign a transaction: %w", err)
} }
network, _ := c.Client.GetNetwork() network := c.CommitteeAct.GetNetwork()
for i := range c.Accounts { for i := range c.Accounts {
if err := c.Accounts[i].SignTx(network, tx); err != nil { if err := c.Accounts[i].SignTx(network, tx); err != nil {
return fmt.Errorf("can't sign a transaction: %w", err) return fmt.Errorf("can't sign a transaction: %w", err)

View file

@ -43,6 +43,6 @@ func (c *initializeContext) setRolesFinished() (bool, error) {
} }
h := c.nativeHash(nativenames.Designation) h := c.nativeHash(nativenames.Designation)
pubs, err := getDesignatedByRole(c.Client, h, noderoles.NeoFSAlphabet, height) pubs, err := getDesignatedByRole(c.ReadOnlyInvoker, h, noderoles.NeoFSAlphabet, height)
return len(pubs) == len(c.Wallets), err return len(pubs) == len(c.Wallets), err
} }

View file

@ -24,6 +24,8 @@ import (
"github.com/nspcc-dev/neo-go/pkg/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/network/payload" "github.com/nspcc-dev/neo-go/pkg/network/payload"
"github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
@ -32,7 +34,6 @@ import (
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate" "github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
"github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -414,16 +415,9 @@ func invokeFunction(c Client, h util.Uint160, method string, parameters []interf
var errGetDesignatedByRoleResponse = errors.New("`getDesignatedByRole`: invalid response") var errGetDesignatedByRoleResponse = errors.New("`getDesignatedByRole`: invalid response")
func getDesignatedByRole(c Client, h util.Uint160, role noderoles.Role, u uint32) (keys.PublicKeys, error) { func getDesignatedByRole(inv *invoker.Invoker, h util.Uint160, role noderoles.Role, u uint32) (keys.PublicKeys, error) {
res, err := invokeFunction(c, h, "getDesignatedByRole", []interface{}{int64(role), int64(u)}, nil) arr, err := unwrap.Array(inv.Call(h, "getDesignatedByRole", int64(role), int64(u)))
if err != nil { if err != nil {
return nil, err
}
if res.State != vmstate.Halt.String() || len(res.Stack) == 0 {
return nil, errGetDesignatedByRoleResponse
}
arr, ok := res.Stack[0].Value().([]stackitem.Item)
if !ok {
return nil, errGetDesignatedByRoleResponse return nil, errGetDesignatedByRoleResponse
} }

View file

@ -14,6 +14,8 @@ import (
"github.com/nspcc-dev/neo-go/pkg/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/network/payload" "github.com/nspcc-dev/neo-go/pkg/network/payload"
"github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
@ -47,10 +49,10 @@ type Client interface {
} }
type clientContext struct { type clientContext struct {
Client Client Client Client // a raw neo-go client OR a local chain implementation
CommitteeAct *actor.Actor // committee actor with the Global witness scope
ReadOnlyInvoker *invoker.Invoker // R/O contract invoker, does not contain any signer
Hashes []util.Uint256 Hashes []util.Uint256
WaitDuration time.Duration
PollInterval time.Duration
} }
func getN3Client(v *viper.Viper) (Client, error) { func getN3Client(v *viper.Viper) (Client, error) {
@ -79,12 +81,23 @@ func getN3Client(v *viper.Viper) (Client, error) {
return c, nil return c, nil
} }
func defaultClientContext(c Client) *clientContext { func defaultClientContext(c Client, committeeAcc *wallet.Account) (*clientContext, error) {
commAct, err := actor.New(c, []actor.SignerAccount{{
Signer: transaction.Signer{
Account: committeeAcc.Contract.ScriptHash(),
Scopes: transaction.Global,
},
Account: committeeAcc,
}})
if err != nil {
return nil, err
}
return &clientContext{ return &clientContext{
Client: c, Client: c,
WaitDuration: time.Second * 30, CommitteeAct: commAct,
PollInterval: time.Second, ReadOnlyInvoker: invoker.New(c, nil),
} }, nil
} }
func (c *clientContext) sendTx(tx *transaction.Transaction, cmd *cobra.Command, await bool) error { func (c *clientContext) sendTx(tx *transaction.Transaction, cmd *cobra.Command, await bool) error {

View file

@ -12,6 +12,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17" "github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -126,8 +127,5 @@ func depositNotary(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("could not send tx: %w", err) return fmt.Errorf("could not send tx: %w", err)
} }
cc := defaultClientContext(c) return awaitTx(cmd, c, []util.Uint256{txHash})
cc.Hashes = append(cc.Hashes, txHash)
return cc.awaitTx(cmd)
} }

View file

@ -37,7 +37,7 @@ func removeNodesCmd(cmd *cobra.Command, args []string) error {
return fmt.Errorf("can't get NNS contract info: %w", err) return fmt.Errorf("can't get NNS contract info: %w", err)
} }
nmHash, err := nnsResolveHash(wCtx.Client, cs.Hash, netmapContract+".neofs") nmHash, err := nnsResolveHash(wCtx.ReadOnlyInvoker, cs.Hash, netmapContract+".neofs")
if err != nil { if err != nil {
return fmt.Errorf("can't get netmap contract hash: %w", err) return fmt.Errorf("can't get netmap contract hash: %w", err)
} }

View file

@ -14,6 +14,7 @@ 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/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
@ -765,11 +766,6 @@ func testInvokeMethod(key keys.PrivateKey, method string, args ...interface{}) (
return nil, fmt.Errorf("NNS contract resolving: %w", err) return nil, fmt.Errorf("NNS contract resolving: %w", err)
} }
subnetHash, err := nnsResolveHash(c, nnsCs.Hash, subnetContract+".neofs")
if err != nil {
return nil, fmt.Errorf("subnet hash resolving: %w", err)
}
cosigner := []transaction.Signer{ cosigner := []transaction.Signer{
{ {
Account: key.PublicKey().GetScriptHash(), Account: key.PublicKey().GetScriptHash(),
@ -777,7 +773,14 @@ func testInvokeMethod(key keys.PrivateKey, method string, args ...interface{}) (
}, },
} }
res, err := invokeFunction(c, subnetHash, method, args, cosigner) inv := invoker.New(c, cosigner)
subnetHash, err := nnsResolveHash(inv, nnsCs.Hash, subnetContract+".neofs")
if err != nil {
return nil, fmt.Errorf("subnet hash resolving: %w", err)
}
res, err := inv.Call(subnetHash, method, args...)
if err != nil { if err != nil {
return nil, fmt.Errorf("invocation parameters prepararion: %w", err) return nil, fmt.Errorf("invocation parameters prepararion: %w", err)
} }
@ -837,11 +840,6 @@ func invokeNonNotary(c Client, key keys.PrivateKey, method string, args ...inter
return fmt.Errorf("NNS contract resolving: %w", err) return fmt.Errorf("NNS contract resolving: %w", err)
} }
subnetHash, err := nnsResolveHash(c, nnsCs.Hash, subnetContract+".neofs")
if err != nil {
return fmt.Errorf("subnet hash resolving: %w", err)
}
acc := wallet.NewAccountFromPrivateKey(&key) acc := wallet.NewAccountFromPrivateKey(&key)
cosigner := []transaction.Signer{ cosigner := []transaction.Signer{
@ -858,7 +856,14 @@ func invokeNonNotary(c Client, key keys.PrivateKey, method string, args ...inter
}, },
} }
test, err := invokeFunction(c, subnetHash, method, args, cosigner) inv := invoker.New(c, cosigner)
subnetHash, err := nnsResolveHash(inv, nnsCs.Hash, subnetContract+".neofs")
if err != nil {
return fmt.Errorf("subnet hash resolving: %w", err)
}
test, err := inv.Call(subnetHash, method, args...)
if err != nil { if err != nil {
return fmt.Errorf("test invocation: %w", err) return fmt.Errorf("test invocation: %w", err)
} }
@ -882,11 +887,6 @@ func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.
return fmt.Errorf("NNS contract resolving: %w", err) return fmt.Errorf("NNS contract resolving: %w", err)
} }
subnetHash, err := nnsResolveHash(c, nnsCs.Hash, subnetContract+".neofs")
if err != nil {
return fmt.Errorf("subnet hash resolving: %w", err)
}
alphabet, err := c.GetCommittee() alphabet, err := c.GetCommittee()
if err != nil { if err != nil {
return fmt.Errorf("alphabet list: %w", err) return fmt.Errorf("alphabet list: %w", err)
@ -902,8 +902,15 @@ func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.
return fmt.Errorf("cosigners collecting: %w", err) return fmt.Errorf("cosigners collecting: %w", err)
} }
inv := invoker.New(c, cosigners)
subnetHash, err := nnsResolveHash(inv, nnsCs.Hash, subnetContract+".neofs")
if err != nil {
return fmt.Errorf("subnet hash resolving: %w", err)
}
// make test invocation of the method // make test invocation of the method
test, err := invokeFunction(c, subnetHash, method, args, cosigners) test, err := inv.Call(subnetHash, method, args...)
if err != nil { if err != nil {
return fmt.Errorf("test invocation: %w", err) return fmt.Errorf("test invocation: %w", err)
} }
@ -974,7 +981,7 @@ func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.
func notaryCosigners(c Client, notaryHash util.Uint160, nnsCs *state.Contract, func notaryCosigners(c Client, notaryHash util.Uint160, nnsCs *state.Contract,
key keys.PrivateKey, alphabetAccount util.Uint160) ([]transaction.Signer, error) { key keys.PrivateKey, alphabetAccount util.Uint160) ([]transaction.Signer, error) {
proxyHash, err := nnsResolveHash(c, nnsCs.Hash, proxyContract+".neofs") proxyHash, err := nnsResolveHash(invoker.New(c, nil), nnsCs.Hash, proxyContract+".neofs")
if err != nil { if err != nil {
return nil, fmt.Errorf("proxy hash resolving: %w", err) return nil, fmt.Errorf("proxy hash resolving: %w", err)
} }