From 76c73a13f852a43937c1d589bb83bb22e778319b Mon Sep 17 00:00:00 2001 From: Ayman Bouchareb Date: Thu, 21 Dec 2023 14:09:54 +0100 Subject: [PATCH] Add new RPC methods debug_getRawBlock, debug_getRawReceipts, debug_getRawHeader, debug_getRawTransaction (#6368) * Fix peer header when no peers to show (#4411) * Fix peer header when no peers to show * Only order once * Better fix maybe * Applying lukasz suggestion * Revise product version (#4322) * Replace submodules with packages (#4374) * Add optional argument Address in parity_pendingTransactions (#4413) * Add enough projects to build benchmark runner (#4431) * Fix peer header when no peers to show (#4411) * Fix peer header when no peers to show * Only order once * Better fix maybe * Applying lukasz suggestion * Revise product version (#4322) * Replace submodules with packages (#4374) * Add optional argument Address in parity_pendingTransactions (#4413) * Add enough projects to build benchmark runner (#4431) * Fix develop branch * Exit early on error (#4220) Exit early on error in steps except for step with "mustInitialize" set to false. * Fix peer header when no peers to show (#4411) * Fix peer header when no peers to show * Only order once * Better fix maybe * Applying lukasz suggestion * Revise product version (#4322) * Replace submodules with packages (#4374) * Add optional argument Address in parity_pendingTransactions (#4413) * Add enough projects to build benchmark runner (#4431) * Fix develop branch * Exit early on error (#4220) Exit early on error in steps except for step with "mustInitialize" set to false. * Changes to BlockForRPC class : Ignored Author field in JsonDeserialization * Changes to TransactionForRPC class : Ignored 'data' field in JsonDeserialization if null or empty, and Assigned ChainId from Signature.ChainId if tx.ChainId is null * Changes to [DebugBridge, IDebugBridge] files : Added utility functions to get Transactions and Receipts per block * Changes to [DebugRpcModule, IDebugRpcModule] files : Added missing debug Functions [getRawBlock, getRawBlockHeader, getRawReceipts, getRawTransaction] * Changes to TransactionForRPC class : Ignored 'data' field in JsonDeserialization if null or empty, and Assigned ChainId from Signature.ChainId if tx.ChainId is null * Changes to ProofConverter class : stripped leading zeros from value field, and stripped leading zeros while keeping lenght even in key * Changes to [DebugRpcModule, IDebugRpcModule] files : new Debug functions only accept Keccak inputs * Changes to [DebugRpcModule, IDebugRpcModule] files : fix getRawReceipts * Changes to [Rlp, ReceiptStorageDecoder] files : added parameterless constructor to RSD, and added a selector method to decorder in RLP * Changes to [ReceiptMessageDecoder] files : added IRlpObjectDecoder interface to RMD * Changes to [Rlp] files : changed Decoder selection strategy to depend on custom attribute * Changes to [DebugRpcModule] files : added custom RlpBehaviour to Rlp.Encode in debug_getRawReceipts * Changes to [EthRpcModule.cs] files : deactivated optimization for eth_createaAccessList * fix merge issues * fix failing tests * fixed ws removed added file * fix merge issue * revert script changes * remove non related changes from PR --------- Co-authored-by: smartprogrammer93 <33181301+smartprogrammer93@users.noreply.github.com> Co-authored-by: Ruben Buniatyan Co-authored-by: Alexey Co-authored-by: DCeleda Co-authored-by: Amirul Ashraf --- scripts/deployment/archive-packages.sh | 0 scripts/deployment/build-runner.sh | 0 .../Modules/DebugModuleTests.cs | 9 ++-- .../Modules/DebugModule/DebugBridge.cs | 42 ++++++++++++++++ .../Modules/DebugModule/DebugRpcModule.cs | 48 ++++++++++++++++++- .../Modules/DebugModule/IDebugBridge.cs | 4 ++ .../Modules/DebugModule/IDebugRpcModule.cs | 12 +++++ 7 files changed, 109 insertions(+), 6 deletions(-) mode change 100755 => 100644 scripts/deployment/archive-packages.sh mode change 100755 => 100644 scripts/deployment/build-runner.sh diff --git a/scripts/deployment/archive-packages.sh b/scripts/deployment/archive-packages.sh old mode 100755 new mode 100644 diff --git a/scripts/deployment/build-runner.sh b/scripts/deployment/build-runner.sh old mode 100755 new mode 100644 diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs index dabb9c414e0..ed059c86e65 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs @@ -20,6 +20,7 @@ using Nethermind.Logging; using Nethermind.Serialization.Rlp; using NSubstitute; +using NSubstitute.ReturnsExtensions; using NUnit.Framework; namespace Nethermind.JsonRpc.Test.Modules; @@ -88,7 +89,7 @@ public async Task Get_block_rlp_by_hash() { BlockDecoder decoder = new(); Rlp rlp = decoder.Encode(Build.A.Block.WithNumber(1).TestObject); - debugBridge.GetBlockRlp(Keccak.Zero).Returns(rlp.Bytes); + debugBridge.GetBlockRlp(new BlockParameter(Keccak.Zero)).Returns(rlp.Bytes); DebugRpcModule rpcModule = new(LimboLogs.Instance, debugBridge, jsonRpcConfig); JsonRpcSuccessResponse? response = await RpcTest.TestRequest(rpcModule, "debug_getBlockRlpByHash", $"{Keccak.Zero.Bytes.ToHexString()}") as JsonRpcSuccessResponse; @@ -101,7 +102,7 @@ public async Task Get_block_rlp() BlockDecoder decoder = new(); IDebugBridge debugBridge = Substitute.For(); Rlp rlp = decoder.Encode(Build.A.Block.WithNumber(1).TestObject); - debugBridge.GetBlockRlp(1).Returns(rlp.Bytes); + debugBridge.GetBlockRlp(new BlockParameter(1)).Returns(rlp.Bytes); DebugRpcModule rpcModule = new(LimboLogs.Instance, debugBridge, jsonRpcConfig); JsonRpcSuccessResponse? response = await RpcTest.TestRequest(rpcModule, "debug_getBlockRlp", "1") as JsonRpcSuccessResponse; @@ -112,7 +113,7 @@ public async Task Get_block_rlp() [Test] public async Task Get_block_rlp_when_missing() { - debugBridge.GetBlockRlp(1).Returns((byte[])null!); + debugBridge.GetBlockRlp(new BlockParameter(1)).ReturnsNull(); DebugRpcModule rpcModule = new(LimboLogs.Instance, debugBridge, jsonRpcConfig); JsonRpcErrorResponse? response = await RpcTest.TestRequest(rpcModule, "debug_getBlockRlp", "1") as JsonRpcErrorResponse; @@ -125,7 +126,7 @@ public async Task Get_block_rlp_by_hash_when_missing() { BlockDecoder decoder = new(); Rlp rlp = decoder.Encode(Build.A.Block.WithNumber(1).TestObject); - debugBridge.GetBlockRlp(Keccak.Zero).Returns((byte[])null!); + debugBridge.GetBlockRlp(new BlockParameter(Keccak.Zero)).ReturnsNull(); DebugRpcModule rpcModule = new(LimboLogs.Instance, debugBridge, jsonRpcConfig); JsonRpcErrorResponse? response = await RpcTest.TestRequest(rpcModule, "debug_getBlockRlpByHash", $"{Keccak.Zero.Bytes.ToHexString()}") as JsonRpcErrorResponse; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs index eb45fb78b4c..c55f8e32c61 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugBridge.cs @@ -118,6 +118,31 @@ public void InsertReceipts(BlockParameter blockParameter, TxReceipt[] txReceipts _receiptStorage.Insert(block, txReceipts); } + public TxReceipt[]? GetReceiptsForBlock(BlockParameter blockParam) + { + SearchResult searchResult = _blockTree.SearchForBlock(blockParam); + if (searchResult.IsError) + { + throw new InvalidDataException(searchResult.Error); + } + + Block block = searchResult.Object; + return _receiptStorage.Get(block); + } + + public Transaction? GetTransactionFromHash(Hash256 txHash) + { + Hash256 blockHash = _receiptStorage.FindBlockHash(txHash); + SearchResult searchResult = _blockTree.SearchForBlock(new BlockParameter(blockHash)); + if (searchResult.IsError) + { + throw new InvalidDataException(searchResult.Error); + } + Block block = searchResult.Object; + TxReceipt txReceipt = _receiptStorage.Get(block).ForTransaction(txHash); + return block?.Transactions[txReceipt.Index]; + } + public GethLikeTxTrace GetTransactionTrace(Hash256 transactionHash, CancellationToken cancellationToken, GethTraceOptions gethTraceOptions = null) { return _tracer.Trace(transactionHash, gethTraceOptions ?? GethTraceOptions.Default, cancellationToken); @@ -153,11 +178,28 @@ public IReadOnlyCollection GetBlockTrace(Rlp blockRlp, Cancella return _tracer.TraceBlock(blockRlp, gethTraceOptions ?? GethTraceOptions.Default, cancellationToken); } + + public byte[]? GetBlockRlp(BlockParameter parameter) + { + if (parameter.BlockHash is Hash256 hash) + { + return GetBlockRlp(hash); + + } + if (parameter.BlockNumber is long num) + { + return GetBlockRlp(num); + } + return null; + } + public byte[] GetBlockRlp(Hash256 blockHash) { return _dbMappings[DbNames.Blocks].Get(blockHash); } + public Block? GetBlock(BlockParameter param) + => _blockTree.FindBlock(param); public byte[] GetBlockRlp(long number) { Hash256 hash = _blockTree.FindHash(number); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs index 4b2ba933ff5..d24f73cb7fc 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs @@ -208,7 +208,7 @@ public ResultWrapper debug_gcStats() public ResultWrapper debug_getBlockRlp(long blockNumber) { - byte[] rlp = _debugBridge.GetBlockRlp(blockNumber); + byte[] rlp = _debugBridge.GetBlockRlp(new BlockParameter(blockNumber)); if (rlp is null) { return ResultWrapper.Fail($"Block {blockNumber} was not found", ErrorCodes.ResourceNotFound); @@ -219,7 +219,7 @@ public ResultWrapper debug_getBlockRlp(long blockNumber) public ResultWrapper debug_getBlockRlpByHash(Hash256 hash) { - byte[] rlp = _debugBridge.GetBlockRlp(hash); + byte[] rlp = _debugBridge.GetBlockRlp(new BlockParameter(hash)); if (rlp is null) { return ResultWrapper.Fail($"Block {hash} was not found", ErrorCodes.ResourceNotFound); @@ -261,6 +261,50 @@ public ResultWrapper debug_resetHead(Hash256 blockHash) return ResultWrapper.Success(true); } + public ResultWrapper debug_getRawTransaction(Hash256 transactionHash) + { + var transaction = _debugBridge.GetTransactionFromHash(transactionHash); + if (transaction == null) + { + return ResultWrapper.Fail($"Transaction {transactionHash} was not found", ErrorCodes.ResourceNotFound); + } + var rlp = Rlp.Encode(transaction); + return ResultWrapper.Success(rlp.Bytes); + } + + public ResultWrapper debug_getRawReceipts(long blockNumber) + { + var receipts = _debugBridge.GetReceiptsForBlock(new BlockParameter(blockNumber)); + if (receipts == null) + { + return ResultWrapper.Fail($"Receipts are not found for block {blockNumber}", ErrorCodes.ResourceNotFound); + } + + var rlp = receipts.Select(tx => Rlp.Encode(tx, RlpBehaviors.Eip658Receipts).Bytes); + return ResultWrapper.Success(rlp.ToArray()); + } + + public ResultWrapper debug_getRawBlock(long blockNumber) + { + var blockRLP = _debugBridge.GetBlockRlp(new BlockParameter(blockNumber)); + if (blockRLP == null) + { + return ResultWrapper.Fail($"Block {blockNumber} was not found", ErrorCodes.ResourceNotFound); + } + return ResultWrapper.Success(blockRLP); + } + + public ResultWrapper debug_getRawHeader(long blockNumber) + { + var block = _debugBridge.GetBlock(new BlockParameter(blockNumber)); + if (block == null) + { + return ResultWrapper.Fail($"Block {blockNumber} was not found", ErrorCodes.ResourceNotFound); + } + Rlp rlp = Rlp.Encode(block.Header); + return ResultWrapper.Success(rlp.Bytes); + } + public Task> debug_getSyncStage() { return ResultWrapper.Success(_debugBridge.GetCurrentSyncStage()); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugBridge.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugBridge.cs index 984f6b20d34..732dcdff7f7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugBridge.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugBridge.cs @@ -22,6 +22,8 @@ public interface IDebugBridge GethLikeTxTrace? GetTransactionTrace(Transaction transaction, BlockParameter blockParameter, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null); IReadOnlyCollection GetBlockTrace(BlockParameter blockParameter, CancellationToken cancellationToken, GethTraceOptions gethTraceOptions = null); IReadOnlyCollection GetBlockTrace(Rlp blockRlp, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null); + byte[] GetBlockRlp(BlockParameter param); + Block? GetBlock(BlockParameter param); byte[] GetBlockRlp(Hash256 blockHash); byte[] GetBlockRlp(long number); byte[] GetDbValue(string dbName, byte[] key); @@ -33,4 +35,6 @@ public interface IDebugBridge void InsertReceipts(BlockParameter blockParameter, TxReceipt[] receipts); SyncReportSymmary GetCurrentSyncStage(); IEnumerable TraceBlockToFile(Hash256 blockHash, CancellationToken cancellationToken, GethTraceOptions? gethTraceOptions = null); + TxReceipt[]? GetReceiptsForBlock(BlockParameter param); + Transaction? GetTransactionFromHash(Hash256 hash); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs index 073dda6b020..932a1d300da 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs @@ -88,6 +88,18 @@ public interface IDebugRpcModule : IRpcModule [JsonRpcMethod(Description = "Insert receipts for the block after verifying receipts root correctness.")] Task> debug_insertReceipts(BlockParameter blockParameter, ReceiptForRpc[] receiptForRpc); + [JsonRpcMethod(Description = "Get Raw Block format.")] + ResultWrapper debug_getRawBlock(long blockNumber); + + [JsonRpcMethod(Description = "Get Raw Receipt format.")] + ResultWrapper debug_getRawReceipts(long blockNumber); + + [JsonRpcMethod(Description = "Get Raw Header format.")] + ResultWrapper debug_getRawHeader(long blockNumber); + + [JsonRpcMethod(Description = "Get Raw Transaction format.")] + ResultWrapper debug_getRawTransaction(Hash256 transactionHash); + [JsonRpcMethod(Description = "Retrives Nethermind Sync Stage, With extra Metadata")] Task> debug_getSyncStage();