First working RPC command eth_blockNumber

This commit is contained in:
Alexey Akhunov 2019-11-29 12:00:46 +00:00 committed by alex.sharov
parent 95ca76e440
commit 335ef77249

View File

@ -2,11 +2,16 @@ package commands
import ( import (
"context" "context"
"encoding/binary"
"fmt" "fmt"
"net"
"os" "os"
"os/signal" "os/signal"
"strings" "strings"
"github.com/ledgerwatch/turbo-geth/common"
"github.com/ledgerwatch/turbo-geth/common/dbutils"
"github.com/ledgerwatch/turbo-geth/ethdb/remote"
"github.com/ledgerwatch/turbo-geth/log" "github.com/ledgerwatch/turbo-geth/log"
"github.com/ledgerwatch/turbo-geth/rpc" "github.com/ledgerwatch/turbo-geth/rpc"
) )
@ -26,14 +31,62 @@ type EthAPI interface {
BlockNumber(ctx context.Context) (uint64, error) BlockNumber(ctx context.Context) (uint64, error)
} }
// EthAPIImpl is implementation of the EthAPI interface based on remote Db access // APIImpl is implementation of the EthAPI interface based on remote Db access
type EthAPIImpl struct { type APIImpl struct {
remoteDbAdddress string remoteDbAdddress string
db *remote.DB
}
func (api *APIImpl) ensureConnected() error {
if api.db == nil {
conn, err := net.Dial("tcp", api.remoteDbAdddress)
if err != nil {
return err
}
api.db, err = remote.NewDB(conn, conn, conn)
if err != nil {
return err
}
}
return nil
}
// ConnectAPIImpl connects to the remote DB and returns APIImpl instance
func ConnectAPIImpl(remoteDbAdddress string) (*APIImpl, error) {
return &APIImpl{remoteDbAdddress: remoteDbAdddress}, nil
} }
// BlockNumber returns the currently highest block number available in the remote db // BlockNumber returns the currently highest block number available in the remote db
func (api *EthAPIImpl) BlockNumber(ctx context.Context) (uint64, error) { func (api *APIImpl) BlockNumber(ctx context.Context) (uint64, error) {
return 0, nil if err := api.ensureConnected(); err != nil {
return 0, err
}
var blockNumber uint64
if err := api.db.View(func(tx *remote.Tx) error {
b := tx.Bucket(dbutils.HeadHeaderKey)
if b == nil {
return fmt.Errorf("bucket %s not found", dbutils.HeadHeaderKey)
}
blockHashData := b.Get(dbutils.HeadHeaderKey)
if len(blockHashData) != common.HashLength {
return fmt.Errorf("head header hash not found or wrong size: %x", blockHashData)
}
b1 := tx.Bucket(dbutils.HeaderNumberPrefix)
if b1 == nil {
return fmt.Errorf("bucket %s not found", dbutils.HeaderNumberPrefix)
}
blockNumberData := b1.Get(blockHashData)
if len(blockNumberData) != 8 {
return fmt.Errorf("head block number not found or wrong size: %x", blockNumberData)
}
blockNumber = binary.BigEndian.Uint64(blockNumberData)
return nil
}); err != nil {
api.db.Close()
api.db = nil
return 0, err
}
return blockNumber, nil
} }
func daemon(cfg Config) { func daemon(cfg Config) {
@ -41,14 +94,20 @@ func daemon(cfg Config) {
cors := splitAndTrim(cfg.rpcCORSDomain) cors := splitAndTrim(cfg.rpcCORSDomain)
enabledApis := splitAndTrim(cfg.rpcAPI) enabledApis := splitAndTrim(cfg.rpcAPI)
var rpcAPI = []rpc.API{} var rpcAPI = []rpc.API{}
apiImpl, err := ConnectAPIImpl(cfg.remoteDbAdddress)
if err != nil {
log.Error("Could not connect to remoteDb", "error", err)
return
}
for _, enabledAPI := range enabledApis { for _, enabledAPI := range enabledApis {
switch enabledAPI { switch enabledAPI {
case "eth": case "eth":
var ethAPI EthAPI = &EthAPIImpl{remoteDbAdddress: cfg.remoteDbAdddress} var api EthAPI
api = apiImpl
rpcAPI = append(rpcAPI, rpc.API{ rpcAPI = append(rpcAPI, rpc.API{
Namespace: "eth", Namespace: "eth",
Public: true, Public: true,
Service: ethAPI, Service: api,
Version: "1.0", Version: "1.0",
}) })
default: default:
@ -56,7 +115,7 @@ func daemon(cfg Config) {
} }
} }
httpEndpoint := fmt.Sprintf("%s:%d", cfg.rpcListenAddress, cfg.rpcPort) httpEndpoint := fmt.Sprintf("%s:%d", cfg.rpcListenAddress, cfg.rpcPort)
listener, _, err := rpc.StartHTTPEndpoint(httpEndpoint, rpcAPI, []string{"test", "eth", "debug", "web3"}, cors, vhosts, rpc.DefaultHTTPTimeouts) listener, _, err := rpc.StartHTTPEndpoint(httpEndpoint, rpcAPI, enabledApis, cors, vhosts, rpc.DefaultHTTPTimeouts)
if err != nil { if err != nil {
log.Error("Could not start RPC api", "error", err) log.Error("Could not start RPC api", "error", err)
return return