mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 22:26:42 +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
|
||||
// the transaction indexer not being finished. The caller must explicitly check
|
||||
// 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()
|
||||
defer bc.txLookupLock.RUnlock()
|
||||
|
||||
// Short circuit if the txlookup already in the cache, retrieve otherwise
|
||||
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)
|
||||
if tx == nil {
|
||||
return nil, nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
lookup := &rawdb.LegacyTxLookupEntry{
|
||||
BlockHash: blockHash,
|
||||
|
|
@ -296,11 +296,11 @@ func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLoo
|
|||
lookup: lookup,
|
||||
transaction: tx,
|
||||
})
|
||||
return lookup, tx, nil
|
||||
return lookup, tx
|
||||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
// 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
|
||||
// this is clearly an unintended and unexpected situation.
|
||||
return true, nil
|
||||
return true
|
||||
}
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -349,22 +349,21 @@ func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction
|
|||
// GetTransaction retrieves the lookup along with the transaction itself associate
|
||||
// with the given transaction hash.
|
||||
//
|
||||
// An error will be returned if the transaction is not found, and background
|
||||
// indexing for transactions is still in progress. The error is used to indicate the
|
||||
// scenario explicitly that the transaction might be reachable shortly.
|
||||
//
|
||||
// A null will be returned in the transaction is not found and background transaction
|
||||
// indexing is already finished. The transaction is not existent from the perspective
|
||||
// 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
|
||||
}
|
||||
// A null will be returned in the transaction is not found. The transaction is not existent
|
||||
// // from the node's perspective. This can be due to
|
||||
// the transaction indexer not being finished. The caller must explicitly check
|
||||
// the indexer progress.
|
||||
func (b *EthAPIBackend) GetTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) {
|
||||
lookup, tx := b.eth.blockchain.GetTransactionLookup(txHash)
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,8 @@ type Backend interface {
|
|||
HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
|
||||
BlockByHash(ctx context.Context, hash common.Hash) (*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
|
||||
ChainConfig() *params.ChainConfig
|
||||
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
|
||||
// and returns them as a JSON object.
|
||||
func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) {
|
||||
found, _, blockHash, blockNumber, index, err := api.backend.GetTransaction(ctx, hash)
|
||||
if err != nil {
|
||||
return nil, ethapi.NewTxIndexingError()
|
||||
}
|
||||
// Only mined txes are supported
|
||||
found, _, blockHash, blockNumber, index := api.backend.GetTransaction(hash)
|
||||
if !found {
|
||||
// Warn in case tx indexer is not done.
|
||||
if !api.backend.TxIndexDone(ctx) {
|
||||
return nil, ethapi.NewTxIndexingError()
|
||||
}
|
||||
// Only mined txes are supported
|
||||
return nil, errTxNotFound
|
||||
}
|
||||
// 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
|
||||
}
|
||||
// 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 {
|
||||
t.tx = tx
|
||||
blockNrOrHash := rpc.BlockNumberOrHashWithHash(blockHash, false)
|
||||
|
|
|
|||
|
|
@ -1333,16 +1333,18 @@ func (api *TransactionAPI) GetTransactionCount(ctx context.Context, address comm
|
|||
// GetTransactionByHash returns the transaction for the given hash
|
||||
func (api *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) {
|
||||
// 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 {
|
||||
// No finalized transaction, try to retrieve it from the pool
|
||||
if tx := api.b.GetPoolTransaction(hash); tx != nil {
|
||||
return NewRPCPendingTransaction(tx, api.b.CurrentHeader(), api.b.ChainConfig()), nil
|
||||
}
|
||||
if err == nil {
|
||||
return nil, nil
|
||||
// If also not in the pool there is a chance the tx indexer is still in progress.
|
||||
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)
|
||||
if err != nil {
|
||||
|
|
@ -1354,27 +1356,31 @@ func (api *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common
|
|||
// GetRawTransactionByHash returns the bytes of the transaction for the given hash.
|
||||
func (api *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
|
||||
// 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 tx = api.b.GetPoolTransaction(hash); tx != nil {
|
||||
return tx.MarshalBinary()
|
||||
}
|
||||
if err == nil {
|
||||
return nil, nil
|
||||
// If also not in the pool there is a chance the tx indexer is still in progress.
|
||||
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()
|
||||
}
|
||||
|
||||
// GetTransactionReceipt returns the transaction receipt for the given transaction hash.
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, NewTxIndexingError() // transaction is not fully indexed
|
||||
}
|
||||
found, tx, blockHash, blockNumber, index := api.b.GetTransaction(hash)
|
||||
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)
|
||||
if err != nil {
|
||||
|
|
@ -1774,15 +1780,17 @@ func (api *DebugAPI) GetRawReceipts(ctx context.Context, blockNrOrHash rpc.Block
|
|||
// GetRawTransaction returns the bytes of the transaction for the given hash.
|
||||
func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
|
||||
// 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 tx = api.b.GetPoolTransaction(hash); tx != nil {
|
||||
return tx.MarshalBinary()
|
||||
}
|
||||
if err == nil {
|
||||
return nil, nil
|
||||
// If also not in the pool there is a chance the tx indexer is still in progress.
|
||||
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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,8 @@ type Backend interface {
|
|||
|
||||
// Transaction pool API
|
||||
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)
|
||||
GetPoolTransaction(txHash common.Hash) *types.Transaction
|
||||
GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
|
||||
|
|
|
|||
Loading…
Reference in a new issue