erigon-pulse/cmd/rpcdaemon/commands/eth_api.go
2020-08-31 06:27:35 +01:00

114 lines
4.2 KiB
Go

package commands
import (
"context"
"fmt"
"github.com/ledgerwatch/turbo-geth/common"
"github.com/ledgerwatch/turbo-geth/common/hexutil"
"github.com/ledgerwatch/turbo-geth/core"
"github.com/ledgerwatch/turbo-geth/core/rawdb"
"github.com/ledgerwatch/turbo-geth/core/types"
"github.com/ledgerwatch/turbo-geth/eth/stagedsync/stages"
"github.com/ledgerwatch/turbo-geth/ethdb"
"github.com/ledgerwatch/turbo-geth/internal/ethapi"
"github.com/ledgerwatch/turbo-geth/rpc"
)
// EthAPI is a collection of functions that are exposed in the
type EthAPI interface {
Coinbase(ctx context.Context) (common.Address, error)
BlockNumber(ctx context.Context) (hexutil.Uint64, error)
GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error)
GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error)
GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error)
GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error)
GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error)
Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *map[common.Address]ethapi.Account) (hexutil.Bytes, error)
EstimateGas(ctx context.Context, args ethapi.CallArgs) (hexutil.Uint64, error)
SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error)
Syncing(ctx context.Context) (interface{}, error)
GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*hexutil.Uint, error)
GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) (*hexutil.Uint, error)
}
// APIImpl is implementation of the EthAPI interface based on remote Db access
type APIImpl struct {
db ethdb.KV
ethBackend ethdb.Backend
dbReader ethdb.Getter
chainContext core.ChainContext
GasCap uint64
}
// NewAPI returns APIImpl instance
func NewAPI(db ethdb.KV, dbReader ethdb.Getter, eth ethdb.Backend, gascap uint64) *APIImpl {
return &APIImpl{
db: db,
dbReader: dbReader,
ethBackend: eth,
GasCap: gascap,
}
}
func (api *APIImpl) BlockNumber(ctx context.Context) (hexutil.Uint64, error) {
execution, _, err := stages.GetStageProgress(api.dbReader, stages.Finish)
if err != nil {
return 0, err
}
return hexutil.Uint64(execution), nil
}
// Syncing - we can return the progress of the very first stage as the highest block, and then the progress of the very last stage as the current block
func (api *APIImpl) Syncing(ctx context.Context) (interface{}, error) {
highestBlock, _, err := stages.GetStageProgress(api.dbReader, stages.Headers)
if err != nil {
return false, err
}
currentBlock, _, err := stages.GetStageProgress(api.dbReader, stages.Finish)
if err != nil {
return false, err
}
// Return not syncing if the synchronisation already completed
if currentBlock >= highestBlock {
return false, nil
}
// Otherwise gather the block sync stats
return map[string]hexutil.Uint64{
"currentBlock": hexutil.Uint64(currentBlock),
"highestBlock": hexutil.Uint64(highestBlock),
}, nil
}
func (api *APIImpl) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*hexutil.Uint, error) {
var blockNum uint64
if blockNr == rpc.LatestBlockNumber || blockNr == rpc.PendingBlockNumber {
var err error
blockNum, _, err = stages.GetStageProgress(api.dbReader, stages.Execution)
if err != nil {
return nil, fmt.Errorf("getting latest block number: %v", err)
}
} else if blockNr == rpc.EarliestBlockNumber {
blockNum = 0
} else {
blockNum = uint64(blockNr.Int64())
}
block := rawdb.ReadBlockByNumber(api.dbReader, blockNum)
if block == nil {
return nil, fmt.Errorf("block not found: %d", blockNum)
}
n := hexutil.Uint(len(block.Transactions()))
return &n, nil
}
func (api *APIImpl) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) (*hexutil.Uint, error) {
block := rawdb.ReadBlockByHash(api.dbReader, blockHash)
if block == nil {
return nil, fmt.Errorf("block not found: %x", blockHash)
}
n := hexutil.Uint(len(block.Transactions()))
return &n, nil
}