diff --git a/pkg/rpc/client/doc.go b/pkg/rpc/client/doc.go index 5ad1eac12..53b5eaaab 100644 --- a/pkg/rpc/client/doc.go +++ b/pkg/rpc/client/doc.go @@ -38,6 +38,7 @@ Supported methods getrawmempool getrawtransaction getstateheight + getstateroot getstorage gettransactionheight getunclaimedgas diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index 2f43dd8e4..ec66ea7f0 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -471,6 +471,24 @@ func (c *Client) FindStates(stateroot util.Uint256, historicalContractHash util. 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. func (c *Client) GetStateHeight() (*result.StateHeight, error) { var ( diff --git a/pkg/rpc/client/rpc_test.go b/pkg/rpc/client/rpc_test.go index c4041c353..51c008785 100644 --- a/pkg/rpc/client/rpc_test.go +++ b/pkg/rpc/client/rpc_test.go @@ -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": { { name: "positive",