diff --git a/eth/api_backend.go b/eth/api_backend.go index 09c38f7922..c031ba69d1 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -316,6 +316,13 @@ func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int { return nil } +func (b *EthAPIBackend) GetTdByNumber(ctx context.Context, blockNr rpc.BlockNumber) *big.Int { + if header, err := b.HeaderByNumber(ctx, blockNr); header != nil && err == nil { + return b.eth.blockchain.GetTd(header.Hash(), uint64(blockNr.Int64())) + } + return nil +} + func (b *EthAPIBackend) GetEVM(ctx context.Context, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM { if vmConfig == nil { vmConfig = b.eth.blockchain.GetVMConfig() diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index ae138e259f..c484e98c0b 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -765,6 +765,32 @@ func (api *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rp return result, nil } +// GetTdByHash returns a map containing the total difficulty (hex-encoded) for the given block hash. +func (api *BlockChainAPI) GetTdByHash(ctx context.Context, hash common.Hash) map[string]interface{} { + td := api.b.GetTd(ctx, hash) + if td == nil { + return nil + } + + resp := make(map[string]interface{}, 2) + resp["blockHash"] = hash.Hex() + resp["totalDifficulty"] = hexutil.EncodeBig(td) + return resp +} + +// GetTdByNumber returns a map containing the total difficulty (hex-encoded) for the given block number. +func (api *BlockChainAPI) GetTdByNumber(ctx context.Context, blockNr rpc.BlockNumber) map[string]interface{} { + td := api.b.GetTdByNumber(ctx, blockNr) + if td == nil { + return nil + } + + resp := make(map[string]interface{}, 2) + resp["blockNumber"] = hexutil.EncodeUint64(uint64(blockNr.Int64())) + resp["totalDifficulty"] = hexutil.EncodeBig(td) + return resp +} + // ChainContextBackend provides methods required to implement ChainContext. type ChainContextBackend interface { Engine() consensus.Engine diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 0af8a3d03f..cb531cb614 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -576,6 +576,10 @@ func (b testBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int { } return big.NewInt(1) } +func (b testBackend) GetTdByNumber(ctx context.Context, blockNr rpc.BlockNumber) *big.Int { + panic("not implemented") +} + func (b testBackend) GetEVM(ctx context.Context, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockContext *vm.BlockContext) *vm.EVM { if vmConfig == nil { vmConfig = b.chain.GetVMConfig() diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index c438c27d3f..58c211a561 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -70,6 +70,8 @@ type Backend interface { Pending() (*types.Block, types.Receipts, *state.StateDB) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) GetEVM(ctx context.Context, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM + GetTd(ctx context.Context, hash common.Hash) *big.Int + GetTdByNumber(ctx context.Context, blockNr rpc.BlockNumber) *big.Int SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index 64231b010b..2da64c99fc 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -481,3 +481,7 @@ func (b *backendMock) CurrentView() *filtermaps.ChainView { return nil } func (b *backendMock) NewMatcherBackend() filtermaps.MatcherBackend { return nil } func (b *backendMock) HistoryPruningCutoff() uint64 { return 0 } + +func (b backendMock) GetTdByNumber(ctx context.Context, blockNr rpc.BlockNumber) *big.Int { + panic("not implemented") +}