Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPC Tx lookup changes #7282

Merged
merged 1 commit into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 30 additions & 21 deletions src/Nethermind/Nethermind.Facade/BlockchainBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Filters;
using Nethermind.Blockchain.Find;
Expand Down Expand Up @@ -94,44 +95,52 @@ public Block? HeadBlock

public bool IsMining { get; }

public (TxReceipt? Receipt, TxGasInfo? GasInfo, int LogIndexStart) GetReceiptAndGasInfo(Hash256 txHash)
private bool TryGetCanonicalTransaction(
Hash256 txHash,
[NotNullWhen(true)] out Transaction? transaction,
[NotNullWhen(true)] out TxReceipt? receipt,
[NotNullWhen(true)] out Block? block,
[NotNullWhen(true)] out TxReceipt[]? receipts)
{
Hash256 blockHash = _receiptFinder.FindBlockHash(txHash);
if (blockHash is not null)
{
Block? block = _blockTree.FindBlock(blockHash, BlockTreeLookupOptions.RequireCanonical);
block = _blockTree.FindBlock(blockHash, BlockTreeLookupOptions.RequireCanonical);
if (block is not null)
{
TxReceipt[] txReceipts = _receiptFinder.Get(block);
TxReceipt txReceipt = txReceipts.ForTransaction(txHash);
int logIndexStart = txReceipts.GetBlockLogFirstIndex(txReceipt.Index);
Transaction tx = block.Transactions[txReceipt.Index];
bool is1559Enabled = _specProvider.GetSpecFor1559(block.Number).IsEip1559Enabled;
return (txReceipt, tx.GetGasInfo(is1559Enabled, block.Header), logIndexStart);
receipts = _receiptFinder.Get(block);
receipt = receipts.ForTransaction(txHash);
transaction = block.Transactions[receipt.Index];
return true;
}
}

return (null, null, 0);
transaction = null;
receipt = null;
receipts = null;
block = null;
return false;
}

public (TxReceipt? Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Hash256 txHash, bool checkTxnPool = true)
public (TxReceipt? Receipt, TxGasInfo? GasInfo, int LogIndexStart) GetReceiptAndGasInfo(Hash256 txHash)
{
Hash256 blockHash = _receiptFinder.FindBlockHash(txHash);
if (blockHash is not null)
if (TryGetCanonicalTransaction(txHash, out Transaction? tx, out TxReceipt? txReceipt, out Block? block, out TxReceipt[]? txReceipts))
{
Block block = _blockTree.FindBlock(blockHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded);
TxReceipt txReceipt = _receiptFinder.Get(block).ForTransaction(txHash);
return (txReceipt, block?.Transactions[txReceipt.Index], block?.BaseFeePerGas);
int logIndexStart = txReceipts.GetBlockLogFirstIndex(txReceipt.Index);
bool is1559Enabled = _specProvider.GetSpecFor1559(block.Number).IsEip1559Enabled;
return (txReceipt, tx.GetGasInfo(is1559Enabled, block.Header), logIndexStart);
}

if (checkTxnPool && _txPool.TryGetPendingTransaction(txHash, out Transaction? transaction))
{
return (null, transaction, null);
}

return (null, null, null);
return (null, null, 0);
}

public (TxReceipt? Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Hash256 txHash, bool checkTxnPool = true) =>
TryGetCanonicalTransaction(txHash, out Transaction? tx, out TxReceipt? txReceipt, out Block? block, out TxReceipt[]? _)
? (txReceipt, tx, block.BaseFeePerGas)
: checkTxnPool && _txPool.TryGetPendingTransaction(txHash, out Transaction? transaction)
? (null, transaction, null)
: (null, null, null);

