rpc/server: implement getstateroot RPC

This commit is contained in:
Evgenii Stratonikov 2020-06-03 18:09:36 +03:00
parent dcaa82b32b
commit 53dc7f27b6
2 changed files with 55 additions and 0 deletions

View file

@ -95,6 +95,7 @@ var rpcHandlers = map[string]func(*Server, request.Params) (interface{}, *respon
"getpeers": (*Server).getPeers, "getpeers": (*Server).getPeers,
"getrawmempool": (*Server).getRawMempool, "getrawmempool": (*Server).getRawMempool,
"getrawtransaction": (*Server).getrawtransaction, "getrawtransaction": (*Server).getrawtransaction,
"getstateroot": (*Server).getStateRoot,
"getstorage": (*Server).getStorage, "getstorage": (*Server).getStorage,
"gettransactionheight": (*Server).getTransactionHeight, "gettransactionheight": (*Server).getTransactionHeight,
"gettxout": (*Server).getTxOut, "gettxout": (*Server).getTxOut,
@ -687,6 +688,28 @@ func (s *Server) getDecimals(h util.Uint160, cache map[util.Uint160]int64) (int6
return d, nil return d, nil
} }
func (s *Server) getStateRoot(ps request.Params) (interface{}, *response.Error) {
p := ps.Value(0)
if p == nil {
return nil, response.NewRPCError("Invalid parameter.", "", nil)
}
var rt *state.MPTRootState
var h util.Uint256
height, err := p.GetInt()
if err == nil {
rt, err = s.chain.GetStateRoot(uint32(height))
} else if h, err = p.GetUint256(); err == nil {
hdr, err := s.chain.GetHeader(h)
if err == nil {
rt, err = s.chain.GetStateRoot(hdr.Index)
}
}
if err != nil {
return nil, response.NewRPCError("Unknown state root.", "", err)
}
return rt, nil
}
func (s *Server) getStorage(ps request.Params) (interface{}, *response.Error) { func (s *Server) getStorage(ps request.Params) (interface{}, *response.Error) {
scriptHash, err := ps.Value(0).GetUint160FromHex() scriptHash, err := ps.Value(0).GetUint160FromHex()
if err != nil { if err != nil {

View file

@ -16,6 +16,7 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/nspcc-dev/neo-go/pkg/core" "github.com/nspcc-dev/neo-go/pkg/core"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"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/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
@ -213,6 +214,18 @@ var rpcTestCases = map[string][]rpcTestCase{
}, },
}, },
}, },
"getstateroot": {
{
name: "no params",
params: `[]`,
fail: true,
},
{
name: "invalid hash",
params: `["0x1234567890"]`,
fail: true,
},
},
"getstorage": { "getstorage": {
{ {
name: "positive", name: "positive",
@ -928,6 +941,25 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
}) })
} }
t.Run("getstateroot", func(t *testing.T) {
testRoot := func(t *testing.T, p string) {
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getstateroot", "params": [%s]}`, p)
fmt.Println(rpc)
body := doRPCCall(rpc, httpSrv.URL, t)
rawRes := checkErrGetResult(t, body, false)
res := new(state.MPTRootState)
require.NoError(t, json.Unmarshal(rawRes, res))
require.NotEqual(t, util.Uint256{}, res.Root) // be sure this test uses valid height
expected, err := e.chain.GetStateRoot(205)
require.NoError(t, err)
require.Equal(t, expected, res)
}
t.Run("ByHeight", func(t *testing.T) { testRoot(t, strconv.FormatInt(205, 10)) })
t.Run("ByHash", func(t *testing.T) { testRoot(t, `"`+chain.GetHeaderHash(205).StringLE()+`"`) })
})
t.Run("getrawtransaction", func(t *testing.T) { t.Run("getrawtransaction", func(t *testing.T) {
block, _ := chain.GetBlock(chain.GetHeaderHash(0)) block, _ := chain.GetBlock(chain.GetHeaderHash(0))
TXHash := block.Transactions[1].Hash() TXHash := block.Transactions[1].Hash()