Merge pull request #2585 from nspcc-dev/move-rpc-code

Move request-related RPC code
This commit is contained in:
Roman Khimov 2022-07-08 18:25:50 +03:00 committed by GitHub
commit aa338b7960
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 466 additions and 463 deletions

View file

@ -172,12 +172,15 @@ func (c *Client) Close() {
c.cli.CloseIdleConnections() c.cli.CloseIdleConnections()
} }
func (c *Client) performRequest(method string, p request.RawParams, v interface{}) error { func (c *Client) performRequest(method string, p []interface{}, v interface{}) error {
if p == nil {
p = []interface{}{} // neo-project/neo-modules#742
}
var r = request.Raw{ var r = request.Raw{
JSONRPC: request.JSONRPCVersion, JSONRPC: request.JSONRPCVersion,
Method: method, Method: method,
RawParams: p.Values, Params: p,
ID: c.getNextRequestID(), ID: c.getNextRequestID(),
} }
raw, err := c.requestF(&r) raw, err := c.requestF(&r)

View file

@ -38,7 +38,7 @@ var errNetworkNotInitialized = errors.New("RPC client network is not initialized
// filled for standard sig/multisig signers. // filled for standard sig/multisig signers.
func (c *Client) CalculateNetworkFee(tx *transaction.Transaction) (int64, error) { func (c *Client) CalculateNetworkFee(tx *transaction.Transaction) (int64, error) {
var ( var (
params = request.NewRawParams(tx.Bytes()) params = []interface{}{tx.Bytes()}
resp = new(result.NetworkFee) resp = new(result.NetworkFee)
) )
if err := c.performRequest("calculatenetworkfee", params, resp); err != nil { if err := c.performRequest("calculatenetworkfee", params, resp); err != nil {
@ -50,11 +50,11 @@ func (c *Client) CalculateNetworkFee(tx *transaction.Transaction) (int64, error)
// GetApplicationLog returns a contract log based on the specified txid. // GetApplicationLog returns a contract log based on the specified txid.
func (c *Client) GetApplicationLog(hash util.Uint256, trig *trigger.Type) (*result.ApplicationLog, error) { func (c *Client) GetApplicationLog(hash util.Uint256, trig *trigger.Type) (*result.ApplicationLog, error) {
var ( var (
params = request.NewRawParams(hash.StringLE()) params = []interface{}{hash.StringLE()}
resp = new(result.ApplicationLog) resp = new(result.ApplicationLog)
) )
if trig != nil { if trig != nil {
params.Values = append(params.Values, trig.String()) params = append(params, trig.String())
} }
if err := c.performRequest("getapplicationlog", params, resp); err != nil { if err := c.performRequest("getapplicationlog", params, resp); err != nil {
return nil, err return nil, err
@ -65,7 +65,7 @@ func (c *Client) GetApplicationLog(hash util.Uint256, trig *trigger.Type) (*resu
// GetBestBlockHash returns the hash of the tallest block in the blockchain. // GetBestBlockHash returns the hash of the tallest block in the blockchain.
func (c *Client) GetBestBlockHash() (util.Uint256, error) { func (c *Client) GetBestBlockHash() (util.Uint256, error) {
var resp = util.Uint256{} var resp = util.Uint256{}
if err := c.performRequest("getbestblockhash", request.NewRawParams(), &resp); err != nil { if err := c.performRequest("getbestblockhash", nil, &resp); err != nil {
return resp, err return resp, err
} }
return resp, nil return resp, nil
@ -74,7 +74,7 @@ func (c *Client) GetBestBlockHash() (util.Uint256, error) {
// GetBlockCount returns the number of blocks in the blockchain. // GetBlockCount returns the number of blocks in the blockchain.
func (c *Client) GetBlockCount() (uint32, error) { func (c *Client) GetBlockCount() (uint32, error) {
var resp uint32 var resp uint32
if err := c.performRequest("getblockcount", request.NewRawParams(), &resp); err != nil { if err := c.performRequest("getblockcount", nil, &resp); err != nil {
return resp, err return resp, err
} }
return resp, nil return resp, nil
@ -83,22 +83,22 @@ func (c *Client) GetBlockCount() (uint32, error) {
// GetBlockByIndex returns a block by its height. You should initialize network magic // GetBlockByIndex returns a block by its height. You should initialize network magic
// with Init before calling GetBlockByIndex. // with Init before calling GetBlockByIndex.
func (c *Client) GetBlockByIndex(index uint32) (*block.Block, error) { func (c *Client) GetBlockByIndex(index uint32) (*block.Block, error) {
return c.getBlock(request.NewRawParams(index)) return c.getBlock(index)
} }
// GetBlockByHash returns a block by its hash. You should initialize network magic // GetBlockByHash returns a block by its hash. You should initialize network magic
// with Init before calling GetBlockByHash. // with Init before calling GetBlockByHash.
func (c *Client) GetBlockByHash(hash util.Uint256) (*block.Block, error) { func (c *Client) GetBlockByHash(hash util.Uint256) (*block.Block, error) {
return c.getBlock(request.NewRawParams(hash.StringLE())) return c.getBlock(hash.StringLE())
} }
func (c *Client) getBlock(params request.RawParams) (*block.Block, error) { func (c *Client) getBlock(param interface{}) (*block.Block, error) {
var ( var (
resp []byte resp []byte
err error err error
b *block.Block b *block.Block
) )
if err = c.performRequest("getblock", params, &resp); err != nil { if err = c.performRequest("getblock", []interface{}{param}, &resp); err != nil {
return nil, err return nil, err
} }
r := io.NewBinReaderFromBuf(resp) r := io.NewBinReaderFromBuf(resp)
@ -118,19 +118,20 @@ func (c *Client) getBlock(params request.RawParams) (*block.Block, error) {
// its height. You should initialize network magic with Init before calling GetBlockByIndexVerbose. // its height. You should initialize network magic with Init before calling GetBlockByIndexVerbose.
// NOTE: to get transaction.ID and transaction.Size, use t.Hash() and io.GetVarSize(t) respectively. // NOTE: to get transaction.ID and transaction.Size, use t.Hash() and io.GetVarSize(t) respectively.
func (c *Client) GetBlockByIndexVerbose(index uint32) (*result.Block, error) { func (c *Client) GetBlockByIndexVerbose(index uint32) (*result.Block, error) {
return c.getBlockVerbose(request.NewRawParams(index, 1)) return c.getBlockVerbose(index)
} }
// GetBlockByHashVerbose returns a block wrapper with additional metadata by // GetBlockByHashVerbose returns a block wrapper with additional metadata by
// its hash. You should initialize network magic with Init before calling GetBlockByHashVerbose. // its hash. You should initialize network magic with Init before calling GetBlockByHashVerbose.
func (c *Client) GetBlockByHashVerbose(hash util.Uint256) (*result.Block, error) { func (c *Client) GetBlockByHashVerbose(hash util.Uint256) (*result.Block, error) {
return c.getBlockVerbose(request.NewRawParams(hash.StringLE(), 1)) return c.getBlockVerbose(hash.StringLE())
} }
func (c *Client) getBlockVerbose(params request.RawParams) (*result.Block, error) { func (c *Client) getBlockVerbose(param interface{}) (*result.Block, error) {
var ( var (
resp = &result.Block{} params = []interface{}{param, 1} // 1 for verbose.
err error resp = &result.Block{}
err error
) )
sr, err := c.StateRootInHeader() sr, err := c.StateRootInHeader()
if err != nil { if err != nil {
@ -146,7 +147,7 @@ func (c *Client) getBlockVerbose(params request.RawParams) (*result.Block, error
// GetBlockHash returns the hash value of the corresponding block based on the specified index. // GetBlockHash returns the hash value of the corresponding block based on the specified index.
func (c *Client) GetBlockHash(index uint32) (util.Uint256, error) { func (c *Client) GetBlockHash(index uint32) (util.Uint256, error) {
var ( var (
params = request.NewRawParams(index) params = []interface{}{index}
resp = util.Uint256{} resp = util.Uint256{}
) )
if err := c.performRequest("getblockhash", params, &resp); err != nil { if err := c.performRequest("getblockhash", params, &resp); err != nil {
@ -160,7 +161,7 @@ func (c *Client) GetBlockHash(index uint32) (util.Uint256, error) {
// with Init before calling GetBlockHeader. // with Init before calling GetBlockHeader.
func (c *Client) GetBlockHeader(hash util.Uint256) (*block.Header, error) { func (c *Client) GetBlockHeader(hash util.Uint256) (*block.Header, error) {
var ( var (
params = request.NewRawParams(hash.StringLE()) params = []interface{}{hash.StringLE()}
resp []byte resp []byte
h *block.Header h *block.Header
) )
@ -184,7 +185,7 @@ func (c *Client) GetBlockHeader(hash util.Uint256) (*block.Header, error) {
// GetBlockHeaderCount returns the number of headers in the main chain. // GetBlockHeaderCount returns the number of headers in the main chain.
func (c *Client) GetBlockHeaderCount() (uint32, error) { func (c *Client) GetBlockHeaderCount() (uint32, error) {
var resp uint32 var resp uint32
if err := c.performRequest("getblockheadercount", request.NewRawParams(), &resp); err != nil { if err := c.performRequest("getblockheadercount", nil, &resp); err != nil {
return resp, err return resp, err
} }
return resp, nil return resp, nil
@ -194,7 +195,7 @@ func (c *Client) GetBlockHeaderCount() (uint32, error) {
// according to the specified script hash. // according to the specified script hash.
func (c *Client) GetBlockHeaderVerbose(hash util.Uint256) (*result.Header, error) { func (c *Client) GetBlockHeaderVerbose(hash util.Uint256) (*result.Header, error) {
var ( var (
params = request.NewRawParams(hash.StringLE(), 1) params = []interface{}{hash.StringLE(), 1}
resp = &result.Header{} resp = &result.Header{}
) )
if err := c.performRequest("getblockheader", params, resp); err != nil { if err := c.performRequest("getblockheader", params, resp); err != nil {
@ -206,7 +207,7 @@ func (c *Client) GetBlockHeaderVerbose(hash util.Uint256) (*result.Header, error
// GetBlockSysFee returns the system fees of the block based on the specified index. // GetBlockSysFee returns the system fees of the block based on the specified index.
func (c *Client) GetBlockSysFee(index uint32) (fixedn.Fixed8, error) { func (c *Client) GetBlockSysFee(index uint32) (fixedn.Fixed8, error) {
var ( var (
params = request.NewRawParams(index) params = []interface{}{index}
resp fixedn.Fixed8 resp fixedn.Fixed8
) )
if err := c.performRequest("getblocksysfee", params, &resp); err != nil { if err := c.performRequest("getblocksysfee", params, &resp); err != nil {
@ -217,11 +218,9 @@ func (c *Client) GetBlockSysFee(index uint32) (fixedn.Fixed8, error) {
// GetConnectionCount returns the current number of the connections for the node. // GetConnectionCount returns the current number of the connections for the node.
func (c *Client) GetConnectionCount() (int, error) { func (c *Client) GetConnectionCount() (int, error) {
var ( var resp int
params = request.NewRawParams()
resp int if err := c.performRequest("getconnectioncount", nil, &resp); err != nil {
)
if err := c.performRequest("getconnectioncount", params, &resp); err != nil {
return resp, err return resp, err
} }
return resp, nil return resp, nil
@ -229,11 +228,9 @@ func (c *Client) GetConnectionCount() (int, error) {
// GetCommittee returns the current public keys of NEO nodes in the committee. // GetCommittee returns the current public keys of NEO nodes in the committee.
func (c *Client) GetCommittee() (keys.PublicKeys, error) { func (c *Client) GetCommittee() (keys.PublicKeys, error) {
var ( var resp = new(keys.PublicKeys)
params = request.NewRawParams()
resp = new(keys.PublicKeys) if err := c.performRequest("getcommittee", nil, resp); err != nil {
)
if err := c.performRequest("getcommittee", params, resp); err != nil {
return nil, err return nil, err
} }
return *resp, nil return *resp, nil
@ -257,7 +254,7 @@ func (c *Client) GetContractStateByID(id int32) (*state.Contract, error) {
// getContractState is an internal representation of GetContractStateBy* methods. // getContractState is an internal representation of GetContractStateBy* methods.
func (c *Client) getContractState(param interface{}) (*state.Contract, error) { func (c *Client) getContractState(param interface{}) (*state.Contract, error) {
var ( var (
params = request.NewRawParams(param) params = []interface{}{param}
resp = &state.Contract{} resp = &state.Contract{}
) )
if err := c.performRequest("getcontractstate", params, resp); err != nil { if err := c.performRequest("getcontractstate", params, resp); err != nil {
@ -268,11 +265,8 @@ func (c *Client) getContractState(param interface{}) (*state.Contract, error) {
// GetNativeContracts queries information about native contracts. // GetNativeContracts queries information about native contracts.
func (c *Client) GetNativeContracts() ([]state.NativeContract, error) { func (c *Client) GetNativeContracts() ([]state.NativeContract, error) {
var ( var resp []state.NativeContract
params = request.NewRawParams() if err := c.performRequest("getnativecontracts", nil, &resp); err != nil {
resp []state.NativeContract
)
if err := c.performRequest("getnativecontracts", params, &resp); err != nil {
return resp, err return resp, err
} }
@ -288,7 +282,7 @@ func (c *Client) GetNativeContracts() ([]state.NativeContract, error) {
// GetNEP11Balances is a wrapper for getnep11balances RPC. // GetNEP11Balances is a wrapper for getnep11balances RPC.
func (c *Client) GetNEP11Balances(address util.Uint160) (*result.NEP11Balances, error) { func (c *Client) GetNEP11Balances(address util.Uint160) (*result.NEP11Balances, error) {
params := request.NewRawParams(address.StringLE()) params := []interface{}{address.StringLE()}
resp := new(result.NEP11Balances) resp := new(result.NEP11Balances)
if err := c.performRequest("getnep11balances", params, resp); err != nil { if err := c.performRequest("getnep11balances", params, resp); err != nil {
return nil, err return nil, err
@ -298,7 +292,7 @@ func (c *Client) GetNEP11Balances(address util.Uint160) (*result.NEP11Balances,
// GetNEP17Balances is a wrapper for getnep17balances RPC. // GetNEP17Balances is a wrapper for getnep17balances RPC.
func (c *Client) GetNEP17Balances(address util.Uint160) (*result.NEP17Balances, error) { func (c *Client) GetNEP17Balances(address util.Uint160) (*result.NEP17Balances, error) {
params := request.NewRawParams(address.StringLE()) params := []interface{}{address.StringLE()}
resp := new(result.NEP17Balances) resp := new(result.NEP17Balances)
if err := c.performRequest("getnep17balances", params, resp); err != nil { if err := c.performRequest("getnep17balances", params, resp); err != nil {
return nil, err return nil, err
@ -312,7 +306,7 @@ func (c *Client) GetNEP17Balances(address util.Uint160) (*result.NEP17Balances,
// attributes like "description", "image", "name" and "tokenURI" it returns strings, // attributes like "description", "image", "name" and "tokenURI" it returns strings,
// while for all others []byte (which can be nil). // while for all others []byte (which can be nil).
func (c *Client) GetNEP11Properties(asset util.Uint160, token []byte) (map[string]interface{}, error) { func (c *Client) GetNEP11Properties(asset util.Uint160, token []byte) (map[string]interface{}, error) {
params := request.NewRawParams(asset.StringLE(), hex.EncodeToString(token)) params := []interface{}{asset.StringLE(), hex.EncodeToString(token)}
resp := make(map[string]interface{}) resp := make(map[string]interface{})
if err := c.performRequest("getnep11properties", params, &resp); err != nil { if err := c.performRequest("getnep11properties", params, &resp); err != nil {
return nil, err return nil, err
@ -346,22 +340,22 @@ func (c *Client) GetNEP11Transfers(address util.Uint160, start, stop *uint64, li
return nil, err return nil, err
} }
resp := new(result.NEP11Transfers) resp := new(result.NEP11Transfers)
if err := c.performRequest("getnep11transfers", *params, resp); err != nil { if err := c.performRequest("getnep11transfers", params, resp); err != nil {
return nil, err return nil, err
} }
return resp, nil return resp, nil
} }
func packTransfersParams(address util.Uint160, start, stop *uint64, limit, page *int) (*request.RawParams, error) { func packTransfersParams(address util.Uint160, start, stop *uint64, limit, page *int) ([]interface{}, error) {
params := request.NewRawParams(address.StringLE()) params := []interface{}{address.StringLE()}
if start != nil { if start != nil {
params.Values = append(params.Values, *start) params = append(params, *start)
if stop != nil { if stop != nil {
params.Values = append(params.Values, *stop) params = append(params, *stop)
if limit != nil { if limit != nil {
params.Values = append(params.Values, *limit) params = append(params, *limit)
if page != nil { if page != nil {
params.Values = append(params.Values, *page) params = append(params, *page)
} }
} else if page != nil { } else if page != nil {
return nil, errors.New("bad parameters") return nil, errors.New("bad parameters")
@ -372,7 +366,7 @@ func packTransfersParams(address util.Uint160, start, stop *uint64, limit, page
} else if stop != nil || limit != nil || page != nil { } else if stop != nil || limit != nil || page != nil {
return nil, errors.New("bad parameters") return nil, errors.New("bad parameters")
} }
return &params, nil return params, nil
} }
// GetNEP17Transfers is a wrapper for getnep17transfers RPC. Address parameter // GetNEP17Transfers is a wrapper for getnep17transfers RPC. Address parameter
@ -386,7 +380,7 @@ func (c *Client) GetNEP17Transfers(address util.Uint160, start, stop *uint64, li
return nil, err return nil, err
} }
resp := new(result.NEP17Transfers) resp := new(result.NEP17Transfers)
if err := c.performRequest("getnep17transfers", *params, resp); err != nil { if err := c.performRequest("getnep17transfers", params, resp); err != nil {
return nil, err return nil, err
} }
return resp, nil return resp, nil
@ -394,11 +388,9 @@ func (c *Client) GetNEP17Transfers(address util.Uint160, start, stop *uint64, li
// GetPeers returns a list of the nodes that the node is currently connected to/disconnected from. // GetPeers returns a list of the nodes that the node is currently connected to/disconnected from.
func (c *Client) GetPeers() (*result.GetPeers, error) { func (c *Client) GetPeers() (*result.GetPeers, error) {
var ( var resp = &result.GetPeers{}
params = request.NewRawParams()
resp = &result.GetPeers{} if err := c.performRequest("getpeers", nil, resp); err != nil {
)
if err := c.performRequest("getpeers", params, resp); err != nil {
return resp, err return resp, err
} }
return resp, nil return resp, nil
@ -406,11 +398,9 @@ func (c *Client) GetPeers() (*result.GetPeers, error) {
// GetRawMemPool returns a list of unconfirmed transactions in the memory. // GetRawMemPool returns a list of unconfirmed transactions in the memory.
func (c *Client) GetRawMemPool() ([]util.Uint256, error) { func (c *Client) GetRawMemPool() ([]util.Uint256, error) {
var ( var resp = new([]util.Uint256)
params = request.NewRawParams()
resp = new([]util.Uint256) if err := c.performRequest("getrawmempool", nil, resp); err != nil {
)
if err := c.performRequest("getrawmempool", params, resp); err != nil {
return *resp, err return *resp, err
} }
return *resp, nil return *resp, nil
@ -419,7 +409,7 @@ func (c *Client) GetRawMemPool() ([]util.Uint256, error) {
// GetRawTransaction returns a transaction by hash. // GetRawTransaction returns a transaction by hash.
func (c *Client) GetRawTransaction(hash util.Uint256) (*transaction.Transaction, error) { func (c *Client) GetRawTransaction(hash util.Uint256) (*transaction.Transaction, error) {
var ( var (
params = request.NewRawParams(hash.StringLE()) params = []interface{}{hash.StringLE()}
resp []byte resp []byte
err error err error
) )
@ -438,7 +428,7 @@ func (c *Client) GetRawTransaction(hash util.Uint256) (*transaction.Transaction,
// NOTE: to get transaction.ID and transaction.Size, use t.Hash() and io.GetVarSize(t) respectively. // NOTE: to get transaction.ID and transaction.Size, use t.Hash() and io.GetVarSize(t) respectively.
func (c *Client) GetRawTransactionVerbose(hash util.Uint256) (*result.TransactionOutputRaw, error) { func (c *Client) GetRawTransactionVerbose(hash util.Uint256) (*result.TransactionOutputRaw, error) {
var ( var (
params = request.NewRawParams(hash.StringLE(), 1) params = []interface{}{hash.StringLE(), 1} // 1 for verbose.
resp = &result.TransactionOutputRaw{} resp = &result.TransactionOutputRaw{}
err error err error
) )
@ -452,7 +442,7 @@ func (c *Client) GetRawTransactionVerbose(hash util.Uint256) (*result.Transactio
// historical contract hash and historical item key. // historical contract hash and historical item key.
func (c *Client) GetState(stateroot util.Uint256, historicalContractHash util.Uint160, historicalKey []byte) ([]byte, error) { func (c *Client) GetState(stateroot util.Uint256, historicalContractHash util.Uint160, historicalKey []byte) ([]byte, error) {
var ( var (
params = request.NewRawParams(stateroot.StringLE(), historicalContractHash.StringLE(), historicalKey) params = []interface{}{stateroot.StringLE(), historicalContractHash.StringLE(), historicalKey}
resp []byte resp []byte
) )
if err := c.performRequest("getstate", params, &resp); err != nil { if err := c.performRequest("getstate", params, &resp); err != nil {
@ -471,17 +461,17 @@ func (c *Client) FindStates(stateroot util.Uint256, historicalContractHash util.
historicalPrefix = []byte{} historicalPrefix = []byte{}
} }
var ( var (
params = request.NewRawParams(stateroot.StringLE(), historicalContractHash.StringLE(), historicalPrefix) params = []interface{}{stateroot.StringLE(), historicalContractHash.StringLE(), historicalPrefix}
resp result.FindStates resp result.FindStates
) )
if start == nil && maxCount != nil { if start == nil && maxCount != nil {
start = []byte{} start = []byte{}
} }
if start != nil { if start != nil {
params.Values = append(params.Values, start) params = append(params, start)
} }
if maxCount != nil { if maxCount != nil {
params.Values = append(params.Values, *maxCount) params = append(params, *maxCount)
} }
if err := c.performRequest("findstates", params, &resp); err != nil { if err := c.performRequest("findstates", params, &resp); err != nil {
return resp, err return resp, err
@ -491,17 +481,17 @@ func (c *Client) FindStates(stateroot util.Uint256, historicalContractHash util.
// GetStateRootByHeight returns the state root for the specified height. // GetStateRootByHeight returns the state root for the specified height.
func (c *Client) GetStateRootByHeight(height uint32) (*state.MPTRoot, error) { func (c *Client) GetStateRootByHeight(height uint32) (*state.MPTRoot, error) {
return c.getStateRoot(request.NewRawParams(height)) return c.getStateRoot(height)
} }
// GetStateRootByBlockHash returns the state root for the block with the specified hash. // GetStateRootByBlockHash returns the state root for the block with the specified hash.
func (c *Client) GetStateRootByBlockHash(hash util.Uint256) (*state.MPTRoot, error) { func (c *Client) GetStateRootByBlockHash(hash util.Uint256) (*state.MPTRoot, error) {
return c.getStateRoot(request.NewRawParams(hash)) return c.getStateRoot(hash)
} }
func (c *Client) getStateRoot(params request.RawParams) (*state.MPTRoot, error) { func (c *Client) getStateRoot(param interface{}) (*state.MPTRoot, error) {
var resp = new(state.MPTRoot) var resp = new(state.MPTRoot)
if err := c.performRequest("getstateroot", params, resp); err != nil { if err := c.performRequest("getstateroot", []interface{}{param}, resp); err != nil {
return nil, err return nil, err
} }
return resp, nil return resp, nil
@ -509,11 +499,9 @@ func (c *Client) getStateRoot(params request.RawParams) (*state.MPTRoot, error)
// GetStateHeight returns the current validated and local node state height. // GetStateHeight returns the current validated and local node state height.
func (c *Client) GetStateHeight() (*result.StateHeight, error) { func (c *Client) GetStateHeight() (*result.StateHeight, error) {
var ( var resp = new(result.StateHeight)
params = request.NewRawParams()
resp = new(result.StateHeight) if err := c.performRequest("getstateheight", nil, resp); err != nil {
)
if err := c.performRequest("getstateheight", params, resp); err != nil {
return nil, err return nil, err
} }
return resp, nil return resp, nil
@ -521,15 +509,15 @@ func (c *Client) GetStateHeight() (*result.StateHeight, error) {
// GetStorageByID returns the stored value according to the contract ID and the stored key. // GetStorageByID returns the stored value according to the contract ID and the stored key.
func (c *Client) GetStorageByID(id int32, key []byte) ([]byte, error) { func (c *Client) GetStorageByID(id int32, key []byte) ([]byte, error) {
return c.getStorage(request.NewRawParams(id, key)) return c.getStorage([]interface{}{id, key})
} }
// GetStorageByHash returns the stored value according to the contract script hash and the stored key. // GetStorageByHash returns the stored value according to the contract script hash and the stored key.
func (c *Client) GetStorageByHash(hash util.Uint160, key []byte) ([]byte, error) { func (c *Client) GetStorageByHash(hash util.Uint160, key []byte) ([]byte, error) {
return c.getStorage(request.NewRawParams(hash.StringLE(), key)) return c.getStorage([]interface{}{hash.StringLE(), key})
} }
func (c *Client) getStorage(params request.RawParams) ([]byte, error) { func (c *Client) getStorage(params []interface{}) ([]byte, error) {
var resp []byte var resp []byte
if err := c.performRequest("getstorage", params, &resp); err != nil { if err := c.performRequest("getstorage", params, &resp); err != nil {
return nil, err return nil, err
@ -540,7 +528,7 @@ func (c *Client) getStorage(params request.RawParams) ([]byte, error) {
// GetTransactionHeight returns the block index where the transaction is found. // GetTransactionHeight returns the block index where the transaction is found.
func (c *Client) GetTransactionHeight(hash util.Uint256) (uint32, error) { func (c *Client) GetTransactionHeight(hash util.Uint256) (uint32, error) {
var ( var (
params = request.NewRawParams(hash.StringLE()) params = []interface{}{hash.StringLE()}
resp uint32 resp uint32
) )
if err := c.performRequest("gettransactionheight", params, &resp); err != nil { if err := c.performRequest("gettransactionheight", params, &resp); err != nil {
@ -552,7 +540,7 @@ func (c *Client) GetTransactionHeight(hash util.Uint256) (uint32, error) {
// GetUnclaimedGas returns the unclaimed GAS amount for the specified address. // GetUnclaimedGas returns the unclaimed GAS amount for the specified address.
func (c *Client) GetUnclaimedGas(address string) (result.UnclaimedGas, error) { func (c *Client) GetUnclaimedGas(address string) (result.UnclaimedGas, error) {
var ( var (
params = request.NewRawParams(address) params = []interface{}{address}
resp result.UnclaimedGas resp result.UnclaimedGas
) )
if err := c.performRequest("getunclaimedgas", params, &resp); err != nil { if err := c.performRequest("getunclaimedgas", params, &resp); err != nil {
@ -564,11 +552,9 @@ func (c *Client) GetUnclaimedGas(address string) (result.UnclaimedGas, error) {
// GetCandidates returns the current list of NEO candidate node with voting data and // GetCandidates returns the current list of NEO candidate node with voting data and
// validator status. // validator status.
func (c *Client) GetCandidates() ([]result.Candidate, error) { func (c *Client) GetCandidates() ([]result.Candidate, error) {
var ( var resp = new([]result.Candidate)
params = request.NewRawParams()
resp = new([]result.Candidate) if err := c.performRequest("getcandidates", nil, resp); err != nil {
)
if err := c.performRequest("getcandidates", params, resp); err != nil {
return nil, err return nil, err
} }
return *resp, nil return *resp, nil
@ -576,11 +562,9 @@ func (c *Client) GetCandidates() ([]result.Candidate, error) {
// GetNextBlockValidators returns the current NEO consensus nodes information and voting data. // GetNextBlockValidators returns the current NEO consensus nodes information and voting data.
func (c *Client) GetNextBlockValidators() ([]result.Validator, error) { func (c *Client) GetNextBlockValidators() ([]result.Validator, error) {
var ( var resp = new([]result.Validator)
params = request.NewRawParams()
resp = new([]result.Validator) if err := c.performRequest("getnextblockvalidators", nil, resp); err != nil {
)
if err := c.performRequest("getnextblockvalidators", params, resp); err != nil {
return nil, err return nil, err
} }
return *resp, nil return *resp, nil
@ -588,11 +572,9 @@ func (c *Client) GetNextBlockValidators() ([]result.Validator, error) {
// GetVersion returns the version information about the queried node. // GetVersion returns the version information about the queried node.
func (c *Client) GetVersion() (*result.Version, error) { func (c *Client) GetVersion() (*result.Version, error) {
var ( var resp = &result.Version{}
params = request.NewRawParams()
resp = &result.Version{} if err := c.performRequest("getversion", nil, resp); err != nil {
)
if err := c.performRequest("getversion", params, resp); err != nil {
return nil, err return nil, err
} }
return resp, nil return resp, nil
@ -601,7 +583,7 @@ func (c *Client) GetVersion() (*result.Version, error) {
// InvokeScript returns the result of the given script after running it true the VM. // InvokeScript returns the result of the given script after running it true the VM.
// NOTE: This is a test invoke and will not affect the blockchain. // NOTE: This is a test invoke and will not affect the blockchain.
func (c *Client) InvokeScript(script []byte, signers []transaction.Signer) (*result.Invoke, error) { func (c *Client) InvokeScript(script []byte, signers []transaction.Signer) (*result.Invoke, error) {
var p = request.NewRawParams(script) var p = []interface{}{script}
return c.invokeSomething("invokescript", p, signers) return c.invokeSomething("invokescript", p, signers)
} }
@ -610,7 +592,7 @@ func (c *Client) InvokeScript(script []byte, signers []transaction.Signer) (*res
// height. // height.
// NOTE: This is a test invoke and will not affect the blockchain. // NOTE: This is a test invoke and will not affect the blockchain.
func (c *Client) InvokeScriptAtHeight(height uint32, script []byte, signers []transaction.Signer) (*result.Invoke, error) { func (c *Client) InvokeScriptAtHeight(height uint32, script []byte, signers []transaction.Signer) (*result.Invoke, error) {
var p = request.NewRawParams(height, script) var p = []interface{}{height, script}
return c.invokeSomething("invokescripthistoric", p, signers) return c.invokeSomething("invokescripthistoric", p, signers)
} }
@ -619,7 +601,7 @@ func (c *Client) InvokeScriptAtHeight(height uint32, script []byte, signers []tr
// hash. // hash.
// NOTE: This is a test invoke and will not affect the blockchain. // NOTE: This is a test invoke and will not affect the blockchain.
func (c *Client) InvokeScriptAtBlock(blockHash util.Uint256, script []byte, signers []transaction.Signer) (*result.Invoke, error) { func (c *Client) InvokeScriptAtBlock(blockHash util.Uint256, script []byte, signers []transaction.Signer) (*result.Invoke, error) {
var p = request.NewRawParams(blockHash.StringLE(), script) var p = []interface{}{blockHash.StringLE(), script}
return c.invokeSomething("invokescripthistoric", p, signers) return c.invokeSomething("invokescripthistoric", p, signers)
} }
@ -628,7 +610,7 @@ func (c *Client) InvokeScriptAtBlock(blockHash util.Uint256, script []byte, sign
// stateroot hash. // stateroot hash.
// NOTE: This is a test invoke and will not affect the blockchain. // NOTE: This is a test invoke and will not affect the blockchain.
func (c *Client) InvokeScriptWithState(stateroot util.Uint256, script []byte, signers []transaction.Signer) (*result.Invoke, error) { func (c *Client) InvokeScriptWithState(stateroot util.Uint256, script []byte, signers []transaction.Signer) (*result.Invoke, error) {
var p = request.NewRawParams(stateroot.StringLE(), script) var p = []interface{}{stateroot.StringLE(), script}
return c.invokeSomething("invokescripthistoric", p, signers) return c.invokeSomething("invokescripthistoric", p, signers)
} }
@ -636,7 +618,7 @@ func (c *Client) InvokeScriptWithState(stateroot util.Uint256, script []byte, si
// with the given operation and parameters. // with the given operation and parameters.
// NOTE: this is test invoke and will not affect the blockchain. // NOTE: this is test invoke and will not affect the blockchain.
func (c *Client) InvokeFunction(contract util.Uint160, operation string, params []smartcontract.Parameter, signers []transaction.Signer) (*result.Invoke, error) { func (c *Client) InvokeFunction(contract util.Uint160, operation string, params []smartcontract.Parameter, signers []transaction.Signer) (*result.Invoke, error) {
var p = request.NewRawParams(contract.StringLE(), operation, params) var p = []interface{}{contract.StringLE(), operation, params}
return c.invokeSomething("invokefunction", p, signers) return c.invokeSomething("invokefunction", p, signers)
} }
@ -645,7 +627,7 @@ func (c *Client) InvokeFunction(contract util.Uint160, operation string, params
// specified by the blockchain height. // specified by the blockchain height.
// NOTE: this is test invoke and will not affect the blockchain. // NOTE: this is test invoke and will not affect the blockchain.
func (c *Client) InvokeFunctionAtHeight(height uint32, contract util.Uint160, operation string, params []smartcontract.Parameter, signers []transaction.Signer) (*result.Invoke, error) { func (c *Client) InvokeFunctionAtHeight(height uint32, contract util.Uint160, operation string, params []smartcontract.Parameter, signers []transaction.Signer) (*result.Invoke, error) {
var p = request.NewRawParams(height, contract.StringLE(), operation, params) var p = []interface{}{height, contract.StringLE(), operation, params}
return c.invokeSomething("invokefunctionhistoric", p, signers) return c.invokeSomething("invokefunctionhistoric", p, signers)
} }
@ -654,7 +636,7 @@ func (c *Client) InvokeFunctionAtHeight(height uint32, contract util.Uint160, op
// specified by the block hash. // specified by the block hash.
// NOTE: this is test invoke and will not affect the blockchain. // NOTE: this is test invoke and will not affect the blockchain.
func (c *Client) InvokeFunctionAtBlock(blockHash util.Uint256, contract util.Uint160, operation string, params []smartcontract.Parameter, signers []transaction.Signer) (*result.Invoke, error) { func (c *Client) InvokeFunctionAtBlock(blockHash util.Uint256, contract util.Uint160, operation string, params []smartcontract.Parameter, signers []transaction.Signer) (*result.Invoke, error) {
var p = request.NewRawParams(blockHash.StringLE(), contract.StringLE(), operation, params) var p = []interface{}{blockHash.StringLE(), contract.StringLE(), operation, params}
return c.invokeSomething("invokefunctionhistoric", p, signers) return c.invokeSomething("invokefunctionhistoric", p, signers)
} }
@ -663,7 +645,7 @@ func (c *Client) InvokeFunctionAtBlock(blockHash util.Uint256, contract util.Uin
// by the specified stateroot hash. // by the specified stateroot hash.
// NOTE: this is test invoke and will not affect the blockchain. // NOTE: this is test invoke and will not affect the blockchain.
func (c *Client) InvokeFunctionWithState(stateroot util.Uint256, contract util.Uint160, operation string, params []smartcontract.Parameter, signers []transaction.Signer) (*result.Invoke, error) { func (c *Client) InvokeFunctionWithState(stateroot util.Uint256, contract util.Uint160, operation string, params []smartcontract.Parameter, signers []transaction.Signer) (*result.Invoke, error) {
var p = request.NewRawParams(stateroot.StringLE(), contract.StringLE(), operation, params) var p = []interface{}{stateroot.StringLE(), contract.StringLE(), operation, params}
return c.invokeSomething("invokefunctionhistoric", p, signers) return c.invokeSomething("invokefunctionhistoric", p, signers)
} }
@ -671,7 +653,7 @@ func (c *Client) InvokeFunctionWithState(stateroot util.Uint256, contract util.U
// with the given parameters under verification trigger type. // with the given parameters under verification trigger type.
// NOTE: this is test invoke and will not affect the blockchain. // NOTE: this is test invoke and will not affect the blockchain.
func (c *Client) InvokeContractVerify(contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) { func (c *Client) InvokeContractVerify(contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) {
var p = request.NewRawParams(contract.StringLE(), params) var p = []interface{}{contract.StringLE(), params}
return c.invokeSomething("invokecontractverify", p, signers, witnesses...) return c.invokeSomething("invokecontractverify", p, signers, witnesses...)
} }
@ -680,7 +662,7 @@ func (c *Client) InvokeContractVerify(contract util.Uint160, params []smartcontr
// at the blockchain state specified by the blockchain height. // at the blockchain state specified by the blockchain height.
// NOTE: this is test invoke and will not affect the blockchain. // NOTE: this is test invoke and will not affect the blockchain.
func (c *Client) InvokeContractVerifyAtHeight(height uint32, contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) { func (c *Client) InvokeContractVerifyAtHeight(height uint32, contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) {
var p = request.NewRawParams(height, contract.StringLE(), params) var p = []interface{}{height, contract.StringLE(), params}
return c.invokeSomething("invokecontractverifyhistoric", p, signers, witnesses...) return c.invokeSomething("invokecontractverifyhistoric", p, signers, witnesses...)
} }
@ -689,7 +671,7 @@ func (c *Client) InvokeContractVerifyAtHeight(height uint32, contract util.Uint1
// at the blockchain state specified by the block hash. // at the blockchain state specified by the block hash.
// NOTE: this is test invoke and will not affect the blockchain. // NOTE: this is test invoke and will not affect the blockchain.
func (c *Client) InvokeContractVerifyAtBlock(blockHash util.Uint256, contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) { func (c *Client) InvokeContractVerifyAtBlock(blockHash util.Uint256, contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) {
var p = request.NewRawParams(blockHash.StringLE(), contract.StringLE(), params) var p = []interface{}{blockHash.StringLE(), contract.StringLE(), params}
return c.invokeSomething("invokecontractverifyhistoric", p, signers, witnesses...) return c.invokeSomething("invokecontractverifyhistoric", p, signers, witnesses...)
} }
@ -698,16 +680,16 @@ func (c *Client) InvokeContractVerifyAtBlock(blockHash util.Uint256, contract ut
// at the blockchain state specified by the stateroot hash. // at the blockchain state specified by the stateroot hash.
// NOTE: this is test invoke and will not affect the blockchain. // NOTE: this is test invoke and will not affect the blockchain.
func (c *Client) InvokeContractVerifyWithState(stateroot util.Uint256, contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) { func (c *Client) InvokeContractVerifyWithState(stateroot util.Uint256, contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) {
var p = request.NewRawParams(stateroot.StringLE(), contract.StringLE(), params) var p = []interface{}{stateroot.StringLE(), contract.StringLE(), params}
return c.invokeSomething("invokecontractverifyhistoric", p, signers, witnesses...) return c.invokeSomething("invokecontractverifyhistoric", p, signers, witnesses...)
} }
// invokeSomething is an inner wrapper for Invoke* functions. // invokeSomething is an inner wrapper for Invoke* functions.
func (c *Client) invokeSomething(method string, p request.RawParams, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) { func (c *Client) invokeSomething(method string, p []interface{}, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) {
var resp = new(result.Invoke) var resp = new(result.Invoke)
if signers != nil { if signers != nil {
if witnesses == nil { if witnesses == nil {
p.Values = append(p.Values, signers) p = append(p, signers)
} else { } else {
if len(witnesses) != len(signers) { if len(witnesses) != len(signers) {
return nil, fmt.Errorf("number of witnesses should match number of signers, got %d vs %d", len(witnesses), len(signers)) return nil, fmt.Errorf("number of witnesses should match number of signers, got %d vs %d", len(witnesses), len(signers))
@ -719,7 +701,7 @@ func (c *Client) invokeSomething(method string, p request.RawParams, signers []t
Witness: witnesses[i], Witness: witnesses[i],
} }
} }
p.Values = append(p.Values, signersWithWitnesses) p = append(p, signersWithWitnesses)
} }
} }
if err := c.performRequest(method, p, resp); err != nil { if err := c.performRequest(method, p, resp); err != nil {
@ -734,7 +716,7 @@ func (c *Client) invokeSomething(method string, p request.RawParams, signers []t
// been broadcasted to the network. // been broadcasted to the network.
func (c *Client) SendRawTransaction(rawTX *transaction.Transaction) (util.Uint256, error) { func (c *Client) SendRawTransaction(rawTX *transaction.Transaction) (util.Uint256, error) {
var ( var (
params = request.NewRawParams(rawTX.Bytes()) params = []interface{}{rawTX.Bytes()}
resp = new(result.RelayResult) resp = new(result.RelayResult)
) )
if err := c.performRequest("sendrawtransaction", params, resp); err != nil { if err := c.performRequest("sendrawtransaction", params, resp); err != nil {
@ -746,7 +728,7 @@ func (c *Client) SendRawTransaction(rawTX *transaction.Transaction) (util.Uint25
// SubmitBlock broadcasts a raw block over the NEO network. // SubmitBlock broadcasts a raw block over the NEO network.
func (c *Client) SubmitBlock(b block.Block) (util.Uint256, error) { func (c *Client) SubmitBlock(b block.Block) (util.Uint256, error) {
var ( var (
params request.RawParams params []interface{}
resp = new(result.RelayResult) resp = new(result.RelayResult)
) )
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
@ -754,7 +736,7 @@ func (c *Client) SubmitBlock(b block.Block) (util.Uint256, error) {
if err := buf.Err; err != nil { if err := buf.Err; err != nil {
return util.Uint256{}, err return util.Uint256{}, err
} }
params = request.NewRawParams(buf.Bytes()) params = []interface{}{buf.Bytes()}
if err := c.performRequest("submitblock", params, resp); err != nil { if err := c.performRequest("submitblock", params, resp); err != nil {
return util.Uint256{}, err return util.Uint256{}, err
@ -764,7 +746,7 @@ func (c *Client) SubmitBlock(b block.Block) (util.Uint256, error) {
// SubmitRawOracleResponse submits a raw oracle response to the oracle node. // SubmitRawOracleResponse submits a raw oracle response to the oracle node.
// Raw params are used to avoid excessive marshalling. // Raw params are used to avoid excessive marshalling.
func (c *Client) SubmitRawOracleResponse(ps request.RawParams) error { func (c *Client) SubmitRawOracleResponse(ps []interface{}) error {
return c.performRequest("submitoracleresponse", ps, new(result.RelayResult)) return c.performRequest("submitoracleresponse", ps, new(result.RelayResult))
} }
@ -997,7 +979,7 @@ func (c *Client) SubmitP2PNotaryRequest(req *payload.P2PNotaryRequest) (util.Uin
if err != nil { if err != nil {
return util.Uint256{}, fmt.Errorf("failed to encode request: %w", err) return util.Uint256{}, fmt.Errorf("failed to encode request: %w", err)
} }
params := request.NewRawParams(bytes) params := []interface{}{bytes}
if err := c.performRequest("submitnotaryrequest", params, resp); err != nil { if err := c.performRequest("submitnotaryrequest", params, resp); err != nil {
return util.Uint256{}, err return util.Uint256{}, err
} }
@ -1007,7 +989,7 @@ func (c *Client) SubmitP2PNotaryRequest(req *payload.P2PNotaryRequest) (util.Uin
// ValidateAddress verifies that the address is a correct NEO address. // ValidateAddress verifies that the address is a correct NEO address.
func (c *Client) ValidateAddress(address string) error { func (c *Client) ValidateAddress(address string) error {
var ( var (
params = request.NewRawParams(address) params = []interface{}{address}
resp = &result.ValidateAddress{} resp = &result.ValidateAddress{}
) )
@ -1161,7 +1143,7 @@ func (c *Client) TraverseIterator(sessionID, iteratorID uuid.UUID, maxItemsCount
maxItemsCount = config.DefaultMaxIteratorResultItems maxItemsCount = config.DefaultMaxIteratorResultItems
} }
var ( var (
params = request.NewRawParams(sessionID.String(), iteratorID.String(), maxItemsCount) params = []interface{}{sessionID.String(), iteratorID.String(), maxItemsCount}
resp []json.RawMessage resp []json.RawMessage
) )
if err := c.performRequest("traverseiterator", params, &resp); err != nil { if err := c.performRequest("traverseiterator", params, &resp); err != nil {
@ -1183,7 +1165,7 @@ func (c *Client) TraverseIterator(sessionID, iteratorID uuid.UUID, maxItemsCount
// the specified session was found on server. // the specified session was found on server.
func (c *Client) TerminateSession(sessionID uuid.UUID) (bool, error) { func (c *Client) TerminateSession(sessionID uuid.UUID) (bool, error) {
var resp bool var resp bool
params := request.NewRawParams(sessionID.String()) params := []interface{}{sessionID.String()}
if err := c.performRequest("terminatesession", params, &resp); err != nil { if err := c.performRequest("terminatesession", params, &resp); err != nil {
return false, err return false, err
} }

File diff suppressed because one or more lines are too long

View file

@ -63,9 +63,9 @@ type Notification struct {
// requestResponse is a combined type for request and response since we can get // requestResponse is a combined type for request and response since we can get
// any of them here. // any of them here.
type requestResponse struct { type requestResponse struct {
request.In response.Raw
Error *response.Error `json:"error,omitempty"` Method string `json:"method"`
Result json.RawMessage `json:"result,omitempty"` RawParams []json.RawMessage `json:"params,omitempty"`
} }
const ( const (
@ -158,7 +158,7 @@ readloop:
connCloseErr = fmt.Errorf("failed to read JSON response (timeout/connection loss/malformed response): %w", err) connCloseErr = fmt.Errorf("failed to read JSON response (timeout/connection loss/malformed response): %w", err)
break readloop break readloop
} }
if rr.RawID == nil && rr.Method != "" { if rr.ID == nil && rr.Method != "" {
event, err := response.GetEventIDFromString(rr.Method) event, err := response.GetEventIDFromString(rr.Method)
if err != nil { if err != nil {
// Bad event received. // Bad event received.
@ -196,7 +196,7 @@ readloop:
break readloop break readloop
} }
if event != response.MissedEventID { if event != response.MissedEventID {
err = json.Unmarshal(rr.RawParams[0].RawMessage, val) err = json.Unmarshal(rr.RawParams[0], val)
if err != nil { if err != nil {
// Bad event received. // Bad event received.
connCloseErr = fmt.Errorf("failed to unmarshal event of type %s from JSON: %w", event, err) connCloseErr = fmt.Errorf("failed to unmarshal event of type %s from JSON: %w", event, err)
@ -204,23 +204,18 @@ readloop:
} }
} }
c.Notifications <- Notification{event, val} c.Notifications <- Notification{event, val}
} else if rr.RawID != nil && (rr.Error != nil || rr.Result != nil) { } else if rr.ID != nil && (rr.Error != nil || rr.Result != nil) {
resp := new(response.Raw) id, err := strconv.ParseUint(string(rr.ID), 10, 64)
resp.ID = rr.RawID
resp.JSONRPC = rr.JSONRPC
resp.Error = rr.Error
resp.Result = rr.Result
id, err := strconv.Atoi(string(resp.ID))
if err != nil { if err != nil {
connCloseErr = fmt.Errorf("failed to retrieve response ID from string %s: %w", string(resp.ID), err) connCloseErr = fmt.Errorf("failed to retrieve response ID from string %s: %w", string(rr.ID), err)
break readloop // Malformed response (invalid response ID). break readloop // Malformed response (invalid response ID).
} }
ch := c.getResponseChannel(uint64(id)) ch := c.getResponseChannel(id)
if ch == nil { if ch == nil {
connCloseErr = fmt.Errorf("unknown response channel for response %d", id) connCloseErr = fmt.Errorf("unknown response channel for response %d", id)
break readloop // Unknown response (unexpected response ID). break readloop // Unknown response (unexpected response ID).
} }
ch <- resp ch <- &rr.Raw
} else { } else {
// Malformed response, neither valid request, nor valid response. // Malformed response, neither valid request, nor valid response.
connCloseErr = fmt.Errorf("malformed response") connCloseErr = fmt.Errorf("malformed response")
@ -261,7 +256,7 @@ writeloop:
break writeloop break writeloop
} }
if err := c.ws.WriteJSON(req); err != nil { if err := c.ws.WriteJSON(req); err != nil {
connCloseErr = fmt.Errorf("failed to write JSON request (%s / %d): %w", req.Method, len(req.RawParams), err) connCloseErr = fmt.Errorf("failed to write JSON request (%s / %d): %w", req.Method, len(req.Params), err)
break writeloop break writeloop
} }
case <-pingTicker.C: case <-pingTicker.C:
@ -320,7 +315,7 @@ func (c *WSClient) makeWsRequest(r *request.Raw) (*response.Raw, error) {
} }
} }
func (c *WSClient) performSubscription(params request.RawParams) (string, error) { func (c *WSClient) performSubscription(params []interface{}) (string, error) {
var resp string var resp string
if err := c.performRequest("subscribe", params, &resp); err != nil { if err := c.performRequest("subscribe", params, &resp); err != nil {
@ -343,7 +338,7 @@ func (c *WSClient) performUnsubscription(id string) error {
if !c.subscriptions[id] { if !c.subscriptions[id] {
return errors.New("no subscription with this ID") return errors.New("no subscription with this ID")
} }
if err := c.performRequest("unsubscribe", request.NewRawParams(id), &resp); err != nil { if err := c.performRequest("unsubscribe", []interface{}{id}, &resp); err != nil {
return err return err
} }
if !resp { if !resp {
@ -357,9 +352,9 @@ func (c *WSClient) performUnsubscription(id string) error {
// of the client. It can be filtered by primary consensus node index, nil value doesn't // of the client. It can be filtered by primary consensus node index, nil value doesn't
// add any filters. // add any filters.
func (c *WSClient) SubscribeForNewBlocks(primary *int) (string, error) { func (c *WSClient) SubscribeForNewBlocks(primary *int) (string, error) {
params := request.NewRawParams("block_added") params := []interface{}{"block_added"}
if primary != nil { if primary != nil {
params.Values = append(params.Values, request.BlockFilter{Primary: *primary}) params = append(params, request.BlockFilter{Primary: *primary})
} }
return c.performSubscription(params) return c.performSubscription(params)
} }
@ -368,9 +363,9 @@ func (c *WSClient) SubscribeForNewBlocks(primary *int) (string, error) {
// this instance of the client. It can be filtered by the sender and/or the signer, nil // this instance of the client. It can be filtered by the sender and/or the signer, nil
// value is treated as missing filter. // value is treated as missing filter.
func (c *WSClient) SubscribeForNewTransactions(sender *util.Uint160, signer *util.Uint160) (string, error) { func (c *WSClient) SubscribeForNewTransactions(sender *util.Uint160, signer *util.Uint160) (string, error) {
params := request.NewRawParams("transaction_added") params := []interface{}{"transaction_added"}
if sender != nil || signer != nil { if sender != nil || signer != nil {
params.Values = append(params.Values, request.TxFilter{Sender: sender, Signer: signer}) params = append(params, request.TxFilter{Sender: sender, Signer: signer})
} }
return c.performSubscription(params) return c.performSubscription(params)
} }
@ -380,9 +375,9 @@ func (c *WSClient) SubscribeForNewTransactions(sender *util.Uint160, signer *uti
// filtered by the contract's hash (that emits notifications), nil value puts no such // filtered by the contract's hash (that emits notifications), nil value puts no such
// restrictions. // restrictions.
func (c *WSClient) SubscribeForExecutionNotifications(contract *util.Uint160, name *string) (string, error) { func (c *WSClient) SubscribeForExecutionNotifications(contract *util.Uint160, name *string) (string, error) {
params := request.NewRawParams("notification_from_execution") params := []interface{}{"notification_from_execution"}
if contract != nil || name != nil { if contract != nil || name != nil {
params.Values = append(params.Values, request.NotificationFilter{Contract: contract, Name: name}) params = append(params, request.NotificationFilter{Contract: contract, Name: name})
} }
return c.performSubscription(params) return c.performSubscription(params)
} }
@ -392,12 +387,12 @@ func (c *WSClient) SubscribeForExecutionNotifications(contract *util.Uint160, na
// be filtered by state (HALT/FAULT) to check for successful or failing // be filtered by state (HALT/FAULT) to check for successful or failing
// transactions, nil value means no filtering. // transactions, nil value means no filtering.
func (c *WSClient) SubscribeForTransactionExecutions(state *string) (string, error) { func (c *WSClient) SubscribeForTransactionExecutions(state *string) (string, error) {
params := request.NewRawParams("transaction_executed") params := []interface{}{"transaction_executed"}
if state != nil { if state != nil {
if *state != "HALT" && *state != "FAULT" { if *state != "HALT" && *state != "FAULT" {
return "", errors.New("bad state parameter") return "", errors.New("bad state parameter")
} }
params.Values = append(params.Values, request.ExecutionFilter{State: *state}) params = append(params, request.ExecutionFilter{State: *state})
} }
return c.performSubscription(params) return c.performSubscription(params)
} }
@ -407,9 +402,9 @@ func (c *WSClient) SubscribeForTransactionExecutions(state *string) (string, err
// request sender's hash, or main tx signer's hash, nil value puts no such // request sender's hash, or main tx signer's hash, nil value puts no such
// restrictions. // restrictions.
func (c *WSClient) SubscribeForNotaryRequests(sender *util.Uint160, mainSigner *util.Uint160) (string, error) { func (c *WSClient) SubscribeForNotaryRequests(sender *util.Uint160, mainSigner *util.Uint160) (string, error) {
params := request.NewRawParams("notary_request_event") params := []interface{}{"notary_request_event"}
if sender != nil { if sender != nil {
params.Values = append(params.Values, request.TxFilter{Sender: sender, Signer: mainSigner}) params = append(params, request.TxFilter{Sender: sender, Signer: mainSigner})
} }
return c.performSubscription(params) return c.performSubscription(params)
} }
@ -426,7 +421,7 @@ func (c *WSClient) UnsubscribeAll() error {
for id := range c.subscriptions { for id := range c.subscriptions {
var resp bool var resp bool
if err := c.performRequest("unsubscribe", request.NewRawParams(id), &resp); err != nil { if err := c.performRequest("unsubscribe", []interface{}{id}, &resp); err != nil {
return err return err
} }
if !resp { if !resp {

View file

@ -18,6 +18,7 @@ import (
"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/network/payload" "github.com/nspcc-dev/neo-go/pkg/network/payload"
"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/server/params"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/atomic" "go.uber.org/atomic"
@ -189,7 +190,7 @@ func TestWSFilteredSubscriptions(t *testing.T) {
var cases = []struct { var cases = []struct {
name string name string
clientCode func(*testing.T, *WSClient) clientCode func(*testing.T, *WSClient)
serverCode func(*testing.T, *request.Params) serverCode func(*testing.T, *params.Params)
}{ }{
{"blocks", {"blocks",
func(t *testing.T, wsc *WSClient) { func(t *testing.T, wsc *WSClient) {
@ -197,7 +198,7 @@ func TestWSFilteredSubscriptions(t *testing.T) {
_, err := wsc.SubscribeForNewBlocks(&primary) _, err := wsc.SubscribeForNewBlocks(&primary)
require.NoError(t, err) require.NoError(t, err)
}, },
func(t *testing.T, p *request.Params) { func(t *testing.T, p *params.Params) {
param := p.Value(1) param := p.Value(1)
filt := new(request.BlockFilter) filt := new(request.BlockFilter)
require.NoError(t, json.Unmarshal(param.RawMessage, filt)) require.NoError(t, json.Unmarshal(param.RawMessage, filt))
@ -210,7 +211,7 @@ func TestWSFilteredSubscriptions(t *testing.T) {
_, err := wsc.SubscribeForNewTransactions(&sender, nil) _, err := wsc.SubscribeForNewTransactions(&sender, nil)
require.NoError(t, err) require.NoError(t, err)
}, },
func(t *testing.T, p *request.Params) { func(t *testing.T, p *params.Params) {
param := p.Value(1) param := p.Value(1)
filt := new(request.TxFilter) filt := new(request.TxFilter)
require.NoError(t, json.Unmarshal(param.RawMessage, filt)) require.NoError(t, json.Unmarshal(param.RawMessage, filt))
@ -224,7 +225,7 @@ func TestWSFilteredSubscriptions(t *testing.T) {
_, err := wsc.SubscribeForNewTransactions(nil, &signer) _, err := wsc.SubscribeForNewTransactions(nil, &signer)
require.NoError(t, err) require.NoError(t, err)
}, },
func(t *testing.T, p *request.Params) { func(t *testing.T, p *params.Params) {
param := p.Value(1) param := p.Value(1)
filt := new(request.TxFilter) filt := new(request.TxFilter)
require.NoError(t, json.Unmarshal(param.RawMessage, filt)) require.NoError(t, json.Unmarshal(param.RawMessage, filt))
@ -239,7 +240,7 @@ func TestWSFilteredSubscriptions(t *testing.T) {
_, err := wsc.SubscribeForNewTransactions(&sender, &signer) _, err := wsc.SubscribeForNewTransactions(&sender, &signer)
require.NoError(t, err) require.NoError(t, err)
}, },
func(t *testing.T, p *request.Params) { func(t *testing.T, p *params.Params) {
param := p.Value(1) param := p.Value(1)
filt := new(request.TxFilter) filt := new(request.TxFilter)
require.NoError(t, json.Unmarshal(param.RawMessage, filt)) require.NoError(t, json.Unmarshal(param.RawMessage, filt))
@ -253,7 +254,7 @@ func TestWSFilteredSubscriptions(t *testing.T) {
_, err := wsc.SubscribeForExecutionNotifications(&contract, nil) _, err := wsc.SubscribeForExecutionNotifications(&contract, nil)
require.NoError(t, err) require.NoError(t, err)
}, },
func(t *testing.T, p *request.Params) { func(t *testing.T, p *params.Params) {
param := p.Value(1) param := p.Value(1)
filt := new(request.NotificationFilter) filt := new(request.NotificationFilter)
require.NoError(t, json.Unmarshal(param.RawMessage, filt)) require.NoError(t, json.Unmarshal(param.RawMessage, filt))
@ -267,7 +268,7 @@ func TestWSFilteredSubscriptions(t *testing.T) {
_, err := wsc.SubscribeForExecutionNotifications(nil, &name) _, err := wsc.SubscribeForExecutionNotifications(nil, &name)
require.NoError(t, err) require.NoError(t, err)
}, },
func(t *testing.T, p *request.Params) { func(t *testing.T, p *params.Params) {
param := p.Value(1) param := p.Value(1)
filt := new(request.NotificationFilter) filt := new(request.NotificationFilter)
require.NoError(t, json.Unmarshal(param.RawMessage, filt)) require.NoError(t, json.Unmarshal(param.RawMessage, filt))
@ -282,7 +283,7 @@ func TestWSFilteredSubscriptions(t *testing.T) {
_, err := wsc.SubscribeForExecutionNotifications(&contract, &name) _, err := wsc.SubscribeForExecutionNotifications(&contract, &name)
require.NoError(t, err) require.NoError(t, err)
}, },
func(t *testing.T, p *request.Params) { func(t *testing.T, p *params.Params) {
param := p.Value(1) param := p.Value(1)
filt := new(request.NotificationFilter) filt := new(request.NotificationFilter)
require.NoError(t, json.Unmarshal(param.RawMessage, filt)) require.NoError(t, json.Unmarshal(param.RawMessage, filt))
@ -296,7 +297,7 @@ func TestWSFilteredSubscriptions(t *testing.T) {
_, err := wsc.SubscribeForTransactionExecutions(&state) _, err := wsc.SubscribeForTransactionExecutions(&state)
require.NoError(t, err) require.NoError(t, err)
}, },
func(t *testing.T, p *request.Params) { func(t *testing.T, p *params.Params) {
param := p.Value(1) param := p.Value(1)
filt := new(request.ExecutionFilter) filt := new(request.ExecutionFilter)
require.NoError(t, json.Unmarshal(param.RawMessage, filt)) require.NoError(t, json.Unmarshal(param.RawMessage, filt))
@ -313,10 +314,10 @@ func TestWSFilteredSubscriptions(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
err = ws.SetReadDeadline(time.Now().Add(2 * time.Second)) err = ws.SetReadDeadline(time.Now().Add(2 * time.Second))
require.NoError(t, err) require.NoError(t, err)
req := request.In{} req := params.In{}
err = ws.ReadJSON(&req) err = ws.ReadJSON(&req)
require.NoError(t, err) require.NoError(t, err)
params := request.Params(req.RawParams) params := params.Params(req.RawParams)
c.serverCode(t, &params) c.serverCode(t, &params)
err = ws.SetWriteDeadline(time.Now().Add(2 * time.Second)) err = ws.SetWriteDeadline(time.Now().Add(2 * time.Second))
require.NoError(t, err) require.NoError(t, err)
@ -370,7 +371,7 @@ func TestWSConcurrentAccess(t *testing.T) {
if err != nil { if err != nil {
break break
} }
r := request.NewIn() r := params.NewIn()
err = json.Unmarshal(p, r) err = json.Unmarshal(p, r)
if err != nil { if err != nil {
t.Fatalf("Cannot decode request body: %s", req.Body) t.Fatalf("Cannot decode request body: %s", req.Body)

View file

@ -1,136 +1,123 @@
package request package request
import ( import (
"bytes"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "strings"
"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/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/util"
) )
const ( const (
// JSONRPCVersion is the only JSON-RPC protocol version supported. // JSONRPCVersion is the only JSON-RPC protocol version supported.
JSONRPCVersion = "2.0" JSONRPCVersion = "2.0"
// maxBatchSize is the maximum number of requests per batch.
maxBatchSize = 100
) )
// RawParams is just a slice of abstract values, used to represent parameters type (
// passed from the client to the server. // Raw represents JSON-RPC request. It's generic enough to be used in many
type RawParams struct { // generic JSON-RPC communication scenarios, yet at the same time it's
Values []interface{} // tailored for NeoGo RPC Client needs.
} Raw struct {
// JSONRPC is the protocol version, only valid when it contains JSONRPCVersion.
// NewRawParams creates RawParams from its parameters. JSONRPC string `json:"jsonrpc"`
func NewRawParams(vals ...interface{}) RawParams { // Method is the method being called.
p := RawParams{} Method string `json:"method"`
p.Values = make([]interface{}, len(vals)) // Params is a set of method-specific parameters passed to the call. They
for i := 0; i < len(p.Values); i++ { // can be anything as long as they can be marshaled to JSON correctly and
p.Values[i] = vals[i] // used by the method implementation on the server side. While JSON-RPC
// technically allows it to be an object, all Neo calls expect params
// to be an array.
Params []interface{} `json:"params"`
// ID is an identifier associated with this request. JSON-RPC itself allows
// any strings to be used for it as well, but NeoGo RPC client uses numeric
// identifiers.
ID uint64 `json:"id"`
} }
return p
}
// Raw represents JSON-RPC request on the Client side. // BlockFilter is a wrapper structure for the block event filter. The only
type Raw struct { // allowed filter is primary index.
JSONRPC string `json:"jsonrpc"` BlockFilter struct {
Method string `json:"method"` Primary int `json:"primary"`
RawParams []interface{} `json:"params"` }
ID uint64 `json:"id"` // TxFilter is a wrapper structure for the transaction event filter. It
} // allows to filter transactions by senders and signers.
TxFilter struct {
Sender *util.Uint160 `json:"sender,omitempty"`
Signer *util.Uint160 `json:"signer,omitempty"`
}
// NotificationFilter is a wrapper structure representing a filter used for
// notifications generated during transaction execution. Notifications can
// be filtered by contract hash and by name.
NotificationFilter struct {
Contract *util.Uint160 `json:"contract,omitempty"`
Name *string `json:"name,omitempty"`
}
// ExecutionFilter is a wrapper structure used for transaction execution
// events. It allows to choose failing or successful transactions based
// on their VM state.
ExecutionFilter struct {
State string `json:"state"`
}
// SignerWithWitness represents transaction's signer with the corresponding witness.
SignerWithWitness struct {
transaction.Signer
transaction.Witness
}
)
// Request contains standard JSON-RPC 2.0 request and batch of // signerWithWitnessAux is an auxiliary struct for JSON marshalling. We need it because of
// requests: http://www.jsonrpc.org/specification. // DisallowUnknownFields JSON marshaller setting.
// It's used in server to represent incoming queries. type signerWithWitnessAux struct {
type Request struct { Account string `json:"account"`
In *In Scopes transaction.WitnessScope `json:"scopes"`
Batch Batch AllowedContracts []util.Uint160 `json:"allowedcontracts,omitempty"`
AllowedGroups []*keys.PublicKey `json:"allowedgroups,omitempty"`
Rules []transaction.WitnessRule `json:"rules,omitempty"`
InvocationScript []byte `json:"invocation,omitempty"`
VerificationScript []byte `json:"verification,omitempty"`
} }
// In represents a standard JSON-RPC 2.0
// request: http://www.jsonrpc.org/specification#request_object.
type In struct {
JSONRPC string `json:"jsonrpc"`
Method string `json:"method"`
RawParams []Param `json:"params,omitempty"`
RawID json.RawMessage `json:"id,omitempty"`
}
// Batch represents a standard JSON-RPC 2.0
// batch: https://www.jsonrpc.org/specification#batch.
type Batch []In
// MarshalJSON implements the json.Marshaler interface. // MarshalJSON implements the json.Marshaler interface.
func (r Request) MarshalJSON() ([]byte, error) { func (s *SignerWithWitness) MarshalJSON() ([]byte, error) {
if r.In != nil { signer := &signerWithWitnessAux{
return json.Marshal(r.In) Account: s.Account.StringLE(),
Scopes: s.Scopes,
AllowedContracts: s.AllowedContracts,
AllowedGroups: s.AllowedGroups,
Rules: s.Rules,
InvocationScript: s.InvocationScript,
VerificationScript: s.VerificationScript,
} }
return json.Marshal(r.Batch) return json.Marshal(signer)
} }
// UnmarshalJSON implements the json.Unmarshaler interface. // UnmarshalJSON implements the json.Unmarshaler interface.
func (r *Request) UnmarshalJSON(data []byte) error { func (s *SignerWithWitness) UnmarshalJSON(data []byte) error {
var ( aux := new(signerWithWitnessAux)
in *In err := json.Unmarshal(data, aux)
batch Batch
)
in = &In{}
err := json.Unmarshal(data, in)
if err == nil {
r.In = in
return nil
}
decoder := json.NewDecoder(bytes.NewReader(data))
t, err := decoder.Token() // read `[`
if err != nil { if err != nil {
return err return fmt.Errorf("not a signer: %w", err)
} }
if t != json.Delim('[') { acc, err := util.Uint160DecodeStringLE(strings.TrimPrefix(aux.Account, "0x"))
return fmt.Errorf("`[` expected, got %s", t) if err != nil {
acc, err = address.StringToUint160(aux.Account)
} }
count := 0 if err != nil {
for decoder.More() { return fmt.Errorf("not a signer: %w", err)
if count > maxBatchSize {
return fmt.Errorf("the number of requests in batch shouldn't exceed %d", maxBatchSize)
}
in = &In{}
decodeErr := decoder.Decode(in)
if decodeErr != nil {
return decodeErr
}
batch = append(batch, *in)
count++
} }
if len(batch) == 0 { s.Signer = transaction.Signer{
return errors.New("empty request") Account: acc,
Scopes: aux.Scopes,
AllowedContracts: aux.AllowedContracts,
AllowedGroups: aux.AllowedGroups,
Rules: aux.Rules,
}
s.Witness = transaction.Witness{
InvocationScript: aux.InvocationScript,
VerificationScript: aux.VerificationScript,
} }
r.Batch = batch
return nil return nil
} }
// DecodeData decodes the given reader into the the request
// struct.
func (r *Request) DecodeData(data io.ReadCloser) error {
defer data.Close()
rawData := json.RawMessage{}
err := json.NewDecoder(data).Decode(&rawData)
if err != nil {
return fmt.Errorf("error parsing JSON payload: %w", err)
}
return r.UnmarshalJSON(rawData)
}
// NewRequest creates a new Request struct.
func NewRequest() *Request {
return &Request{}
}
// NewIn creates a new In struct.
func NewIn() *In {
return &In{
JSONRPC: JSONRPCVersion,
}
}

View file

@ -1,4 +1,4 @@
package request package params
import ( import (
"bytes" "bytes"
@ -13,8 +13,8 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"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/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
) )
@ -34,35 +34,6 @@ type (
Type smartcontract.ParamType `json:"type"` Type smartcontract.ParamType `json:"type"`
Value Param `json:"value"` Value Param `json:"value"`
} }
// BlockFilter is a wrapper structure for the block event filter. The only
// allowed filter is primary index.
BlockFilter struct {
Primary int `json:"primary"`
}
// TxFilter is a wrapper structure for the transaction event filter. It
// allows to filter transactions by senders and signers.
TxFilter struct {
Sender *util.Uint160 `json:"sender,omitempty"`
Signer *util.Uint160 `json:"signer,omitempty"`
}
// NotificationFilter is a wrapper structure representing a filter used for
// notifications generated during transaction execution. Notifications can
// be filtered by contract hash and by name.
NotificationFilter struct {
Contract *util.Uint160 `json:"contract,omitempty"`
Name *string `json:"name,omitempty"`
}
// ExecutionFilter is a wrapper structure used for transaction execution
// events. It allows to choose failing or successful transactions based
// on their VM state.
ExecutionFilter struct {
State string `json:"state"`
}
// SignerWithWitness represents transaction's signer with the corresponding witness.
SignerWithWitness struct {
transaction.Signer
transaction.Witness
}
) )
var ( var (
@ -409,33 +380,13 @@ func (p *Param) GetBytesBase64() ([]byte, error) {
return base64.StdEncoding.DecodeString(s) return base64.StdEncoding.DecodeString(s)
} }
// GetSignerWithWitness returns a SignerWithWitness value of the parameter. // GetSignerWithWitness returns a request.SignerWithWitness value of the parameter.
func (p *Param) GetSignerWithWitness() (SignerWithWitness, error) { func (p *Param) GetSignerWithWitness() (request.SignerWithWitness, error) {
// This one doesn't need to be cached, it's used only once. // This one doesn't need to be cached, it's used only once.
aux := new(signerWithWitnessAux) c := request.SignerWithWitness{}
err := json.Unmarshal(p.RawMessage, aux) err := json.Unmarshal(p.RawMessage, &c)
if err != nil { if err != nil {
return SignerWithWitness{}, fmt.Errorf("not a signer: %w", err) return request.SignerWithWitness{}, fmt.Errorf("not a signer: %w", err)
}
acc, err := util.Uint160DecodeStringLE(strings.TrimPrefix(aux.Account, "0x"))
if err != nil {
acc, err = address.StringToUint160(aux.Account)
}
if err != nil {
return SignerWithWitness{}, fmt.Errorf("not a signer: %w", err)
}
c := SignerWithWitness{
Signer: transaction.Signer{
Account: acc,
Scopes: aux.Scopes,
AllowedContracts: aux.AllowedContracts,
AllowedGroups: aux.AllowedGroups,
Rules: aux.Rules,
},
Witness: transaction.Witness{
InvocationScript: aux.InvocationScript,
VerificationScript: aux.VerificationScript,
},
} }
return c, nil return c, nil
} }
@ -480,32 +431,6 @@ func (p *Param) IsNull() bool {
return bytes.Equal(p.RawMessage, jsonNullBytes) return bytes.Equal(p.RawMessage, jsonNullBytes)
} }
// signerWithWitnessAux is an auxiliary struct for JSON marshalling. We need it because of
// DisallowUnknownFields JSON marshaller setting.
type signerWithWitnessAux struct {
Account string `json:"account"`
Scopes transaction.WitnessScope `json:"scopes"`
AllowedContracts []util.Uint160 `json:"allowedcontracts,omitempty"`
AllowedGroups []*keys.PublicKey `json:"allowedgroups,omitempty"`
Rules []transaction.WitnessRule `json:"rules,omitempty"`
InvocationScript []byte `json:"invocation,omitempty"`
VerificationScript []byte `json:"verification,omitempty"`
}
// MarshalJSON implements the json.Marshaler interface.
func (s *SignerWithWitness) MarshalJSON() ([]byte, error) {
signer := &signerWithWitnessAux{
Account: s.Account.StringLE(),
Scopes: s.Scopes,
AllowedContracts: s.AllowedContracts,
AllowedGroups: s.AllowedGroups,
Rules: s.Rules,
InvocationScript: s.InvocationScript,
VerificationScript: s.VerificationScript,
}
return json.Marshal(signer)
}
// GetUUID returns UUID from parameter. // GetUUID returns UUID from parameter.
func (p *Param) GetUUID() (uuid.UUID, error) { func (p *Param) GetUUID() (uuid.UUID, error) {
s, err := p.GetString() s, err := p.GetString()

View file

@ -1,4 +1,4 @@
package request package params
import ( import (
"encoding/base64" "encoding/base64"
@ -12,6 +12,7 @@ import (
"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/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -154,7 +155,7 @@ func TestParam_UnmarshalJSON(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
expectedAcc, err := util.Uint160DecodeStringLE("cadb3dc2faa3ef14a13b619c9a43124755aa2569") expectedAcc, err := util.Uint160DecodeStringLE("cadb3dc2faa3ef14a13b619c9a43124755aa2569")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, SignerWithWitness{Signer: transaction.Signer{Account: expectedAcc}}, actual) require.Equal(t, request.SignerWithWitness{Signer: transaction.Signer{Account: expectedAcc}}, actual)
}, },
expectedRawMessage: []byte(`{"account": "0xcadb3dc2faa3ef14a13b619c9a43124755aa2569"}`), expectedRawMessage: []byte(`{"account": "0xcadb3dc2faa3ef14a13b619c9a43124755aa2569"}`),
}, },
@ -164,7 +165,7 @@ func TestParam_UnmarshalJSON(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
expectedAcc, err := address.StringToUint160("NYxb4fSZVKAz8YsgaPK2WkT3KcAE9b3Vag") expectedAcc, err := address.StringToUint160("NYxb4fSZVKAz8YsgaPK2WkT3KcAE9b3Vag")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, SignerWithWitness{Signer: transaction.Signer{Account: expectedAcc, Scopes: transaction.Global}}, actual) require.Equal(t, request.SignerWithWitness{Signer: transaction.Signer{Account: expectedAcc, Scopes: transaction.Global}}, actual)
}, },
expectedRawMessage: []byte(`{"account": "NYxb4fSZVKAz8YsgaPK2WkT3KcAE9b3Vag", "scopes": "Global"}`), expectedRawMessage: []byte(`{"account": "NYxb4fSZVKAz8YsgaPK2WkT3KcAE9b3Vag", "scopes": "Global"}`),
}, },
@ -243,21 +244,21 @@ func TestGetWitness(t *testing.T) {
testCases := []struct { testCases := []struct {
raw string raw string
expected SignerWithWitness expected request.SignerWithWitness
}{ }{
{`{"account": "0xcadb3dc2faa3ef14a13b619c9a43124755aa2569"}`, SignerWithWitness{ {`{"account": "0xcadb3dc2faa3ef14a13b619c9a43124755aa2569"}`, request.SignerWithWitness{
Signer: transaction.Signer{ Signer: transaction.Signer{
Account: accountHash, Account: accountHash,
Scopes: transaction.None, Scopes: transaction.None,
}}, }},
}, },
{`{"account": "NYxb4fSZVKAz8YsgaPK2WkT3KcAE9b3Vag", "scopes": "Global"}`, SignerWithWitness{ {`{"account": "NYxb4fSZVKAz8YsgaPK2WkT3KcAE9b3Vag", "scopes": "Global"}`, request.SignerWithWitness{
Signer: transaction.Signer{ Signer: transaction.Signer{
Account: addrHash, Account: addrHash,
Scopes: transaction.Global, Scopes: transaction.Global,
}}, }},
}, },
{`{"account": "0xcadb3dc2faa3ef14a13b619c9a43124755aa2569", "scopes": "Global"}`, SignerWithWitness{ {`{"account": "0xcadb3dc2faa3ef14a13b619c9a43124755aa2569", "scopes": "Global"}`, request.SignerWithWitness{
Signer: transaction.Signer{ Signer: transaction.Signer{
Account: accountHash, Account: accountHash,
Scopes: transaction.Global, Scopes: transaction.Global,
@ -404,7 +405,7 @@ func TestParamGetBytesBase64(t *testing.T) {
} }
func TestParamGetSigner(t *testing.T) { func TestParamGetSigner(t *testing.T) {
c := SignerWithWitness{ c := request.SignerWithWitness{
Signer: transaction.Signer{ Signer: transaction.Signer{
Account: util.Uint160{1, 2, 3, 4}, Account: util.Uint160{1, 2, 3, 4},
Scopes: transaction.Global, Scopes: transaction.Global,

View file

@ -1,4 +1,4 @@
package request package params
import "fmt" import "fmt"

View file

@ -1,4 +1,4 @@
package request package params
import ( import (
"errors" "errors"

View file

@ -1,4 +1,4 @@
package request package params
import ( import (
"encoding/base64" "encoding/base64"

View file

@ -0,0 +1,111 @@
package params
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
)
const (
// maxBatchSize is the maximum number of requests per batch.
maxBatchSize = 100
)
// Request contains standard JSON-RPC 2.0 request and batch of
// requests: http://www.jsonrpc.org/specification.
// It's used in server to represent incoming queries.
type Request struct {
In *In
Batch Batch
}
// In represents a standard JSON-RPC 2.0
// request: http://www.jsonrpc.org/specification#request_object.
type In struct {
JSONRPC string `json:"jsonrpc"`
Method string `json:"method"`
RawParams []Param `json:"params,omitempty"`
RawID json.RawMessage `json:"id,omitempty"`
}
// Batch represents a standard JSON-RPC 2.0
// batch: https://www.jsonrpc.org/specification#batch.
type Batch []In
// MarshalJSON implements the json.Marshaler interface.
func (r Request) MarshalJSON() ([]byte, error) {
if r.In != nil {
return json.Marshal(r.In)
}
return json.Marshal(r.Batch)
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (r *Request) UnmarshalJSON(data []byte) error {
var (
in *In
batch Batch
)
in = &In{}
err := json.Unmarshal(data, in)
if err == nil {
r.In = in
return nil
}
decoder := json.NewDecoder(bytes.NewReader(data))
t, err := decoder.Token() // read `[`
if err != nil {
return err
}
if t != json.Delim('[') {
return fmt.Errorf("`[` expected, got %s", t)
}
count := 0
for decoder.More() {
if count > maxBatchSize {
return fmt.Errorf("the number of requests in batch shouldn't exceed %d", maxBatchSize)
}
in = &In{}
decodeErr := decoder.Decode(in)
if decodeErr != nil {
return decodeErr
}
batch = append(batch, *in)
count++
}
if len(batch) == 0 {
return errors.New("empty request")
}
r.Batch = batch
return nil
}
// DecodeData decodes the given reader into the the request
// struct.
func (r *Request) DecodeData(data io.ReadCloser) error {
defer data.Close()
rawData := json.RawMessage{}
err := json.NewDecoder(data).Decode(&rawData)
if err != nil {
return fmt.Errorf("error parsing JSON payload: %w", err)
}
return r.UnmarshalJSON(rawData)
}
// NewRequest creates a new Request struct.
func NewRequest() *Request {
return &Request{}
}
// NewIn creates a new In struct.
func NewIn() *In {
return &In{
JSONRPC: request.JSONRPCVersion,
}
}

View file

@ -1,4 +1,4 @@
package request package params
import ( import (
"bytes" "bytes"

View file

@ -44,6 +44,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/rpc/response" "github.com/nspcc-dev/neo-go/pkg/rpc/response"
"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/rpc/response/result/subscriptions" "github.com/nspcc-dev/neo-go/pkg/rpc/response/result/subscriptions"
"github.com/nspcc-dev/neo-go/pkg/rpc/server/params"
"github.com/nspcc-dev/neo-go/pkg/services/oracle" "github.com/nspcc-dev/neo-go/pkg/services/oracle"
"github.com/nspcc-dev/neo-go/pkg/services/oracle/broadcaster" "github.com/nspcc-dev/neo-go/pkg/services/oracle/broadcaster"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
@ -148,7 +149,7 @@ const (
defaultSessionPoolSize = 20 defaultSessionPoolSize = 20
) )
var rpcHandlers = map[string]func(*Server, request.Params) (interface{}, *response.Error){ var rpcHandlers = map[string]func(*Server, params.Params) (interface{}, *response.Error){
"calculatenetworkfee": (*Server).calculateNetworkFee, "calculatenetworkfee": (*Server).calculateNetworkFee,
"findstates": (*Server).findStates, "findstates": (*Server).findStates,
"getapplicationlog": (*Server).getApplicationLog, "getapplicationlog": (*Server).getApplicationLog,
@ -197,7 +198,7 @@ var rpcHandlers = map[string]func(*Server, request.Params) (interface{}, *respon
"verifyproof": (*Server).verifyProof, "verifyproof": (*Server).verifyProof,
} }
var rpcWsHandlers = map[string]func(*Server, request.Params, *subscriber) (interface{}, *response.Error){ var rpcWsHandlers = map[string]func(*Server, params.Params, *subscriber) (interface{}, *response.Error){
"subscribe": (*Server).subscribe, "subscribe": (*Server).subscribe,
"unsubscribe": (*Server).unsubscribe, "unsubscribe": (*Server).unsubscribe,
} }
@ -366,7 +367,7 @@ func (s *Server) Shutdown() {
} }
func (s *Server) handleHTTPRequest(w http.ResponseWriter, httpRequest *http.Request) { func (s *Server) handleHTTPRequest(w http.ResponseWriter, httpRequest *http.Request) {
req := request.NewRequest() req := params.NewRequest()
if httpRequest.URL.Path == "/ws" && httpRequest.Method == "GET" { if httpRequest.URL.Path == "/ws" && httpRequest.Method == "GET" {
// Technically there is a race between this check and // Technically there is a race between this check and
@ -378,7 +379,7 @@ func (s *Server) handleHTTPRequest(w http.ResponseWriter, httpRequest *http.Requ
s.subsLock.RUnlock() s.subsLock.RUnlock()
if numOfSubs >= maxSubscribers { if numOfSubs >= maxSubscribers {
s.writeHTTPErrorResponse( s.writeHTTPErrorResponse(
request.NewIn(), params.NewIn(),
w, w,
response.NewInternalServerError("websocket users limit reached"), response.NewInternalServerError("websocket users limit reached"),
) )
@ -402,7 +403,7 @@ func (s *Server) handleHTTPRequest(w http.ResponseWriter, httpRequest *http.Requ
if httpRequest.Method != "POST" { if httpRequest.Method != "POST" {
s.writeHTTPErrorResponse( s.writeHTTPErrorResponse(
request.NewIn(), params.NewIn(),
w, w,
response.NewInvalidParamsError(fmt.Sprintf("invalid method '%s', please retry with 'POST'", httpRequest.Method)), response.NewInvalidParamsError(fmt.Sprintf("invalid method '%s', please retry with 'POST'", httpRequest.Method)),
) )
@ -411,7 +412,7 @@ func (s *Server) handleHTTPRequest(w http.ResponseWriter, httpRequest *http.Requ
err := req.DecodeData(httpRequest.Body) err := req.DecodeData(httpRequest.Body)
if err != nil { if err != nil {
s.writeHTTPErrorResponse(request.NewIn(), w, response.NewParseError(err.Error())) s.writeHTTPErrorResponse(params.NewIn(), w, response.NewParseError(err.Error()))
return return
} }
@ -419,7 +420,7 @@ func (s *Server) handleHTTPRequest(w http.ResponseWriter, httpRequest *http.Requ
s.writeHTTPServerResponse(req, w, resp) s.writeHTTPServerResponse(req, w, resp)
} }
func (s *Server) handleRequest(req *request.Request, sub *subscriber) abstractResult { func (s *Server) handleRequest(req *params.Request, sub *subscriber) abstractResult {
if req.In != nil { if req.In != nil {
req.In.Method = escapeForLog(req.In.Method) // No valid method name will be changed by it. req.In.Method = escapeForLog(req.In.Method) // No valid method name will be changed by it.
return s.handleIn(req.In, sub) return s.handleIn(req.In, sub)
@ -432,14 +433,14 @@ func (s *Server) handleRequest(req *request.Request, sub *subscriber) abstractRe
return resp return resp
} }
func (s *Server) handleIn(req *request.In, sub *subscriber) abstract { func (s *Server) handleIn(req *params.In, sub *subscriber) abstract {
var res interface{} var res interface{}
var resErr *response.Error var resErr *response.Error
if req.JSONRPC != request.JSONRPCVersion { if req.JSONRPC != request.JSONRPCVersion {
return s.packResponse(req, nil, response.NewInvalidParamsError(fmt.Sprintf("problem parsing JSON: invalid version, expected 2.0 got '%s'", req.JSONRPC))) return s.packResponse(req, nil, response.NewInvalidParamsError(fmt.Sprintf("problem parsing JSON: invalid version, expected 2.0 got '%s'", req.JSONRPC)))
} }
reqParams := request.Params(req.RawParams) reqParams := params.Params(req.RawParams)
s.log.Debug("processing rpc request", s.log.Debug("processing rpc request",
zap.String("method", req.Method), zap.String("method", req.Method),
@ -519,7 +520,7 @@ func (s *Server) handleWsReads(ws *websocket.Conn, resChan chan<- abstractResult
ws.SetPongHandler(func(string) error { return ws.SetReadDeadline(time.Now().Add(wsPongLimit)) }) ws.SetPongHandler(func(string) error { return ws.SetReadDeadline(time.Now().Add(wsPongLimit)) })
requestloop: requestloop:
for err == nil { for err == nil {
req := request.NewRequest() req := params.NewRequest()
err := ws.ReadJSON(req) err := ws.ReadJSON(req)
if err != nil { if err != nil {
break break
@ -546,23 +547,23 @@ requestloop:
ws.Close() ws.Close()
} }
func (s *Server) getBestBlockHash(_ request.Params) (interface{}, *response.Error) { func (s *Server) getBestBlockHash(_ params.Params) (interface{}, *response.Error) {
return "0x" + s.chain.CurrentBlockHash().StringLE(), nil return "0x" + s.chain.CurrentBlockHash().StringLE(), nil
} }
func (s *Server) getBlockCount(_ request.Params) (interface{}, *response.Error) { func (s *Server) getBlockCount(_ params.Params) (interface{}, *response.Error) {
return s.chain.BlockHeight() + 1, nil return s.chain.BlockHeight() + 1, nil
} }
func (s *Server) getBlockHeaderCount(_ request.Params) (interface{}, *response.Error) { func (s *Server) getBlockHeaderCount(_ params.Params) (interface{}, *response.Error) {
return s.chain.HeaderHeight() + 1, nil return s.chain.HeaderHeight() + 1, nil
} }
func (s *Server) getConnectionCount(_ request.Params) (interface{}, *response.Error) { func (s *Server) getConnectionCount(_ params.Params) (interface{}, *response.Error) {
return s.coreServer.PeerCount(), nil return s.coreServer.PeerCount(), nil
} }
func (s *Server) blockHashFromParam(param *request.Param) (util.Uint256, *response.Error) { func (s *Server) blockHashFromParam(param *params.Param) (util.Uint256, *response.Error) {
var ( var (
hash util.Uint256 hash util.Uint256
err error err error
@ -581,7 +582,7 @@ func (s *Server) blockHashFromParam(param *request.Param) (util.Uint256, *respon
return hash, nil return hash, nil
} }
func (s *Server) getBlock(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getBlock(reqParams params.Params) (interface{}, *response.Error) {
param := reqParams.Value(0) param := reqParams.Value(0)
hash, respErr := s.blockHashFromParam(param) hash, respErr := s.blockHashFromParam(param)
if respErr != nil { if respErr != nil {
@ -601,7 +602,7 @@ func (s *Server) getBlock(reqParams request.Params) (interface{}, *response.Erro
return writer.Bytes(), nil return writer.Bytes(), nil
} }
func (s *Server) getBlockHash(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getBlockHash(reqParams params.Params) (interface{}, *response.Error) {
num, err := s.blockHeightFromParam(reqParams.Value(0)) num, err := s.blockHeightFromParam(reqParams.Value(0))
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -610,7 +611,7 @@ func (s *Server) getBlockHash(reqParams request.Params) (interface{}, *response.
return s.chain.GetHeaderHash(num), nil return s.chain.GetHeaderHash(num), nil
} }
func (s *Server) getVersion(_ request.Params) (interface{}, *response.Error) { func (s *Server) getVersion(_ params.Params) (interface{}, *response.Error) {
port, err := s.coreServer.Port() port, err := s.coreServer.Port()
if err != nil { if err != nil {
return nil, response.NewInternalServerError(fmt.Sprintf("cannot fetch tcp port: %s", err)) return nil, response.NewInternalServerError(fmt.Sprintf("cannot fetch tcp port: %s", err))
@ -638,7 +639,7 @@ func (s *Server) getVersion(_ request.Params) (interface{}, *response.Error) {
}, nil }, nil
} }
func (s *Server) getPeers(_ request.Params) (interface{}, *response.Error) { func (s *Server) getPeers(_ params.Params) (interface{}, *response.Error) {
peers := result.NewGetPeers() peers := result.NewGetPeers()
peers.AddUnconnected(s.coreServer.UnconnectedPeers()) peers.AddUnconnected(s.coreServer.UnconnectedPeers())
peers.AddConnected(s.coreServer.ConnectedPeers()) peers.AddConnected(s.coreServer.ConnectedPeers())
@ -646,7 +647,7 @@ func (s *Server) getPeers(_ request.Params) (interface{}, *response.Error) {
return peers, nil return peers, nil
} }
func (s *Server) getRawMempool(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getRawMempool(reqParams params.Params) (interface{}, *response.Error) {
verbose, _ := reqParams.Value(0).GetBoolean() verbose, _ := reqParams.Value(0).GetBoolean()
mp := s.chain.GetMemPool() mp := s.chain.GetMemPool()
hashList := make([]util.Uint256, 0) hashList := make([]util.Uint256, 0)
@ -663,7 +664,7 @@ func (s *Server) getRawMempool(reqParams request.Params) (interface{}, *response
}, nil }, nil
} }
func (s *Server) validateAddress(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) validateAddress(reqParams params.Params) (interface{}, *response.Error) {
param, err := reqParams.Value(0).GetString() param, err := reqParams.Value(0).GetString()
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -676,7 +677,7 @@ func (s *Server) validateAddress(reqParams request.Params) (interface{}, *respon
} }
// calculateNetworkFee calculates network fee for the transaction. // calculateNetworkFee calculates network fee for the transaction.
func (s *Server) calculateNetworkFee(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) calculateNetworkFee(reqParams params.Params) (interface{}, *response.Error) {
if len(reqParams) < 1 { if len(reqParams) < 1 {
return 0, response.ErrInvalidParams return 0, response.ErrInvalidParams
} }
@ -730,7 +731,7 @@ func (s *Server) calculateNetworkFee(reqParams request.Params) (interface{}, *re
} }
// getApplicationLog returns the contract log based on the specified txid or blockid. // getApplicationLog returns the contract log based on the specified txid or blockid.
func (s *Server) getApplicationLog(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getApplicationLog(reqParams params.Params) (interface{}, *response.Error) {
hash, err := reqParams.Value(0).GetUint256() hash, err := reqParams.Value(0).GetUint256()
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -779,7 +780,7 @@ func (s *Server) getNEP11Tokens(h util.Uint160, acc util.Uint160, bw *io.BufBinW
return vals, sym, int(dec.Int64()), nil return vals, sym, int(dec.Int64()), nil
} }
func (s *Server) getNEP11Balances(ps request.Params) (interface{}, *response.Error) { func (s *Server) getNEP11Balances(ps params.Params) (interface{}, *response.Error) {
u, err := ps.Value(0).GetUint160FromAddressOrHex() u, err := ps.Value(0).GetUint160FromAddressOrHex()
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -868,7 +869,7 @@ func (s *Server) invokeNEP11Properties(h util.Uint160, id []byte, bw *io.BufBinW
return item.Value().([]stackitem.MapElement), nil return item.Value().([]stackitem.MapElement), nil
} }
func (s *Server) getNEP11Properties(ps request.Params) (interface{}, *response.Error) { func (s *Server) getNEP11Properties(ps params.Params) (interface{}, *response.Error) {
asset, err := ps.Value(0).GetUint160FromAddressOrHex() asset, err := ps.Value(0).GetUint160FromAddressOrHex()
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -904,7 +905,7 @@ func (s *Server) getNEP11Properties(ps request.Params) (interface{}, *response.E
return res, nil return res, nil
} }
func (s *Server) getNEP17Balances(ps request.Params) (interface{}, *response.Error) { func (s *Server) getNEP17Balances(ps params.Params) (interface{}, *response.Error) {
u, err := ps.Value(0).GetUint160FromAddressOrHex() u, err := ps.Value(0).GetUint160FromAddressOrHex()
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -1034,7 +1035,7 @@ func (s *Server) getNEP11DTokenBalance(h util.Uint160, acc util.Uint160, id []by
return res, nil return res, nil
} }
func getTimestampsAndLimit(ps request.Params, index int) (uint64, uint64, int, int, error) { func getTimestampsAndLimit(ps params.Params, index int) (uint64, uint64, int, int, error) {
var start, end uint64 var start, end uint64
var limit, page int var limit, page int
@ -1084,15 +1085,15 @@ func getTimestampsAndLimit(ps request.Params, index int) (uint64, uint64, int, i
return start, end, limit, page, nil return start, end, limit, page, nil
} }
func (s *Server) getNEP11Transfers(ps request.Params) (interface{}, *response.Error) { func (s *Server) getNEP11Transfers(ps params.Params) (interface{}, *response.Error) {
return s.getTokenTransfers(ps, true) return s.getTokenTransfers(ps, true)
} }
func (s *Server) getNEP17Transfers(ps request.Params) (interface{}, *response.Error) { func (s *Server) getNEP17Transfers(ps params.Params) (interface{}, *response.Error) {
return s.getTokenTransfers(ps, false) return s.getTokenTransfers(ps, false)
} }
func (s *Server) getTokenTransfers(ps request.Params, isNEP11 bool) (interface{}, *response.Error) { func (s *Server) getTokenTransfers(ps params.Params, isNEP11 bool) (interface{}, *response.Error) {
u, err := ps.Value(0).GetUint160FromAddressOrHex() u, err := ps.Value(0).GetUint160FromAddressOrHex()
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -1209,7 +1210,7 @@ func (s *Server) getHash(contractID int32, cache map[int32]util.Uint160) (util.U
return h, nil return h, nil
} }
func (s *Server) contractIDFromParam(param *request.Param) (int32, *response.Error) { func (s *Server) contractIDFromParam(param *params.Param) (int32, *response.Error) {
var result int32 var result int32
if param == nil { if param == nil {
return 0, response.ErrInvalidParams return 0, response.ErrInvalidParams
@ -1234,7 +1235,7 @@ func (s *Server) contractIDFromParam(param *request.Param) (int32, *response.Err
} }
// getContractScriptHashFromParam returns the contract script hash by hex contract hash, address, id or native contract name. // getContractScriptHashFromParam returns the contract script hash by hex contract hash, address, id or native contract name.
func (s *Server) contractScriptHashFromParam(param *request.Param) (util.Uint160, *response.Error) { func (s *Server) contractScriptHashFromParam(param *params.Param) (util.Uint160, *response.Error) {
var result util.Uint160 var result util.Uint160
if param == nil { if param == nil {
return result, response.ErrInvalidParams return result, response.ErrInvalidParams
@ -1274,7 +1275,7 @@ func makeStorageKey(id int32, key []byte) []byte {
var errKeepOnlyLatestState = errors.New("'KeepOnlyLatestState' setting is enabled") var errKeepOnlyLatestState = errors.New("'KeepOnlyLatestState' setting is enabled")
func (s *Server) getProof(ps request.Params) (interface{}, *response.Error) { func (s *Server) getProof(ps params.Params) (interface{}, *response.Error) {
if s.chain.GetConfig().KeepOnlyLatestState { if s.chain.GetConfig().KeepOnlyLatestState {
return nil, response.NewInvalidRequestError(fmt.Sprintf("'getproof' is not supported: %s", errKeepOnlyLatestState)) return nil, response.NewInvalidRequestError(fmt.Sprintf("'getproof' is not supported: %s", errKeepOnlyLatestState))
} }
@ -1305,7 +1306,7 @@ func (s *Server) getProof(ps request.Params) (interface{}, *response.Error) {
}, nil }, nil
} }
func (s *Server) verifyProof(ps request.Params) (interface{}, *response.Error) { func (s *Server) verifyProof(ps params.Params) (interface{}, *response.Error) {
if s.chain.GetConfig().KeepOnlyLatestState { if s.chain.GetConfig().KeepOnlyLatestState {
return nil, response.NewInvalidRequestError(fmt.Sprintf("'verifyproof' is not supported: %s", errKeepOnlyLatestState)) return nil, response.NewInvalidRequestError(fmt.Sprintf("'verifyproof' is not supported: %s", errKeepOnlyLatestState))
} }
@ -1329,7 +1330,7 @@ func (s *Server) verifyProof(ps request.Params) (interface{}, *response.Error) {
return vp, nil return vp, nil
} }
func (s *Server) getState(ps request.Params) (interface{}, *response.Error) { func (s *Server) getState(ps params.Params) (interface{}, *response.Error) {
root, err := ps.Value(0).GetUint256() root, err := ps.Value(0).GetUint256()
if err != nil { if err != nil {
return nil, response.WrapErrorWithData(response.ErrInvalidParams, "invalid stateroot") return nil, response.WrapErrorWithData(response.ErrInvalidParams, "invalid stateroot")
@ -1363,7 +1364,7 @@ func (s *Server) getState(ps request.Params) (interface{}, *response.Error) {
return res, nil return res, nil
} }
func (s *Server) findStates(ps request.Params) (interface{}, *response.Error) { func (s *Server) findStates(ps params.Params) (interface{}, *response.Error) {
root, err := ps.Value(0).GetUint256() root, err := ps.Value(0).GetUint256()
if err != nil { if err != nil {
return nil, response.WrapErrorWithData(response.ErrInvalidParams, "invalid stateroot") return nil, response.WrapErrorWithData(response.ErrInvalidParams, "invalid stateroot")
@ -1471,7 +1472,7 @@ func (s *Server) getHistoricalContractState(root util.Uint256, csHash util.Uint1
return contract, nil return contract, nil
} }
func (s *Server) getStateHeight(_ request.Params) (interface{}, *response.Error) { func (s *Server) getStateHeight(_ params.Params) (interface{}, *response.Error) {
var height = s.chain.BlockHeight() var height = s.chain.BlockHeight()
var stateHeight = s.chain.GetStateModule().CurrentValidatedHeight() var stateHeight = s.chain.GetStateModule().CurrentValidatedHeight()
if s.chain.GetConfig().StateRootInHeader { if s.chain.GetConfig().StateRootInHeader {
@ -1483,7 +1484,7 @@ func (s *Server) getStateHeight(_ request.Params) (interface{}, *response.Error)
}, nil }, nil
} }
func (s *Server) getStateRoot(ps request.Params) (interface{}, *response.Error) { func (s *Server) getStateRoot(ps params.Params) (interface{}, *response.Error) {
p := ps.Value(0) p := ps.Value(0)
if p == nil { if p == nil {
return nil, response.NewInvalidParamsError("missing stateroot identifier") return nil, response.NewInvalidParamsError("missing stateroot identifier")
@ -1509,7 +1510,7 @@ func (s *Server) getStateRoot(ps request.Params) (interface{}, *response.Error)
return rt, nil return rt, nil
} }
func (s *Server) getStorage(ps request.Params) (interface{}, *response.Error) { func (s *Server) getStorage(ps params.Params) (interface{}, *response.Error) {
id, rErr := s.contractIDFromParam(ps.Value(0)) id, rErr := s.contractIDFromParam(ps.Value(0))
if rErr == response.ErrUnknown { if rErr == response.ErrUnknown {
return nil, nil return nil, nil
@ -1531,7 +1532,7 @@ func (s *Server) getStorage(ps request.Params) (interface{}, *response.Error) {
return []byte(item), nil return []byte(item), nil
} }
func (s *Server) getrawtransaction(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getrawtransaction(reqParams params.Params) (interface{}, *response.Error) {
txHash, err := reqParams.Value(0).GetUint256() txHash, err := reqParams.Value(0).GetUint256()
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -1561,7 +1562,7 @@ func (s *Server) getrawtransaction(reqParams request.Params) (interface{}, *resp
return tx.Bytes(), nil return tx.Bytes(), nil
} }
func (s *Server) getTransactionHeight(ps request.Params) (interface{}, *response.Error) { func (s *Server) getTransactionHeight(ps params.Params) (interface{}, *response.Error) {
h, err := ps.Value(0).GetUint256() h, err := ps.Value(0).GetUint256()
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -1577,7 +1578,7 @@ func (s *Server) getTransactionHeight(ps request.Params) (interface{}, *response
// getContractState returns contract state (contract information, according to the contract script hash, // getContractState returns contract state (contract information, according to the contract script hash,
// contract id or native contract name). // contract id or native contract name).
func (s *Server) getContractState(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getContractState(reqParams params.Params) (interface{}, *response.Error) {
scriptHash, err := s.contractScriptHashFromParam(reqParams.Value(0)) scriptHash, err := s.contractScriptHashFromParam(reqParams.Value(0))
if err != nil { if err != nil {
return nil, err return nil, err
@ -1589,12 +1590,12 @@ func (s *Server) getContractState(reqParams request.Params) (interface{}, *respo
return cs, nil return cs, nil
} }
func (s *Server) getNativeContracts(_ request.Params) (interface{}, *response.Error) { func (s *Server) getNativeContracts(_ params.Params) (interface{}, *response.Error) {
return s.chain.GetNatives(), nil return s.chain.GetNatives(), nil
} }
// getBlockSysFee returns the system fees of the block, based on the specified index. // getBlockSysFee returns the system fees of the block, based on the specified index.
func (s *Server) getBlockSysFee(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getBlockSysFee(reqParams params.Params) (interface{}, *response.Error) {
num, err := s.blockHeightFromParam(reqParams.Value(0)) num, err := s.blockHeightFromParam(reqParams.Value(0))
if err != nil { if err != nil {
return 0, response.NewRPCError("Invalid height", "invalid block identifier") return 0, response.NewRPCError("Invalid height", "invalid block identifier")
@ -1615,7 +1616,7 @@ func (s *Server) getBlockSysFee(reqParams request.Params) (interface{}, *respons
} }
// getBlockHeader returns the corresponding block header information according to the specified script hash. // getBlockHeader returns the corresponding block header information according to the specified script hash.
func (s *Server) getBlockHeader(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getBlockHeader(reqParams params.Params) (interface{}, *response.Error) {
param := reqParams.Value(0) param := reqParams.Value(0)
hash, respErr := s.blockHashFromParam(param) hash, respErr := s.blockHashFromParam(param)
if respErr != nil { if respErr != nil {
@ -1641,7 +1642,7 @@ func (s *Server) getBlockHeader(reqParams request.Params) (interface{}, *respons
} }
// getUnclaimedGas returns unclaimed GAS amount of the specified address. // getUnclaimedGas returns unclaimed GAS amount of the specified address.
func (s *Server) getUnclaimedGas(ps request.Params) (interface{}, *response.Error) { func (s *Server) getUnclaimedGas(ps params.Params) (interface{}, *response.Error) {
u, err := ps.Value(0).GetUint160FromAddressOrHex() u, err := ps.Value(0).GetUint160FromAddressOrHex()
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -1664,7 +1665,7 @@ func (s *Server) getUnclaimedGas(ps request.Params) (interface{}, *response.Erro
} }
// getCandidates returns the current list of candidates with their active/inactive voting status. // getCandidates returns the current list of candidates with their active/inactive voting status.
func (s *Server) getCandidates(_ request.Params) (interface{}, *response.Error) { func (s *Server) getCandidates(_ params.Params) (interface{}, *response.Error) {
var validators keys.PublicKeys var validators keys.PublicKeys
validators, err := s.chain.GetNextBlockValidators() validators, err := s.chain.GetNextBlockValidators()
@ -1687,7 +1688,7 @@ func (s *Server) getCandidates(_ request.Params) (interface{}, *response.Error)
} }
// getNextBlockValidators returns validators for the next block with voting status. // getNextBlockValidators returns validators for the next block with voting status.
func (s *Server) getNextBlockValidators(_ request.Params) (interface{}, *response.Error) { func (s *Server) getNextBlockValidators(_ params.Params) (interface{}, *response.Error) {
var validators keys.PublicKeys var validators keys.PublicKeys
validators, err := s.chain.GetNextBlockValidators() validators, err := s.chain.GetNextBlockValidators()
@ -1712,7 +1713,7 @@ func (s *Server) getNextBlockValidators(_ request.Params) (interface{}, *respons
} }
// getCommittee returns the current list of NEO committee members. // getCommittee returns the current list of NEO committee members.
func (s *Server) getCommittee(_ request.Params) (interface{}, *response.Error) { func (s *Server) getCommittee(_ params.Params) (interface{}, *response.Error) {
keys, err := s.chain.GetCommittee() keys, err := s.chain.GetCommittee()
if err != nil { if err != nil {
return nil, response.NewInternalServerError(fmt.Sprintf("can't get committee members: %s", err)) return nil, response.NewInternalServerError(fmt.Sprintf("can't get committee members: %s", err))
@ -1721,7 +1722,7 @@ func (s *Server) getCommittee(_ request.Params) (interface{}, *response.Error) {
} }
// invokeFunction implements the `invokeFunction` RPC call. // invokeFunction implements the `invokeFunction` RPC call.
func (s *Server) invokeFunction(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) invokeFunction(reqParams params.Params) (interface{}, *response.Error) {
tx, verbose, respErr := s.getInvokeFunctionParams(reqParams) tx, verbose, respErr := s.getInvokeFunctionParams(reqParams)
if respErr != nil { if respErr != nil {
return nil, respErr return nil, respErr
@ -1730,7 +1731,7 @@ func (s *Server) invokeFunction(reqParams request.Params) (interface{}, *respons
} }
// invokeFunctionHistoric implements the `invokeFunctionHistoric` RPC call. // invokeFunctionHistoric implements the `invokeFunctionHistoric` RPC call.
func (s *Server) invokeFunctionHistoric(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) invokeFunctionHistoric(reqParams params.Params) (interface{}, *response.Error) {
b, respErr := s.getHistoricParams(reqParams) b, respErr := s.getHistoricParams(reqParams)
if respErr != nil { if respErr != nil {
return nil, respErr return nil, respErr
@ -1745,7 +1746,7 @@ func (s *Server) invokeFunctionHistoric(reqParams request.Params) (interface{},
return s.runScriptInVM(trigger.Application, tx.Script, util.Uint160{}, tx, b, verbose) return s.runScriptInVM(trigger.Application, tx.Script, util.Uint160{}, tx, b, verbose)
} }
func (s *Server) getInvokeFunctionParams(reqParams request.Params) (*transaction.Transaction, bool, *response.Error) { func (s *Server) getInvokeFunctionParams(reqParams params.Params) (*transaction.Transaction, bool, *response.Error) {
if len(reqParams) < 2 { if len(reqParams) < 2 {
return nil, false, response.ErrInvalidParams return nil, false, response.ErrInvalidParams
} }
@ -1757,9 +1758,9 @@ func (s *Server) getInvokeFunctionParams(reqParams request.Params) (*transaction
if err != nil { if err != nil {
return nil, false, response.ErrInvalidParams return nil, false, response.ErrInvalidParams
} }
var params *request.Param var invparams *params.Param
if len(reqParams) > 2 { if len(reqParams) > 2 {
params = &reqParams[2] invparams = &reqParams[2]
} }
tx := &transaction.Transaction{} tx := &transaction.Transaction{}
if len(reqParams) > 3 { if len(reqParams) > 3 {
@ -1779,7 +1780,7 @@ func (s *Server) getInvokeFunctionParams(reqParams request.Params) (*transaction
if len(tx.Signers) == 0 { if len(tx.Signers) == 0 {
tx.Signers = []transaction.Signer{{Account: util.Uint160{}, Scopes: transaction.None}} tx.Signers = []transaction.Signer{{Account: util.Uint160{}, Scopes: transaction.None}}
} }
script, err := request.CreateFunctionInvocationScript(scriptHash, method, params) script, err := params.CreateFunctionInvocationScript(scriptHash, method, invparams)
if err != nil { if err != nil {
return nil, false, response.NewInternalServerError(fmt.Sprintf("can't create invocation script: %s", err)) return nil, false, response.NewInternalServerError(fmt.Sprintf("can't create invocation script: %s", err))
} }
@ -1788,7 +1789,7 @@ func (s *Server) getInvokeFunctionParams(reqParams request.Params) (*transaction
} }
// invokescript implements the `invokescript` RPC call. // invokescript implements the `invokescript` RPC call.
func (s *Server) invokescript(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) invokescript(reqParams params.Params) (interface{}, *response.Error) {
tx, verbose, respErr := s.getInvokeScriptParams(reqParams) tx, verbose, respErr := s.getInvokeScriptParams(reqParams)
if respErr != nil { if respErr != nil {
return nil, respErr return nil, respErr
@ -1797,7 +1798,7 @@ func (s *Server) invokescript(reqParams request.Params) (interface{}, *response.
} }
// invokescripthistoric implements the `invokescripthistoric` RPC call. // invokescripthistoric implements the `invokescripthistoric` RPC call.
func (s *Server) invokescripthistoric(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) invokescripthistoric(reqParams params.Params) (interface{}, *response.Error) {
b, respErr := s.getHistoricParams(reqParams) b, respErr := s.getHistoricParams(reqParams)
if respErr != nil { if respErr != nil {
return nil, respErr return nil, respErr
@ -1812,7 +1813,7 @@ func (s *Server) invokescripthistoric(reqParams request.Params) (interface{}, *r
return s.runScriptInVM(trigger.Application, tx.Script, util.Uint160{}, tx, b, verbose) return s.runScriptInVM(trigger.Application, tx.Script, util.Uint160{}, tx, b, verbose)
} }
func (s *Server) getInvokeScriptParams(reqParams request.Params) (*transaction.Transaction, bool, *response.Error) { func (s *Server) getInvokeScriptParams(reqParams params.Params) (*transaction.Transaction, bool, *response.Error) {
script, err := reqParams.Value(0).GetBytesBase64() script, err := reqParams.Value(0).GetBytesBase64()
if err != nil { if err != nil {
return nil, false, response.ErrInvalidParams return nil, false, response.ErrInvalidParams
@ -1842,7 +1843,7 @@ func (s *Server) getInvokeScriptParams(reqParams request.Params) (*transaction.T
} }
// invokeContractVerify implements the `invokecontractverify` RPC call. // invokeContractVerify implements the `invokecontractverify` RPC call.
func (s *Server) invokeContractVerify(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) invokeContractVerify(reqParams params.Params) (interface{}, *response.Error) {
scriptHash, tx, invocationScript, respErr := s.getInvokeContractVerifyParams(reqParams) scriptHash, tx, invocationScript, respErr := s.getInvokeContractVerifyParams(reqParams)
if respErr != nil { if respErr != nil {
return nil, respErr return nil, respErr
@ -1851,7 +1852,7 @@ func (s *Server) invokeContractVerify(reqParams request.Params) (interface{}, *r
} }
// invokeContractVerifyHistoric implements the `invokecontractverifyhistoric` RPC call. // invokeContractVerifyHistoric implements the `invokecontractverifyhistoric` RPC call.
func (s *Server) invokeContractVerifyHistoric(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) invokeContractVerifyHistoric(reqParams params.Params) (interface{}, *response.Error) {
b, respErr := s.getHistoricParams(reqParams) b, respErr := s.getHistoricParams(reqParams)
if respErr != nil { if respErr != nil {
return nil, respErr return nil, respErr
@ -1866,7 +1867,7 @@ func (s *Server) invokeContractVerifyHistoric(reqParams request.Params) (interfa
return s.runScriptInVM(trigger.Verification, invocationScript, scriptHash, tx, b, false) return s.runScriptInVM(trigger.Verification, invocationScript, scriptHash, tx, b, false)
} }
func (s *Server) getInvokeContractVerifyParams(reqParams request.Params) (util.Uint160, *transaction.Transaction, []byte, *response.Error) { func (s *Server) getInvokeContractVerifyParams(reqParams params.Params) (util.Uint160, *transaction.Transaction, []byte, *response.Error) {
scriptHash, responseErr := s.contractScriptHashFromParam(reqParams.Value(0)) scriptHash, responseErr := s.contractScriptHashFromParam(reqParams.Value(0))
if responseErr != nil { if responseErr != nil {
return util.Uint160{}, nil, nil, responseErr return util.Uint160{}, nil, nil, responseErr
@ -1879,7 +1880,7 @@ func (s *Server) getInvokeContractVerifyParams(reqParams request.Params) (util.U
return util.Uint160{}, nil, nil, response.WrapErrorWithData(response.ErrInvalidParams, err.Error()) return util.Uint160{}, nil, nil, response.WrapErrorWithData(response.ErrInvalidParams, err.Error())
} }
if len(args) > 0 { if len(args) > 0 {
err := request.ExpandArrayIntoScript(bw.BinWriter, args) err := params.ExpandArrayIntoScript(bw.BinWriter, args)
if err != nil { if err != nil {
return util.Uint160{}, nil, nil, response.NewInternalServerError(fmt.Sprintf("can't create witness invocation script: %s", err)) return util.Uint160{}, nil, nil, response.NewInternalServerError(fmt.Sprintf("can't create witness invocation script: %s", err))
} }
@ -1906,7 +1907,7 @@ func (s *Server) getInvokeContractVerifyParams(reqParams request.Params) (util.U
// with the specified index to perform the historic call. It also checks that // with the specified index to perform the historic call. It also checks that
// specified stateroot is stored at the specified height for further request // specified stateroot is stored at the specified height for further request
// handling consistency. // handling consistency.
func (s *Server) getHistoricParams(reqParams request.Params) (*block.Block, *response.Error) { func (s *Server) getHistoricParams(reqParams params.Params) (*block.Block, *response.Error) {
if s.chain.GetConfig().KeepOnlyLatestState { if s.chain.GetConfig().KeepOnlyLatestState {
return nil, response.NewInvalidRequestError(fmt.Sprintf("only latest state is supported: %s", errKeepOnlyLatestState)) return nil, response.NewInvalidRequestError(fmt.Sprintf("only latest state is supported: %s", errKeepOnlyLatestState))
} }
@ -2065,7 +2066,7 @@ func (s *Server) runScriptInVM(t trigger.Type, script []byte, contractScriptHash
return result.NewInvoke(ic, script, faultException, registerIterator, s.config.MaxIteratorResultItems), nil return result.NewInvoke(ic, script, faultException, registerIterator, s.config.MaxIteratorResultItems), nil
} }
func (s *Server) traverseIterator(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) traverseIterator(reqParams params.Params) (interface{}, *response.Error) {
if !s.config.SessionEnabled { if !s.config.SessionEnabled {
return nil, response.NewInvalidRequestError("sessions are disabled") return nil, response.NewInvalidRequestError("sessions are disabled")
} }
@ -2154,7 +2155,7 @@ func (s *Server) traverseIterator(reqParams request.Params) (interface{}, *respo
return result, nil return result, nil
} }
func (s *Server) terminateSession(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) terminateSession(reqParams params.Params) (interface{}, *response.Error) {
if !s.config.SessionEnabled { if !s.config.SessionEnabled {
return nil, response.NewInvalidRequestError("sessions are disabled") return nil, response.NewInvalidRequestError("sessions are disabled")
} }
@ -2183,7 +2184,7 @@ func (s *Server) terminateSession(reqParams request.Params) (interface{}, *respo
} }
// submitBlock broadcasts a raw block over the NEO network. // submitBlock broadcasts a raw block over the NEO network.
func (s *Server) submitBlock(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) submitBlock(reqParams params.Params) (interface{}, *response.Error) {
blockBytes, err := reqParams.Value(0).GetBytesBase64() blockBytes, err := reqParams.Value(0).GetBytesBase64()
if err != nil { if err != nil {
return nil, response.NewInvalidParamsError(fmt.Sprintf("missing parameter or not a base64: %s", err)) return nil, response.NewInvalidParamsError(fmt.Sprintf("missing parameter or not a base64: %s", err))
@ -2209,7 +2210,7 @@ func (s *Server) submitBlock(reqParams request.Params) (interface{}, *response.E
} }
// submitNotaryRequest broadcasts P2PNotaryRequest over the NEO network. // submitNotaryRequest broadcasts P2PNotaryRequest over the NEO network.
func (s *Server) submitNotaryRequest(ps request.Params) (interface{}, *response.Error) { func (s *Server) submitNotaryRequest(ps params.Params) (interface{}, *response.Error) {
if !s.chain.P2PSigExtensionsEnabled() { if !s.chain.P2PSigExtensionsEnabled() {
return nil, response.NewRPCError("P2PSignatureExtensions are disabled", "") return nil, response.NewRPCError("P2PSignatureExtensions are disabled", "")
} }
@ -2243,7 +2244,7 @@ func getRelayResult(err error, hash util.Uint256) (interface{}, *response.Error)
} }
} }
func (s *Server) submitOracleResponse(ps request.Params) (interface{}, *response.Error) { func (s *Server) submitOracleResponse(ps params.Params) (interface{}, *response.Error) {
if s.oracle == nil { if s.oracle == nil {
return nil, response.NewRPCError("Oracle is not enabled", "") return nil, response.NewRPCError("Oracle is not enabled", "")
} }
@ -2275,7 +2276,7 @@ func (s *Server) submitOracleResponse(ps request.Params) (interface{}, *response
return json.RawMessage([]byte("{}")), nil return json.RawMessage([]byte("{}")), nil
} }
func (s *Server) sendrawtransaction(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) sendrawtransaction(reqParams params.Params) (interface{}, *response.Error) {
if len(reqParams) < 1 { if len(reqParams) < 1 {
return nil, response.NewInvalidParamsError("not enough parameters") return nil, response.NewInvalidParamsError("not enough parameters")
} }
@ -2291,7 +2292,7 @@ func (s *Server) sendrawtransaction(reqParams request.Params) (interface{}, *res
} }
// subscribe handles subscription requests from websocket clients. // subscribe handles subscription requests from websocket clients.
func (s *Server) subscribe(reqParams request.Params, sub *subscriber) (interface{}, *response.Error) { func (s *Server) subscribe(reqParams params.Params, sub *subscriber) (interface{}, *response.Error) {
streamName, err := reqParams.Value(0).GetString() streamName, err := reqParams.Value(0).GetString()
if err != nil { if err != nil {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -2392,7 +2393,7 @@ func (s *Server) subscribeToChannel(event response.EventID) {
} }
// unsubscribe handles unsubscription requests from websocket clients. // unsubscribe handles unsubscription requests from websocket clients.
func (s *Server) unsubscribe(reqParams request.Params, sub *subscriber) (interface{}, *response.Error) { func (s *Server) unsubscribe(reqParams params.Params, sub *subscriber) (interface{}, *response.Error) {
id, err := reqParams.Value(0).GetInt() id, err := reqParams.Value(0).GetInt()
if err != nil || id < 0 { if err != nil || id < 0 {
return nil, response.ErrInvalidParams return nil, response.ErrInvalidParams
@ -2562,7 +2563,7 @@ drainloop:
close(s.notaryRequestCh) close(s.notaryRequestCh)
} }
func (s *Server) blockHeightFromParam(param *request.Param) (int, *response.Error) { func (s *Server) blockHeightFromParam(param *params.Param) (int, *response.Error) {
num, err := param.GetInt() num, err := param.GetInt()
if err != nil { if err != nil {
return 0, response.ErrInvalidParams return 0, response.ErrInvalidParams
@ -2574,7 +2575,7 @@ func (s *Server) blockHeightFromParam(param *request.Param) (int, *response.Erro
return num, nil return num, nil
} }
func (s *Server) packResponse(r *request.In, result interface{}, respErr *response.Error) abstract { func (s *Server) packResponse(r *params.In, result interface{}, respErr *response.Error) abstract {
resp := abstract{ resp := abstract{
Header: response.Header{ Header: response.Header{
JSONRPC: r.JSONRPC, JSONRPC: r.JSONRPC,
@ -2590,7 +2591,7 @@ func (s *Server) packResponse(r *request.In, result interface{}, respErr *respon
} }
// logRequestError is a request error logger. // logRequestError is a request error logger.
func (s *Server) logRequestError(r *request.Request, jsonErr *response.Error) { func (s *Server) logRequestError(r *params.Request, jsonErr *response.Error) {
logFields := []zap.Field{ logFields := []zap.Field{
zap.Int64("code", jsonErr.Code), zap.Int64("code", jsonErr.Code),
} }
@ -2600,7 +2601,7 @@ func (s *Server) logRequestError(r *request.Request, jsonErr *response.Error) {
if r.In != nil { if r.In != nil {
logFields = append(logFields, zap.String("method", r.In.Method)) logFields = append(logFields, zap.String("method", r.In.Method))
params := request.Params(r.In.RawParams) params := params.Params(r.In.RawParams)
logFields = append(logFields, zap.Any("params", params)) logFields = append(logFields, zap.Any("params", params))
} }
@ -2614,12 +2615,12 @@ func (s *Server) logRequestError(r *request.Request, jsonErr *response.Error) {
} }
// writeHTTPErrorResponse writes an error response to the ResponseWriter. // writeHTTPErrorResponse writes an error response to the ResponseWriter.
func (s *Server) writeHTTPErrorResponse(r *request.In, w http.ResponseWriter, jsonErr *response.Error) { func (s *Server) writeHTTPErrorResponse(r *params.In, w http.ResponseWriter, jsonErr *response.Error) {
resp := s.packResponse(r, nil, jsonErr) resp := s.packResponse(r, nil, jsonErr)
s.writeHTTPServerResponse(&request.Request{In: r}, w, resp) s.writeHTTPServerResponse(&params.Request{In: r}, w, resp)
} }
func (s *Server) writeHTTPServerResponse(r *request.Request, w http.ResponseWriter, resp abstractResult) { func (s *Server) writeHTTPServerResponse(r *params.Request, w http.ResponseWriter, resp abstractResult) {
// Errors can happen in many places and we can only catch ALL of them here. // Errors can happen in many places and we can only catch ALL of them here.
resp.RunForErrors(func(jsonErr *response.Error) { resp.RunForErrors(func(jsonErr *response.Error) {
s.logRequestError(r, jsonErr) s.logRequestError(r, jsonErr)

View file

@ -35,9 +35,9 @@ import (
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/network" "github.com/nspcc-dev/neo-go/pkg/network"
"github.com/nspcc-dev/neo-go/pkg/network/payload" "github.com/nspcc-dev/neo-go/pkg/network/payload"
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
"github.com/nspcc-dev/neo-go/pkg/rpc/response" "github.com/nspcc-dev/neo-go/pkg/rpc/response"
"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/rpc/server/params"
rpc2 "github.com/nspcc-dev/neo-go/pkg/services/oracle/broadcaster" rpc2 "github.com/nspcc-dev/neo-go/pkg/services/oracle/broadcaster"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
@ -3138,7 +3138,7 @@ func BenchmarkHandleIn(b *testing.B) {
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
b.StopTimer() b.StopTimer()
in := new(request.In) in := new(params.In)
b.StartTimer() b.StartTimer()
err := json.Unmarshal(req, in) err := json.Unmarshal(req, in)
if err != nil { if err != nil {

View file

@ -3,7 +3,6 @@ package rpcbroadcaster
import ( import (
"time" "time"
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -11,7 +10,7 @@ import (
type RPCBroadcaster struct { type RPCBroadcaster struct {
Clients map[string]*RPCClient Clients map[string]*RPCClient
Log *zap.Logger Log *zap.Logger
Responses chan request.RawParams Responses chan []interface{}
close chan struct{} close chan struct{}
finished chan struct{} finished chan struct{}
@ -25,7 +24,7 @@ func NewRPCBroadcaster(log *zap.Logger, sendTimeout time.Duration) *RPCBroadcast
Log: log, Log: log,
close: make(chan struct{}), close: make(chan struct{}),
finished: make(chan struct{}), finished: make(chan struct{}),
Responses: make(chan request.RawParams), Responses: make(chan []interface{}),
sendTimeout: sendTimeout, sendTimeout: sendTimeout,
} }
} }
@ -66,7 +65,7 @@ drain:
} }
// SendParams sends a request using all clients if the broadcaster is active. // SendParams sends a request using all clients if the broadcaster is active.
func (r *RPCBroadcaster) SendParams(params request.RawParams) { func (r *RPCBroadcaster) SendParams(params []interface{}) {
select { select {
case <-r.close: case <-r.close:
case r.Responses <- params: case r.Responses <- params:

View file

@ -5,7 +5,6 @@ import (
"time" "time"
"github.com/nspcc-dev/neo-go/pkg/rpc/client" "github.com/nspcc-dev/neo-go/pkg/rpc/client"
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -15,17 +14,17 @@ type RPCClient struct {
addr string addr string
close chan struct{} close chan struct{}
finished chan struct{} finished chan struct{}
responses chan request.RawParams responses chan []interface{}
log *zap.Logger log *zap.Logger
sendTimeout time.Duration sendTimeout time.Duration
method SendMethod method SendMethod
} }
// SendMethod represents an rpc method for sending data to other nodes. // SendMethod represents an rpc method for sending data to other nodes.
type SendMethod func(*client.Client, request.RawParams) error type SendMethod func(*client.Client, []interface{}) error
// NewRPCClient returns a new rpc client for the provided address and method. // NewRPCClient returns a new rpc client for the provided address and method.
func (r *RPCBroadcaster) NewRPCClient(addr string, method SendMethod, timeout time.Duration, ch chan request.RawParams) *RPCClient { func (r *RPCBroadcaster) NewRPCClient(addr string, method SendMethod, timeout time.Duration, ch chan []interface{}) *RPCClient {
return &RPCClient{ return &RPCClient{
addr: addr, addr: addr,
close: r.close, close: r.close,

View file

@ -9,7 +9,6 @@ import (
"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/rpc/client" "github.com/nspcc-dev/neo-go/pkg/rpc/client"
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
"github.com/nspcc-dev/neo-go/pkg/services/helpers/rpcbroadcaster" "github.com/nspcc-dev/neo-go/pkg/services/helpers/rpcbroadcaster"
"github.com/nspcc-dev/neo-go/pkg/services/oracle" "github.com/nspcc-dev/neo-go/pkg/services/oracle"
"go.uber.org/zap" "go.uber.org/zap"
@ -35,7 +34,7 @@ func New(cfg config.OracleConfiguration, log *zap.Logger) oracle.Broadcaster {
} }
for i := range cfg.Nodes { for i := range cfg.Nodes {
r.Clients[cfg.Nodes[i]] = r.NewRPCClient(cfg.Nodes[i], (*client.Client).SubmitRawOracleResponse, r.Clients[cfg.Nodes[i]] = r.NewRPCClient(cfg.Nodes[i], (*client.Client).SubmitRawOracleResponse,
cfg.ResponseTimeout, make(chan request.RawParams, defaultChanCapacity)) cfg.ResponseTimeout, make(chan []interface{}, defaultChanCapacity))
} }
return r return r
} }
@ -45,12 +44,12 @@ func (r *oracleBroadcaster) SendResponse(priv *keys.PrivateKey, resp *transactio
pub := priv.PublicKey() pub := priv.PublicKey()
data := GetMessage(pub.Bytes(), resp.ID, txSig) data := GetMessage(pub.Bytes(), resp.ID, txSig)
msgSig := priv.Sign(data) msgSig := priv.Sign(data)
params := request.NewRawParams( params := []interface{}{
base64.StdEncoding.EncodeToString(pub.Bytes()), base64.StdEncoding.EncodeToString(pub.Bytes()),
resp.ID, resp.ID,
base64.StdEncoding.EncodeToString(txSig), base64.StdEncoding.EncodeToString(txSig),
base64.StdEncoding.EncodeToString(msgSig), base64.StdEncoding.EncodeToString(msgSig),
) }
r.SendParams(params) r.SendParams(params)
} }