Merge pull request #2637 from nspcc-dev/cli-use-actor-more

Use Actor more in the CLI
This commit is contained in:
Roman Khimov 2022-08-10 18:26:18 +03:00 committed by GitHub
commit 5cd3b0c923
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -11,9 +11,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/crypto/keys" "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/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"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"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"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/urfave/cli" "github.com/urfave/cli"
) )
@ -76,14 +78,24 @@ func newValidatorCommands() []cli.Command {
} }
func handleRegister(ctx *cli.Context) error { func handleRegister(ctx *cli.Context) error {
return handleCandidate(ctx, "registerCandidate", 100000000) // 1 additional GAS. return handleCandidate(ctx, true)
} }
func handleUnregister(ctx *cli.Context) error { func handleUnregister(ctx *cli.Context) error {
return handleCandidate(ctx, "unregisterCandidate", -1) return handleCandidate(ctx, false)
} }
func handleCandidate(ctx *cli.Context, method string, sysGas int64) error { func handleCandidate(ctx *cli.Context, register bool) error {
const (
regMethod = "registerCandidate"
unregMethod = "unregisterCandidate"
)
var (
err error
script []byte
sysGas int64
)
if err := cmdargs.EnsureNone(ctx); err != nil { if err := cmdargs.EnsureNone(ctx); err != nil {
return err return err
} }
@ -110,12 +122,9 @@ func handleCandidate(ctx *cli.Context, method string, sysGas int64) error {
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }
if sysGas >= 0 { act, err := actor.NewSimple(c, acc)
regPrice, err := c.GetCandidateRegisterPrice() if err != nil {
if err != nil { return cli.NewExitError(fmt.Errorf("RPC actor issue: %w", err), 1)
return cli.NewExitError(err, 1)
}
sysGas += regPrice
} }
gas := flags.Fixed8FromContext(ctx, "gas") gas := flags.Fixed8FromContext(ctx, "gas")
@ -123,17 +132,40 @@ func handleCandidate(ctx *cli.Context, method string, sysGas int64) error {
if err != nil { if err != nil {
return err return err
} }
script, err := smartcontract.CreateCallWithAssertScript(neoContractHash, method, acc.PrivateKey().PublicKey().Bytes()) unregScript, err := smartcontract.CreateCallWithAssertScript(neoContractHash, unregMethod, acc.PrivateKey().PublicKey().Bytes())
if err != nil { if err != nil {
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }
res, err := c.SignAndPushInvocationTx(script, acc, sysGas, gas, []rpcclient.SignerAccount{{ //nolint:staticcheck // SA1019: c.SignAndPushInvocationTx is deprecated if !register {
Signer: transaction.Signer{ script = unregScript
Account: acc.Contract.ScriptHash(), } else {
Scopes: transaction.CalledByEntry, script, err = smartcontract.CreateCallWithAssertScript(neoContractHash, regMethod, acc.PrivateKey().PublicKey().Bytes())
}, if err != nil {
Account: acc, return cli.NewExitError(err, 1)
}}) }
}
// Registration price is normally much bigger than MaxGasInvoke, so to
// determine proper amount of GAS we _always_ run unreg script and then
// add registration price to it if needed.
r, err := act.Run(unregScript)
if err != nil {
return cli.NewExitError(fmt.Errorf("Run failure: %w", err), 1)
}
sysGas = r.GasConsumed
if register {
// Deregistration will fail, so there is no point in checking State.
regPrice, err := c.GetCandidateRegisterPrice()
if err != nil {
return cli.NewExitError(err, 1)
}
sysGas += regPrice
} else if r.State != vmstate.Halt.String() {
return cli.NewExitError(fmt.Errorf("unregister transaction failed: %s", r.FaultException), 1)
}
res, _, err := act.SendUncheckedRun(script, sysGas, nil, func(t *transaction.Transaction) error {
t.NetworkFee += int64(gas)
return nil
})
if err != nil { if err != nil {
return cli.NewExitError(fmt.Errorf("failed to push transaction: %w", err), 1) return cli.NewExitError(fmt.Errorf("failed to push transaction: %w", err), 1)
} }
@ -176,6 +208,10 @@ func handleVote(ctx *cli.Context) error {
if err != nil { if err != nil {
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }
act, err := actor.NewSimple(c, acc)
if err != nil {
return cli.NewExitError(fmt.Errorf("RPC actor issue: %w", err), 1)
}
var pubArg interface{} var pubArg interface{}
if pub != nil { if pub != nil {
@ -191,12 +227,13 @@ func handleVote(ctx *cli.Context) error {
if err != nil { if err != nil {
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }
res, err := c.SignAndPushInvocationTx(script, acc, -1, gas, []rpcclient.SignerAccount{{ //nolint:staticcheck // SA1019: c.SignAndPushInvocationTx is deprecated res, _, err := act.SendTunedRun(script, nil, func(r *result.Invoke, t *transaction.Transaction) error {
Signer: transaction.Signer{ if r.State != vmstate.Halt.String() {
Account: acc.Contract.ScriptHash(), return fmt.Errorf("invocation failed: %s", r.FaultException)
Scopes: transaction.CalledByEntry, }
}, t.NetworkFee += int64(gas)
Account: acc}}) return nil
})
if err != nil { if err != nil {
return cli.NewExitError(fmt.Errorf("failed to push invocation transaction: %w", err), 1) return cli.NewExitError(fmt.Errorf("failed to push invocation transaction: %w", err), 1)
} }