mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
check progress at the end
This commit is contained in:
parent
0fab68d072
commit
c134d6b40e
6 changed files with 57 additions and 47 deletions
|
|
@ -275,17 +275,17 @@ func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, max
|
||||||
// // from the node's perspective. This can be due to
|
// // from the node's perspective. This can be due to
|
||||||
// the transaction indexer not being finished. The caller must explicitly check
|
// the transaction indexer not being finished. The caller must explicitly check
|
||||||
// the indexer progress.
|
// the indexer progress.
|
||||||
func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLookupEntry, *types.Transaction, error) {
|
func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLookupEntry, *types.Transaction) {
|
||||||
bc.txLookupLock.RLock()
|
bc.txLookupLock.RLock()
|
||||||
defer bc.txLookupLock.RUnlock()
|
defer bc.txLookupLock.RUnlock()
|
||||||
|
|
||||||
// Short circuit if the txlookup already in the cache, retrieve otherwise
|
// Short circuit if the txlookup already in the cache, retrieve otherwise
|
||||||
if item, exist := bc.txLookupCache.Get(hash); exist {
|
if item, exist := bc.txLookupCache.Get(hash); exist {
|
||||||
return item.lookup, item.transaction, nil
|
return item.lookup, item.transaction
|
||||||
}
|
}
|
||||||
tx, blockHash, blockNumber, txIndex := rawdb.ReadTransaction(bc.db, hash)
|
tx, blockHash, blockNumber, txIndex := rawdb.ReadTransaction(bc.db, hash)
|
||||||
if tx == nil {
|
if tx == nil {
|
||||||
return nil, nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
lookup := &rawdb.LegacyTxLookupEntry{
|
lookup := &rawdb.LegacyTxLookupEntry{
|
||||||
BlockHash: blockHash,
|
BlockHash: blockHash,
|
||||||
|
|
@ -296,11 +296,11 @@ func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLoo
|
||||||
lookup: lookup,
|
lookup: lookup,
|
||||||
transaction: tx,
|
transaction: tx,
|
||||||
})
|
})
|
||||||
return lookup, tx, nil
|
return lookup, tx
|
||||||
}
|
}
|
||||||
|
|
||||||
// TxIndexDone returns true if the transaction indexer has finished indexing.
|
// TxIndexDone returns true if the transaction indexer has finished indexing.
|
||||||
func (bc *BlockChain) TxIndexDone(ctx context.Context) (bool, error) {
|
func (bc *BlockChain) TxIndexDone(ctx context.Context) bool {
|
||||||
progress, err := bc.TxIndexProgress(ctx)
|
progress, err := bc.TxIndexProgress(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// No error is returned if the transaction indexing progress is unreachable
|
// No error is returned if the transaction indexing progress is unreachable
|
||||||
|
|
@ -310,12 +310,12 @@ func (bc *BlockChain) TxIndexDone(ctx context.Context) (bool, error) {
|
||||||
//
|
//
|
||||||
// In such scenarios, the transaction is treated as unreachable, though
|
// In such scenarios, the transaction is treated as unreachable, though
|
||||||
// this is clearly an unintended and unexpected situation.
|
// this is clearly an unintended and unexpected situation.
|
||||||
return true, nil
|
return true
|
||||||
}
|
}
|
||||||
if !progress.Done() {
|
if !progress.Done() {
|
||||||
return false, nil
|
return false
|
||||||
}
|
}
|
||||||
return true, nil
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasState checks if state trie is fully present in the database or not.
|
// HasState checks if state trie is fully present in the database or not.
|
||||||
|
|
|
||||||
|
|
@ -349,22 +349,21 @@ func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction
|
||||||
// GetTransaction retrieves the lookup along with the transaction itself associate
|
// GetTransaction retrieves the lookup along with the transaction itself associate
|
||||||
// with the given transaction hash.
|
// with the given transaction hash.
|
||||||
//
|
//
|
||||||
// An error will be returned if the transaction is not found, and background
|
// A null will be returned in the transaction is not found. The transaction is not existent
|
||||||
// indexing for transactions is still in progress. The error is used to indicate the
|
// // from the node's perspective. This can be due to
|
||||||
// scenario explicitly that the transaction might be reachable shortly.
|
// the transaction indexer not being finished. The caller must explicitly check
|
||||||
//
|
// the indexer progress.
|
||||||
// A null will be returned in the transaction is not found and background transaction
|
func (b *EthAPIBackend) GetTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) {
|
||||||
// indexing is already finished. The transaction is not existent from the perspective
|
lookup, tx := b.eth.blockchain.GetTransactionLookup(txHash)
|
||||||
// of node.
|
|
||||||
func (b *EthAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) {
|
|
||||||
lookup, tx, err := b.eth.blockchain.GetTransactionLookup(ctx, txHash)
|
|
||||||
if err != nil {
|
|
||||||
return false, nil, common.Hash{}, 0, 0, err
|
|
||||||
}
|
|
||||||
if lookup == nil || tx == nil {
|
if lookup == nil || tx == nil {
|
||||||
return false, nil, common.Hash{}, 0, 0, nil
|
return false, nil, common.Hash{}, 0, 0
|
||||||
}
|
}
|
||||||
return true, tx, lookup.BlockHash, lookup.BlockIndex, lookup.Index, nil
|
return true, tx, lookup.BlockHash, lookup.BlockIndex, lookup.Index
|
||||||
|
}
|
||||||
|
|
||||||
|
// TxIndexDone returns true if the transaction indexer has finished indexing.
|
||||||
|
func (b *EthAPIBackend) TxIndexDone(ctx context.Context) bool {
|
||||||
|
return b.eth.blockchain.TxIndexDone(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
|
func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,8 @@ type Backend interface {
|
||||||
HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
|
HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
|
||||||
BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
|
BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
|
||||||
BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
|
BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
|
||||||
GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error)
|
GetTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64)
|
||||||
|
TxIndexDone(ctx context.Context) bool
|
||||||
RPCGasCap() uint64
|
RPCGasCap() uint64
|
||||||
ChainConfig() *params.ChainConfig
|
ChainConfig() *params.ChainConfig
|
||||||
Engine() consensus.Engine
|
Engine() consensus.Engine
|
||||||
|
|
@ -858,12 +859,13 @@ func containsTx(block *types.Block, hash common.Hash) bool {
|
||||||
// TraceTransaction returns the structured logs created during the execution of EVM
|
// TraceTransaction returns the structured logs created during the execution of EVM
|
||||||
// and returns them as a JSON object.
|
// and returns them as a JSON object.
|
||||||
func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) {
|
func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) {
|
||||||
found, _, blockHash, blockNumber, index, err := api.backend.GetTransaction(ctx, hash)
|
found, _, blockHash, blockNumber, index := api.backend.GetTransaction(hash)
|
||||||
if err != nil {
|
if !found {
|
||||||
|
// Warn in case tx indexer is not done.
|
||||||
|
if !api.backend.TxIndexDone(ctx) {
|
||||||
return nil, ethapi.NewTxIndexingError()
|
return nil, ethapi.NewTxIndexingError()
|
||||||
}
|
}
|
||||||
// Only mined txes are supported
|
// Only mined txes are supported
|
||||||
if !found {
|
|
||||||
return nil, errTxNotFound
|
return nil, errTxNotFound
|
||||||
}
|
}
|
||||||
// It shouldn't happen in practice.
|
// It shouldn't happen in practice.
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,7 @@ func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, *Block)
|
||||||
return t.tx, t.block
|
return t.tx, t.block
|
||||||
}
|
}
|
||||||
// Try to return an already finalized transaction
|
// Try to return an already finalized transaction
|
||||||
found, tx, blockHash, _, index, _ := t.r.backend.GetTransaction(ctx, t.hash)
|
found, tx, blockHash, _, index := t.r.backend.GetTransaction(t.hash)
|
||||||
if found {
|
if found {
|
||||||
t.tx = tx
|
t.tx = tx
|
||||||
blockNrOrHash := rpc.BlockNumberOrHashWithHash(blockHash, false)
|
blockNrOrHash := rpc.BlockNumberOrHashWithHash(blockHash, false)
|
||||||
|
|
|
||||||
|
|
@ -1333,17 +1333,19 @@ func (api *TransactionAPI) GetTransactionCount(ctx context.Context, address comm
|
||||||
// GetTransactionByHash returns the transaction for the given hash
|
// GetTransactionByHash returns the transaction for the given hash
|
||||||
func (api *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) {
|
func (api *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) {
|
||||||
// Try to return an already finalized transaction
|
// Try to return an already finalized transaction
|
||||||
found, tx, blockHash, blockNumber, index, err := api.b.GetTransaction(ctx, hash)
|
found, tx, blockHash, blockNumber, index := api.b.GetTransaction(hash)
|
||||||
if !found {
|
if !found {
|
||||||
// No finalized transaction, try to retrieve it from the pool
|
// No finalized transaction, try to retrieve it from the pool
|
||||||
if tx := api.b.GetPoolTransaction(hash); tx != nil {
|
if tx := api.b.GetPoolTransaction(hash); tx != nil {
|
||||||
return NewRPCPendingTransaction(tx, api.b.CurrentHeader(), api.b.ChainConfig()), nil
|
return NewRPCPendingTransaction(tx, api.b.CurrentHeader(), api.b.ChainConfig()), nil
|
||||||
}
|
}
|
||||||
if err == nil {
|
// If also not in the pool there is a chance the tx indexer is still in progress.
|
||||||
return nil, nil
|
if !api.b.TxIndexDone(ctx) {
|
||||||
}
|
|
||||||
return nil, NewTxIndexingError()
|
return nil, NewTxIndexingError()
|
||||||
}
|
}
|
||||||
|
// If the transaction is not found in the pool and the indexer is done, return nil
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
header, err := api.b.HeaderByHash(ctx, blockHash)
|
header, err := api.b.HeaderByHash(ctx, blockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -1354,27 +1356,31 @@ func (api *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common
|
||||||
// GetRawTransactionByHash returns the bytes of the transaction for the given hash.
|
// GetRawTransactionByHash returns the bytes of the transaction for the given hash.
|
||||||
func (api *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
|
func (api *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
|
||||||
// Retrieve a finalized transaction, or a pooled otherwise
|
// Retrieve a finalized transaction, or a pooled otherwise
|
||||||
found, tx, _, _, _, err := api.b.GetTransaction(ctx, hash)
|
found, tx, _, _, _ := api.b.GetTransaction(hash)
|
||||||
if !found {
|
if !found {
|
||||||
if tx = api.b.GetPoolTransaction(hash); tx != nil {
|
if tx = api.b.GetPoolTransaction(hash); tx != nil {
|
||||||
return tx.MarshalBinary()
|
return tx.MarshalBinary()
|
||||||
}
|
}
|
||||||
if err == nil {
|
// If also not in the pool there is a chance the tx indexer is still in progress.
|
||||||
return nil, nil
|
if !api.b.TxIndexDone(ctx) {
|
||||||
}
|
|
||||||
return nil, NewTxIndexingError()
|
return nil, NewTxIndexingError()
|
||||||
}
|
}
|
||||||
|
// If the transaction is not found in the pool and the indexer is done, return nil
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
return tx.MarshalBinary()
|
return tx.MarshalBinary()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTransactionReceipt returns the transaction receipt for the given transaction hash.
|
// GetTransactionReceipt returns the transaction receipt for the given transaction hash.
|
||||||
func (api *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
|
func (api *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
|
||||||
found, tx, blockHash, blockNumber, index, err := api.b.GetTransaction(ctx, hash)
|
found, tx, blockHash, blockNumber, index := api.b.GetTransaction(hash)
|
||||||
if err != nil {
|
|
||||||
return nil, NewTxIndexingError() // transaction is not fully indexed
|
|
||||||
}
|
|
||||||
if !found {
|
if !found {
|
||||||
return nil, nil // transaction is not existent or reachable
|
// Make sure indexer is done.
|
||||||
|
if !api.b.TxIndexDone(ctx) {
|
||||||
|
return nil, NewTxIndexingError()
|
||||||
|
}
|
||||||
|
// No such tx.
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
header, err := api.b.HeaderByHash(ctx, blockHash)
|
header, err := api.b.HeaderByHash(ctx, blockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1774,16 +1780,18 @@ func (api *DebugAPI) GetRawReceipts(ctx context.Context, blockNrOrHash rpc.Block
|
||||||
// GetRawTransaction returns the bytes of the transaction for the given hash.
|
// GetRawTransaction returns the bytes of the transaction for the given hash.
|
||||||
func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
|
func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
|
||||||
// Retrieve a finalized transaction, or a pooled otherwise
|
// Retrieve a finalized transaction, or a pooled otherwise
|
||||||
found, tx, _, _, _, err := api.b.GetTransaction(ctx, hash)
|
found, tx, _, _, _ := api.b.GetTransaction(hash)
|
||||||
if !found {
|
if !found {
|
||||||
if tx = api.b.GetPoolTransaction(hash); tx != nil {
|
if tx = api.b.GetPoolTransaction(hash); tx != nil {
|
||||||
return tx.MarshalBinary()
|
return tx.MarshalBinary()
|
||||||
}
|
}
|
||||||
if err == nil {
|
// If also not in the pool there is a chance the tx indexer is still in progress.
|
||||||
return nil, nil
|
if !api.b.TxIndexDone(ctx) {
|
||||||
}
|
|
||||||
return nil, NewTxIndexingError()
|
return nil, NewTxIndexingError()
|
||||||
}
|
}
|
||||||
|
// Transaction is not found in the pool and the indexer is done.
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
return tx.MarshalBinary()
|
return tx.MarshalBinary()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,8 @@ type Backend interface {
|
||||||
|
|
||||||
// Transaction pool API
|
// Transaction pool API
|
||||||
SendTx(ctx context.Context, signedTx *types.Transaction) error
|
SendTx(ctx context.Context, signedTx *types.Transaction) error
|
||||||
GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error)
|
GetTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64)
|
||||||
|
TxIndexDone(ctx context.Context) bool
|
||||||
GetPoolTransactions() (types.Transactions, error)
|
GetPoolTransactions() (types.Transactions, error)
|
||||||
GetPoolTransaction(txHash common.Hash) *types.Transaction
|
GetPoolTransaction(txHash common.Hash) *types.Transaction
|
||||||
GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
|
GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue