From f747b39bc6efefb3784daa26c0d2b96aa813919a Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 3 Mar 2020 18:15:26 +0300 Subject: [PATCH 1/4] docs: update RPC server documentation, add missing methods And drop doc.go from server package as it duplicates docs/rpc.md and has no value of its own (TODO list is managed with GitHub issues, really). Also, RPC server is not really expected to be used by non-neo-go packages (contrary to the client). --- docs/rpc.md | 26 +++++++++++++++++++++++ pkg/rpc/server/doc.go | 48 ------------------------------------------- 2 files changed, 26 insertions(+), 48 deletions(-) delete mode 100644 pkg/rpc/server/doc.go diff --git a/docs/rpc.md b/docs/rpc.md index 259015cde..6781a18f1 100644 --- a/docs/rpc.md +++ b/docs/rpc.md @@ -42,7 +42,9 @@ which would yield the response: | `getblock` | Yes | | `getblockcount` | Yes | | `getblockhash` | Yes | +| `getblockheader` | No (#711) | | `getblocksysfee` | Yes | +| `getclaimable` | Yes | | `getconnectioncount` | Yes | | `getcontractstate` | Yes | | `getnep5balances` | No (#498) | @@ -51,8 +53,11 @@ which would yield the response: | `getrawmempool` | Yes | | `getrawtransaction` | Yes | | `getstorage` | Yes | +| `gettransactionheight` | No (#713) | | `gettxout` | Yes | +| `getunclaimed` | No (#712) | | `getunspents` | Yes | +| `getvalidators` | No (#714) | | `getversion` | Yes | | `invoke` | Yes | | `invokefunction` | Yes | @@ -61,6 +66,27 @@ which would yield the response: | `submitblock` | No (#344) | | `validateaddress` | Yes | +### Unsupported methods + +Methods listed down below are not going to be supported for various reasons +and we're not accepting issues related to them. + +| Method | Reason | +| ------- | ------------| +| `claimgas` | Doesn't fit neo-go wallet model, use CLI to do that | +| `dumpprivkey` | Shouldn't exist for security reasons, see `claimgas` comment also | +| `getbalance` | Use `getaccountstate` instead, see `claimgas` comment also | +| `getmetricblocktimestamp` | Not really useful, use other means for node monitoring | +| `getnewaddress` | See `claimgas` comment | +| `getunclaimedgas` | Use `getunclaimed` instead, see `claimgas` comment also | +| `getwalletheight` | Not applicable to neo-go, see `claimgas` comment | +| `importprivkey` | Not applicable to neo-go, see `claimgas` comment | +| `listaddress` | Not applicable to neo-go, see `claimgas` comment | +| `listplugins` | neo-go doesn't have any plugins, so it makes no sense | +| `sendfrom` | Not applicable to neo-go, see `claimgas` comment | +| `sendmany` | Not applicable to neo-go, see `claimgas` comment | +| `sendtoaddress` | Not applicable to neo-go, see `claimgas` comment | + #### Implementation notices ##### `invokefunction` and `invoke` diff --git a/pkg/rpc/server/doc.go b/pkg/rpc/server/doc.go deleted file mode 100644 index dbf7aae9a..000000000 --- a/pkg/rpc/server/doc.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Package server implements NEO-specific JSON-RPC 2.0 server. -This package is currently in alpha and is subject to change. - -Server - -The server is written to support as much of the JSON-RPC 2.0 Spec as possible. -The server is run as part of the node currently. - -TODO: - Implement HTTPS server. - Add remaining methods (Documented below). - Add Swagger spec and test using dredd in circleCI. - -Example call - -An example would be viewing the version of the node: - - $ curl -X POST -d '{"jsonrpc": "2.0", "method": "getversion", "params": [], "id": 1}' http://localhost:20332 - -which would yield the response: - - { - "jsonrpc" : "2.0", - "id" : 1, - "result" : { - "port" : 20333, - "useragent" : "/NEO-GO:0.36.0-dev/", - "nonce" : 9318417 - } - } - -Unsupported methods - - getblocksysfee - getcontractstate (needs to be implemented in pkg/core/blockchain.go) - getrawmempool (needs to be implemented on in pkg/network/server.go) - getrawtransaction (needs to be implemented in pkg/core/blockchain.go) - getstorage (lacks VM functionality) - gettxout (needs to be implemented in pkg/core/blockchain.go) - invoke (lacks VM functionality) - invokefunction (lacks VM functionality) - invokescript (lacks VM functionality) - sendrawtransaction (needs to be implemented in pkg/core/blockchain.go) - submitblock (needs to be implemented in pkg/core/blockchain.go) - -*/ -package server From 685e34d83c06c1d9d95238136fa5e95317edae0f Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 3 Mar 2020 18:59:21 +0300 Subject: [PATCH 2/4] rpc: update client documentation Add missing methods, move example into something that can be compiled (and fix it along the way). --- pkg/rpc/client/doc.go | 76 +++++++++++++++++++------------------- pkg/rpc/client/doc_test.go | 33 +++++++++++++++++ 2 files changed, 71 insertions(+), 38 deletions(-) create mode 100644 pkg/rpc/client/doc_test.go diff --git a/pkg/rpc/client/doc.go b/pkg/rpc/client/doc.go index 8c82d20c9..2effd97ff 100644 --- a/pkg/rpc/client/doc.go +++ b/pkg/rpc/client/doc.go @@ -11,59 +11,59 @@ Some of the methods also allow to pass a verbose bool. This will return a more pretty printed response from the server instead of a raw hex string. -An example: - endpoint := "http://seed5.bridgeprotocol.io:10332" - opts := client.Options{} - - c, err := client.New(context.TODO(), endpoint, opts) - if err != nil { - log.Fatal(err) - } - - if err := c.Ping(); err != nil { - log.Fatal(err) - } - - resp, err := c.GetAccountState("ATySFJAbLW7QHsZGHScLhxq6EyNBxx3eFP") - if err != nil { - log.Fatal(err) - } - log.Println(resp.Result.ScriptHash) - log.Println(resp.Result.Balances) - TODO: - Merge structs so can be used by both server and client. Add missing methods to client. Allow client to connect using client cert. More in-depth examples. Supported methods - getblock getaccountstate + getclaimable getunspents - invokescript - invokefunction - sendrawtransaction invoke - getrawtransaction + invokefunction + invokescript + sendrawtransaction Unsupported methods - validateaddress - getblocksysfee - getcontractstate - getrawmempool - getstorage - submitblock - gettxout + claimgas + dumpprivkey + getapplicationlog getassetstate - getpeers - getversion - getconnectioncount - getblockhash - getblockcount + getbalance getbestblockhash + getblock + getblockcount + getblockhash + getblockheader + getblocksysfee + getconnectioncount + getcontractstate + getmetricblocktimestamp + getnep5balances + getnep5transfers + getnewaddress + getpeers + getrawmempool + getrawtransaction + getstorage + gettransactionheight + gettxout + getunclaimed + getunclaimedgas + getvalidators + getversion + getwalletheight + importprivkey + listaddress + listplugins + sendfrom + sendmany + sendtoaddress + submitblock + validateaddress */ package client diff --git a/pkg/rpc/client/doc_test.go b/pkg/rpc/client/doc_test.go new file mode 100644 index 000000000..b7f3e5f00 --- /dev/null +++ b/pkg/rpc/client/doc_test.go @@ -0,0 +1,33 @@ +package client_test + +import ( + "context" + "fmt" + "os" + + "github.com/nspcc-dev/neo-go/pkg/rpc/client" +) + +func Example() { + endpoint := "http://seed5.bridgeprotocol.io:10332" + opts := client.Options{} + + c, err := client.New(context.TODO(), endpoint, opts) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + if err := c.Ping(); err != nil { + fmt.Println(err) + os.Exit(1) + } + + resp, err := c.GetAccountState("ATySFJAbLW7QHsZGHScLhxq6EyNBxx3eFP") + if err != nil { + fmt.Println(err) + os.Exit(1) + } + fmt.Println(resp.ScriptHash) + fmt.Println(resp.Balances) +} From f01766131b22c8867562d1cee67dba2a6a86a45c Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 3 Mar 2020 20:26:56 +0300 Subject: [PATCH 3/4] rpc/client: add a set of GetBlock methods They differ in input and output types (and data), thus four methods are added. --- pkg/rpc/client/doc.go | 2 +- pkg/rpc/client/rpc.go | 74 +++++++++++++++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/pkg/rpc/client/doc.go b/pkg/rpc/client/doc.go index 2effd97ff..916420095 100644 --- a/pkg/rpc/client/doc.go +++ b/pkg/rpc/client/doc.go @@ -19,6 +19,7 @@ TODO: Supported methods getaccountstate + getblock getclaimable getunspents invoke @@ -34,7 +35,6 @@ Unsupported methods getassetstate getbalance getbestblockhash - getblock getblockcount getblockhash getblockheader diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index 834868ac1..166271a26 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -4,8 +4,10 @@ import ( "encoding/hex" "github.com/nspcc-dev/neo-go/pkg/core" + "github.com/nspcc-dev/neo-go/pkg/core/block" "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/io" "github.com/nspcc-dev/neo-go/pkg/rpc/request" "github.com/nspcc-dev/neo-go/pkg/rpc/response/result" "github.com/nspcc-dev/neo-go/pkg/smartcontract" @@ -14,23 +16,6 @@ import ( "github.com/pkg/errors" ) -// getBlock returns a block by its hash or index/height. If verbose is true -// the response will contain a pretty Block object instead of the raw hex string. -// missing output wrapper at the moment, thus commented out -// func (c *Client) getBlock(indexOrHash interface{}, verbose bool) (*response, error) { -// var ( -// params = request.NewRawParams(indexOrHash) -// resp = &response{} -// ) -// if verbose { -// params = request.NewRawParams(indexOrHash, 1) -// } -// if err := c.performRequest("getblock", params, resp); err != nil { -// return nil, err -// } -// return resp, nil -// } - // GetAccountState returns detailed information about a NEO account. func (c *Client) GetAccountState(address string) (*result.AccountState, error) { var ( @@ -43,6 +28,61 @@ func (c *Client) GetAccountState(address string) (*result.AccountState, error) { return resp, nil } +// GetBlockByIndex returns a block by its height. +func (c *Client) GetBlockByIndex(index uint32) (*block.Block, error) { + return c.getBlock(request.NewRawParams(index)) +} + +// GetBlockByHash returns a block by its hash. +func (c *Client) GetBlockByHash(hash util.Uint256) (*block.Block, error) { + return c.getBlock(request.NewRawParams(hash.StringLE())) +} + +func (c *Client) getBlock(params request.RawParams) (*block.Block, error) { + var ( + resp string + err error + b *block.Block + ) + if err = c.performRequest("getblock", params, &resp); err != nil { + return nil, err + } + blockBytes, err := hex.DecodeString(resp) + if err != nil { + return nil, err + } + r := io.NewBinReaderFromBuf(blockBytes) + b = new(block.Block) + b.DecodeBinary(r) + if r.Err != nil { + return nil, r.Err + } + return b, nil +} + +// GetBlockByIndexVerbose returns a block wrapper with additional metadata by +// its height. +func (c *Client) GetBlockByIndexVerbose(index uint32) (*result.Block, error) { + return c.getBlockVerbose(request.NewRawParams(index, 1)) +} + +// GetBlockByHashVerbose returns a block wrapper with additional metadata by +// its hash. +func (c *Client) GetBlockByHashVerbose(hash util.Uint256) (*result.Block, error) { + return c.getBlockVerbose(request.NewRawParams(hash.StringLE(), 1)) +} + +func (c *Client) getBlockVerbose(params request.RawParams) (*result.Block, error) { + var ( + resp = &result.Block{} + err error + ) + if err = c.performRequest("getblock", params, &resp); err != nil { + return nil, err + } + return resp, nil +} + // GetClaimable returns tx outputs which can be claimed. func (c *Client) GetClaimable(address string) (*result.ClaimableInfo, error) { params := request.NewRawParams(address) From a9d8c9e0d3a2be1eafa29708ea36a5d399a6722c Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 3 Mar 2020 20:43:57 +0300 Subject: [PATCH 4/4] rpc/client: implement GetRawTransaction, fix #586 --- pkg/rpc/client/doc.go | 2 +- pkg/rpc/client/rpc.go | 50 ++++++++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/pkg/rpc/client/doc.go b/pkg/rpc/client/doc.go index 916420095..1df4f0682 100644 --- a/pkg/rpc/client/doc.go +++ b/pkg/rpc/client/doc.go @@ -21,6 +21,7 @@ Supported methods getaccountstate getblock getclaimable + getrawtransaction getunspents invoke invokefunction @@ -47,7 +48,6 @@ Unsupported methods getnewaddress getpeers getrawmempool - getrawtransaction getstorage gettransactionheight gettxout diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index 166271a26..beeef25cf 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -93,6 +93,43 @@ func (c *Client) GetClaimable(address string) (*result.ClaimableInfo, error) { return resp, nil } +// GetRawTransaction returns a transaction by hash. +func (c *Client) GetRawTransaction(hash util.Uint256) (*transaction.Transaction, error) { + var ( + params = request.NewRawParams(hash.StringLE()) + resp string + err error + ) + if err = c.performRequest("getrawtransaction", params, &resp); err != nil { + return nil, err + } + txBytes, err := hex.DecodeString(resp) + if err != nil { + return nil, err + } + r := io.NewBinReaderFromBuf(txBytes) + tx := new(transaction.Transaction) + tx.DecodeBinary(r) + if r.Err != nil { + return nil, r.Err + } + return tx, nil +} + +// GetRawTransactionVerbose returns a transaction wrapper with additional +// metadata by transaction's hash. +func (c *Client) GetRawTransactionVerbose(hash util.Uint256) (*result.TransactionOutputRaw, error) { + var ( + params = request.NewRawParams(hash.StringLE(), 1) + resp = &result.TransactionOutputRaw{} + err error + ) + if err = c.performRequest("getrawtransaction", params, &resp); err != nil { + return nil, err + } + return resp, nil +} + // GetUnspents returns UTXOs for the given NEO account. func (c *Client) GetUnspents(address string) (*result.Unspents, error) { var ( @@ -145,19 +182,6 @@ func (c *Client) Invoke(script string, params []smartcontract.Parameter) (*resul return resp, nil } -// getRawTransaction queries a transaction by hash. -// missing output wrapper at the moment, thus commented out -// func (c *Client) getRawTransaction(hash string, verbose bool) (*response, error) { -// var ( -// params = request.NewRawParams(hash, verbose) -// resp = &response{} -// ) -// if err := c.performRequest("getrawtransaction", params, resp); err != nil { -// return nil, err -// } -// return resp, nil -// } - // SendRawTransaction broadcasts a transaction over the NEO network. // The given hex string needs to be signed with a keypair. // When the result of the response object is true, the TX has successfully