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/node/rpc.go

207 lines
5.7 KiB

package node
import (
"fmt"
"net"
"strconv"
"strings"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/hmy"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/hmyapi"
"github.com/harmony-one/harmony/internal/hmyapi/apiv1"
"github.com/harmony-one/harmony/internal/hmyapi/apiv2"
"github.com/harmony-one/harmony/internal/hmyapi/filters"
"github.com/harmony-one/harmony/internal/utils"
"github.com/libp2p/go-libp2p-core/peer"
)
const (
rpcHTTPPortOffset = 500
rpcWSPortOffset = 800
)
var (
// HTTP RPC
httpListener net.Listener
httpHandler *rpc.Server
httpEndpoint = ""
wsEndpoint = ""
httpModules = []string{"hmy", "hmyv2", "net", "netv2", "explorer"}
httpVirtualHosts = []string{"*"}
httpTimeouts = rpc.DefaultHTTPTimeouts
httpOrigins = []string{"*"}
wsModules = []string{"hmy", "hmyv2", "net", "netv2", "web3"}
wsOrigins = []string{"*"}
harmony *hmy.Harmony
)
// IsCurrentlyLeader exposes if node is currently the leader node
func (node *Node) IsCurrentlyLeader() bool {
return node.Consensus.IsLeader()
}
// PeerConnectivity ..
func (node *Node) PeerConnectivity() (int, int, int) {
return node.host.C()
}
// ListPeer return list of peers for a certain topic
func (node *Node) ListPeer(topic string) []peer.ID {
return node.host.ListPeer(topic)
}
// ListTopic return list of topics the node subscribed
func (node *Node) ListTopic() []string {
return node.host.ListTopic()
}
// ListBlockedPeer return list of blocked peers
func (node *Node) ListBlockedPeer() []peer.ID {
return node.host.ListBlockedPeer()
}
// PendingCXReceipts returns node.pendingCXReceiptsProof
func (node *Node) PendingCXReceipts() []*types.CXReceiptsProof {
cxReceipts := make([]*types.CXReceiptsProof, len(node.pendingCXReceipts))
i := 0
for _, cxReceipt := range node.pendingCXReceipts {
cxReceipts[i] = cxReceipt
i++
}
return cxReceipts
}
Fix error sink msg duplication & false positives (#2924) * [types] Add TransactionErrorSink to report failed txs [node] Create ErrorSink handler for unique error msgs Implemented with a LRU cache. [node] Rename ErrorSink to TransactionErrorSink * Rename RPCTransactionError to TransactionError [node] Make tx error sink not return err on Add & Remove [node] Make tx errorSink Contains check take string as tx hash param [errorsink] Move tx error sink into errorsink pkg [errorsink] Rename Errors and Count methods [errorsink] Rename NewTransactionErrorSink to NewTransactionSink [types] Move error sink to core/types * Rename NewTransactionSink to NewTransactionErrorSink * [types] Fix log msg for unfound errors * [types] Rename TransactionError to TransactionErrorReport * [core] Remove RPCTransactionError & refactor tx_pool to use TxErrorSink * [staking] Remove RPCTransactionError * [node] Refactor tx_pool init to use new TxErrorSink * [main] Construct transaction error sink before initing the node * [node] Refactor error sink reporting at RPC layer * [rpc] Refactor returned type of ErrorSink RPCs to 1 type * [core] Remove tx from TxErrorSink on Add to tx_pool * [types] Make NewTransactionErrorSink not return err * [node] Make node.New create error sink * [cmd] Revert to origin main.go * [core] Add TxErrorSink unit test & fix bad ErrExcessiveBLSKeys in tests * [testnet config] Change testnet config to allow for 5*4 external keys * [cmd] Revert main.go to original node instantiation * [rpc] Add GetPoolStats rpc to fetch pending and queued tx counts
5 years ago
// ReportStakingErrorSink is the report of failed staking transactions this node has (held inmemory only)
func (node *Node) ReportStakingErrorSink() types.TransactionErrorReports {
return node.TransactionErrorSink.StakingReport()
}
// GetNodeBootTime ..
func (node *Node) GetNodeBootTime() int64 {
return node.unixTimeAtNodeStart
}
Fix error sink msg duplication & false positives (#2924) * [types] Add TransactionErrorSink to report failed txs [node] Create ErrorSink handler for unique error msgs Implemented with a LRU cache. [node] Rename ErrorSink to TransactionErrorSink * Rename RPCTransactionError to TransactionError [node] Make tx error sink not return err on Add & Remove [node] Make tx errorSink Contains check take string as tx hash param [errorsink] Move tx error sink into errorsink pkg [errorsink] Rename Errors and Count methods [errorsink] Rename NewTransactionErrorSink to NewTransactionSink [types] Move error sink to core/types * Rename NewTransactionSink to NewTransactionErrorSink * [types] Fix log msg for unfound errors * [types] Rename TransactionError to TransactionErrorReport * [core] Remove RPCTransactionError & refactor tx_pool to use TxErrorSink * [staking] Remove RPCTransactionError * [node] Refactor tx_pool init to use new TxErrorSink * [main] Construct transaction error sink before initing the node * [node] Refactor error sink reporting at RPC layer * [rpc] Refactor returned type of ErrorSink RPCs to 1 type * [core] Remove tx from TxErrorSink on Add to tx_pool * [types] Make NewTransactionErrorSink not return err * [node] Make node.New create error sink * [cmd] Revert to origin main.go * [core] Add TxErrorSink unit test & fix bad ErrExcessiveBLSKeys in tests * [testnet config] Change testnet config to allow for 5*4 external keys * [cmd] Revert main.go to original node instantiation * [rpc] Add GetPoolStats rpc to fetch pending and queued tx counts
5 years ago
// ReportPlainErrorSink is the report of failed transactions this node has (held inmemory only)
func (node *Node) ReportPlainErrorSink() types.TransactionErrorReports {
return node.TransactionErrorSink.PlainReport()
}
// StartRPC start RPC service
func (node *Node) StartRPC(nodePort string) error {
// Gather all the possible APIs to surface
harmony, _ = hmy.New(
node, node.TxPool, node.CxPool, new(event.TypeMux), node.Consensus.ShardID,
)
apis := node.APIs()
for _, service := range node.serviceManager.GetServices() {
apis = append(apis, service.APIs()...)
}
port, _ := strconv.Atoi(nodePort)
ip := ""
if !nodeconfig.GetPublicRPC() {
ip = "127.0.0.1"
}
httpEndpoint = fmt.Sprintf("%v:%v", ip, port+rpcHTTPPortOffset)
if err := node.startHTTP(httpEndpoint, apis, httpModules, httpOrigins, httpVirtualHosts, httpTimeouts); err != nil {
return err
}
wsEndpoint = fmt.Sprintf("%v:%v", ip, port+rpcWSPortOffset)
if err := node.startWS(wsEndpoint, apis, wsModules, wsOrigins, true); err != nil {
node.stopHTTP()
return err
}
return nil
}
// startHTTP initializes and starts the HTTP RPC endpoint.
func (node *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string, timeouts rpc.HTTPTimeouts) error {
// Short circuit if the HTTP endpoint isn't being exposed
if endpoint == "" {
return nil
}
listener, handler, err := rpc.StartHTTPEndpoint(endpoint, apis, modules, cors, vhosts, timeouts)
if err != nil {
return err
}
utils.Logger().Info().
Str("url", fmt.Sprintf("http://%s", endpoint)).
Str("cors", strings.Join(cors, ",")).
Str("vhosts", strings.Join(vhosts, ",")).
Msg("HTTP endpoint opened")
// All listeners booted successfully
httpListener = listener
httpHandler = handler
return nil
}
// stopHTTP terminates the HTTP RPC endpoint.
func (node *Node) stopHTTP() {
if httpListener != nil {
httpListener.Close()
httpListener = nil
utils.Logger().Info().Str("url", fmt.Sprintf("http://%s", httpEndpoint)).Msg("HTTP endpoint closed")
}
if httpHandler != nil {
httpHandler.Stop()
httpHandler = nil
}
}
// startWS initializes and starts the websocket RPC endpoint.
func (node *Node) startWS(
endpoint string, apis []rpc.API, modules []string, wsOrigins []string, exposeAll bool,
) error {
// Short circuit if the WS endpoint isn't being exposed
if endpoint == "" {
return nil
}
listener, _, err := rpc.StartWSEndpoint(endpoint, apis, modules, wsOrigins, exposeAll)
if err != nil {
return err
}
utils.Logger().Info().
Str("url", fmt.Sprintf("ws://%s", listener.Addr())).
Msg("WebSocket endpoint opened")
return nil
}
// APIs return the collection of RPC services the ethereum package offers.
// NOTE, some of these services probably need to be moved to somewhere else.
func (node *Node) APIs() []rpc.API {
// Gather all the possible APIs to surface
apis := hmyapi.GetAPIs(harmony.APIBackend)
// Append all the local APIs and return
return append(apis, []rpc.API{
{
Namespace: "hmy",
Version: "1.0",
Service: filters.NewPublicFilterAPI(harmony.APIBackend, false),
Public: true,
},
6 years ago
{
Namespace: "net",
Version: "1.0",
Service: apiv1.NewPublicNetAPI(node.host, harmony.APIBackend.NetVersion()),
Public: true,
},
{
Namespace: "netv2",
Version: "1.0",
Service: apiv2.NewPublicNetAPI(node.host, harmony.APIBackend.NetVersion()),
6 years ago
Public: true,
},
}...)
}