Skip to content

Commit

Permalink
cli: add wallet candidat getstate
Browse files Browse the repository at this point in the history
  • Loading branch information
AnnaShaleva committed May 28, 2021
1 parent 8371c80 commit c8be613
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 1 deletion.
15 changes: 14 additions & 1 deletion cli/candidate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"encoding/hex"
"math/big"
"strconv"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -48,14 +49,23 @@ func TestRegisterCandidate(t *testing.T) {
"--wallet", validatorWallet,
"--address", validatorPriv.Address(),
"--candidate", hex.EncodeToString(validatorPriv.PublicKey().Bytes()))
e.checkTxPersisted(t)
_, index := e.checkTxPersisted(t)

vs, err = e.Chain.GetEnrollments()
require.Equal(t, 1, len(vs))
require.Equal(t, validatorPriv.PublicKey(), vs[0].Key)
b, _ := e.Chain.GetGoverningTokenBalance(validatorPriv.GetScriptHash())
require.Equal(t, b, vs[0].Votes)

// check state
e.Run(t, "neo-go", "wallet", "candidate", "getstate",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--address", validatorPriv.Address())
e.checkNextLine(t, "^\\s*Voted:\\s+"+validatorPriv.Address())
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$")
e.checkNextLine(t, "^\\s*Block\\s*:\\s*"+strconv.FormatUint(uint64(index), 10))
e.checkEOF(t)

// unvote
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "candidate", "vote",
Expand Down Expand Up @@ -84,4 +94,7 @@ func TestRegisterCandidate(t *testing.T) {

vs, err = e.Chain.GetEnrollments()
require.Equal(t, 0, len(vs))

// getstate: missing address
e.RunWithError(t, "neo-go", "wallet", "candidate", "getstate")
}
78 changes: 78 additions & 0 deletions cli/wallet/validator.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package wallet

import (
"crypto/elliptic"
"fmt"

"github.com/nspcc-dev/neo-go/cli/flags"
Expand All @@ -10,12 +11,15 @@ 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/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"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/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/urfave/cli"
)
Expand Down Expand Up @@ -71,6 +75,18 @@ func newValidatorCommands() []cli.Command {
},
}, options.RPC...),
},
{
Name: "getstate",
Usage: "print NEO holder account state",
UsageText: "getstate -a <addr>",
Action: getAccountState,
Flags: append([]cli.Flag{
flags.AddressFlag{
Name: "address, a",
Usage: "Address to get state of",
},
}, options.RPC...),
},
}
}

Expand Down Expand Up @@ -204,3 +220,65 @@ func getDecryptedAccount(ctx *cli.Context, wall *wallet.Wallet, addr util.Uint16
}
return acc, nil
}

func getAccountState(ctx *cli.Context) error {
addrFlag := ctx.Generic("address").(*flags.Address)
if !addrFlag.IsSet {
return cli.NewExitError("address was not provided", 1)
}

gctx, cancel := options.GetTimeoutContext(ctx)
defer cancel()
c, exitErr := options.GetRPCClient(gctx, ctx)
if exitErr != nil {
return exitErr
}

neoHash, err := c.GetNativeContractHash(nativenames.Neo)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to get NEO contract hash: %w", err), 1)
}
res, err := c.InvokeFunction(neoHash, "getAccountState", []smartcontract.Parameter{
{
Type: smartcontract.Hash160Type,
Value: addrFlag.Uint160(),
},
}, nil)
if err != nil {
return cli.NewExitError(err, 1)
}
if res.State != "HALT" {
return cli.NewExitError(fmt.Errorf("invocation failed: %s", res.FaultException), 1)
}
if len(res.Stack) == 0 {
return cli.NewExitError("result stack is empty", 1)
}
arr, ok := res.Stack[0].Value().([]stackitem.Item)
if !ok || len(arr) < 3 {
return cli.NewExitError("invalid result stackitem item", 1)
}
amount, err := arr[0].TryInteger()
if err != nil {
return cli.NewExitError(fmt.Errorf("invalid amount item: %w", err), 1)
}
dec, err := c.NEP17Decimals(neoHash)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to get decimals: %w", err), 1)
}
block, err := arr[1].TryInteger()
if err != nil {
return cli.NewExitError(fmt.Errorf("invalid block item: %w", err), 1)
}
pubBytes, err := arr[2].TryBytes()
if err != nil {
return cli.NewExitError(fmt.Errorf("invalid publick key item: %w", err), 1)
}
pk, err := keys.NewPublicKeyFromBytes(pubBytes, elliptic.P256())
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to decode public key from bytes: %w", err), 1)
}
fmt.Fprintf(ctx.App.Writer, "\tVoted: %s\n", address.Uint160ToString(pk.GetScriptHash()))
fmt.Fprintf(ctx.App.Writer, "\tAmount : %s\n", fixedn.ToString(amount, int(dec)))
fmt.Fprintf(ctx.App.Writer, "\tBlock: %d\n", block)
return nil
}

0 comments on commit c8be613

Please sign in to comment.