From 4bd8608b37c5b2c920356a80a3edc2295c62dc22 Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Mon, 29 Aug 2022 22:31:32 +0300 Subject: [PATCH] [#1711] *: Simplify code using neo-go actors Signed-off-by: Pavel Karpy --- .../internal/modules/morph/config.go | 2 +- .../internal/modules/morph/container.go | 2 +- .../internal/modules/morph/deploy.go | 2 +- cmd/neofs-adm/internal/modules/morph/epoch.go | 2 +- .../internal/modules/morph/generate.go | 2 +- .../internal/modules/morph/initialize.go | 78 ++++++++----------- .../modules/morph/initialize_deploy.go | 35 +++------ .../internal/modules/morph/initialize_nns.go | 6 +- .../modules/morph/initialize_register.go | 2 +- .../modules/morph/initialize_roles.go | 2 +- .../internal/modules/morph/local_client.go | 15 ++++ .../internal/modules/morph/n3client.go | 5 ++ .../internal/modules/morph/notary.go | 40 ++++------ .../internal/modules/morph/policy.go | 2 +- .../internal/modules/morph/remove_node.go | 2 +- 15 files changed, 92 insertions(+), 105 deletions(-) diff --git a/cmd/neofs-adm/internal/modules/morph/config.go b/cmd/neofs-adm/internal/modules/morph/config.go index 5c1259065..3e7da25cb 100644 --- a/cmd/neofs-adm/internal/modules/morph/config.go +++ b/cmd/neofs-adm/internal/modules/morph/config.go @@ -134,7 +134,7 @@ func setConfigCmd(cmd *cobra.Command, args []string) error { } } - err = wCtx.sendCommitteeTx(bw.Bytes(), -1, true) + err = wCtx.sendCommitteeTx(bw.Bytes(), true) if err != nil { return err } diff --git a/cmd/neofs-adm/internal/modules/morph/container.go b/cmd/neofs-adm/internal/modules/morph/container.go index abd02fe4e..b7ae960dc 100644 --- a/cmd/neofs-adm/internal/modules/morph/container.go +++ b/cmd/neofs-adm/internal/modules/morph/container.go @@ -188,7 +188,7 @@ func restoreContainers(cmd *cobra.Command, _ []string) error { panic(bw.Err) } - if err := wCtx.sendCommitteeTx(bw.Bytes(), -1, true); err != nil { + if err := wCtx.sendCommitteeTx(bw.Bytes(), true); err != nil { return err } } diff --git a/cmd/neofs-adm/internal/modules/morph/deploy.go b/cmd/neofs-adm/internal/modules/morph/deploy.go index 48ce35839..b164d85ee 100644 --- a/cmd/neofs-adm/internal/modules/morph/deploy.go +++ b/cmd/neofs-adm/internal/modules/morph/deploy.go @@ -168,7 +168,7 @@ func deployContractCmd(cmd *cobra.Command, args []string) error { panic(fmt.Errorf("BUG: can't create deployment script: %w", w.Err)) } - if err := c.sendCommitteeTx(w.Bytes(), -1, false); err != nil { + if err := c.sendCommitteeTx(w.Bytes(), false); err != nil { return err } return c.awaitTx() diff --git a/cmd/neofs-adm/internal/modules/morph/epoch.go b/cmd/neofs-adm/internal/modules/morph/epoch.go index bbf498e27..4e7637f7b 100644 --- a/cmd/neofs-adm/internal/modules/morph/epoch.go +++ b/cmd/neofs-adm/internal/modules/morph/epoch.go @@ -34,7 +34,7 @@ func forceNewEpochCmd(cmd *cobra.Command, args []string) error { return err } - if err := wCtx.sendCommitteeTx(bw.Bytes(), -1, true); err != nil { + if err := wCtx.sendCommitteeTx(bw.Bytes(), true); err != nil { return err } diff --git a/cmd/neofs-adm/internal/modules/morph/generate.go b/cmd/neofs-adm/internal/modules/morph/generate.go index 7602620dc..26c0530d2 100644 --- a/cmd/neofs-adm/internal/modules/morph/generate.go +++ b/cmd/neofs-adm/internal/modules/morph/generate.go @@ -195,7 +195,7 @@ func refillGas(cmd *cobra.Command, gasFlag string, createWallet bool) error { return fmt.Errorf("BUG: invalid transfer arguments: %w", bw.Err) } - if err := wCtx.sendCommitteeTx(bw.Bytes(), -1, false); err != nil { + if err := wCtx.sendCommitteeTx(bw.Bytes(), false); err != nil { return err } diff --git a/cmd/neofs-adm/internal/modules/morph/initialize.go b/cmd/neofs-adm/internal/modules/morph/initialize.go index 4fc5065f1..b2b10b8c6 100644 --- a/cmd/neofs-adm/internal/modules/morph/initialize.go +++ b/cmd/neofs-adm/internal/modules/morph/initialize.go @@ -11,7 +11,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/rpcclient" + "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/vmstate" @@ -364,57 +364,45 @@ loop: } // sendCommitteeTx creates transaction from script and sends it to RPC. -// If sysFee is -1, it is calculated automatically. If tryGroup is false, -// global scope is used for the signer (useful when working with native contracts). -func (c *initializeContext) sendCommitteeTx(script []byte, sysFee int64, tryGroup bool) error { - cosigners := []rpcclient.SignerAccount{{ - Signer: c.getSigner(tryGroup), - Account: c.CommitteeAcc, - }} - tx, err := c.Client.CreateTxFromScript(script, c.CommitteeAcc, sysFee, 0, cosigners) +// Test invocation will be performed and the result will be checked. If tryGroup +// is false, global scope is used for the signer (useful when working with native +// contracts). +func (c *initializeContext) sendCommitteeTx(script []byte, tryGroup bool) error { + sigCount := len(c.CommitteeAcc.Contract.Parameters) + + signers := make([]actor.SignerAccount, 0, sigCount) + signer := c.getSigner(tryGroup) + + for i, w := range c.Wallets { + if i == sigCount { + break + } + + 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 { - return fmt.Errorf("can't create tx: %w", err) + return fmt.Errorf("could not create actor: %w", err) } - tx.Attributes = append(tx.Attributes, transaction.Attribute{Type: transaction.HighPriority}) - - // Calculate network fee again, because tx size has changed. - _, accounts, err := getSigners(c.CommitteeAcc, cosigners) + txHash, _, err := act.SendTunedRun(script, []transaction.Attribute{{Type: transaction.HighPriority}}, nil) if err != nil { - panic(fmt.Errorf("BUG: can't calculate network fee: %w", err)) + return fmt.Errorf("cound not send transaction: %w", err) } - tx.NetworkFee = 0 - err = c.Client.AddNetworkFee(tx, 0, accounts...) - if err != nil { - return fmt.Errorf("failed to add network fee: %w", err) - } - return c.multiSignAndSend(tx, committeeAccountName) -} + c.Hashes = append(c.Hashes, txHash) -// sendSingleTx creates transaction signed by a simple account and pushes in onto the chain. -// It neither waits until tx persists nor checks the execution result. -func (c *initializeContext) sendSingleTx(script []byte, sysFee int64, acc *wallet.Account) error { - tx, err := c.Client.CreateTxFromScript(script, acc, sysFee, 0, []rpcclient.SignerAccount{{ - Signer: transaction.Signer{ - Account: acc.Contract.ScriptHash(), - Scopes: transaction.CalledByEntry, - }, - Account: acc, - }}) - if err != nil { - return err - } - - magic, err := c.Client.GetNetwork() - if err != nil { - return fmt.Errorf("can't fetch network magic: %w", err) - } - if err := acc.SignTx(magic, tx); err != nil { - return fmt.Errorf("can't sign tx: %w", err) - } - - return c.sendTx(tx, c.Command, false) + return nil } func getWalletAccount(w *wallet.Wallet, typ string) (*wallet.Account, error) { diff --git a/cmd/neofs-adm/internal/modules/morph/initialize_deploy.go b/cmd/neofs-adm/internal/modules/morph/initialize_deploy.go index eb270b8f3..0c15d22b9 100644 --- a/cmd/neofs-adm/internal/modules/morph/initialize_deploy.go +++ b/cmd/neofs-adm/internal/modules/morph/initialize_deploy.go @@ -18,6 +18,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/encoding/address" io2 "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/rpcclient" + "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "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/manifest" @@ -203,18 +204,7 @@ func (c *initializeContext) updateContracts() error { emit.AppCallNoArgs(w.BinWriter, ctrHash, updateMethodName, callflag.All) } - res, err := c.Client.InvokeScript(w.Bytes(), []transaction.Signer{{ - Account: c.CommitteeAcc.Contract.ScriptHash(), - Scopes: transaction.Global, - }}) - if err != nil { - return fmt.Errorf("can't update alphabet contracts: %w", err) - } - if res.State != vmstate.Halt.String() { - return fmt.Errorf("can't update alphabet contracts: %s", res.FaultException) - } - - if err := c.sendCommitteeTx(res.Script, res.GasConsumed, false); err != nil { + if err := c.sendCommitteeTx(w.Bytes(), false); err != nil { return err } @@ -294,7 +284,7 @@ func (c *initializeContext) updateContracts() error { emit.Opcodes(w.BinWriter, opcode.LDSFLD0) emit.AppCallNoArgs(w.BinWriter, nnsHash, "setPrice", callflag.All) - if err := c.sendCommitteeTx(w.Bytes(), -1, false); err != nil { + if err := c.sendCommitteeTx(w.Bytes(), false); err != nil { return err } return c.awaitTx() @@ -325,20 +315,17 @@ func (c *initializeContext) deployContracts() error { keysParam = append(keysParam, acc.PrivateKey().PublicKey().Bytes()) params := getContractDeployParameters(alphaCs, c.getAlphabetDeployItems(i, len(c.Wallets))) - res, err := invokeFunction(c.Client, mgmtHash, deployMethodName, params, []transaction.Signer{{ - Account: acc.Contract.ScriptHash(), - Scopes: transaction.CalledByEntry, - }}) + act, err := actor.NewSimple(c.Client, acc) + if err != nil { + return fmt.Errorf("could not create actor: %w", err) + } + + txHash, _, err := act.SendCall(mgmtHash, deployMethodName, params...) if err != nil { return fmt.Errorf("can't deploy alphabet #%d contract: %w", i, err) } - if res.State != vmstate.Halt.String() { - return fmt.Errorf("can't deploy alpabet #%d contract: %s", i, res.FaultException) - } - if err := c.sendSingleTx(res.Script, res.GasConsumed, acc); err != nil { - return err - } + c.Hashes = append(c.Hashes, txHash) } for _, ctrName := range contractList { @@ -369,7 +356,7 @@ func (c *initializeContext) deployContracts() error { return fmt.Errorf("can't deploy %s contract: %s", ctrName, res.FaultException) } - if err := c.sendCommitteeTx(res.Script, res.GasConsumed, false); err != nil { + if err := c.sendCommitteeTx(res.Script, false); err != nil { return err } } diff --git a/cmd/neofs-adm/internal/modules/morph/initialize_nns.go b/cmd/neofs-adm/internal/modules/morph/initialize_nns.go index 9e8a97cc8..4cedfba3d 100644 --- a/cmd/neofs-adm/internal/modules/morph/initialize_nns.go +++ b/cmd/neofs-adm/internal/modules/morph/initialize_nns.go @@ -40,7 +40,7 @@ func (c *initializeContext) setNNS() error { "neofs", c.CommitteeAcc.Contract.ScriptHash(), "ops@nspcc.ru", int64(3600), int64(600), int64(defaultExpirationTime), int64(3600)) emit.Opcodes(bw.BinWriter, opcode.ASSERT) - if err := c.sendCommitteeTx(bw.Bytes(), -1, true); err != nil { + if err := c.sendCommitteeTx(bw.Bytes(), true); err != nil { return fmt.Errorf("can't add domain root to NNS: %w", err) } if err := c.awaitTx(); err != nil { @@ -94,7 +94,7 @@ func (c *initializeContext) updateNNSGroup(nnsHash util.Uint160, pub *keys.Publi script = w.Bytes() } - return c.sendCommitteeTx(script, -1, true) + return c.sendCommitteeTx(script, true) } // emitUpdateNNSGroupScript emits script for updating group key stored in NNS. @@ -199,7 +199,7 @@ func (c *initializeContext) nnsRegisterDomain(nnsHash, expectedHash util.Uint160 domain, int64(nns.TXT), expectedHash.StringLE()) emit.AppCall(w.BinWriter, nnsHash, "addRecord", callflag.All, domain, int64(nns.TXT), address.Uint160ToString(expectedHash)) - return c.sendCommitteeTx(w.Bytes(), -1, true) + return c.sendCommitteeTx(w.Bytes(), true) } func (c *initializeContext) nnsRootRegistered(nnsHash util.Uint160, zone string) (bool, error) { diff --git a/cmd/neofs-adm/internal/modules/morph/initialize_register.go b/cmd/neofs-adm/internal/modules/morph/initialize_register.go index 42706c8aa..66769fbee 100644 --- a/cmd/neofs-adm/internal/modules/morph/initialize_register.go +++ b/cmd/neofs-adm/internal/modules/morph/initialize_register.go @@ -104,7 +104,7 @@ func (c *initializeContext) transferNEOToAlphabetContracts() error { emit.Opcodes(bw.BinWriter, opcode.ASSERT) } - if err := c.sendCommitteeTx(bw.Bytes(), -1, false); err != nil { + if err := c.sendCommitteeTx(bw.Bytes(), false); err != nil { return err } diff --git a/cmd/neofs-adm/internal/modules/morph/initialize_roles.go b/cmd/neofs-adm/internal/modules/morph/initialize_roles.go index 2103b9f8f..7577b981a 100644 --- a/cmd/neofs-adm/internal/modules/morph/initialize_roles.go +++ b/cmd/neofs-adm/internal/modules/morph/initialize_roles.go @@ -29,7 +29,7 @@ func (c *initializeContext) setNotaryAndAlphabetNodes() error { emit.AppCall(w.BinWriter, designateHash, "designateAsRole", callflag.States|callflag.AllowNotify, int64(noderoles.NeoFSAlphabet), pubs) - if err := c.sendCommitteeTx(w.Bytes(), -1, false); err != nil { + if err := c.sendCommitteeTx(w.Bytes(), false); err != nil { return err } diff --git a/cmd/neofs-adm/internal/modules/morph/local_client.go b/cmd/neofs-adm/internal/modules/morph/local_client.go index bb4132bf0..a0a9ac72d 100644 --- a/cmd/neofs-adm/internal/modules/morph/local_client.go +++ b/cmd/neofs-adm/internal/modules/morph/local_client.go @@ -179,6 +179,21 @@ func (l *localClient) SignAndPushInvocationTx(_ []byte, _ *wallet.Account, _ int panic("unexpected call") } +func (l *localClient) GetVersion() (*result.Version, error) { + // not used by `morph init` command + panic("unexpected call") +} + +func (l *localClient) InvokeContractVerify(contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) { + // not used by `morph init` command + panic("unexpected call") +} + +func (l *localClient) CalculateNetworkFee(tx *transaction.Transaction) (int64, error) { + // not used by `morph init` command + panic("unexpected call") +} + // AddNetworkFee adds network fee for each witness script and optional extra // network fee to transaction. `accs` is an array signer's accounts. // Copied from neo-go with minor corrections (no need to support contract signers): diff --git a/cmd/neofs-adm/internal/modules/morph/n3client.go b/cmd/neofs-adm/internal/modules/morph/n3client.go index 8e7f7a300..2ced34c4c 100644 --- a/cmd/neofs-adm/internal/modules/morph/n3client.go +++ b/cmd/neofs-adm/internal/modules/morph/n3client.go @@ -14,6 +14,7 @@ import ( "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/rpcclient" + "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/wallet" @@ -30,12 +31,16 @@ type Client interface { GetNativeContracts() ([]state.NativeContract, error) GetNetwork() (netmode.Magic, error) GetApplicationLog(util.Uint256, *trigger.Type) (*result.ApplicationLog, error) + GetVersion() (*result.Version, error) CreateTxFromScript([]byte, *wallet.Account, int64, int64, []rpcclient.SignerAccount) (*transaction.Transaction, error) NEP17BalanceOf(util.Uint160, util.Uint160) (int64, error) + InvokeContractVerify(contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) + InvokeFunction(contract util.Uint160, operation string, params []smartcontract.Parameter, signers []transaction.Signer) (*result.Invoke, error) InvokeScript([]byte, []transaction.Signer) (*result.Invoke, error) SendRawTransaction(*transaction.Transaction) (util.Uint256, error) GetCommittee() (keys.PublicKeys, error) CalculateNotaryFee(uint8) (int64, error) + CalculateNetworkFee(tx *transaction.Transaction) (int64, error) AddNetworkFee(*transaction.Transaction, int64, ...*wallet.Account) error SignAndPushInvocationTx([]byte, *wallet.Account, int64, fixedn.Fixed8, []rpcclient.SignerAccount) (util.Uint256, error) SignAndPushP2PNotaryRequest(*transaction.Transaction, []byte, int64, int64, uint32, *wallet.Account) (*payload.P2PNotaryRequest, error) diff --git a/cmd/neofs-adm/internal/modules/morph/notary.go b/cmd/neofs-adm/internal/modules/morph/notary.go index 58baec389..c0a2c18c2 100644 --- a/cmd/neofs-adm/internal/modules/morph/notary.go +++ b/cmd/neofs-adm/internal/modules/morph/notary.go @@ -2,6 +2,7 @@ package morph import ( "fmt" + "math/big" "strconv" "github.com/nspcc-dev/neo-go/cli/input" @@ -9,11 +10,8 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/address" - "github.com/nspcc-dev/neo-go/pkg/io" - "github.com/nspcc-dev/neo-go/pkg/rpcclient" - "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/opcode" + "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/wallet" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -105,15 +103,7 @@ func depositNotary(cmd *cobra.Command, _ []string) error { return fmt.Errorf("can't get current height: %v", err) } - bw := io.NewBufBinWriter() - emit.AppCall(bw.BinWriter, gasHash, "transfer", callflag.All, - accHash, notaryHash.BytesBE(), int64(gasAmount), []interface{}{nil, int64(height) + till}) - emit.Opcodes(bw.BinWriter, opcode.ASSERT) - if bw.Err != nil { - return fmt.Errorf("BUG: invalid transfer arguments: %w", bw.Err) - } - - tx, err := c.CreateTxFromScript(bw.Bytes(), acc, -1, 0, []rpcclient.SignerAccount{{ + act, err := actor.New(c, []actor.SignerAccount{{ Signer: transaction.Signer{ Account: acc.Contract.ScriptHash(), Scopes: transaction.Global, @@ -121,21 +111,23 @@ func depositNotary(cmd *cobra.Command, _ []string) error { Account: acc, }}) if err != nil { - return fmt.Errorf("can't create tx: %w", err) + return fmt.Errorf("could not create actor: %w", err) } - mn, err := c.GetNetwork() - if err != nil { - // error appears only if client - // has not been initialized - panic(err) - } + gas := nep17.New(act, gasHash) - err = acc.SignTx(mn, tx) + txHash, _, err := gas.Transfer( + accHash, + notaryHash, + big.NewInt(int64(gasAmount)), + []interface{}{nil, int64(height) + till}, + ) if err != nil { - return fmt.Errorf("can't sign tx: %w", err) + return fmt.Errorf("could not send tx: %w", err) } cc := defaultClientContext(c) - return cc.sendTx(tx, cmd, true) + cc.Hashes = append(cc.Hashes, txHash) + + return cc.awaitTx(cmd) } diff --git a/cmd/neofs-adm/internal/modules/morph/policy.go b/cmd/neofs-adm/internal/modules/morph/policy.go index 26994662b..86e095fc4 100644 --- a/cmd/neofs-adm/internal/modules/morph/policy.go +++ b/cmd/neofs-adm/internal/modules/morph/policy.go @@ -48,7 +48,7 @@ func setPolicyCmd(cmd *cobra.Command, args []string) error { emit.AppCall(bw.BinWriter, policyHash, "set"+kv[0], callflag.All, int64(value)) } - if err := wCtx.sendCommitteeTx(bw.Bytes(), -1, false); err != nil { + if err := wCtx.sendCommitteeTx(bw.Bytes(), false); err != nil { return err } diff --git a/cmd/neofs-adm/internal/modules/morph/remove_node.go b/cmd/neofs-adm/internal/modules/morph/remove_node.go index c351d9af7..b07612393 100644 --- a/cmd/neofs-adm/internal/modules/morph/remove_node.go +++ b/cmd/neofs-adm/internal/modules/morph/remove_node.go @@ -52,7 +52,7 @@ func removeNodesCmd(cmd *cobra.Command, args []string) error { return err } - if err := wCtx.sendCommitteeTx(bw.Bytes(), -1, true); err != nil { + if err := wCtx.sendCommitteeTx(bw.Bytes(), true); err != nil { return err }