forked from TrueCloudLab/neoneo-go
cli/query: add 'candidates' and 'committee', fix #2067
This commit is contained in:
parent
14a52c9e1b
commit
753e61bcff
4 changed files with 160 additions and 6 deletions
|
@ -15,6 +15,8 @@ import (
|
||||||
func TestRegisterCandidate(t *testing.T) {
|
func TestRegisterCandidate(t *testing.T) {
|
||||||
e := newExecutor(t, true)
|
e := newExecutor(t, true)
|
||||||
|
|
||||||
|
validatorHex := hex.EncodeToString(validatorPriv.PublicKey().Bytes())
|
||||||
|
|
||||||
e.In.WriteString("one\r")
|
e.In.WriteString("one\r")
|
||||||
e.Run(t, "neo-go", "wallet", "nep17", "multitransfer",
|
e.Run(t, "neo-go", "wallet", "nep17", "multitransfer",
|
||||||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||||
|
@ -24,6 +26,15 @@ func TestRegisterCandidate(t *testing.T) {
|
||||||
"GAS:"+validatorPriv.Address()+":10000")
|
"GAS:"+validatorPriv.Address()+":10000")
|
||||||
e.checkTxPersisted(t)
|
e.checkTxPersisted(t)
|
||||||
|
|
||||||
|
e.Run(t, "neo-go", "query", "committee",
|
||||||
|
"--rpc-endpoint", "http://"+e.RPC.Addr)
|
||||||
|
e.checkNextLine(t, "^\\s*"+validatorHex)
|
||||||
|
|
||||||
|
e.Run(t, "neo-go", "query", "candidates",
|
||||||
|
"--rpc-endpoint", "http://"+e.RPC.Addr)
|
||||||
|
e.checkNextLine(t, "^\\s*Key.+$") // Header.
|
||||||
|
e.checkEOF(t)
|
||||||
|
|
||||||
// missing address
|
// missing address
|
||||||
e.RunWithError(t, "neo-go", "wallet", "candidate", "register",
|
e.RunWithError(t, "neo-go", "wallet", "candidate", "register",
|
||||||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||||
|
@ -48,7 +59,7 @@ func TestRegisterCandidate(t *testing.T) {
|
||||||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||||
"--wallet", validatorWallet,
|
"--wallet", validatorWallet,
|
||||||
"--address", validatorPriv.Address(),
|
"--address", validatorPriv.Address(),
|
||||||
"--candidate", hex.EncodeToString(validatorPriv.PublicKey().Bytes()))
|
"--candidate", validatorHex)
|
||||||
_, index := e.checkTxPersisted(t)
|
_, index := e.checkTxPersisted(t)
|
||||||
|
|
||||||
vs, err = e.Chain.GetEnrollments()
|
vs, err = e.Chain.GetEnrollments()
|
||||||
|
@ -57,6 +68,16 @@ func TestRegisterCandidate(t *testing.T) {
|
||||||
b, _ := e.Chain.GetGoverningTokenBalance(validatorPriv.GetScriptHash())
|
b, _ := e.Chain.GetGoverningTokenBalance(validatorPriv.GetScriptHash())
|
||||||
require.Equal(t, b, vs[0].Votes)
|
require.Equal(t, b, vs[0].Votes)
|
||||||
|
|
||||||
|
e.Run(t, "neo-go", "query", "committee",
|
||||||
|
"--rpc-endpoint", "http://"+e.RPC.Addr)
|
||||||
|
e.checkNextLine(t, "^\\s*"+validatorHex)
|
||||||
|
|
||||||
|
e.Run(t, "neo-go", "query", "candidates",
|
||||||
|
"--rpc-endpoint", "http://"+e.RPC.Addr)
|
||||||
|
e.checkNextLine(t, "^\\s*Key.+$") // Header.
|
||||||
|
e.checkNextLine(t, "^\\s*"+validatorHex+"\\s*"+b.String()+"\\s*true\\s*true$")
|
||||||
|
e.checkEOF(t)
|
||||||
|
|
||||||
// check state
|
// check state
|
||||||
e.Run(t, "neo-go", "wallet", "candidate", "getstate",
|
e.Run(t, "neo-go", "wallet", "candidate", "getstate",
|
||||||
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
"--rpc-endpoint", "http://"+e.RPC.Addr,
|
||||||
|
|
|
@ -3,7 +3,9 @@ package query
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
@ -29,6 +31,18 @@ func NewCommands() []cli.Command {
|
||||||
Name: "query",
|
Name: "query",
|
||||||
Usage: "Query data from RPC node",
|
Usage: "Query data from RPC node",
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
|
{
|
||||||
|
Name: "candidates",
|
||||||
|
Usage: "Get candidates and votes",
|
||||||
|
Action: queryCandidates,
|
||||||
|
Flags: options.RPC,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "committee",
|
||||||
|
Usage: "Get committee list",
|
||||||
|
Action: queryCommittee,
|
||||||
|
Flags: options.RPC,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "tx",
|
Name: "tx",
|
||||||
Usage: "Query transaction status",
|
Usage: "Query transaction status",
|
||||||
|
@ -113,3 +127,65 @@ func dumpApplicationLog(ctx *cli.Context, res *result.ApplicationLog, tx *result
|
||||||
_ = tw.Flush()
|
_ = tw.Flush()
|
||||||
fmt.Fprint(ctx.App.Writer, buf.String())
|
fmt.Fprint(ctx.App.Writer, buf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func queryCandidates(ctx *cli.Context) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
c, err := options.GetRPCClient(gctx, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError(err, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
vals, err := c.GetNextBlockValidators()
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError(err, 1)
|
||||||
|
}
|
||||||
|
comm, err := c.GetCommittee()
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError(err, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(vals, func(i, j int) bool {
|
||||||
|
if vals[i].Active != vals[j].Active {
|
||||||
|
return vals[i].Active
|
||||||
|
}
|
||||||
|
if vals[i].Votes != vals[j].Votes {
|
||||||
|
return vals[i].Votes > vals[j].Votes
|
||||||
|
}
|
||||||
|
return vals[i].PublicKey.Cmp(&vals[j].PublicKey) == -1
|
||||||
|
})
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
tw := tabwriter.NewWriter(buf, 0, 2, 2, ' ', 0)
|
||||||
|
_, _ = tw.Write([]byte("Key\tVotes\tCommittee\tConsensus\n"))
|
||||||
|
for _, val := range vals {
|
||||||
|
_, _ = tw.Write([]byte(fmt.Sprintf("%s\t%d\t%t\t%t\n", hex.EncodeToString(val.PublicKey.Bytes()), val.Votes, comm.Contains(&val.PublicKey), val.Active)))
|
||||||
|
}
|
||||||
|
_ = tw.Flush()
|
||||||
|
fmt.Fprint(ctx.App.Writer, buf.String())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func queryCommittee(ctx *cli.Context) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
c, err := options.GetRPCClient(gctx, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError(err, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
comm, err := c.GetCommittee()
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError(err, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range comm {
|
||||||
|
fmt.Fprintln(ctx.App.Writer, hex.EncodeToString(k.Bytes()))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
59
docs/cli.md
59
docs/cli.md
|
@ -464,7 +464,9 @@ You can also vote for candidates if you own NEO:
|
||||||
./bin/neo-go wallet candidate vote -a NMe64G6j6nkPZby26JAgpaCNrn1Ee4wW6E -w wallet.json -r http://localhost:20332 -c 03cecd63d7d8120c3b194c3b2880dd4aafe1475c57e40c852872d7305615258140
|
./bin/neo-go wallet candidate vote -a NMe64G6j6nkPZby26JAgpaCNrn1Ee4wW6E -w wallet.json -r http://localhost:20332 -c 03cecd63d7d8120c3b194c3b2880dd4aafe1475c57e40c852872d7305615258140
|
||||||
```
|
```
|
||||||
|
|
||||||
### Querying transaction status
|
### Getting data from chain
|
||||||
|
|
||||||
|
#### Transaction status
|
||||||
`query tx` provides convenient wrapper over RPC calls to query transaction status.
|
`query tx` provides convenient wrapper over RPC calls to query transaction status.
|
||||||
```
|
```
|
||||||
./bin/neo-go query tx --rpc-endpoint http://localhost:20332 aaf87628851e0c03ee086ff88596bc24de87082e9e5c73d75bb1c740d1d68088
|
./bin/neo-go query tx --rpc-endpoint http://localhost:20332 aaf87628851e0c03ee086ff88596bc24de87082e9e5c73d75bb1c740d1d68088
|
||||||
|
@ -476,6 +478,61 @@ Success: true
|
||||||
`OnChain` is true if transaction was included in block and `Success` is true
|
`OnChain` is true if transaction was included in block and `Success` is true
|
||||||
if it was executed successfully.
|
if it was executed successfully.
|
||||||
|
|
||||||
|
#### Committee members
|
||||||
|
`query commitee` returns a list of current committee members:
|
||||||
|
```
|
||||||
|
$ ./bin/neo-go query committee -r http://localhost:20332
|
||||||
|
03009b7540e10f2562e5fd8fac9eaec25166a58b26e412348ff5a86927bfac22a2
|
||||||
|
030205e9cefaea5a1dfc580af20c8d5aa2468bb0148f1a5e4605fc622c80e604ba
|
||||||
|
0207da870cedb777fceff948641021714ec815110ca111ccc7a54c168e065bda70
|
||||||
|
02147c1b1d5728e1954958daff2f88ee2fa50a06890a8a9db3fa9e972b66ae559f
|
||||||
|
0214baf0ceea3a66f17e7e1e839ea25fd8bed6cd82e6bb6e68250189065f44ff01
|
||||||
|
03184b018d6b2bc093e535519732b3fd3f7551c8cffaf4621dd5a0b89482ca66c9
|
||||||
|
0231edee3978d46c335e851c76059166eb8878516f459e085c0dd092f0f1d51c21
|
||||||
|
023e9b32ea89b94d066e649b124fd50e396ee91369e8e2a6ae1b11c170d022256d
|
||||||
|
03408dcd416396f64783ac587ea1e1593c57d9fea880c8a6a1920e92a259477806
|
||||||
|
035056669864feea401d8c31e447fb82dd29f342a9476cfd449584ce2a6165e4d7
|
||||||
|
025831cee3708e87d78211bec0d1bfee9f4c85ae784762f042e7f31c0d40c329b8
|
||||||
|
026328aae34f149853430f526ecaa9cf9c8d78a4ea82d08bdf63dd03c4d0693be6
|
||||||
|
0370c75c54445565df62cfe2e76fbec4ba00d1298867972213530cae6d418da636
|
||||||
|
03840415b0a0fcf066bcc3dc92d8349ebd33a6ab1402ef649bae00e5d9f5840828
|
||||||
|
03957af9e77282ae3263544b7b2458903624adc3f5dee303957cb6570524a5f254
|
||||||
|
02a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b
|
||||||
|
02ba2c70f5996f357a43198705859fae2cfea13e1172962800772b3d588a9d4abd
|
||||||
|
03c609bea5a4825908027e4ab217e7efc06e311f19ecad9d417089f14927a173d5
|
||||||
|
02c69a8d084ee7319cfecf5161ff257aa2d1f53e79bf6c6f164cff5d94675c38b3
|
||||||
|
02cf9dc6e85d581480d91e88e8cbeaa0c153a046e89ded08b4cefd851e1d7325b5
|
||||||
|
03d84d22b8753cf225d263a3a782a4e16ca72ef323cfde04977c74f14873ab1e4c
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Candidate/voting data
|
||||||
|
`query candidates` returns all current candidates, number of votes for them
|
||||||
|
and their committee/consensus status:
|
||||||
|
```
|
||||||
|
$ ./bin/neo-go query candidates -r http://localhost:20332
|
||||||
|
Key Votes Committee Consensus
|
||||||
|
03009b7540e10f2562e5fd8fac9eaec25166a58b26e412348ff5a86927bfac22a2 2000000 true true
|
||||||
|
030205e9cefaea5a1dfc580af20c8d5aa2468bb0148f1a5e4605fc622c80e604ba 2000000 true true
|
||||||
|
0214baf0ceea3a66f17e7e1e839ea25fd8bed6cd82e6bb6e68250189065f44ff01 2000000 true true
|
||||||
|
023e9b32ea89b94d066e649b124fd50e396ee91369e8e2a6ae1b11c170d022256d 2000000 true true
|
||||||
|
03408dcd416396f64783ac587ea1e1593c57d9fea880c8a6a1920e92a259477806 2000000 true true
|
||||||
|
02a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b 2000000 true true
|
||||||
|
02ba2c70f5996f357a43198705859fae2cfea13e1172962800772b3d588a9d4abd 2000000 true true
|
||||||
|
025664cef0abcba7787ad5fb12f3af31c5cdc7a479068aa2ad8ee78804768bffe9 1000000 false false
|
||||||
|
03650a684461a64bf46bee561d9981a4c57adc6ccbd3a9512b83701480b30218ab 1000000 false false
|
||||||
|
026a10aa2b4d7639c5deafa4ff081467db10b5d00432749a2a5ee1d2bfed23e1c0 1000000 false false
|
||||||
|
02d5786a9214a8a3f1757d7596fd10f5241205e2c0d68362f4766579bac6189249 1000000 false false
|
||||||
|
033d8e35f8cd9a33852280b6d93093c7292ed5ce90d90f149fa2da50ba6168dfce 100000 false false
|
||||||
|
0349c7ef0b4aaf181f0a3e1350c527b136cc5b42498cb83ab8880c05ed95167e1c 100000 false false
|
||||||
|
035b4f9be2b853e06eb5a09c167e038b96b4804235961510423252f2ee3dbba583 100000 false false
|
||||||
|
027e459b264b6f7e325ab4b0bb0fa641081fb68517fd613ebd7a94cb79d3081e4f 100000 false false
|
||||||
|
0288cad442a877960c76b4f688f4be30f768256d9a3da2492b0180b91243918b4f 100000 false false
|
||||||
|
02a40c552798f79636095817ec88924fc6cb7094e5a3cb059a9b3bc91ea3bf0d3d 100000 false false
|
||||||
|
02db79e69c518ae9254e314b6f5f4b63e914cdd4b2574dc2f9236c01c1fc1d8973 100000 false false
|
||||||
|
02ec143f00b88524caf36a0121c2de09eef0519ddbe1c710a00f0e2663201ee4c0 100000 false false
|
||||||
|
03d8d58d2257ca6cb14522b76513d4783f7d481801695893794c2186515c6de76f 0 false false
|
||||||
|
```
|
||||||
|
|
||||||
### NEP-17 token functions
|
### NEP-17 token functions
|
||||||
|
|
||||||
`wallet nep17` contains a set of commands to use for NEP-17 tokens.
|
`wallet nep17` contains a set of commands to use for NEP-17 tokens.
|
||||||
|
|
|
@ -92,16 +92,16 @@ use.
|
||||||
This command will create and send appropriate transaction to the network and
|
This command will create and send appropriate transaction to the network and
|
||||||
you should then wait for it to settle in a block. If all goes well it'll end
|
you should then wait for it to settle in a block. If all goes well it'll end
|
||||||
with "HALT" state and your registration will be completed. You can use
|
with "HALT" state and your registration will be completed. You can use
|
||||||
`query tx` command to see transaction status or
|
`query tx` command to see transaction status or `query candidates` to see if
|
||||||
`getnextblockvalidators` to see if your candidate was added.
|
your candidate was added.
|
||||||
|
|
||||||
### Voting
|
### Voting
|
||||||
|
|
||||||
After registration completion if you own some NEO you can also vote for your
|
After registration completion if you own some NEO you can also vote for your
|
||||||
candidate to help it become CN and receive additional voter GAS. To do that
|
candidate to help it become CN and receive additional voter GAS. To do that
|
||||||
you need to know the public key of your candidate, which can either be seen in
|
you need to know the public key of your candidate, which can either be seen in
|
||||||
`getnextblockvalidators` RPC call output or extracted from wallet `wallet
|
`query candidates` command output or extracted from wallet `wallet dump-keys`
|
||||||
dump-keys` command:
|
command:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ neo-go wallet dump-keys -w wallet.json
|
$ neo-go wallet dump-keys -w wallet.json
|
||||||
|
|
Loading…
Reference in a new issue