The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
woop/rpc/rpc.go

271 lines
7.3 KiB

package rpc
import (
"fmt"
"net"
"strings"
"time"
"github.com/harmony-one/harmony/eth/rpc"
"github.com/harmony-one/harmony/hmy"
"github.com/harmony-one/harmony/internal/configs/harmony"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/utils"
eth "github.com/harmony-one/harmony/rpc/eth"
v1 "github.com/harmony-one/harmony/rpc/v1"
v2 "github.com/harmony-one/harmony/rpc/v2"
)
// Version enum
const (
V1 Version = iota
V2
Eth
Debug
Trace
)
const (
// APIVersion used for DApp's, bumped after RPC refactor (7/2020)
APIVersion = "1.1"
// CallTimeout is the timeout given to all contract calls
CallTimeout = 5 * time.Second
// LogTag is the tag found in the log for all RPC logs
LogTag = "[RPC]"
// HTTPPortOffset ..
HTTPPortOffset = 500
// WSPortOffset ..
WSPortOffset = 800
netNamespace = "net"
netV1Namespace = "netv1"
netV2Namespace = "netv2"
web3Namespace = "web3"
)
var (
// HTTPModules ..
HTTPModules = []string{"hmy", "hmyv2", "eth", "debug", "trace", netNamespace, netV1Namespace, netV2Namespace, web3Namespace, "explorer"}
// WSModules ..
WSModules = []string{"hmy", "hmyv2", "eth", "debug", "trace", netNamespace, netV1Namespace, netV2Namespace, web3Namespace, "web3"}
httpListener net.Listener
httpHandler *rpc.Server
wsListener net.Listener
wsHandler *rpc.Server
httpEndpoint = ""
httpAuthEndpoint = ""
wsEndpoint = ""
wsAuthEndpoint = ""
httpVirtualHosts = []string{"*"}
httpTimeouts = rpc.DefaultHTTPTimeouts
httpOrigins = []string{"*"}
wsOrigins = []string{"*"}
)
// Version of the RPC
type Version int
// Namespace of the RPC version
func (n Version) Namespace() string {
return HTTPModules[n]
}
// StartServers starts the http & ws servers
func StartServers(hmy *hmy.Harmony, apis []rpc.API, config nodeconfig.RPCServerConfig, rpcOpt harmony.RpcOptConfig) error {
apis = append(apis, getAPIs(hmy, config)...)
authApis := append(apis, getAuthAPIs(hmy, config.DebugEnabled, config.RateLimiterEnabled, config.RequestsPerSecond)...)
// load method filter from file (if exist)
var rmf rpc.RpcMethodFilter
rpcFilterFilePath := strings.Trim(rpcOpt.RpcFilterFile, " ")
if len(rpcFilterFilePath) > 0 {
if err := rmf.LoadRpcMethodFiltersFromFile(rpcFilterFilePath); err != nil {
return err
}
} else {
rmf.ExposeAll()
}
if config.HTTPEnabled {
httpEndpoint = fmt.Sprintf("%v:%v", config.HTTPIp, config.HTTPPort)
if err := startHTTP(apis, &rmf); err != nil {
return err
}
httpAuthEndpoint = fmt.Sprintf("%v:%v", config.HTTPIp, config.HTTPAuthPort)
if err := startAuthHTTP(authApis, &rmf); err != nil {
return err
}
}
if config.WSEnabled {
wsEndpoint = fmt.Sprintf("%v:%v", config.WSIp, config.WSPort)
if err := startWS(apis, &rmf); err != nil {
return err
}
wsAuthEndpoint = fmt.Sprintf("%v:%v", config.WSIp, config.WSAuthPort)
if err := startAuthWS(authApis, &rmf); err != nil {
return err
}
}
return nil
}
// StopServers stops the http & ws servers
func StopServers() error {
if httpListener != nil {
if err := httpListener.Close(); err != nil {
return err
}
httpListener = nil
utils.Logger().Info().
Str("url", fmt.Sprintf("http://%s", httpEndpoint)).
Msg("HTTP endpoint closed")
}
if httpHandler != nil {
httpHandler.Stop()
httpHandler = nil
}
if wsListener != nil {
if err := wsListener.Close(); err != nil {
return err
}
wsListener = nil
utils.Logger().Info().
Str("url", fmt.Sprintf("http://%s", wsEndpoint)).
Msg("WS endpoint closed")
}
if wsHandler != nil {
wsHandler.Stop()
wsHandler = nil
}
return nil
}
func getAuthAPIs(hmy *hmy.Harmony, debugEnable bool, rateLimiterEnable bool, ratelimit int) []rpc.API {
return []rpc.API{
NewPublicTraceAPI(hmy, Debug), // Debug version means geth trace rpc
NewPublicTraceAPI(hmy, Trace), // Trace version means parity trace rpc
}
}
// getAPIs returns all the API methods for the RPC interface
func getAPIs(hmy *hmy.Harmony, config nodeconfig.RPCServerConfig) []rpc.API {
publicAPIs := []rpc.API{
// Public methods
NewPublicHarmonyAPI(hmy, V1),
NewPublicHarmonyAPI(hmy, V2),
NewPublicBlockchainAPI(hmy, V1, config.RateLimiterEnabled, config.RequestsPerSecond),
NewPublicBlockchainAPI(hmy, V2, config.RateLimiterEnabled, config.RequestsPerSecond),
NewPublicContractAPI(hmy, V1),
NewPublicContractAPI(hmy, V2),
NewPublicTransactionAPI(hmy, V1),
NewPublicTransactionAPI(hmy, V2),
NewPublicPoolAPI(hmy, V1),
NewPublicPoolAPI(hmy, V2),
}
// Legacy methods (subject to removal)
if config.LegacyRPCsEnabled {
publicAPIs = append(publicAPIs,
v1.NewPublicLegacyAPI(hmy, "hmy"),
v2.NewPublicLegacyAPI(hmy, "hmyv2"),
)
}
if config.StakingRPCsEnabled {
publicAPIs = append(publicAPIs,
NewPublicStakingAPI(hmy, V1),
NewPublicStakingAPI(hmy, V2),
)
}
if config.EthRPCsEnabled {
publicAPIs = append(publicAPIs,
NewPublicHarmonyAPI(hmy, Eth),
NewPublicBlockchainAPI(hmy, Eth, config.RateLimiterEnabled, config.RequestsPerSecond),
NewPublicContractAPI(hmy, Eth),
NewPublicTransactionAPI(hmy, Eth),
NewPublicPoolAPI(hmy, Eth),
eth.NewPublicEthService(hmy, "eth"),
)
}
publicDebugAPIs := []rpc.API{
//Public debug API
NewPublicDebugAPI(hmy, V1),
NewPublicDebugAPI(hmy, V2),
}
privateAPIs := []rpc.API{
NewPrivateDebugAPI(hmy, V1),
NewPrivateDebugAPI(hmy, V2),
}
if config.DebugEnabled {
apis := append(publicAPIs, publicDebugAPIs...)
return append(apis, privateAPIs...)
}
return publicAPIs
}
func startHTTP(apis []rpc.API, rmf *rpc.RpcMethodFilter) (err error) {
httpListener, httpHandler, err = rpc.StartHTTPEndpoint(
httpEndpoint, apis, HTTPModules, rmf, httpOrigins, httpVirtualHosts, httpTimeouts,
)
if err != nil {
return err
}
utils.Logger().Info().
Str("url", fmt.Sprintf("http://%s", httpEndpoint)).
Str("cors", strings.Join(httpOrigins, ",")).
Str("vhosts", strings.Join(httpVirtualHosts, ",")).
Msg("HTTP endpoint opened")
fmt.Printf("Started RPC server at: %v\n", httpEndpoint)
return nil
}
func startAuthHTTP(apis []rpc.API, rmf *rpc.RpcMethodFilter) (err error) {
httpListener, httpHandler, err = rpc.StartHTTPEndpoint(
httpAuthEndpoint, apis, HTTPModules, rmf, httpOrigins, httpVirtualHosts, httpTimeouts,
)
if err != nil {
return err
}
utils.Logger().Info().
Str("url", fmt.Sprintf("http://%s", httpAuthEndpoint)).
Str("cors", strings.Join(httpOrigins, ",")).
Str("vhosts", strings.Join(httpVirtualHosts, ",")).
Msg("HTTP endpoint opened")
fmt.Printf("Started Auth-RPC server at: %v\n", httpAuthEndpoint)
return nil
}
func startWS(apis []rpc.API, rmf *rpc.RpcMethodFilter) (err error) {
wsListener, wsHandler, err = rpc.StartWSEndpoint(wsEndpoint, apis, WSModules, rmf, wsOrigins, true)
if err != nil {
return err
}
utils.Logger().Info().
Str("url", fmt.Sprintf("ws://%s", wsListener.Addr())).
Msg("WebSocket endpoint opened")
fmt.Printf("Started WS server at: %v\n", wsEndpoint)
return nil
}
func startAuthWS(apis []rpc.API, rmf *rpc.RpcMethodFilter) (err error) {
wsListener, wsHandler, err = rpc.StartWSEndpoint(wsAuthEndpoint, apis, WSModules, rmf, wsOrigins, true)
if err != nil {
return err
}
utils.Logger().Info().
Str("url", fmt.Sprintf("ws://%s", wsListener.Addr())).
Msg("WebSocket endpoint opened")
fmt.Printf("Started Auth-WS server at: %v\n", wsAuthEndpoint)
return nil
}