8a9395819c
* Make transactions requests in parallel * Update transaction error handling
132 lines
2.9 KiB
Go
132 lines
2.9 KiB
Go
package node
|
|
|
|
import (
|
|
"context"
|
|
|
|
"strconv"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
"log"
|
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
"github.com/ethereum/go-ethereum/p2p"
|
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
|
)
|
|
|
|
type PropertiesReader interface {
|
|
NodeInfo() (id string, name string)
|
|
NetworkId() float64
|
|
GenesisBlock() string
|
|
}
|
|
|
|
type ClientWrapper struct {
|
|
ContextCaller
|
|
IPCPath string
|
|
}
|
|
|
|
type ContextCaller interface {
|
|
CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
|
|
SupportedModules() (map[string]string, error)
|
|
}
|
|
|
|
type ParityClient struct {
|
|
ClientWrapper
|
|
}
|
|
|
|
type GethClient struct {
|
|
ClientWrapper
|
|
}
|
|
|
|
type InfuraClient struct {
|
|
ClientWrapper
|
|
}
|
|
|
|
func (clientWrapper ClientWrapper) NodeType() core.NodeType {
|
|
if strings.Contains(clientWrapper.IPCPath, "infura") {
|
|
return core.INFURA
|
|
}
|
|
modules, _ := clientWrapper.SupportedModules()
|
|
if _, ok := modules["admin"]; ok {
|
|
return core.GETH
|
|
}
|
|
return core.PARITY
|
|
}
|
|
|
|
func makePropertiesReader(wrapper ClientWrapper) PropertiesReader {
|
|
switch wrapper.NodeType() {
|
|
case core.GETH:
|
|
return GethClient{ClientWrapper: wrapper}
|
|
case core.PARITY:
|
|
return ParityClient{ClientWrapper: wrapper}
|
|
case core.INFURA:
|
|
return InfuraClient{ClientWrapper: wrapper}
|
|
default:
|
|
return wrapper
|
|
}
|
|
}
|
|
|
|
func MakeNode(wrapper ClientWrapper) core.Node {
|
|
pr := makePropertiesReader(wrapper)
|
|
id, name := pr.NodeInfo()
|
|
return core.Node{
|
|
GenesisBlock: pr.GenesisBlock(),
|
|
NetworkID: pr.NetworkId(),
|
|
ID: id,
|
|
ClientName: name,
|
|
}
|
|
}
|
|
|
|
func (client ClientWrapper) NetworkId() float64 {
|
|
var version string
|
|
err := client.CallContext(context.Background(), &version, "net_version")
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
networkId, _ := strconv.ParseFloat(version, 64)
|
|
return networkId
|
|
}
|
|
|
|
func (client ClientWrapper) GenesisBlock() string {
|
|
var header *types.Header
|
|
blockZero := "0x0"
|
|
includeTransactions := false
|
|
client.CallContext(context.Background(), &header, "eth_getBlockByNumber", blockZero, includeTransactions)
|
|
return header.Hash().Hex()
|
|
}
|
|
|
|
func (client ClientWrapper) NodeInfo() (string, string) {
|
|
var info p2p.NodeInfo
|
|
client.CallContext(context.Background(), &info, "admin_nodeInfo")
|
|
return info.ID, info.Name
|
|
}
|
|
|
|
func (client ParityClient) NodeInfo() (string, string) {
|
|
nodeInfo := client.parityNodeInfo()
|
|
id := client.parityID()
|
|
return id, nodeInfo
|
|
}
|
|
|
|
func (client InfuraClient) NodeInfo() (string, string) {
|
|
return "infura", "infura"
|
|
}
|
|
|
|
func (client ParityClient) parityNodeInfo() string {
|
|
var nodeInfo core.ParityNodeInfo
|
|
client.CallContext(context.Background(), &nodeInfo, "parity_versionInfo")
|
|
return nodeInfo.String()
|
|
}
|
|
|
|
func (client ParityClient) parityID() string {
|
|
var enodeId = regexp.MustCompile(`^enode://(.+)@.+$`)
|
|
var enodeURL string
|
|
client.CallContext(context.Background(), &enodeURL, "parity_enode")
|
|
enode := enodeId.FindStringSubmatch(enodeURL)
|
|
if len(enode) < 2 {
|
|
return ""
|
|
}
|
|
return enode[1]
|
|
}
|