public ResultWrapper <TransactionForRpc> eth_getTransactionByBlockNumberAndIndex(BlockParameter blockParameter, UInt256 positionIndex) { SearchResult <Block> searchResult = _blockFinder.SearchForBlock(blockParameter); if (searchResult.IsError) { return(ResultWrapper <TransactionForRpc> .Fail(searchResult)); } Block block = searchResult.Object; if (positionIndex < 0 || positionIndex > block.Transactions.Length - 1) { return(ResultWrapper <TransactionForRpc> .Fail("Position Index is incorrect", ErrorCodes.InvalidParams)); } Transaction transaction = block.Transactions[(int)positionIndex]; RecoverTxSenderIfNeeded(transaction); TransactionForRpc transactionModel = new TransactionForRpc(block.Hash, block.Number, (int)positionIndex, transaction); if (_logger.IsDebug) { _logger.Debug($"eth_getTransactionByBlockNumberAndIndex request {blockParameter}, index: {positionIndex}, result: {transactionModel.Hash}"); } return(ResultWrapper <TransactionForRpc> .Success(transactionModel)); }
public ResultWrapper <TransactionForRpc> eth_getTransactionByBlockHashAndIndex(Keccak blockHash, UInt256 positionIndex) { SearchResult <Block> searchResult = _blockFinder.SearchForBlock(new BlockParameter(blockHash)); if (searchResult.IsError) { return(ResultWrapper <TransactionForRpc> .Fail(searchResult)); } Block block = searchResult.Object; if (positionIndex < 0 || positionIndex > block.Transactions.Length - 1) { return(ResultWrapper <TransactionForRpc> .Fail("Position Index is incorrect", ErrorCodes.InvalidParams)); } Transaction transaction = block.Transactions[(int)positionIndex]; RecoverTxSenderIfNeeded(transaction); TransactionForRpc transactionModel = new(block.Hash, block.Number, (int)positionIndex, transaction, block.BaseFeePerGas); return(ResultWrapper <TransactionForRpc> .Success(transactionModel)); }
public void RecoverTxSenders(Block block) { for (int i = 0; i < block.Transactions.Length; i++) { RecoverTxSender(block.Transactions[i], block.Number); } }
private static void LoadGenesisBlock( ChainSpec chainSpec, Keccak expectedGenesisHash, IBlockTree blockTree, IStateProvider stateProvider, ISpecProvider specProvider) { // if we already have a database with blocks then we do not need to load genesis from spec if (blockTree.Genesis != null) { return; } foreach ((Address address, (UInt256 balance, byte[] code)) in chainSpec.Allocations) { stateProvider.CreateAccount(address, balance); if (code != null) { Keccak codeHash = stateProvider.UpdateCode(code); stateProvider.UpdateCodeHash(address, codeHash, specProvider.GenesisSpec); } } stateProvider.Commit(specProvider.GenesisSpec); Block genesis = chainSpec.Genesis; genesis.StateRoot = stateProvider.StateRoot; genesis.Hash = BlockHeader.CalculateHash(genesis.Header); ManualResetEventSlim genesisProcessedEvent = new ManualResetEventSlim(false); bool genesisLoaded = false; void GenesisProcessed(object sender, BlockEventArgs args) { genesisLoaded = true; blockTree.NewHeadBlock -= GenesisProcessed; genesisProcessedEvent.Set(); } blockTree.NewHeadBlock += GenesisProcessed; blockTree.SuggestBlock(genesis); genesisProcessedEvent.Wait(TimeSpan.FromSeconds(5)); if (!genesisLoaded) { throw new BlockchainException("Genesis block processing failure"); } // if expectedGenesisHash is null here then it means that we do not care about the exact value in advance (e.g. in test scenarios) if (expectedGenesisHash != null && blockTree.Genesis.Hash != expectedGenesisHash) { throw new Exception($"Unexpected genesis hash, expected {expectedGenesisHash}, but was {blockTree.Genesis.Hash}"); } }
public void RecoverTxSenders(Block block) { for (int i = 0; i < block.Transactions.Length; i++) { var transaction = block.Transactions[i]; if (transaction.SenderAddress == null) { RecoverTxSender(transaction, block.Number); } } }
public (TxReceipt Receipt, Transaction Transaction) GetTransaction(Keccak transactionHash) { TxReceipt txReceipt = _receiptStorage.Find(transactionHash); if (txReceipt?.BlockHash == null) { return(null, null); } Block block = _blockTree.FindBlock(txReceipt.BlockHash, BlockTreeLookupOptions.RequireCanonical); return(txReceipt, block?.Transactions[txReceipt.Index]); }
public (TransactionReceipt Receipt, Transaction Transaction) GetTransaction(Keccak transactionHash) { TransactionReceipt receipt = _receiptStorage.Get(transactionHash); if (receipt.BlockHash == null) { return(null, null); } Block block = _blockTree.FindBlock(receipt.BlockHash, true); return(receipt, block.Transactions[receipt.Index]); }
public long EstimateGas(Block block, Transaction transaction) { _stateProvider.StateRoot = _blockTree.Head.StateRoot; BlockHeader header = new BlockHeader(block.Hash, Keccak.OfAnEmptySequenceRlp, block.Beneficiary, block.Difficulty, block.Number + 1, block.GasLimit, block.Timestamp + 1, Bytes.Empty); transaction.Nonce = _stateProvider.GetNonce(transaction.SenderAddress); transaction.Hash = Nethermind.Core.Transaction.CalculateHash(transaction); CallOutputTracer callOutputTracer = new CallOutputTracer(); _transactionProcessor.CallAndRestore(transaction, header, callOutputTracer); _stateProvider.Reset(); return(callOutputTracer.GasSpent); }
public void Can_serialize_reward() { Block block = Build.A.Block.WithNumber(long.Parse("4563918244f40000".AsSpan(), NumberStyles.AllowHexSpecifier)).TestObject; IBlockTracer blockTracer = new ParityLikeBlockTracer(ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); blockTracer.StartNewBlockTrace(block); ITxTracer txTracer = blockTracer.StartNewTxTrace(null); txTracer.ReportBalanceChange(TestItem.AddressA, 0, 3.Ether()); blockTracer.EndTxTrace(); blockTracer.ReportReward(TestItem.AddressA, "block", UInt256.One); ParityLikeTxTrace trace = ((ParityLikeBlockTracer)blockTracer).BuildResult().SingleOrDefault(); TestOneWaySerialization(trace, "{\"trace\":[{\"action\":{\"callType\":\"reward\",\"from\":null,\"gas\":\"0x0\",\"input\":null,\"to\":null,\"value\":\"0x1\"},\"blockHash\":\"0xfed4f714d3626e046786ef043cbb30a4b87cdc288469d0b70e4529bbd4e15396\",\"blockNumber\":\"0x4563918244f40000\",\"result\":{\"gasUsed\":\"0x0\",\"output\":null},\"subtraces\":0,\"traceAddress\":\"[]\",\"transactionHash\":null,\"transactionPosition\":null,\"type\":\"reward\"}],\"stateDiff\":{\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\":{\"balance\":{\"*\":{\"from\":\"0x0\",\"to\":\"0x29a2241af62c0000\"}},\"code\":\"=\",\"nonce\":\"=\",\"storage\":{}}}}"); }
public void Can_serialize_reward_state_only() { Block block = Build.A.Block.WithNumber(long.Parse("4563918244f40000".AsSpan(), NumberStyles.AllowHexSpecifier)).TestObject; IBlockTracer blockTracer = new ParityLikeBlockTracer(ParityTraceTypes.StateDiff); blockTracer.StartNewBlockTrace(block); ITxTracer txTracer = blockTracer.StartNewTxTrace(null); txTracer.ReportBalanceChange(TestItem.AddressA, 0, 3.Ether()); blockTracer.EndTxTrace(); blockTracer.ReportReward(TestItem.AddressA, "block", UInt256.One); ParityLikeTxTrace trace = ((ParityLikeBlockTracer)blockTracer).BuildResult().SingleOrDefault(); TestOneWaySerialization(trace, "{\"trace\":null,\"stateDiff\":{\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\":{\"balance\":{\"*\":{\"from\":\"0x0\",\"to\":\"0x29a2241af62c0000\"}},\"code\":\"=\",\"nonce\":\"=\",\"storage\":{}}}}"); }
public (TxReceipt Receipt, UInt256?EffectiveGasPrice) GetReceiptAndEffectiveGasPrice(Keccak txHash) { Keccak blockHash = _receiptFinder.FindBlockHash(txHash); if (blockHash != null) { Block block = _blockTree.FindBlock(blockHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded); TxReceipt txReceipt = _receiptFinder.Get(block).ForTransaction(txHash); Transaction tx = block?.Transactions[txReceipt.Index]; bool is1559Enabled = _specProvider.GetSpec(block.Number).IsEip1559Enabled; UInt256 effectiveGasPrice = tx.CalculateEffectiveGasPrice(is1559Enabled, block.Header.BaseFeePerGas); return(txReceipt, effectiveGasPrice); } return(null, null); }
public (TxReceipt Receipt, Transaction Transaction) GetTransaction(Keccak transactionHash) { TxReceipt txReceipt = _receiptStorage.Find(transactionHash); if (txReceipt?.BlockHash != null) { Block block = _blockTree.FindBlock(txReceipt.BlockHash, BlockTreeLookupOptions.RequireCanonical); return(txReceipt, block?.Transactions[txReceipt.Index]); } else if (_txPool.TryGetPendingTransaction(transactionHash, out var transaction)) { return(null, transaction); } else { return(null, null); } }
public (TxReceipt Receipt, Transaction Transaction, UInt256?baseFee) GetTransaction(Keccak txHash) { Keccak blockHash = _receiptFinder.FindBlockHash(txHash); if (blockHash is not null) { Block block = _processingEnv.BlockTree.FindBlock(blockHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded); TxReceipt txReceipt = _receiptFinder.Get(block).ForTransaction(txHash); return(txReceipt, block?.Transactions[txReceipt.Index], block?.BaseFeePerGas); } if (_txPool.TryGetPendingTransaction(txHash, out Transaction? transaction)) { return(null, transaction, null); } return(null, null, null); }
public (TxReceipt Receipt, Transaction Transaction) GetTransaction(Keccak txHash) { Keccak blockHash = _receiptFinder.FindBlockHash(txHash); if (blockHash != null) { Block block = _blockTree.FindBlock(blockHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded); TxReceipt txReceipt = _receiptFinder.Get(block).ForTransaction(txHash); return(txReceipt, block?.Transactions[txReceipt.Index]); } if (_txPool.TryGetPendingTransaction(txHash, out var transaction)) { return(null, transaction); } return(null, null); }
private ResultWrapper <BlockForRpc> GetBlock(BlockParameter blockParameter, bool returnFullTransactionObjects) { SearchResult <Block> searchResult = _blockFinder.SearchForBlock(blockParameter, true); if (searchResult.IsError) { return(ResultWrapper <BlockForRpc> .Fail(searchResult)); } Block block = searchResult.Object; if (block != null) { _blockchainBridge.RecoverTxSenders(block); } return(ResultWrapper <BlockForRpc> .Success(block == null?null : new BlockForRpc(block, returnFullTransactionObjects))); }
private ResultWrapper <BlockForRpc> GetUncle(BlockParameter blockParameter, UInt256 positionIndex) { SearchResult <Block> searchResult = _blockFinder.SearchForBlock(blockParameter); if (searchResult.IsError) { return(ResultWrapper <BlockForRpc> .Fail(searchResult)); } Block block = searchResult.Object; if (positionIndex < 0 || positionIndex > block.Uncles.Length - 1) { return(ResultWrapper <BlockForRpc> .Fail("Position Index is incorrect", ErrorCodes.InvalidParams)); } BlockHeader uncleHeader = block.Uncles[(int)positionIndex]; return(ResultWrapper <BlockForRpc> .Success(new BlockForRpc(new Block(uncleHeader, BlockBody.Empty), false, _specProvider))); }
public byte[] Call(Block block, Transaction transaction) { try { _readerWriterLockSlim.EnterWriteLock(); _stateProvider.StateRoot = _blockTree.Head.StateRoot; BlockHeader header = new BlockHeader(block.Hash, Keccak.OfAnEmptySequenceRlp, block.Beneficiary, block.Difficulty, block.Number + 1, (long)transaction.GasLimit, block.Timestamp + 1, Bytes.Empty); transaction.Nonce = _stateProvider.GetNonce(transaction.SenderAddress); transaction.Hash = Transaction.CalculateHash(transaction); CallOutputTracer callOutputTracer = new CallOutputTracer(); _transactionProcessor.CallAndRestore(transaction, header, callOutputTracer); _stateProvider.Reset(); return(callOutputTracer.ReturnValue); } finally { _readerWriterLockSlim.ExitWriteLock(); } }
private void LoadGenesisBlock(Keccak expectedGenesisHash) { // if we already have a database with blocks then we do not need to load genesis from spec if (_blockTree.Genesis != null) { ValidateGenesisHash(expectedGenesisHash); return; } Block genesis = _chainSpec.Genesis; CreateSystemAccounts(); foreach ((Address address, ChainSpecAllocation allocation) in _chainSpec.Allocations) { _stateProvider.CreateAccount(address, allocation.Balance); if (allocation.Code != null) { Keccak codeHash = _stateProvider.UpdateCode(allocation.Code); _stateProvider.UpdateCodeHash(address, codeHash, _specProvider.GenesisSpec); } if (allocation.Constructor != null) { Transaction constructorTransaction = new Transaction(true) { SenderAddress = address, Init = allocation.Constructor, GasLimit = genesis.GasLimit }; _transactionProcessor.Execute(constructorTransaction, genesis.Header, NullTxTracer.Instance); } } _storageProvider.Commit(); _stateProvider.Commit(_specProvider.GenesisSpec); _storageProvider.CommitTrees(); _stateProvider.CommitTree(); _dbProvider.StateDb.Commit(); _dbProvider.CodeDb.Commit(); genesis.StateRoot = _stateProvider.StateRoot; genesis.Hash = BlockHeader.CalculateHash(genesis.Header); ManualResetEventSlim genesisProcessedEvent = new ManualResetEventSlim(false); bool genesisLoaded = false; void GenesisProcessed(object sender, BlockEventArgs args) { genesisLoaded = true; _blockTree.NewHeadBlock -= GenesisProcessed; genesisProcessedEvent.Set(); } _blockTree.NewHeadBlock += GenesisProcessed; _blockTree.SuggestBlock(genesis); genesisProcessedEvent.Wait(TimeSpan.FromSeconds(5)); if (!genesisLoaded) { throw new BlockchainException("Genesis block processing failure"); } ValidateGenesisHash(expectedGenesisHash); }
public TxReceipt[] GetReceipts(Block block) => _receiptStorage.FindForBlock(block);