Merge pull request #715 from nspcc-dev/rpc-doc-and-client

Update RPC docs, implement client-side getblock and getrawtransaction
This commit is contained in:
Roman Khimov 2020-03-04 11:48:43 +03:00 committed by GitHub
commit 8141d49e5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 188 additions and 113 deletions

View file

@ -42,7 +42,9 @@ which would yield the response:
| `getblock` | Yes | | `getblock` | Yes |
| `getblockcount` | Yes | | `getblockcount` | Yes |
| `getblockhash` | Yes | | `getblockhash` | Yes |
| `getblockheader` | No (#711) |
| `getblocksysfee` | Yes | | `getblocksysfee` | Yes |
| `getclaimable` | Yes |
| `getconnectioncount` | Yes | | `getconnectioncount` | Yes |
| `getcontractstate` | Yes | | `getcontractstate` | Yes |
| `getnep5balances` | No (#498) | | `getnep5balances` | No (#498) |
@ -51,8 +53,11 @@ which would yield the response:
| `getrawmempool` | Yes | | `getrawmempool` | Yes |
| `getrawtransaction` | Yes | | `getrawtransaction` | Yes |
| `getstorage` | Yes | | `getstorage` | Yes |
| `gettransactionheight` | No (#713) |
| `gettxout` | Yes | | `gettxout` | Yes |
| `getunclaimed` | No (#712) |
| `getunspents` | Yes | | `getunspents` | Yes |
| `getvalidators` | No (#714) |
| `getversion` | Yes | | `getversion` | Yes |
| `invoke` | Yes | | `invoke` | Yes |
| `invokefunction` | Yes | | `invokefunction` | Yes |
@ -61,6 +66,27 @@ which would yield the response:
| `submitblock` | No (#344) | | `submitblock` | No (#344) |
| `validateaddress` | Yes | | `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 #### Implementation notices
##### `invokefunction` and `invoke` ##### `invokefunction` and `invoke`

View file

@ -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 return a more pretty printed response from the server instead of
a raw hex string. 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: TODO:
Merge structs so can be used by both server and client.
Add missing methods to client. Add missing methods to client.
Allow client to connect using client cert. Allow client to connect using client cert.
More in-depth examples. More in-depth examples.
Supported methods Supported methods
getblock
getaccountstate getaccountstate
getunspents getblock
invokescript getclaimable
invokefunction
sendrawtransaction
invoke
getrawtransaction getrawtransaction
getunspents
invoke
invokefunction
invokescript
sendrawtransaction
Unsupported methods Unsupported methods
validateaddress claimgas
dumpprivkey
getapplicationlog
getassetstate
getbalance
getbestblockhash
getblockcount
getblockhash
getblockheader
getblocksysfee getblocksysfee
getconnectioncount
getcontractstate getcontractstate
getmetricblocktimestamp
getnep5balances
getnep5transfers
getnewaddress
getpeers
getrawmempool getrawmempool
getstorage getstorage
submitblock gettransactionheight
gettxout gettxout
getassetstate getunclaimed
getpeers getunclaimedgas
getvalidators
getversion getversion
getconnectioncount getwalletheight
getblockhash importprivkey
getblockcount listaddress
getbestblockhash listplugins
sendfrom
sendmany
sendtoaddress
submitblock
validateaddress
*/ */
package client package client

View file

@ -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)
}

View file

@ -4,8 +4,10 @@ import (
"encoding/hex" "encoding/hex"
"github.com/nspcc-dev/neo-go/pkg/core" "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/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/io"
"github.com/nspcc-dev/neo-go/pkg/rpc/request" "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/rpc/response/result"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
@ -14,23 +16,6 @@ import (
"github.com/pkg/errors" "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. // GetAccountState returns detailed information about a NEO account.
func (c *Client) GetAccountState(address string) (*result.AccountState, error) { func (c *Client) GetAccountState(address string) (*result.AccountState, error) {
var ( var (
@ -43,6 +28,61 @@ func (c *Client) GetAccountState(address string) (*result.AccountState, error) {
return resp, nil 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. // GetClaimable returns tx outputs which can be claimed.
func (c *Client) GetClaimable(address string) (*result.ClaimableInfo, error) { func (c *Client) GetClaimable(address string) (*result.ClaimableInfo, error) {
params := request.NewRawParams(address) params := request.NewRawParams(address)
@ -53,6 +93,43 @@ func (c *Client) GetClaimable(address string) (*result.ClaimableInfo, error) {
return resp, nil 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. // GetUnspents returns UTXOs for the given NEO account.
func (c *Client) GetUnspents(address string) (*result.Unspents, error) { func (c *Client) GetUnspents(address string) (*result.Unspents, error) {
var ( var (
@ -105,19 +182,6 @@ func (c *Client) Invoke(script string, params []smartcontract.Parameter) (*resul
return resp, nil 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. // SendRawTransaction broadcasts a transaction over the NEO network.
// The given hex string needs to be signed with a keypair. // The given hex string needs to be signed with a keypair.
// When the result of the response object is true, the TX has successfully // When the result of the response object is true, the TX has successfully

View file

@ -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