2020-10-12 14:17:34 +00:00
|
|
|
package commands
|
|
|
|
|
2020-10-14 15:59:42 +00:00
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
2021-05-20 18:25:53 +00:00
|
|
|
"github.com/ledgerwatch/erigon/common/hexutil"
|
|
|
|
"github.com/ledgerwatch/erigon/core/rawdb"
|
|
|
|
"github.com/ledgerwatch/erigon/core/types"
|
|
|
|
"github.com/ledgerwatch/erigon/eth/ethconfig"
|
|
|
|
"github.com/ledgerwatch/erigon/eth/gasprice"
|
|
|
|
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
|
|
|
|
"github.com/ledgerwatch/erigon/ethdb"
|
|
|
|
"github.com/ledgerwatch/erigon/log"
|
|
|
|
"github.com/ledgerwatch/erigon/params"
|
|
|
|
"github.com/ledgerwatch/erigon/rpc"
|
2020-10-14 15:59:42 +00:00
|
|
|
)
|
|
|
|
|
2020-10-24 17:03:52 +00:00
|
|
|
// BlockNumber implements eth_blockNumber. Returns the block number of most recent block.
|
2021-03-30 09:53:54 +00:00
|
|
|
func (api *APIImpl) BlockNumber(ctx context.Context) (hexutil.Uint64, error) {
|
2021-04-03 06:26:00 +00:00
|
|
|
tx, err := api.db.BeginRo(ctx)
|
2021-03-30 09:53:54 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
2021-04-08 11:03:45 +00:00
|
|
|
execution, err := stages.GetStageProgress(tx, stages.Finish)
|
2020-10-14 15:59:42 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return hexutil.Uint64(execution), nil
|
|
|
|
}
|
|
|
|
|
2020-10-24 17:03:52 +00:00
|
|
|
// Syncing implements eth_syncing. Returns a data object detaling the status of the sync process or false if not syncing.
|
2021-01-02 19:28:22 +00:00
|
|
|
func (api *APIImpl) Syncing(ctx context.Context) (interface{}, error) {
|
2021-04-03 06:26:00 +00:00
|
|
|
tx, err := api.db.BeginRo(ctx)
|
2021-01-02 19:28:22 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
2021-04-08 11:03:45 +00:00
|
|
|
highestBlock, err := stages.GetStageProgress(tx, stages.Headers)
|
2020-10-14 15:59:42 +00:00
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
2021-04-08 11:03:45 +00:00
|
|
|
currentBlock, err := stages.GetStageProgress(tx, stages.Finish)
|
2020-10-14 15:59:42 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-10-24 17:03:52 +00:00
|
|
|
// ChainId implements eth_chainId. Returns the current ethereum chainId.
|
2020-10-14 15:59:42 +00:00
|
|
|
func (api *APIImpl) ChainId(ctx context.Context) (hexutil.Uint64, error) {
|
2021-04-03 06:26:00 +00:00
|
|
|
tx, err := api.db.BeginRo(ctx)
|
2020-10-14 15:59:42 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
2021-01-02 19:28:22 +00:00
|
|
|
chainConfig, err := api.chainConfig(tx)
|
2020-10-24 06:57:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
2020-10-14 15:59:42 +00:00
|
|
|
return hexutil.Uint64(chainConfig.ChainID.Uint64()), nil
|
|
|
|
}
|
|
|
|
|
2020-10-24 17:03:52 +00:00
|
|
|
// ProtocolVersion implements eth_protocolVersion. Returns the current ethereum protocol version.
|
2021-04-24 15:46:29 +00:00
|
|
|
func (api *APIImpl) ProtocolVersion(ctx context.Context) (hexutil.Uint, error) {
|
|
|
|
ver, err := api.ethBackend.ProtocolVersion(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return hexutil.Uint(ver), nil
|
2020-10-14 15:59:42 +00:00
|
|
|
}
|
|
|
|
|
2020-10-24 17:03:52 +00:00
|
|
|
// GasPrice implements eth_gasPrice. Returns the current price per gas in wei.
|
2020-11-06 07:59:50 +00:00
|
|
|
func (api *APIImpl) GasPrice(ctx context.Context) (*hexutil.Big, error) {
|
2021-03-14 18:52:15 +00:00
|
|
|
oracle := gasprice.NewOracle(api, ethconfig.Defaults.GPO)
|
2020-11-06 07:59:50 +00:00
|
|
|
price, err := oracle.SuggestPrice(ctx)
|
|
|
|
return (*hexutil.Big)(price), err
|
|
|
|
}
|
|
|
|
|
|
|
|
// HeaderByNumber is necessary for gasprice.OracleBackend implementation
|
|
|
|
func (api *APIImpl) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
|
2021-04-03 06:26:00 +00:00
|
|
|
tx, err := api.db.BeginRo(ctx)
|
2020-11-06 07:59:50 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
|
|
|
blockNum, err := getBlockNumber(number, tx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-03-30 09:53:54 +00:00
|
|
|
header := rawdb.ReadHeaderByNumber(ethdb.NewRoTxDb(tx), blockNum)
|
2020-11-06 07:59:50 +00:00
|
|
|
if header == nil {
|
|
|
|
return nil, fmt.Errorf("header not found: %d", blockNum)
|
|
|
|
}
|
|
|
|
return header, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// BlockByNumber is necessary for gasprice.OracleBackend implementation
|
|
|
|
func (api *APIImpl) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
|
2021-04-03 06:26:00 +00:00
|
|
|
tx, err := api.db.BeginRo(ctx)
|
2020-11-06 07:59:50 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
|
|
|
blockNum, err := getBlockNumber(number, tx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-05-01 07:42:23 +00:00
|
|
|
block, err := rawdb.ReadBlockByNumber(tx, blockNum)
|
2020-11-06 07:59:50 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if block == nil {
|
|
|
|
return nil, fmt.Errorf("block not found: %d", blockNum)
|
|
|
|
}
|
|
|
|
return block, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ChainConfig is necessary for gasprice.OracleBackend implementation
|
|
|
|
func (api *APIImpl) ChainConfig() *params.ChainConfig {
|
2021-04-03 06:26:00 +00:00
|
|
|
tx, err := api.db.BeginRo(context.TODO())
|
2020-11-08 05:46:53 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Warn("Could not read chain config from the db, defaulting to MainnetChainConfig", "err", err)
|
|
|
|
return params.MainnetChainConfig
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
2021-01-02 19:28:22 +00:00
|
|
|
chainConfig, err := api.chainConfig(tx)
|
2020-11-08 05:46:53 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Warn("Could not read chain config from the db, defaulting to MainnetChainConfig", "err", err)
|
|
|
|
return params.MainnetChainConfig
|
|
|
|
}
|
|
|
|
return chainConfig
|
2020-10-14 15:59:42 +00:00
|
|
|
}
|