[pkg] Add two RPC methods, address golint issues, refactor types

pull/26/head
Edgar Aroutiounian 5 years ago
parent e6dee1c0f4
commit 2b1aad92f7
  1. 4
      pkg/rpc/handler.go
  2. 222
      pkg/rpc/methods.go
  3. 25
      pkg/rpc/query.go
  4. 2
      pkg/sharding/structure.go

@ -3,14 +3,14 @@ package rpc
type Reply map[string]interface{}
type T interface {
SendRPC(RPCMethod, []interface{}) (Reply, error)
SendRPC(string, []interface{}) (Reply, error)
}
type HTTPMessenger struct {
node string
}
func (M *HTTPMessenger) SendRPC(meth RPCMethod, params []interface{}) (Reply, error) {
func (M *HTTPMessenger) SendRPC(meth string, params []interface{}) (Reply, error) {
return Request(meth, M.node, params)
}

@ -1,52 +1,58 @@
package rpc
import (
"github.com/pkg/errors"
"fmt"
"github.com/pkg/errors"
)
// Adapted from https://github.com/harmony-one/sdk/blob/master/packages/harmony-network/src/rpcMethod/rpc.ts
type RPCMethod string
// Using alias for now
type method = string
type RPCErrorCode int
type errorCode int
type rpcEnumList struct {
GetShardingStructure RPCMethod
GetBlockByHash RPCMethod
GetBlockByNumber RPCMethod
GetBlockTransactionCountByHash RPCMethod
GetBlockTransactionCountByNumber RPCMethod
GetCode RPCMethod
GetTransactionByBlockHashAndIndex RPCMethod
GetTransactionByBlockNumberAndIndex RPCMethod
GetTransactionByHash RPCMethod
GetTransactionReceipt RPCMethod
Syncing RPCMethod
PeerCount RPCMethod
GetBalance RPCMethod
GetStorageAt RPCMethod
GetTransactionCount RPCMethod
SendTransaction RPCMethod
SendRawTransaction RPCMethod
Subscribe RPCMethod
GetPastLogs RPCMethod
GetWork RPCMethod
GetProof RPCMethod
GetFilterChanges RPCMethod
NewPendingTransactionFilter RPCMethod
NewBlockFilter RPCMethod
NewFilter RPCMethod
Call RPCMethod
EstimateGas RPCMethod
GasPrice RPCMethod
BlockNumber RPCMethod
UnSubscribe RPCMethod
NetVersion RPCMethod
ProtocolVersion RPCMethod
GetShardingStructure method
GetBlockByHash method
GetBlockByNumber method
GetBlockTransactionCountByHash method
GetBlockTransactionCountByNumber method
GetCode method
GetTransactionByBlockHashAndIndex method
GetTransactionByBlockNumberAndIndex method
GetTransactionByHash method
GetTransactionReceipt method
Syncing method
PeerCount method
GetBalance method
GetStorageAt method
GetTransactionCount method
SendTransaction method
SendRawTransaction method
Subscribe method
GetPastLogs method
GetWork method
GetProof method
GetFilterChanges method
NewPendingTransactionFilter method
NewBlockFilter method
NewFilter method
Call method
EstimateGas method
GasPrice method
BlockNumber method
UnSubscribe method
NetVersion method
ProtocolVersion method
GetNodeMetadata method
GetLatestBlockHeader method
}
// Method is a list of known RPC methods
var Method = rpcEnumList{
GetShardingStructure: "hmy_getShardingStructure",
GetNodeMetadata: "hmy_getNodeMetadata",
GetLatestBlockHeader: "hmy_latestHeader",
GetBlockByHash: "hmy_getBlockByHash",
GetBlockByNumber: "hmy_getBlockByNumber",
GetBlockTransactionCountByHash: "hmy_getBlockTransactionCountByHash",
@ -80,26 +86,37 @@ var Method = rpcEnumList{
ProtocolVersion: "hmy_protocolVersion",
}
// TODO Use Reflection here to avoid typing out the cases
// ValidatedMethod checks if given method is known
func ValidatedMethod(m method) string {
switch m := method(m); m {
default:
return string(m)
}
}
type rpcErrorCodeList struct {
rpcInvalidRequest RPCErrorCode
rpcMethodNotFound RPCErrorCode
rpcInvalidParams RPCErrorCode
rpcInternalError RPCErrorCode
rpcParseError RPCErrorCode
rpcMiscError RPCErrorCode
rpcTypeError RPCErrorCode
rpcInvalidAddressOrKey RPCErrorCode
rpcInvalidParameter RPCErrorCode
rpcDatabaseError RPCErrorCode
rpcDeserializationError RPCErrorCode
rpcVerifyError RPCErrorCode
rpcVerifyRejected RPCErrorCode
rpcInWarmup RPCErrorCode
rpcMethodDeprecated RPCErrorCode
rpcInvalidRequest errorCode
rpcMethodNotFound errorCode
rpcInvalidParams errorCode
rpcInternalError errorCode
rpcParseError errorCode
rpcMiscError errorCode
rpcTypeError errorCode
rpcInvalidAddressOrKey errorCode
rpcInvalidParameter errorCode
rpcDatabaseError errorCode
rpcDeserializationError errorCode
rpcVerifyError errorCode
rpcVerifyRejected errorCode
rpcInWarmup errorCode
rpcMethodDeprecated errorCode
rpcIncorrectChainID errorCode
}
// TODO Turn these error codes into error values in query.go
var ErrorCode = rpcErrorCodeList{
// TODO Do not punt on the field names
var errorCodeEnumeration = rpcErrorCodeList{
// Standard JSON-RPC 2.0 errors
// RPC_INVALID_REQUEST is internally mapped to HTTP_BAD_REQUEST (400).
// It should not be used for application-layer errors.
@ -107,80 +124,85 @@ var ErrorCode = rpcErrorCodeList{
// RPC_METHOD_NOT_FOUND is internally mapped to HTTP_NOT_FOUND (404).
// It should not be used for application-layer errors.
rpcMethodNotFound: -32601,
rpcInvalidParams: -32602,
rpcInvalidParams: -32602,
// RPC_INTERNAL_ERROR should only be used for genuine errors in bitcoind
// (for example datadir corruption).
rpcInternalError: -32603,
rpcParseError: -32700,
// General application defined errors
rpcMiscError: -1, // std::exception thrown in command handling
rpcTypeError: -3, // Unexpected type was passed as parameter
rpcInvalidAddressOrKey: -5, // Invalid address or key
rpcInvalidParameter: -8, // Invalid, missing or duplicate parameter
rpcDatabaseError: -20, // Database error
rpcDeserializationError: -22, // Error parsing or validating structure in raw format
rpcVerifyError: -25, // General error during transaction or block submission
rpcVerifyRejected: -26, // Transaction or block was rejected by network rules
rpcInWarmup: -28, // Client still warming up
rpcMethodDeprecated: -32, // RPC method is deprecated
rpcMiscError: -1, // std::exception thrown in command handling
rpcTypeError: -3, // Unexpected type was passed as parameter
rpcInvalidAddressOrKey: -5, // Invalid address or key
rpcInvalidParameter: -8, // Invalid, missing or duplicate parameter
rpcDatabaseError: -20, // Database error
rpcDeserializationError: -22, // Error parsing or validating structure in raw format
rpcVerifyError: -25, // General error during transaction or block submission
rpcVerifyRejected: -26, // Transaction or block was rejected by network rules
rpcInWarmup: -28, // Client still warming up
rpcMethodDeprecated: -32, // RPC method is deprecated
rpcIncorrectChainID: -32000,
}
const (
invalidRequestError = "Invalid Request object"
methodNotFoundError = "Method not found"
invalidParamsError = "Invalid method parameter(s)"
internalError = "Internal JSON-RPC error"
parseError = "Error while parsing the JSON text"
miscError = "std::exception thrown in command handling"
typeError = "Unexpected type was passed as parameter"
invalidAddressOrKeyError = "Invalid address or key"
invalidParameterError = "Invalid, missing or duplicate parameter"
databaseError = "Database error"
deserializationError = "Error parsing or validating structure in raw format"
verifyError = "General error during transaction or block submission"
verifyRejectedError = "Transaction or block was rejected by network rules"
rpcInWarmupError = "Client still warming up"
methodDeprecatedError = "RPC method is deprecated"
invalidRequestError = "Invalid Request object"
methodNotFoundError = "Method not found"
invalidParamsError = "Invalid method parameter(s)"
internalError = "Internal JSON-RPC error"
parseError = "Error while parsing the JSON text"
miscError = "std::exception thrown in command handling"
typeError = "Unexpected type was passed as parameter"
invalidAddressOrKeyError = "Invalid address or key"
invalidParameterError = "Invalid, missing or duplicate parameter"
databaseError = "Database error"
deserializationError = "Error parsing or validating structure in raw format"
verifyError = "General error during transaction or block submission"
verifyRejectedError = "Transaction or block was rejected by network rules"
rpcInWarmupError = "Client still warming up"
methodDeprecatedError = "RPC method deprecated"
wrongChain = "ChainID on node differs from received chainID"
)
func ErrorNumberToError(message string,err float64) error {
return errors.Wrap(errors.New(message),getErrorMessage(err))
// ErrorCodeToError lifts an untyped error code from RPC to Error value
func ErrorCodeToError(message string, code float64) error {
return errors.Wrap(errors.New(message), codeToMessage(code))
}
func getErrorMessage(err float64) string {
errorcode := RPCErrorCode(err)
switch errorcode {
case ErrorCode.rpcInvalidRequest:
// TODO Use reflection here instead of typing out the cases or at least a map
func codeToMessage(err float64) string {
switch e := errorCode(err); e {
case errorCodeEnumeration.rpcInvalidRequest:
return invalidRequestError
case ErrorCode.rpcMethodNotFound:
case errorCodeEnumeration.rpcMethodNotFound:
return methodNotFoundError
case ErrorCode.rpcInvalidParams:
case errorCodeEnumeration.rpcInvalidParams:
return invalidParamsError
case ErrorCode.rpcInternalError:
case errorCodeEnumeration.rpcInternalError:
return internalError
case ErrorCode.rpcParseError:
case errorCodeEnumeration.rpcParseError:
return parseError
case ErrorCode.rpcMiscError:
case errorCodeEnumeration.rpcMiscError:
return miscError
case ErrorCode.rpcTypeError:
case errorCodeEnumeration.rpcTypeError:
return typeError
case ErrorCode.rpcInvalidAddressOrKey:
case errorCodeEnumeration.rpcInvalidAddressOrKey:
return invalidAddressOrKeyError
case ErrorCode.rpcInvalidParameter:
case errorCodeEnumeration.rpcInvalidParameter:
return invalidParameterError
case ErrorCode.rpcDatabaseError:
case errorCodeEnumeration.rpcDatabaseError:
return databaseError
case ErrorCode.rpcDeserializationError:
case errorCodeEnumeration.rpcDeserializationError:
return deserializationError
case ErrorCode.rpcVerifyError:
case errorCodeEnumeration.rpcVerifyError:
return verifyError
case ErrorCode.rpcVerifyRejected:
case errorCodeEnumeration.rpcVerifyRejected:
return verifyRejectedError
case ErrorCode.rpcInWarmup:
case errorCodeEnumeration.rpcInWarmup:
return rpcInWarmupError
case ErrorCode.rpcMethodDeprecated:
case errorCodeEnumeration.rpcMethodDeprecated:
return methodDeprecatedError
case errorCodeEnumeration.rpcIncorrectChainID:
return wrongChain
default:
panic(fmt.Sprintf("Error number %v not found", err))
}
}
}

@ -15,7 +15,7 @@ var (
post = []byte("POST")
)
func baseRequest(method RPCMethod, node string, params interface{}) ([]byte, error) {
func baseRequest(method string, node string, params interface{}) ([]byte, error) {
requestBody, _ := json.Marshal(map[string]interface{}{
"jsonrpc": common.JSONRPCVersion,
"id": strconv.Itoa(queryID),
@ -36,36 +36,37 @@ func baseRequest(method RPCMethod, node string, params interface{}) ([]byte, err
body := res.Body()
result := make([]byte, len(body))
copy(result, body)
fasthttp.ReleaseResponse(res) // Only when you are done with body!
fasthttp.ReleaseResponse(res)
if common.DebugRPC {
fmt.Printf("URL: %s, Request Body: %s\n\n", node, string(requestBody))
}
if common.DebugRPC {
fmt.Printf("URL: %s, Response Body: %s\n\n", node, string(body))
}
queryID++
return result, nil
}
// TODO add the error code usage here, change return signature, make CLI be consumer that checks error
func Request(method RPCMethod, node string, params interface{}) (map[string]interface{}, error) {
rpcJson := make(map[string]interface{})
// TODO Check if Method known, return error when not known, good intern task
// Request processes
func Request(method string, node string, params interface{}) (Reply, error) {
rpcJSON := make(map[string]interface{})
rawReply, err := baseRequest(method, node, params)
if err != nil {
return nil, err
}
json.Unmarshal(rawReply, &rpcJson)
if oops := rpcJson["error"]; oops != nil {
json.Unmarshal(rawReply, &rpcJSON)
if oops := rpcJSON["error"]; oops != nil {
errNo := oops.(map[string]interface{})["code"].(float64)
errMessage := ""
if oops.(map[string]interface{})["message"] != nil {
errMessage = oops.(map[string]interface{})["message"].(string)
}
return nil, ErrorNumberToError(errMessage, errNo)
return nil, ErrorCodeToError(errMessage, errNo)
}
return rpcJson, nil
return rpcJSON, nil
}
func RawRequest(method RPCMethod, node string, params interface{}) ([]byte, error) {
// RawRequest is to sidestep the lifting done by Request
func RawRequest(method string, node string, params interface{}) ([]byte, error) {
return baseRequest(method, node, params)
}

@ -6,12 +6,14 @@ import (
"github.com/harmony-one/go-sdk/pkg/rpc"
)
// RPCRoutes reflects the RPC endpoints of the target network across shards
type RPCRoutes struct {
HTTP string `json:"http"`
ShardID int `json:"shardID"`
WS string `json:"ws"`
}
// Structure produces a slice of RPCRoutes for the network across shards
func Structure(node string) ([]RPCRoutes, error) {
type r struct {
Result []RPCRoutes `json:"result"`

Loading…
Cancel
Save