@ -24,6 +24,7 @@ import (
"math/big"
"math/big"
"sort"
"sort"
"strconv"
"strconv"
"sync"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
@ -80,12 +81,26 @@ type Account struct {
r * Resolver
r * Resolver
address common . Address
address common . Address
blockNrOrHash rpc . BlockNumberOrHash
blockNrOrHash rpc . BlockNumberOrHash
state * state . StateDB
mu sync . Mutex
}
}
// getState fetches the StateDB object for an account.
// getState fetches the StateDB object for an account.
func ( a * Account ) getState ( ctx context . Context ) ( * state . StateDB , error ) {
func ( a * Account ) getState ( ctx context . Context ) ( * state . StateDB , error ) {
a . mu . Lock ( )
defer a . mu . Unlock ( )
if a . state != nil {
return a . state , nil
}
state , _ , err := a . r . backend . StateAndHeaderByNumberOrHash ( ctx , a . blockNrOrHash )
state , _ , err := a . r . backend . StateAndHeaderByNumberOrHash ( ctx , a . blockNrOrHash )
return state , err
if err != nil {
return nil , err
}
a . state = state
// Cache the state object. This is done so that concurrent resolvers
// don't have to fetch the object from DB individually.
a . state . GetOrNewStateObject ( a . address )
return a . state , nil
}
}
func ( a * Account ) Address ( ctx context . Context ) ( common . Address , error ) {
func ( a * Account ) Address ( ctx context . Context ) ( common . Address , error ) {
@ -185,15 +200,22 @@ func (at *AccessTuple) StorageKeys(ctx context.Context) []common.Hash {
// backend and hash are mandatory; all others will be fetched when required.
// backend and hash are mandatory; all others will be fetched when required.
type Transaction struct {
type Transaction struct {
r * Resolver
r * Resolver
hash common . Hash
hash common . Hash // Must be present after initialization
mu sync . Mutex
// mu protects following resources
tx * types . Transaction
tx * types . Transaction
block * Block
block * Block
index uint64
index uint64
}
}
// resolve returns the internal transaction object, fetching it if needed.
// resolve returns the internal transaction object, fetching it if needed.
func ( t * Transaction ) resolve ( ctx context . Context ) ( * types . Transaction , error ) {
// It also returns the block the tx blongs to, unless it is a pending tx.
if t . tx == nil {
func ( t * Transaction ) resolve ( ctx context . Context ) ( * types . Transaction , * Block , error ) {
t . mu . Lock ( )
defer t . mu . Unlock ( )
if t . tx != nil {
return t . tx , t . block , nil
}
// Try to return an already finalized transaction
// Try to return an already finalized transaction
tx , blockHash , _ , index , err := t . r . backend . GetTransaction ( ctx , t . hash )
tx , blockHash , _ , index , err := t . r . backend . GetTransaction ( ctx , t . hash )
if err == nil && tx != nil {
if err == nil && tx != nil {
@ -202,14 +224,14 @@ func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, error) {
t . block = & Block {
t . block = & Block {
r : t . r ,
r : t . r ,
numberOrHash : & blockNrOrHash ,
numberOrHash : & blockNrOrHash ,
hash : blockHash ,
}
}
t . index = index
t . index = index
return t . tx , nil
return t . tx , t . block , nil
}
}
// No finalized transaction, try to retrieve it from the pool
// No finalized transaction, try to retrieve it from the pool
t . tx = t . r . backend . GetPoolTransaction ( t . hash )
t . tx = t . r . backend . GetPoolTransaction ( t . hash )
}
return t . tx , nil , nil
return t . tx , nil
}
}
func ( t * Transaction ) Hash ( ctx context . Context ) common . Hash {
func ( t * Transaction ) Hash ( ctx context . Context ) common . Hash {
@ -217,7 +239,7 @@ func (t *Transaction) Hash(ctx context.Context) common.Hash {
}
}
func ( t * Transaction ) InputData ( ctx context . Context ) ( hexutil . Bytes , error ) {
func ( t * Transaction ) InputData ( ctx context . Context ) ( hexutil . Bytes , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return hexutil . Bytes { } , err
return hexutil . Bytes { } , err
}
}
@ -225,7 +247,7 @@ func (t *Transaction) InputData(ctx context.Context) (hexutil.Bytes, error) {
}
}
func ( t * Transaction ) Gas ( ctx context . Context ) ( hexutil . Uint64 , error ) {
func ( t * Transaction ) Gas ( ctx context . Context ) ( hexutil . Uint64 , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return 0 , err
return 0 , err
}
}
@ -233,7 +255,7 @@ func (t *Transaction) Gas(ctx context.Context) (hexutil.Uint64, error) {
}
}
func ( t * Transaction ) GasPrice ( ctx context . Context ) ( hexutil . Big , error ) {
func ( t * Transaction ) GasPrice ( ctx context . Context ) ( hexutil . Big , error ) {
tx , err := t . resolve ( ctx )
tx , block , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return hexutil . Big { } , err
return hexutil . Big { } , err
}
}
@ -241,8 +263,8 @@ func (t *Transaction) GasPrice(ctx context.Context) (hexutil.Big, error) {
case types . AccessListTxType :
case types . AccessListTxType :
return hexutil . Big ( * tx . GasPrice ( ) ) , nil
return hexutil . Big ( * tx . GasPrice ( ) ) , nil
case types . DynamicFeeTxType :
case types . DynamicFeeTxType :
if t . block != nil {
if block != nil {
if baseFee , _ := t . block . BaseFeePerGas ( ctx ) ; baseFee != nil {
if baseFee , _ := block . BaseFeePerGas ( ctx ) ; baseFee != nil {
// price = min(tip, gasFeeCap - baseFee) + baseFee
// price = min(tip, gasFeeCap - baseFee) + baseFee
return ( hexutil . Big ) ( * math . BigMin ( new ( big . Int ) . Add ( tx . GasTipCap ( ) , baseFee . ToInt ( ) ) , tx . GasFeeCap ( ) ) ) , nil
return ( hexutil . Big ) ( * math . BigMin ( new ( big . Int ) . Add ( tx . GasTipCap ( ) , baseFee . ToInt ( ) ) , tx . GasFeeCap ( ) ) ) , nil
}
}
@ -254,15 +276,15 @@ func (t *Transaction) GasPrice(ctx context.Context) (hexutil.Big, error) {
}
}
func ( t * Transaction ) EffectiveGasPrice ( ctx context . Context ) ( * hexutil . Big , error ) {
func ( t * Transaction ) EffectiveGasPrice ( ctx context . Context ) ( * hexutil . Big , error ) {
tx , err := t . resolve ( ctx )
tx , block , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return nil , err
return nil , err
}
}
// Pending tx
// Pending tx
if t . block == nil {
if block == nil {
return nil , nil
return nil , nil
}
}
header , err := t . block . resolveHeader ( ctx )
header , err := block . resolveHeader ( ctx )
if err != nil || header == nil {
if err != nil || header == nil {
return nil , err
return nil , err
}
}
@ -273,7 +295,7 @@ func (t *Transaction) EffectiveGasPrice(ctx context.Context) (*hexutil.Big, erro
}
}
func ( t * Transaction ) MaxFeePerGas ( ctx context . Context ) ( * hexutil . Big , error ) {
func ( t * Transaction ) MaxFeePerGas ( ctx context . Context ) ( * hexutil . Big , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return nil , err
return nil , err
}
}
@ -288,7 +310,7 @@ func (t *Transaction) MaxFeePerGas(ctx context.Context) (*hexutil.Big, error) {
}
}
func ( t * Transaction ) MaxPriorityFeePerGas ( ctx context . Context ) ( * hexutil . Big , error ) {
func ( t * Transaction ) MaxPriorityFeePerGas ( ctx context . Context ) ( * hexutil . Big , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return nil , err
return nil , err
}
}
@ -303,15 +325,15 @@ func (t *Transaction) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, e
}
}
func ( t * Transaction ) EffectiveTip ( ctx context . Context ) ( * hexutil . Big , error ) {
func ( t * Transaction ) EffectiveTip ( ctx context . Context ) ( * hexutil . Big , error ) {
tx , err := t . resolve ( ctx )
tx , block , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return nil , err
return nil , err
}
}
// Pending tx
// Pending tx
if t . block == nil {
if block == nil {
return nil , nil
return nil , nil
}
}
header , err := t . block . resolveHeader ( ctx )
header , err := block . resolveHeader ( ctx )
if err != nil || header == nil {
if err != nil || header == nil {
return nil , err
return nil , err
}
}
@ -327,7 +349,7 @@ func (t *Transaction) EffectiveTip(ctx context.Context) (*hexutil.Big, error) {
}
}
func ( t * Transaction ) Value ( ctx context . Context ) ( hexutil . Big , error ) {
func ( t * Transaction ) Value ( ctx context . Context ) ( hexutil . Big , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return hexutil . Big { } , err
return hexutil . Big { } , err
}
}
@ -338,7 +360,7 @@ func (t *Transaction) Value(ctx context.Context) (hexutil.Big, error) {
}
}
func ( t * Transaction ) Nonce ( ctx context . Context ) ( hexutil . Uint64 , error ) {
func ( t * Transaction ) Nonce ( ctx context . Context ) ( hexutil . Uint64 , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return 0 , err
return 0 , err
}
}
@ -346,7 +368,7 @@ func (t *Transaction) Nonce(ctx context.Context) (hexutil.Uint64, error) {
}
}
func ( t * Transaction ) To ( ctx context . Context , args BlockNumberArgs ) ( * Account , error ) {
func ( t * Transaction ) To ( ctx context . Context , args BlockNumberArgs ) ( * Account , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return nil , err
return nil , err
}
}
@ -362,7 +384,7 @@ func (t *Transaction) To(ctx context.Context, args BlockNumberArgs) (*Account, e
}
}
func ( t * Transaction ) From ( ctx context . Context , args BlockNumberArgs ) ( * Account , error ) {
func ( t * Transaction ) From ( ctx context . Context , args BlockNumberArgs ) ( * Account , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return nil , err
return nil , err
}
}
@ -376,17 +398,20 @@ func (t *Transaction) From(ctx context.Context, args BlockNumberArgs) (*Account,
}
}
func ( t * Transaction ) Block ( ctx context . Context ) ( * Block , error ) {
func ( t * Transaction ) Block ( ctx context . Context ) ( * Block , error ) {
if _ , err := t . resolve ( ctx ) ; err != nil {
_ , block , err := t . resolve ( ctx )
if err != nil {
return nil , err
return nil , err
}
}
return t . block , nil
return block , nil
}
}
func ( t * Transaction ) Index ( ctx context . Context ) ( * int32 , error ) {
func ( t * Transaction ) Index ( ctx context . Context ) ( * int32 , error ) {
if _ , err := t . resolve ( ctx ) ; err != nil {
_ , block , err := t . resolve ( ctx )
if err != nil {
return nil , err
return nil , err
}
}
if t . block == nil {
// Pending tx
if block == nil {
return nil , nil
return nil , nil
}
}
index := int32 ( t . index )
index := int32 ( t . index )
@ -395,13 +420,15 @@ func (t *Transaction) Index(ctx context.Context) (*int32, error) {
// getReceipt returns the receipt associated with this transaction, if any.
// getReceipt returns the receipt associated with this transaction, if any.
func ( t * Transaction ) getReceipt ( ctx context . Context ) ( * types . Receipt , error ) {
func ( t * Transaction ) getReceipt ( ctx context . Context ) ( * types . Receipt , error ) {
if _ , err := t . resolve ( ctx ) ; err != nil {
_ , block , err := t . resolve ( ctx )
if err != nil {
return nil , err
return nil , err
}
}
if t . block == nil {
// Pending tx
if block == nil {
return nil , nil
return nil , nil
}
}
receipts , err := t . block . resolveReceipts ( ctx )
receipts , err := block . resolveReceipts ( ctx )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
@ -451,28 +478,25 @@ func (t *Transaction) CreatedContract(ctx context.Context, args BlockNumberArgs)
}
}
func ( t * Transaction ) Logs ( ctx context . Context ) ( * [ ] * Log , error ) {
func ( t * Transaction ) Logs ( ctx context . Context ) ( * [ ] * Log , error ) {
if _ , err := t . resolve ( ctx ) ; err != nil {
_ , block , err := t . resolve ( ctx )
if err != nil {
return nil , err
return nil , err
}
}
if t . block == nil {
// Pending tx
if block == nil {
return nil , nil
return nil , nil
}
}
if _ , ok := t . block . numberOrHash . Hash ( ) ; ! ok {
h , err := block . Hash ( ctx )
header , err := t . r . backend . HeaderByNumberOrHash ( ctx , * t . block . numberOrHash )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
hash := header . Hash ( )
return t . getLogs ( ctx , h )
t . block . numberOrHash . BlockHash = & hash
}
return t . getLogs ( ctx )
}
}
// getLogs returns log objects for the given tx.
// getLogs returns log objects for the given tx.
// Assumes block hash is resolved.
// Assumes block hash is resolved.
func ( t * Transaction ) getLogs ( ctx context . Context ) ( * [ ] * Log , error ) {
func ( t * Transaction ) getLogs ( ctx context . Context , hash common . Hash ) ( * [ ] * Log , error ) {
var (
var (
hash , _ = t . block . numberOrHash . Hash ( )
filter = t . r . filterSystem . NewBlockFilter ( hash , nil , nil )
filter = t . r . filterSystem . NewBlockFilter ( hash , nil , nil )
logs , err = filter . Logs ( ctx )
logs , err = filter . Logs ( ctx )
)
)
@ -494,7 +518,7 @@ func (t *Transaction) getLogs(ctx context.Context) (*[]*Log, error) {
}
}
func ( t * Transaction ) Type ( ctx context . Context ) ( * int32 , error ) {
func ( t * Transaction ) Type ( ctx context . Context ) ( * int32 , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
@ -503,7 +527,7 @@ func (t *Transaction) Type(ctx context.Context) (*int32, error) {
}
}
func ( t * Transaction ) AccessList ( ctx context . Context ) ( * [ ] * AccessTuple , error ) {
func ( t * Transaction ) AccessList ( ctx context . Context ) ( * [ ] * AccessTuple , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return nil , err
return nil , err
}
}
@ -519,7 +543,7 @@ func (t *Transaction) AccessList(ctx context.Context) (*[]*AccessTuple, error) {
}
}
func ( t * Transaction ) R ( ctx context . Context ) ( hexutil . Big , error ) {
func ( t * Transaction ) R ( ctx context . Context ) ( hexutil . Big , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return hexutil . Big { } , err
return hexutil . Big { } , err
}
}
@ -528,7 +552,7 @@ func (t *Transaction) R(ctx context.Context) (hexutil.Big, error) {
}
}
func ( t * Transaction ) S ( ctx context . Context ) ( hexutil . Big , error ) {
func ( t * Transaction ) S ( ctx context . Context ) ( hexutil . Big , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return hexutil . Big { } , err
return hexutil . Big { } , err
}
}
@ -537,7 +561,7 @@ func (t *Transaction) S(ctx context.Context) (hexutil.Big, error) {
}
}
func ( t * Transaction ) V ( ctx context . Context ) ( hexutil . Big , error ) {
func ( t * Transaction ) V ( ctx context . Context ) ( hexutil . Big , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return hexutil . Big { } , err
return hexutil . Big { } , err
}
}
@ -546,7 +570,7 @@ func (t *Transaction) V(ctx context.Context) (hexutil.Big, error) {
}
}
func ( t * Transaction ) Raw ( ctx context . Context ) ( hexutil . Bytes , error ) {
func ( t * Transaction ) Raw ( ctx context . Context ) ( hexutil . Bytes , error ) {
tx , err := t . resolve ( ctx )
tx , _ , err := t . resolve ( ctx )
if err != nil || tx == nil {
if err != nil || tx == nil {
return hexutil . Bytes { } , err
return hexutil . Bytes { } , err
}
}
@ -568,8 +592,10 @@ type BlockType int
// when required.
// when required.
type Block struct {
type Block struct {
r * Resolver
r * Resolver
numberOrHash * rpc . BlockNumberOrHash
numberOrHash * rpc . BlockNumberOrHash // Field resolvers assume numberOrHash is always present
hash common . Hash
mu sync . Mutex
// mu protects following resources
hash common . Hash // Must be resolved during initialization
header * types . Header
header * types . Header
block * types . Block
block * types . Block
receipts [ ] * types . Receipt
receipts [ ] * types . Receipt
@ -578,6 +604,8 @@ type Block struct {
// resolve returns the internal Block object representing this block, fetching
// resolve returns the internal Block object representing this block, fetching
// it if necessary.
// it if necessary.
func ( b * Block ) resolve ( ctx context . Context ) ( * types . Block , error ) {
func ( b * Block ) resolve ( ctx context . Context ) ( * types . Block , error ) {
b . mu . Lock ( )
defer b . mu . Unlock ( )
if b . block != nil {
if b . block != nil {
return b . block , nil
return b . block , nil
}
}
@ -587,10 +615,10 @@ func (b *Block) resolve(ctx context.Context) (*types.Block, error) {
}
}
var err error
var err error
b . block , err = b . r . backend . BlockByNumberOrHash ( ctx , * b . numberOrHash )
b . block , err = b . r . backend . BlockByNumberOrHash ( ctx , * b . numberOrHash )
if b . block != nil && b . header == nil {
if b . block != nil {
b . hash = b . block . Hash ( )
if b . header == nil {
b . header = b . block . Header ( )
b . header = b . block . Header ( )
if hash , ok := b . numberOrHash . Hash ( ) ; ok {
b . hash = hash
}
}
}
}
return b . block , err
return b . block , err
@ -600,39 +628,39 @@ func (b *Block) resolve(ctx context.Context) (*types.Block, error) {
// if necessary. Call this function instead of `resolve` unless you need the
// if necessary. Call this function instead of `resolve` unless you need the
// additional data (transactions and uncles).
// additional data (transactions and uncles).
func ( b * Block ) resolveHeader ( ctx context . Context ) ( * types . Header , error ) {
func ( b * Block ) resolveHeader ( ctx context . Context ) ( * types . Header , error ) {
b . mu . Lock ( )
defer b . mu . Unlock ( )
if b . header != nil {
return b . header , nil
}
if b . numberOrHash == nil && b . hash == ( common . Hash { } ) {
if b . numberOrHash == nil && b . hash == ( common . Hash { } ) {
return nil , errBlockInvariant
return nil , errBlockInvariant
}
}
var err error
var err error
if b . header == nil {
if b . hash != ( common . Hash { } ) {
b . header , err = b . r . backend . HeaderByHash ( ctx , b . hash )
} else {
b . header , err = b . r . backend . HeaderByNumberOrHash ( ctx , * b . numberOrHash )
b . header , err = b . r . backend . HeaderByNumberOrHash ( ctx , * b . numberOrHash )
if err != nil {
return nil , err
}
}
if b . hash == ( common . Hash { } ) {
b . hash = b . header . Hash ( )
}
}
return b . header , err
return b . header , nil
}
}
// resolveReceipts returns the list of receipts for this block, fetching them
// resolveReceipts returns the list of receipts for this block, fetching them
// if necessary.
// if necessary.
func ( b * Block ) resolveReceipts ( ctx context . Context ) ( [ ] * types . Receipt , error ) {
func ( b * Block ) resolveReceipts ( ctx context . Context ) ( [ ] * types . Receipt , error ) {
if b . receipts == nil {
b . mu . Lock ( )
hash := b . hash
defer b . mu . Unlock ( )
if hash == ( common . Hash { } ) {
if b . receipts != nil {
header , err := b . resolveHeader ( ctx )
return b . receipts , nil
if err != nil {
return nil , err
}
hash = header . Hash ( )
}
}
receipts , err := b . r . backend . GetReceipts ( ctx , hash )
receipts , err := b . r . backend . GetReceipts ( ctx , b . hash )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
b . receipts = receipts
b . receipts = receipts
}
return receipts , nil
return b . receipts , nil
}
}
func ( b * Block ) Number ( ctx context . Context ) ( Long , error ) {
func ( b * Block ) Number ( ctx context . Context ) ( Long , error ) {
@ -645,13 +673,8 @@ func (b *Block) Number(ctx context.Context) (Long, error) {
}
}
func ( b * Block ) Hash ( ctx context . Context ) ( common . Hash , error ) {
func ( b * Block ) Hash ( ctx context . Context ) ( common . Hash , error ) {
if b . hash == ( common . Hash { } ) {
b . mu . Lock ( )
header , err := b . resolveHeader ( ctx )
defer b . mu . Unlock ( )
if err != nil {
return common . Hash { } , err
}
b . hash = header . Hash ( )
}
return b . hash , nil
return b . hash , nil
}
}
@ -705,11 +728,18 @@ func (b *Block) Parent(ctx context.Context) (*Block, error) {
if b . header == nil || b . header . Number . Uint64 ( ) < 1 {
if b . header == nil || b . header . Number . Uint64 ( ) < 1 {
return nil , nil
return nil , nil
}
}
num := rpc . BlockNumberOrHashWithNumber ( rpc . BlockNumber ( b . header . Number . Uint64 ( ) - 1 ) )
var (
num = rpc . BlockNumber ( b . header . Number . Uint64 ( ) - 1 )
hash = b . header . ParentHash
numOrHash = rpc . BlockNumberOrHash {
BlockNumber : & num ,
BlockHash : & hash ,
}
)
return & Block {
return & Block {
r : b . r ,
r : b . r ,
numberOrHash : & num ,
numberOrHash : & numOrHash ,
hash : b . header . ParentHash ,
hash : hash ,
} , nil
} , nil
}
}
@ -798,6 +828,7 @@ func (b *Block) Ommers(ctx context.Context) (*[]*Block, error) {
r : b . r ,
r : b . r ,
numberOrHash : & blockNumberOrHash ,
numberOrHash : & blockNumberOrHash ,
header : uncle ,
header : uncle ,
hash : uncle . Hash ( ) ,
} )
} )
}
}
return & ret , nil
return & ret , nil
@ -820,17 +851,13 @@ func (b *Block) LogsBloom(ctx context.Context) (hexutil.Bytes, error) {
}
}
func ( b * Block ) TotalDifficulty ( ctx context . Context ) ( hexutil . Big , error ) {
func ( b * Block ) TotalDifficulty ( ctx context . Context ) ( hexutil . Big , error ) {
h := b . hash
hash , err := b . Hash ( ctx )
if h == ( common . Hash { } ) {
header , err := b . resolveHeader ( ctx )
if err != nil {
if err != nil {
return hexutil . Big { } , err
return hexutil . Big { } , err
}
}
h = header . Hash ( )
td := b . r . backend . GetTd ( ctx , hash )
}
td := b . r . backend . GetTd ( ctx , h )
if td == nil {
if td == nil {
return hexutil . Big { } , fmt . Errorf ( "total difficulty not found %x" , b . hash )
return hexutil . Big { } , fmt . Errorf ( "total difficulty not found %x" , hash )
}
}
return hexutil . Big ( * td ) , nil
return hexutil . Big ( * td ) , nil
}
}
@ -948,6 +975,7 @@ func (b *Block) OmmerAt(ctx context.Context, args struct{ Index int32 }) (*Block
r : b . r ,
r : b . r ,
numberOrHash : & blockNumberOrHash ,
numberOrHash : & blockNumberOrHash ,
header : uncle ,
header : uncle ,
hash : uncle . Hash ( ) ,
} , nil
} , nil
}
}
@ -997,15 +1025,11 @@ func (b *Block) Logs(ctx context.Context, args struct{ Filter BlockFilterCriteri
if args . Filter . Topics != nil {
if args . Filter . Topics != nil {
topics = * args . Filter . Topics
topics = * args . Filter . Topics
}
}
hash := b . hash
// Construct the range filter
if hash == ( common . Hash { } ) {
hash , err := b . Hash ( ctx )
header , err := b . resolveHeader ( ctx )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
hash = header . Hash ( )
}
// Construct the range filter
filter := b . r . filterSystem . NewBlockFilter ( hash , addresses , topics )
filter := b . r . filterSystem . NewBlockFilter ( hash , addresses , topics )
// Run the filter and return all the logs
// Run the filter and return all the logs
@ -1015,12 +1039,6 @@ func (b *Block) Logs(ctx context.Context, args struct{ Filter BlockFilterCriteri
func ( b * Block ) Account ( ctx context . Context , args struct {
func ( b * Block ) Account ( ctx context . Context , args struct {
Address common . Address
Address common . Address
} ) ( * Account , error ) {
} ) ( * Account , error ) {
if b . numberOrHash == nil {
_ , err := b . resolveHeader ( ctx )
if err != nil {
return nil , err
}
}
return & Account {
return & Account {
r : b . r ,
r : b . r ,
address : args . Address ,
address : args . Address ,
@ -1063,12 +1081,6 @@ func (c *CallResult) Status() Long {
func ( b * Block ) Call ( ctx context . Context , args struct {
func ( b * Block ) Call ( ctx context . Context , args struct {
Data ethapi . TransactionArgs
Data ethapi . TransactionArgs
} ) ( * CallResult , error ) {
} ) ( * CallResult , error ) {
if b . numberOrHash == nil {
_ , err := b . resolve ( ctx )
if err != nil {
return nil , err
}
}
result , err := ethapi . DoCall ( ctx , b . r . backend , args . Data , * b . numberOrHash , nil , b . r . backend . RPCEVMTimeout ( ) , b . r . backend . RPCGasCap ( ) )
result , err := ethapi . DoCall ( ctx , b . r . backend , args . Data , * b . numberOrHash , nil , b . r . backend . RPCEVMTimeout ( ) , b . r . backend . RPCGasCap ( ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
@ -1088,12 +1100,6 @@ func (b *Block) Call(ctx context.Context, args struct {
func ( b * Block ) EstimateGas ( ctx context . Context , args struct {
func ( b * Block ) EstimateGas ( ctx context . Context , args struct {
Data ethapi . TransactionArgs
Data ethapi . TransactionArgs
} ) ( Long , error ) {
} ) ( Long , error ) {
if b . numberOrHash == nil {
_ , err := b . resolveHeader ( ctx )
if err != nil {
return 0 , err
}
}
gas , err := ethapi . DoEstimateGas ( ctx , b . r . backend , args . Data , * b . numberOrHash , b . r . backend . RPCGasCap ( ) )
gas , err := ethapi . DoEstimateGas ( ctx , b . r . backend , args . Data , * b . numberOrHash , b . r . backend . RPCGasCap ( ) )
return Long ( gas ) , err
return Long ( gas ) , err
}
}
@ -1173,30 +1179,22 @@ func (r *Resolver) Block(ctx context.Context, args struct {
Number * Long
Number * Long
Hash * common . Hash
Hash * common . Hash
} ) ( * Block , error ) {
} ) ( * Block , error ) {
var block * Block
var numberOrHash rpc . BlockNumberOrHash
if args . Number != nil {
if args . Number != nil {
if * args . Number < 0 {
if * args . Number < 0 {
return nil , nil
return nil , nil
}
}
number := rpc . BlockNumber ( * args . Number )
number := rpc . BlockNumber ( * args . Number )
numberOrHash := rpc . BlockNumberOrHashWithNumber ( number )
numberOrHash = rpc . BlockNumberOrHashWithNumber ( number )
block = & Block {
r : r ,
numberOrHash : & numberOrHash ,
}
} else if args . Hash != nil {
} else if args . Hash != nil {
numberOrHash := rpc . BlockNumberOrHashWithHash ( * args . Hash , false )
numberOrHash = rpc . BlockNumberOrHashWithHash ( * args . Hash , false )
block = & Block {
r : r ,
numberOrHash : & numberOrHash ,
}
} else {
} else {
numberOrHash := rpc . BlockNumberOrHashWithNumber ( rpc . LatestBlockNumber )
numberOrHash = rpc . BlockNumberOrHashWithNumber ( rpc . LatestBlockNumber )
block = & Block {
}
block := & Block {
r : r ,
r : r ,
numberOrHash : & numberOrHash ,
numberOrHash : & numberOrHash ,
}
}
}
// Resolve the header, return nil if it doesn't exist.
// Resolve the header, return nil if it doesn't exist.
// Note we don't resolve block directly here since it will require an
// Note we don't resolve block directly here since it will require an
// additional network request for light client.
// additional network request for light client.
@ -1256,7 +1254,7 @@ func (r *Resolver) Transaction(ctx context.Context, args struct{ Hash common.Has
hash : args . Hash ,
hash : args . Hash ,
}
}
// Resolve the transaction; if it doesn't exist, return nil.
// Resolve the transaction; if it doesn't exist, return nil.
t , err := tx . resolve ( ctx )
t , _ , err := tx . resolve ( ctx )
if err != nil {
if err != nil {
return nil , err
return nil , err
} else if t == nil {
} else if t == nil {