2020-10-12 14:17:34 +00:00
package commands
2020-10-14 15:59:42 +00:00
import (
"context"
"fmt"
2020-10-12 14:17:34 +00:00
2020-10-14 15:59:42 +00:00
"github.com/ledgerwatch/turbo-geth/common"
"github.com/ledgerwatch/turbo-geth/common/hexutil"
"github.com/ledgerwatch/turbo-geth/core/rawdb"
2020-10-25 08:38:55 +00:00
"github.com/ledgerwatch/turbo-geth/ethdb"
2020-10-14 15:59:42 +00:00
"github.com/ledgerwatch/turbo-geth/rpc"
"github.com/ledgerwatch/turbo-geth/turbo/adapter/ethapi"
)
2020-10-24 17:03:52 +00:00
// GetBlockByNumber implements eth_getBlockByNumber. Returns information about a block given the block's number.
2020-10-14 15:59:42 +00:00
func ( api * APIImpl ) GetBlockByNumber ( ctx context . Context , number rpc . BlockNumber , fullTx bool ) ( map [ string ] interface { } , error ) {
2020-10-25 08:38:55 +00:00
tx , err := api . dbReader . Begin ( ctx , ethdb . RO )
2020-10-14 15:59:42 +00:00
if err != nil {
return nil , err
}
defer tx . Rollback ( )
blockNum , err := getBlockNumber ( number , tx )
if err != nil {
return nil , err
}
additionalFields := make ( map [ string ] interface { } )
2020-10-24 06:57:09 +00:00
block , err := rawdb . ReadBlockByNumber ( tx , blockNum )
if err != nil {
return nil , err
}
2020-10-14 15:59:42 +00:00
if block == nil {
return nil , fmt . Errorf ( "block not found: %d" , blockNum )
}
2020-10-24 06:57:09 +00:00
td , err := rawdb . ReadTd ( tx , block . Hash ( ) , blockNum )
if err != nil {
return nil , err
}
additionalFields [ "totalDifficulty" ] = ( * hexutil . Big ) ( td )
2020-10-14 15:59:42 +00:00
response , err := ethapi . RPCMarshalBlock ( block , true , fullTx , additionalFields )
if err == nil && number == rpc . PendingBlockNumber {
// Pending blocks need to nil out a few fields
for _ , field := range [ ] string { "hash" , "nonce" , "miner" } {
response [ field ] = nil
}
}
return response , err
}
2020-10-24 17:03:52 +00:00
// GetBlockByHash implements eth_getBlockByHash. Returns information about a block given the block's hash.
2020-11-06 07:59:50 +00:00
func ( api * APIImpl ) GetBlockByHash ( ctx context . Context , numberOrHash rpc . BlockNumberOrHash , fullTx bool ) ( map [ string ] interface { } , error ) {
if numberOrHash . BlockHash == nil {
// some web3.js based apps (like ethstats client) for some reason call
// eth_getBlockByHash with a block number as a parameter
// so no matter how weird that is, we would love to support that.
if numberOrHash . BlockNumber != nil {
return api . GetBlockByNumber ( ctx , * numberOrHash . BlockNumber , fullTx )
}
return nil , fmt . Errorf ( "block not found" )
}
hash := * numberOrHash . BlockHash
2020-10-25 08:38:55 +00:00
tx , err := api . dbReader . Begin ( ctx , ethdb . RO )
2020-10-14 15:59:42 +00:00
if err != nil {
return nil , err
}
defer tx . Rollback ( )
additionalFields := make ( map [ string ] interface { } )
2020-10-24 06:57:09 +00:00
block , err := rawdb . ReadBlockByHash ( tx , hash )
if err != nil {
return nil , err
}
2020-10-14 15:59:42 +00:00
if block == nil {
return nil , fmt . Errorf ( "block not found: %x" , hash )
}
number := block . NumberU64 ( )
2020-10-24 06:57:09 +00:00
td , err := rawdb . ReadTd ( tx , hash , number )
if err != nil {
return nil , err
}
additionalFields [ "totalDifficulty" ] = ( * hexutil . Big ) ( td )
2020-10-14 15:59:42 +00:00
response , err := ethapi . RPCMarshalBlock ( block , true , fullTx , additionalFields )
if err == nil && int64 ( number ) == rpc . PendingBlockNumber . Int64 ( ) {
// Pending blocks need to nil out a few fields
for _ , field := range [ ] string { "hash" , "nonce" , "miner" } {
response [ field ] = nil
}
}
return response , err
}
2020-10-24 17:03:52 +00:00
// GetBlockTransactionCountByNumber implements eth_getBlockTransactionCountByNumber. Returns the number of transactions in a block given the block's block number.
2020-10-14 15:59:42 +00:00
func ( api * APIImpl ) GetBlockTransactionCountByNumber ( ctx context . Context , blockNr rpc . BlockNumber ) ( * hexutil . Uint , error ) {
2020-10-25 08:38:55 +00:00
tx , err := api . dbReader . Begin ( ctx , ethdb . RO )
2020-10-14 15:59:42 +00:00
if err != nil {
return nil , err
}
defer tx . Rollback ( )
blockNum , err := getBlockNumber ( blockNr , tx )
if err != nil {
return nil , err
}
2020-10-24 06:57:09 +00:00
block , err := rawdb . ReadBlockByNumber ( tx , blockNum )
if err != nil {
return nil , err
}
2020-10-14 15:59:42 +00:00
if block == nil {
return nil , fmt . Errorf ( "block not found: %d" , blockNum )
}
n := hexutil . Uint ( len ( block . Transactions ( ) ) )
return & n , nil
}
2020-10-24 17:03:52 +00:00
// GetBlockTransactionCountByHash implements eth_getBlockTransactionCountByHash. Returns the number of transactions in a block given the block's block hash.
2020-10-14 15:59:42 +00:00
func ( api * APIImpl ) GetBlockTransactionCountByHash ( ctx context . Context , blockHash common . Hash ) ( * hexutil . Uint , error ) {
2020-10-25 08:38:55 +00:00
tx , err := api . dbReader . Begin ( ctx , ethdb . RO )
2020-10-14 15:59:42 +00:00
if err != nil {
return nil , err
}
defer tx . Rollback ( )
2020-10-24 06:57:09 +00:00
block , err := rawdb . ReadBlockByHash ( tx , blockHash )
if err != nil {
return nil , err
}
2020-10-14 15:59:42 +00:00
if block == nil {
return nil , fmt . Errorf ( "block not found: %x" , blockHash )
}
n := hexutil . Uint ( len ( block . Transactions ( ) ) )
return & n , nil
}