public TxReceipt? GetReceipt(Hash256 txHash)
{
Hash256? blockHash = _receiptFinder.FindBlockHash(txHash);
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface IBlockchainBridge : ILogFinder
Address? RecoverTxSender(Transaction tx);
TxReceipt GetReceipt(Hash256 txHash);
(TxReceipt? Receipt, TxGasInfo? GasInfo, int LogIndexStart) GetReceiptAndGasInfo(Hash256 txHash);
(TxReceipt? Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Hash256 txHash, bool checkTxnPool = true);
(TxReceipt? Receipt, Transaction? Transaction, UInt256? baseFee) GetTransaction(Hash256 txHash, bool checkTxnPool = true);
CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken);
SimulateOutput Simulate(BlockHeader header, SimulatePayload<TransactionWithSourceDetails> payload, CancellationToken cancellationToken);
CallOutput EstimateGas(BlockHeader header, Transaction tx, int errorMarginBasisPoints, CancellationToken cancellationToken);
Expand Down
22 changes: 7 additions & 15 deletions src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public partial class EthRpcModule(
protected readonly IBlockFinder _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder));
protected readonly IReceiptFinder _receiptFinder = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder));
protected readonly IStateReader _stateReader = stateReader ?? throw new ArgumentNullException(nameof(stateReader));
protected readonly ITxPool _txPoolBridge = txPool ?? throw new ArgumentNullException(nameof(txPool));
protected readonly ITxPool _txPool = txPool ?? throw new ArgumentNullException(nameof(txPool));
protected readonly ITxSender _txSender = txSender ?? throw new ArgumentNullException(nameof(txSender));
protected readonly IWallet _wallet = wallet ?? throw new ArgumentNullException(nameof(wallet));
protected readonly ISpecProvider _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
Expand Down Expand Up @@ -184,7 +184,7 @@ public Task<ResultWrapper<UInt256>> eth_getTransactionCount(Address address, Blo
{
if (blockParameter == BlockParameter.Pending)
{
UInt256 pendingNonce = _txPoolBridge.GetLatestPendingNonce(address);
UInt256 pendingNonce = _txPool.GetLatestPendingNonce(address);
return Task.FromResult(ResultWrapper<UInt256>.Success(pendingNonce));
}

Expand Down Expand Up @@ -369,29 +369,21 @@ public ResultWrapper<BlockForRpc> eth_getBlockByNumber(BlockParameter blockParam

public Task<ResultWrapper<TransactionForRpc>> eth_getTransactionByHash(Hash256 transactionHash)
{
UInt256? baseFee = null;
_txPoolBridge.TryGetPendingTransaction(transactionHash, out Transaction transaction);
TxReceipt receipt = null; // note that if transaction is pending then for sure no receipt is known
(TxReceipt? receipt, Transaction? transaction, UInt256? baseFee) = _blockchainBridge.GetTransaction(transactionHash, checkTxnPool: true);
if (transaction is null)
{
(receipt, transaction, baseFee) = _blockchainBridge.GetTransaction(transactionHash, checkTxnPool: false);
if (transaction is null)
{
return Task.FromResult(ResultWrapper<TransactionForRpc>.Success(null));
}
return Task.FromResult(ResultWrapper<TransactionForRpc>.Success(null));
}

RecoverTxSenderIfNeeded(transaction);
TransactionForRpc transactionModel =
new(receipt?.BlockHash, receipt?.BlockNumber, receipt?.Index, transaction, baseFee);
if (_logger.IsTrace)
_logger.Trace($"eth_getTransactionByHash request {transactionHash}, result: {transactionModel.Hash}");
TransactionForRpc transactionModel = new(receipt?.BlockHash, receipt?.BlockNumber, receipt?.Index, transaction, baseFee);
if (_logger.IsTrace) _logger.Trace($"eth_getTransactionByHash request {transactionHash}, result: {transactionModel.Hash}");
return Task.FromResult(ResultWrapper<TransactionForRpc>.Success(transactionModel));
}

public ResultWrapper<TransactionForRpc[]> eth_pendingTransactions()
{
Transaction[] transactions = _txPoolBridge.GetPendingTransactions();
Transaction[] transactions = _txPool.GetPendingTransactions();
TransactionForRpc[] transactionsModels = new TransactionForRpc[transactions.Length];
for (int i = 0; i < transactions.Length; i++)
{
Expand Down
13 changes: 3 additions & 10 deletions src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,22 +163,15 @@ public override async Task<ResultWrapper<Hash256>> eth_sendRawTransaction(byte[]

public new Task<ResultWrapper<OptimismTransactionForRpc?>> eth_getTransactionByHash(Hash256 transactionHash)
{
UInt256? baseFee = null;
_txPoolBridge.TryGetPendingTransaction(transactionHash, out Transaction? transaction);
TxReceipt? receipt = null; // note that if transaction is pending then for sure no receipt is known
(TxReceipt? receipt, Transaction? transaction, UInt256? baseFee) = _blockchainBridge.GetTransaction(transactionHash, checkTxnPool: true);
if (transaction is null)
{
(receipt, transaction, baseFee) = _blockchainBridge.GetTransaction(transactionHash, checkTxnPool: false);
if (transaction is null)
{
return Task.FromResult(ResultWrapper<OptimismTransactionForRpc?>.Success(null!));
}
return Task.FromResult(ResultWrapper<OptimismTransactionForRpc?>.Success(null!));
}

RecoverTxSenderIfNeeded(transaction);
OptimismTransactionForRpc transactionModel = new(receipt?.BlockHash, receipt as OptimismTxReceipt, transaction, baseFee);
if (_logger.IsTrace)
_logger.Trace($"eth_getTransactionByHash request {transactionHash}, result: {transactionModel.Hash}");
if (_logger.IsTrace) _logger.Trace($"eth_getTransactionByHash request {transactionHash}, result: {transactionModel.Hash}");
return Task.FromResult(ResultWrapper<OptimismTransactionForRpc?>.Success(transactionModel));
}

Expand Down