forked from TrueCloudLab/neoneo-go
Merge pull request #2328 from nspcc-dev/rpc/getstateroot-client
rpc: add `getstateroot` to RPC client
This commit is contained in:
commit
0afe8826ba
4 changed files with 76 additions and 5 deletions
|
@ -18,6 +18,7 @@ TODO:
|
||||||
Supported methods
|
Supported methods
|
||||||
|
|
||||||
calculatenetworkfee
|
calculatenetworkfee
|
||||||
|
findstates
|
||||||
getapplicationlog
|
getapplicationlog
|
||||||
getbestblockhash
|
getbestblockhash
|
||||||
getblock
|
getblock
|
||||||
|
@ -37,7 +38,9 @@ Supported methods
|
||||||
getpeers
|
getpeers
|
||||||
getrawmempool
|
getrawmempool
|
||||||
getrawtransaction
|
getrawtransaction
|
||||||
|
getstate
|
||||||
getstateheight
|
getstateheight
|
||||||
|
getstateroot
|
||||||
getstorage
|
getstorage
|
||||||
gettransactionheight
|
gettransactionheight
|
||||||
getunclaimedgas
|
getunclaimedgas
|
||||||
|
|
|
@ -458,10 +458,19 @@ func (c *Client) GetState(stateroot util.Uint256, historicalContractHash util.Ui
|
||||||
// If `maxCount` specified, then maximum number of items to be returned equals to `maxCount`.
|
// If `maxCount` specified, then maximum number of items to be returned equals to `maxCount`.
|
||||||
func (c *Client) FindStates(stateroot util.Uint256, historicalContractHash util.Uint160, historicalPrefix []byte,
|
func (c *Client) FindStates(stateroot util.Uint256, historicalContractHash util.Uint160, historicalPrefix []byte,
|
||||||
start []byte, maxCount *int) (result.FindStates, error) {
|
start []byte, maxCount *int) (result.FindStates, error) {
|
||||||
|
if historicalPrefix == nil {
|
||||||
|
historicalPrefix = []byte{}
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
params = request.NewRawParams(stateroot.StringLE(), historicalContractHash.StringLE(), historicalPrefix, historicalPrefix, start)
|
params = request.NewRawParams(stateroot.StringLE(), historicalContractHash.StringLE(), historicalPrefix)
|
||||||
resp result.FindStates
|
resp result.FindStates
|
||||||
)
|
)
|
||||||
|
if start == nil && maxCount != nil {
|
||||||
|
start = []byte{}
|
||||||
|
}
|
||||||
|
if start != nil {
|
||||||
|
params.Values = append(params.Values, start)
|
||||||
|
}
|
||||||
if maxCount != nil {
|
if maxCount != nil {
|
||||||
params.Values = append(params.Values, *maxCount)
|
params.Values = append(params.Values, *maxCount)
|
||||||
}
|
}
|
||||||
|
@ -471,6 +480,24 @@ func (c *Client) FindStates(stateroot util.Uint256, historicalContractHash util.
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetStateRootByHeight returns state root for the specified height.
|
||||||
|
func (c *Client) GetStateRootByHeight(height uint32) (*state.MPTRoot, error) {
|
||||||
|
return c.getStateRoot(request.NewRawParams(height))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStateRootByBlockHash returns state root for block with specified hash.
|
||||||
|
func (c *Client) GetStateRootByBlockHash(hash util.Uint256) (*state.MPTRoot, error) {
|
||||||
|
return c.getStateRoot(request.NewRawParams(hash))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getStateRoot(params request.RawParams) (*state.MPTRoot, error) {
|
||||||
|
var resp = new(state.MPTRoot)
|
||||||
|
if err := c.performRequest("getstateroot", params, resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetStateHeight returns current validated and local node state height.
|
// GetStateHeight returns current validated and local node state height.
|
||||||
func (c *Client) GetStateHeight() (*result.StateHeight, error) {
|
func (c *Client) GetStateHeight() (*result.StateHeight, error) {
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -769,6 +769,47 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"getstateroot": {
|
||||||
|
{
|
||||||
|
name: "positive, by height",
|
||||||
|
invoke: func(c *Client) (interface{}, error) {
|
||||||
|
return c.GetStateRootByHeight(5)
|
||||||
|
},
|
||||||
|
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"version":0,"index":5,"roothash":"0x65d19151694321e70c6d184b37a2bcf7af4a2c60c099af332a4f7815e3670686","witnesses":[]}}`,
|
||||||
|
result: func(c *Client) interface{} {
|
||||||
|
h, err := util.Uint256DecodeStringLE("65d19151694321e70c6d184b37a2bcf7af4a2c60c099af332a4f7815e3670686")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return &state.MPTRoot{
|
||||||
|
Version: 0,
|
||||||
|
Index: 5,
|
||||||
|
Root: h,
|
||||||
|
Witness: []transaction.Witness{},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "positive, by hash",
|
||||||
|
invoke: func(c *Client) (interface{}, error) {
|
||||||
|
hash, err := util.Uint256DecodeStringLE("86fe1061140b2ea791b0739fb9732abc6e5e47de4927228a1ac41de3d93eb7cb")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return c.GetStateRootByBlockHash(hash)
|
||||||
|
},
|
||||||
|
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"version":0,"index":5,"roothash":"0x65d19151694321e70c6d184b37a2bcf7af4a2c60c099af332a4f7815e3670686","witnesses":[]}}`,
|
||||||
|
result: func(c *Client) interface{} {
|
||||||
|
h, _ := util.Uint256DecodeStringLE("65d19151694321e70c6d184b37a2bcf7af4a2c60c099af332a4f7815e3670686")
|
||||||
|
return &state.MPTRoot{
|
||||||
|
Version: 0,
|
||||||
|
Index: 5,
|
||||||
|
Root: h,
|
||||||
|
Witness: []transaction.Witness{},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"getstate": {
|
"getstate": {
|
||||||
{
|
{
|
||||||
name: "positive",
|
name: "positive",
|
||||||
|
|
|
@ -1235,11 +1235,11 @@ func (s *Server) findStates(ps request.Params) (interface{}, *response.Error) {
|
||||||
}
|
}
|
||||||
csHash, err := ps.Value(1).GetUint160FromHex()
|
csHash, err := ps.Value(1).GetUint160FromHex()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, response.WrapErrorWithData(response.ErrInvalidParams, errors.New("invalid contract hash"))
|
return nil, response.WrapErrorWithData(response.ErrInvalidParams, fmt.Errorf("invalid contract hash: %w", err))
|
||||||
}
|
}
|
||||||
prefix, err := ps.Value(2).GetBytesBase64()
|
prefix, err := ps.Value(2).GetBytesBase64()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, response.WrapErrorWithData(response.ErrInvalidParams, errors.New("invalid prefix"))
|
return nil, response.WrapErrorWithData(response.ErrInvalidParams, fmt.Errorf("invalid prefix: %w", err))
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
key []byte
|
key []byte
|
||||||
|
@ -1248,7 +1248,7 @@ func (s *Server) findStates(ps request.Params) (interface{}, *response.Error) {
|
||||||
if len(ps) > 3 {
|
if len(ps) > 3 {
|
||||||
key, err = ps.Value(3).GetBytesBase64()
|
key, err = ps.Value(3).GetBytesBase64()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, response.WrapErrorWithData(response.ErrInvalidParams, errors.New("invalid key"))
|
return nil, response.WrapErrorWithData(response.ErrInvalidParams, fmt.Errorf("invalid key: %w", err))
|
||||||
}
|
}
|
||||||
if len(key) > 0 {
|
if len(key) > 0 {
|
||||||
if !bytes.HasPrefix(key, prefix) {
|
if !bytes.HasPrefix(key, prefix) {
|
||||||
|
@ -1263,7 +1263,7 @@ func (s *Server) findStates(ps request.Params) (interface{}, *response.Error) {
|
||||||
if len(ps) > 4 {
|
if len(ps) > 4 {
|
||||||
count, err = ps.Value(4).GetInt()
|
count, err = ps.Value(4).GetInt()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, response.WrapErrorWithData(response.ErrInvalidParams, errors.New("invalid count"))
|
return nil, response.WrapErrorWithData(response.ErrInvalidParams, fmt.Errorf("invalid count: %w", err))
|
||||||
}
|
}
|
||||||
if count > s.config.MaxFindResultItems {
|
if count > s.config.MaxFindResultItems {
|
||||||
count = s.config.MaxFindResultItems
|
count = s.config.MaxFindResultItems
|
||||||
|
|
Loading…
Reference in a new issue