From 402a1ad0f631814212c1187e6c32f46dc6a8d7b1 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Thu, 23 May 2024 09:48:41 +0300 Subject: [PATCH 1/5] Refactor interface --- .../Steps/RegisterRpcModules.cs | 15 +- .../Nethermind.Optimism/L1GasInfo.cs | 16 + .../Rpc/IOptimismEthRpcModule.cs | 337 ++++++++++++++++++ .../Rpc/OptimismEthModuleFactory.cs | 4 +- .../Rpc/OptimismEthRpcModule.cs | 26 +- .../Rpc/OptimismReceiptForRpc.cs | 33 ++ .../Rpc/RegisterOptimismRpcModules.cs | 14 +- 7 files changed, 430 insertions(+), 15 deletions(-) create mode 100644 src/Nethermind/Nethermind.Optimism/L1GasInfo.cs create mode 100644 src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs create mode 100644 src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs diff --git a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs index 15c023cb579..673bf3eb88c 100644 --- a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs +++ b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs @@ -81,10 +81,9 @@ public virtual async Task Execute(CancellationToken cancellationToken) StepDependencyException.ThrowIfNull(_api.GasPriceOracle); StepDependencyException.ThrowIfNull(_api.EthSyncingInfo); - ModuleFactoryBase ethModuleFactory = CreateEthModuleFactory(); - RpcLimits.Init(_jsonRpcConfig.RequestQueueLimit); - rpcModuleProvider.RegisterBounded(ethModuleFactory, _jsonRpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, _jsonRpcConfig.Timeout); + RegisterEthRpcModule(rpcModuleProvider); + StepDependencyException.ThrowIfNull(_api.DbProvider); StepDependencyException.ThrowIfNull(_api.BlockPreprocessor); @@ -213,7 +212,7 @@ public virtual async Task Execute(CancellationToken cancellationToken) await Task.CompletedTask; } - protected virtual ModuleFactoryBase CreateEthModuleFactory() + protected ModuleFactoryBase CreateEthModuleFactory() { StepDependencyException.ThrowIfNull(_api.BlockTree); StepDependencyException.ThrowIfNull(_api.ReceiptStorage); @@ -242,4 +241,12 @@ protected virtual ModuleFactoryBase CreateEthModuleFactory() _api.EthSyncingInfo, feeHistoryOracle); } + + protected virtual void RegisterEthRpcModule(IRpcModuleProvider rpcModuleProvider) + { + ModuleFactoryBase ethModuleFactory = CreateEthModuleFactory(); + + rpcModuleProvider.RegisterBounded(ethModuleFactory, + _jsonRpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, _jsonRpcConfig.Timeout); + } } diff --git a/src/Nethermind/Nethermind.Optimism/L1GasInfo.cs b/src/Nethermind/Nethermind.Optimism/L1GasInfo.cs new file mode 100644 index 00000000000..6ac141d037b --- /dev/null +++ b/src/Nethermind/Nethermind.Optimism/L1GasInfo.cs @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Int256; + +namespace Nethermind.Optimism; + +public class L1GasInfo +{ + public UInt256? L1BaseFeeScalar; + public UInt256? L1BlobBaseFee; + public UInt256? L1BlobBaseFeeScalar; + public UInt256? L1Fee; + public UInt256? L1GasPrice; + public UInt256? L1GasUsed; +} diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs new file mode 100644 index 00000000000..839dae544fa --- /dev/null +++ b/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs @@ -0,0 +1,337 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using System.Threading.Tasks; +using Nethermind.Blockchain.Find; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Facade.Eth; +using Nethermind.Facade.Filters; +using Nethermind.Int256; +using Nethermind.JsonRpc; +using Nethermind.JsonRpc.Data; +using Nethermind.JsonRpc.Modules; +using Nethermind.JsonRpc.Modules.Eth; +using Nethermind.State.Proofs; + +namespace Nethermind.Optimism; + +[RpcModule(ModuleType.Eth)] +public interface IOptimismEthRpcModule : IRpcModule +{ + [JsonRpcMethod(IsImplemented = true, + Description = "Returns ChainID", + IsSharable = true, + ExampleResponse = "0x4")] + ResultWrapper eth_chainId(); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns ETH protocol version", + IsSharable = true, + ExampleResponse = "0x41")] + ResultWrapper eth_protocolVersion(); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns syncing status", + IsSharable = true, + ExampleResponse = + "{\"isSyncing\":true,\"startingBlock\":\"0x0\",\"currentBlock\":\"0x0\",\"highestBlock\":\"0x4df8a4\"},\"id\":1}")] + ResultWrapper eth_syncing(); + + [JsonRpcMethod(IsImplemented = false, + Description = "Returns miner's coinbase", + IsSharable = true, + ExampleResponse = "0x0000000000000000000000000000000000000000")] + ResultWrapper
eth_coinbase(); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns block fee history.", + IsSharable = true, + ExampleResponse = + "{\"baseFeePerGas\": [\"0x116c1cbb03\", \"0x10c3714c06\"], \"gasUsedRatio\": [0.3487305666666667, 0.3], \"oldestBlock\": \"0xc7e5ff\", \"reward\": [[\"0x3b9aca00\",\"0x3b9aca00\"], [\"0x0\",\"0x3bb24dfa\"]]}")] + ResultWrapper eth_feeHistory(int blockCount, BlockParameter newestBlock, + double[]? rewardPercentiles = null); + + [JsonRpcMethod(IsImplemented = false, Description = "Returns full state snapshot", IsSharable = true)] + ResultWrapper eth_snapshot(); + + [JsonRpcMethod(IsImplemented = false, Description = "", IsSharable = true)] + ResultWrapper eth_maxPriorityFeePerGas(); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns miner's gas price", + IsSharable = true, + ExampleResponse = "0x4a817c800")] + ResultWrapper eth_gasPrice(); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns the base fee per blob gas in wei", + IsSharable = true, + ExampleResponse = "0x1")] + ResultWrapper eth_blobBaseFee(); + + [JsonRpcMethod(IsImplemented = false, + Description = "Returns accounts", + IsSharable = true, + ExampleResponse = "[\"0x9b96a7841d6e0b76872c85c86082959189a27342\"]")] + ResultWrapper> eth_accounts(); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns current block number", + IsSharable = true, + ExampleResponse = "0x885480")] + Task> eth_blockNumber(); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns account balance", + IsSharable = true, + ExampleResponse = "0x6c8ae945bfe6e")] + Task> eth_getBalance( + [JsonRpcParameter(ExampleValue = "[\"0x78467cada5f1883e79fcf0f3ebfa50abeec8c820\"]")] Address address, + BlockParameter? blockParameter = null); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns storage data at address. storage_index", + IsSharable = true, + ExampleResponse = "0x")] + ResultWrapper eth_getStorageAt( + [JsonRpcParameter(ExampleValue = + "[\"0x000000000000000000000000c666d239cbda32aa7ebca894b6dc598ddb881285\",\"0x2\"]")] + Address address, UInt256 positionIndex, BlockParameter? blockParameter = null); + + [JsonRpcMethod(IsImplemented = true, + Description = + "Returns account nonce (number of trnsactions from the account since genesis) at the given block number", + IsSharable = true, + ExampleResponse = "0x3e")] + Task> eth_getTransactionCount( + [JsonRpcParameter(ExampleValue = "[\"0xae3ed7a6ccdddf2914133d0669b5f02ff6fa8ad2\"]")] Address address, + BlockParameter? blockParameter = null); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns number of transactions in the block block hash", + IsSharable = true, + ExampleResponse = "0x20")] + ResultWrapper eth_getBlockTransactionCountByHash( + [JsonRpcParameter(ExampleValue = "[\"0x199c2ef63392fb67f929fe0580e11f62fa6c54b9951a624896da91375a6805b1\"]")] + Hash256 blockHash); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns number of transactions in the block by block number", + IsSharable = true, + ExampleResponse = "0x20")] + ResultWrapper eth_getBlockTransactionCountByNumber( + [JsonRpcParameter(ExampleValue = "[\"8934677\"]")] BlockParameter blockParameter); + + [JsonRpcMethod( + Description = + "Get receipts from all transactions from particular block, more efficient than fetching the receipts one-by-one.", + IsImplemented = true, + ExampleResponse = + "{\"jsonrpc\":\"2.0\",\"result\":[{\"transactionHash\":\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"transactionIndex\":\"0x0\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"cumulativeGasUsed\":\"0x5208\",\"gasUsed\":\"0x5208\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"contractAddress\":null,\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x1\",\"type\":\"0x0\"},{\"transactionHash\":\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\",\"transactionIndex\":\"0x1\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"cumulativeGasUsed\":\"0xa410\",\"gasUsed\":\"0x5208\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"contractAddress\":null,\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x1\",\"type\":\"0x0\"}],\"id\":67}")] + ResultWrapper eth_getBlockReceipts( + [JsonRpcParameter(ExampleValue = "latest")] BlockParameter blockParameter); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns number of uncles in the block by block hash", + IsSharable = true, + ExampleResponse = "0x0")] + ResultWrapper eth_getUncleCountByBlockHash( + [JsonRpcParameter(ExampleValue = "[\"0xe495c3385bb9162103bc07989d7160c38759e017c37c7d0608268bd5989d6bed \"]")] + Hash256 blockHash); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns number of uncles in the block by block number", + IsSharable = true, + ExampleResponse = "0x0")] + ResultWrapper eth_getUncleCountByBlockNumber( + [JsonRpcParameter(ExampleValue = "[\"5127400\"]")] BlockParameter blockParameter); + + [JsonRpcMethod(IsImplemented = true, Description = "Returns account code at given address and block", + IsSharable = true)] + ResultWrapper eth_getCode(Address address, BlockParameter? blockParameter = null); + + [JsonRpcMethod(IsImplemented = false, Description = "Signs a transaction", IsSharable = true)] + ResultWrapper eth_sign(Address addressData, byte[] message); + + [JsonRpcMethod(IsImplemented = true, + Description = "Send a transaction to the tx pool and broadcasting", + IsSharable = true, + ExampleResponse = "0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760")] + Task> eth_sendTransaction( + [JsonRpcParameter(ExampleValue = + "[{\"From\": \"0xc2208fe87805279b03c1a8a78d7ee4bfdb0e48ee\", \"Gas\":\"21000\",\"GasPrice\":\"20000000000\", \"Nonce\":\"23794\", \"To\":\"0x2d44c0e097f6cd0f514edac633d82e01280b4a5c\"}]")] + TransactionForRpc rpcTx); + + [JsonRpcMethod(IsImplemented = true, + Description = "Send a raw transaction to the tx pool and broadcasting", + IsSharable = true, + ExampleResponse = "0x7a5a94d5b5e3ce017ce2c2022f02ec5db10611c43695c3256861bdb19317ab0e" + )] + Task> eth_sendRawTransaction( + [JsonRpcParameter(ExampleValue = + "[\"0xf86380843b9aca0082520894b943b13292086848d8180d75c73361107920bb1a80802ea0385656b91b8f1f5139e9ba3449b946a446c9cfe7adb91b180ddc22c33b17ac4da01fe821879d386b140fd8080dcaaa98b8c709c5025c8c4dea1334609ebac41b6c\"]")] + byte[] transaction); + + [JsonRpcMethod(IsImplemented = true, + Description = "Executes a tx call (does not create a transaction)", + IsSharable = false, + ExampleResponse = "0x")] + ResultWrapper eth_call( + [JsonRpcParameter(ExampleValue = + "[{\"from\":\"0x0001020304050607080910111213141516171819\",\"gasPrice\":\"0x100000\", \"data\": \"0x70a082310000000000000000000000006c1f09f6271fbe133db38db9c9280307f5d22160\", \"to\": \"0x0d8775f648430679a709e98d2b0cb6250d2887ef\"}]")] + TransactionForRpc transactionCall, BlockParameter? blockParameter = null); + + [JsonRpcMethod(IsImplemented = true, + Description = "Executes a tx call and returns gas used (does not create a transaction)", + IsSharable = false, + ExampleResponse = "0x")] + ResultWrapper eth_estimateGas( + [JsonRpcParameter(ExampleValue = + "[\"{\"from\": \"0x0001020304050607080910111213141516171819\", \"gasPrice\": \"1048576\", \"to\": \"0x0d8775f648430679a709e98d2b0cb6250d2887ef\"}\"]")] + TransactionForRpc transactionCall, BlockParameter? blockParameter = null); + + [JsonRpcMethod(IsImplemented = true, + Description = + "Creates an [EIP2930](https://eips.ethereum.org/EIPS/eip-2930) type AccessList for the given transaction", + EdgeCaseHint = + "If your transaction has code executed, then you can generate transaction access list with eth_createAccessList. If you send it with your transaction then it will lower your gas cost on Ethereum", + IsSharable = false, + ExampleResponse = + "{\"accessList\":[{\"address\":\"0xfffffffffffffffffffffffffffffffffffffffe\",\"storageKeys\":[\"0x0000000000000000000000000000000000000000000000000000000000000001\",\"0x0000000000000000000000000000000000000000000000000000000000000002\"]},{\"address\":\"0x76e68a8696537e4141926f3e528733af9e237d69\",\"storageKeys\":[]}],\"gasUsed\":\"0xf71b\"}")] + ResultWrapper eth_createAccessList( + [JsonRpcParameter(Description = "Transaction's details", ExampleValue = "[\"{\"type\":\"0x1\"]")] + TransactionForRpc transactionCall, + [JsonRpcParameter(Description = "(optional)")] + BlockParameter? blockParameter = null, + [JsonRpcParameter(Description = "(optional)")] + bool optimize = true); + + [JsonRpcMethod(IsImplemented = true, + Description = "Retrieves a block by hash", + IsSharable = true, + ExampleResponse = + "{\"author\":\"0x0000000000000000000000000000000000000000\",\"difficulty\":\"0x1\",\"extraData\":\"0x000000000000436f6e73656e5379732048797065726c656467657220426573754d3f7b71165a8266fcc569c96b6fcf9971ee4a8df59eeec4dcced0df8d778733429988e21d0124918859f988be9debf4b25fb5282ea41a2fc15f827f446ec93200\",\"gasLimit\":\"0x1c9c364\",\"gasUsed\":\"0x3aa87\",\"hash\":\"0xf33507f93a046dbdbb80dee5f47b84283297f6c53f1b665adc3cb6fe4138aa84\",\"logsBloom\":\"0x00000000000020000000000008000060000000000000000000000000000000000000000000000000201000020008000000000000000000000100000000200020000000000000000000000008000000000000000010000000000000000000000000000000000000000000080000000000000000000000002000000010000000000000000000000000000000000000000000040000001000000000000000020000020400000000000000000000000000000000000000000000000000010000000000000002080000000000000000020000000000000000000000000000000000000010020000000000000000000000000100000000000000000000010000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x4e3d79\",\"parentHash\":\"0x01dba3a7eb61dc6dba3f9663c8fb632f76f60a476f57df74c3e5bd9d0a246339\",\"receiptsRoot\":\"0x70f3bd929735d8edeb953cd30a27e703e7dd3ec4af32cb74fe8ac302f9e7fb87\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x754\",\"stateRoot\":\"0x71af7e25302d1baa4c988c267450eb2c7fa20938fac377809c8d77f8ff8108ac\",\"totalDifficulty\":\"0x726275\",\"timestamp\":\"0x60ec1218\",\"baseFeePerGas\":\"0x7\",\"transactions\":[\"0xa65d391d8149ed0906fab923e870d2bc7f6d27c2be10fe1bcfc6f02869b38ef3\",\"0x369a89354041b7a8cb40edce51c36ebb0ee6ffa4d8056f5a658d90f3bbe1a81a\",\"0xf857daf60d03381b9a6ecb341b62798b424d20dc05763858e13955dd866b489d\"],\"transactionsRoot\":\"0x90115f8dc10c08e748675f52f3904615729a014461ca80d72c60239bf75ee209\",\"uncles\":[]}")] + ResultWrapper eth_getBlockByHash( + [JsonRpcParameter(ExampleValue = "[\"0xf33507f93a046dbdbb80dee5f47b84283297f6c53f1b665adc3cb6fe4138aa84\"]")] + Hash256 blockHash, bool returnFullTransactionObjects = false); + + [JsonRpcMethod(IsImplemented = true, + Description = "Retrieves a block by number", + IsSharable = true, + ExampleResponse = + "{\"author\":\"0x0000000000000000000000000000000000000000\",\"difficulty\":\"0x1\",\"extraData\":\"0x000000000000436f6e73656e5379732048797065726c656467657220426573754d3f7b71165a8266fcc569c96b6fcf9971ee4a8df59eeec4dcced0df8d778733429988e21d0124918859f988be9debf4b25fb5282ea41a2fc15f827f446ec93200\",\"gasLimit\":\"0x1c9c364\",\"gasUsed\":\"0x3aa87\",\"hash\":\"0xf33507f93a046dbdbb80dee5f47b84283297f6c53f1b665adc3cb6fe4138aa84\",\"logsBloom\":\"0x00000000000020000000000008000060000000000000000000000000000000000000000000000000201000020008000000000000000000000100000000200020000000000000000000000008000000000000000010000000000000000000000000000000000000000000080000000000000000000000002000000010000000000000000000000000000000000000000000040000001000000000000000020000020400000000000000000000000000000000000000000000000000010000000000000002080000000000000000020000000000000000000000000000000000000010020000000000000000000000000100000000000000000000010000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x4e3d79\",\"parentHash\":\"0x01dba3a7eb61dc6dba3f9663c8fb632f76f60a476f57df74c3e5bd9d0a246339\",\"receiptsRoot\":\"0x70f3bd929735d8edeb953cd30a27e703e7dd3ec4af32cb74fe8ac302f9e7fb87\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x754\",\"stateRoot\":\"0x71af7e25302d1baa4c988c267450eb2c7fa20938fac377809c8d77f8ff8108ac\",\"totalDifficulty\":\"0x726275\",\"timestamp\":\"0x60ec1218\",\"baseFeePerGas\":\"0x7\",\"transactions\":[\"0xa65d391d8149ed0906fab923e870d2bc7f6d27c2be10fe1bcfc6f02869b38ef3\",\"0x369a89354041b7a8cb40edce51c36ebb0ee6ffa4d8056f5a658d90f3bbe1a81a\",\"0xf857daf60d03381b9a6ecb341b62798b424d20dc05763858e13955dd866b489d\"],\"transactionsRoot\":\"0x90115f8dc10c08e748675f52f3904615729a014461ca80d72c60239bf75ee209\",\"uncles\":[]}")] + ResultWrapper eth_getBlockByNumber( + [JsonRpcParameter(ExampleValue = "[\"5127545\"]")] BlockParameter blockParameter, + bool returnFullTransactionObjects = false); + + [JsonRpcMethod(IsImplemented = true, + Description = "Retrieves a transaction by hash", + IsSharable = true, + ExampleResponse = + "{\"hash\":\"0xabca23910646013d608ec671de099447ab60b2b7159ad8319c3c088e8d9ea0fa\",\"nonce\":\"0x1a\",\"blockHash\":\"0xcb6756f69e0469acd5e5bb77966be580786ec2c11de85c9ddfd75257010e34f8\",\"blockNumber\":\"0x4dfbc7\",\"transactionIndex\":\"0xb\",\"from\":\"0xe1e7ab1c643dbe5b24739fdf2a5c7c193b54dd99\",\"to\":\"0x0b10e304088b2ba2b2acfd2f72573faad31a13a5\",\"value\":\"0x0\",\"gasPrice\":\"0x2540be400\",\"gas\":\"0xb4a4\",\"data\":\"0x095ea7b300000000000000000000000092c1576845703089cf6c0788379ed81f75f45dd500000000000000000000000000000000000000000000000000000002540be400\",\"input\":\"0x095ea7b300000000000000000000000092c1576845703089cf6c0788379ed81f75f45dd500000000000000000000000000000000000000000000000000000002540be400\",\"type\":\"0x0\",\"v\":\"0x2d\",\"s\":\"0x496d72d435ead8a8a9a865b14d6a102c1a9f848681d050dbbf11c522c612235\",\"r\":\"0xc8350e831203fecc8bff41f5cf858ac1d121e4b4d9e59c1137cc9440516ca9fd\"}")] + Task> eth_getTransactionByHash( + [JsonRpcParameter(ExampleValue = "\"0xabca23910646013d608ec671de099447ab60b2b7159ad8319c3c088e8d9ea0fa\"")] + Hash256 transactionHash); + + [JsonRpcMethod(IsImplemented = true, + Description = "Returns the pending transactions list", + IsSharable = true, + ExampleResponse = "[]")] + ResultWrapper eth_pendingTransactions(); + + [JsonRpcMethod(IsImplemented = true, + Description = "Retrieves a transaction by block hash and index", + IsSharable = true, + ExampleResponse = + "{\"hash\":\"0xb87ec4c8cb36a06f49cdd93c2e9f63e0b7db9af07a605c8bcf1fbe705162344e\",\"nonce\":\"0x5d\",\"blockHash\":\"0xfe47fb3539ccce9d19a032473effdd6ce19e3c921bbae2746152ccf82ceef48e\",\"blockNumber\":\"0x4dfc90\",\"transactionIndex\":\"0x2\",\"from\":\"0xaa9a0f962e433755c843175488fe088fccf8526f\",\"to\":\"0x074b24cef703f17fe123fa1b82081055775b7004\",\"value\":\"0x0\",\"gasPrice\":\"0x2540be401\",\"gas\":\"0x130ab\",\"data\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"input\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"type\":\"0x0\",\"v\":\"0x2e\",\"s\":\"0x696f6db060a6dd30435a7f592506ba3213f81cf4704e211a1a45a99f8984189a\",\"r\":\"0x7e07076186e38b68cb7e4f68a04258a5744c5a2ad1a7153456ee662a07902954\"}")] + ResultWrapper eth_getTransactionByBlockHashAndIndex( + [JsonRpcParameter(ExampleValue = + "[\"0xfe47fb3539ccce9d19a032473effdd6ce19e3c921bbae2746152ccf82ceef48e\",\"0x2\"]")] + Hash256 blockHash, UInt256 positionIndex); + + [JsonRpcMethod(IsImplemented = true, + Description = "Retrieves a transaction by block number and index", + IsSharable = true, + ExampleResponse = + "{\"hash\":\"0xfd320a4949990929f64b52041c58a74c8ce13289b3d6853bd8073b0580aa031a\",\"nonce\":\"0x5b\",\"blockHash\":\"0xd779e1a5ce8f34544d66d219bb3e5331a7b280fae89a36d7d52813a23e1ca1e3\",\"blockNumber\":\"0x4dfdd8\",\"transactionIndex\":\"0x8\",\"from\":\"0xadb540569e2db497bd973c141b0b63be98461e40\",\"to\":\"0x074b24cef703f17fe123fa1b82081055775b7004\",\"value\":\"0x0\",\"gasPrice\":\"0x12a05f200\",\"gas\":\"0x927c0\",\"data\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"input\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"type\":\"0x0\",\"v\":\"0x2e\",\"s\":\"0x37b90a929884787df717c87258f0434e2f115ce2fbb4bfc230322112fa9d5bbc\",\"r\":\"0x5222eff9e16b5c3e9e8901d9c45fc8e0f9cf774e8a56546a504025ef67ceefec\"}")] + ResultWrapper eth_getTransactionByBlockNumberAndIndex( + [JsonRpcParameter(ExampleValue = "[\"5111256\",\"0x8\"]")] + BlockParameter blockParameter, UInt256 positionIndex); + + [JsonRpcMethod(IsImplemented = true, + Description = "Retrieves a transaction receipt by tx hash", + IsSharable = true, + ExampleResponse = + "{\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"transactionIndex\":\"0x7\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"cumulativeGasUsed\":\"0x62c9d\",\"gasUsed\":\"0xe384\",\"effectiveGasPrice\":\"0x12a05f200\",\"from\":\"0x0afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"to\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"contractAddress\":null,\"logs\":[{\"removed\":false,\"logIndex\":\"0x0\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x2ac3c1d3e24b45c6c310534bc2dd84b5ed576335\",\"data\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x00000000000000000000000019e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\"]},{\"removed\":false,\"logIndex\":\"0x1\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"data\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007735940000000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0x950494fc3642fae5221b6c32e0e45765c95ebb382a04a71b160db0843e74c99f\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\"]}],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000020000000000000800000000000000000000400000000000000000000000000000000000000002000000000000000000000000008000000000000000000000000000000000000000000000002002000000000000000000000000000000000000000000812000000000000000000000000000001000000000000000000000008000400008000000000000000000000000000000000000000000000000000000000800000000000000000000002000000000000000000000000000000000000100000000000000000002000000000000000000000000010000000000000000000000400000000020000\",\"status\":\"0x1\",\"type\":\"0x0\"}")] + Task> eth_getTransactionReceipt( + [JsonRpcParameter(ExampleValue = "[\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\"]")] + Hash256 txHashData); + + [JsonRpcMethod(IsImplemented = true, + Description = "Retrieves an uncle block header by block hash and uncle index", + IsSharable = true)] + ResultWrapper eth_getUncleByBlockHashAndIndex(Hash256 blockHashData, UInt256 positionIndex); + + [JsonRpcMethod(IsImplemented = true, + Description = "Retrieves an uncle block header by block number and uncle index", IsSharable = true)] + ResultWrapper eth_getUncleByBlockNumberAndIndex(BlockParameter blockParameter, UInt256 positionIndex); + + [JsonRpcMethod(IsImplemented = true, + Description = "Creates an update filter", + IsSharable = false, + ExampleResponse = "0x9")] + ResultWrapper + eth_newFilter([JsonRpcParameter(ExampleValue = "[{\"toBlock\":\"latest\"}]")] Filter filter); + + [JsonRpcMethod(IsImplemented = true, + Description = "Creates an update filter", + IsSharable = false, + ExampleResponse = "0x0")] + ResultWrapper eth_newBlockFilter(); + + [JsonRpcMethod(IsImplemented = true, + Description = "Creates an update filter", + IsSharable = false, + ExampleResponse = "0x1")] + ResultWrapper eth_newPendingTransactionFilter(); + + [JsonRpcMethod(IsImplemented = true, + Description = "Creates an update filter", + IsSharable = false)] + ResultWrapper eth_uninstallFilter(UInt256 filterId); + + [JsonRpcMethod(IsImplemented = true, + Description = "Reads filter changes", + IsSharable = true, + ExampleResponse = "[]")] + ResultWrapper> eth_getFilterChanges( + [JsonRpcParameter(ExampleValue = "[\"0x9\"]")] UInt256 filterId); + + [JsonRpcMethod(IsImplemented = true, + Description = "Reads filter changes", + IsSharable = true, + ExampleResponse = "[]")] + ResultWrapper> eth_getFilterLogs( + [JsonRpcParameter(ExampleValue = "[\"0x9\"]")] UInt256 filterId); + + [JsonRpcMethod(IsImplemented = true, Description = "Reads logs", IsSharable = false)] + ResultWrapper> eth_getLogs(Filter filter); + + [JsonRpcMethod(Description = "https://github.com/ethereum/EIPs/issues/1186", + IsImplemented = true, + IsSharable = true, + ExampleResponse = + " \"accountProof\": [\"0xf90211a0446f43a2d3e433732c75bcf3519f4844e0441a4d39b31395ee9a65700c30d3b4a0b9720db63afe9909418fb6e02c9d9f225310856549cc1b66b486041f2d867250a046e6e560e52d4fe0d2f6609f489ba85f18ad1655fee18452588dc08388fbd711a01e68f36c91bd15cbf65587d6db2a7cbd6635907291e77dd80152161da9a28a48a0d2178a1891c26ccaa2d2cec82c231a0640a26a1f5e07c7b5493761bdb3aa94e5a0fa909327d406980a2e602eadd3f56cf8dc89320d4662340962e9cac2beee3d8da0a0fc71e7dec6320a993b4b65b2f82544910d0a4a7c6f8c5a1ebaa38357d259e3a0680161dec84c5f1c8d5e2a585c9708b1b6fbc2dc664a432e045d99f5e7d89259a0f76a745765be58d46d795c44d3900a4a05b6396530244d50822616c8bbb11e19a0594824352d58f5caff819c8df9581b6a41d0e94eb584ed0431d48b48f320bb5ca0e762eb52b2bcacd728fac605de6229dc83588001ecddcd3b454b64c393ee69eda0d319cf1021af0a8535e4916c3404c84917957d73d0711f71fd6456b4533993bba0878240238a894e6fa798671ac3792563c6666a7c7fba8066d090b65d6a7aa701a03c03fdb4d8f4b241442814cbab24ddb42b75c78874f92fedc162b65d0820fc4da06a3318509aa9ff009b9acb9b348f197a134a46a46295714f436d4fbb19057e69a04139df1b6e0a59b093b35f34f9e5e890bc06832e63b366d768dc29e8638b828480\",\"0xf90211a023459f17e04fba3d19c6993f5be413969842fdbdc85d234a91b2f6b08a38be87a0153060eafecbff55ef0794802ef722b6c66698141cdc0610352d3a426976adeba0bd642b7c5111a1fd09da33feb6df031dc352b6cb20fbbe5ebe3eb328db233bd4a0705bff29e05c7ef69c07fecaa5db2457b2f124befc82f9fe6b0e54c8e35632eba03c1b4ffc076434de97050d2351c24689cfaefaa6cf8dc398dd3b8ce365e652c1a0a1ebf845ea0eb252e2a2e5c422ccd74878a3733144dfd62bcaad34758cc98652a01e4184586f5bdbb17ba74fd87539f02378c7adcef99f1538108f9555520e32d6a0b8acdfd5b644fa2c9a54f68039a3af4c6562c1e7f91ea9e63bda5a849f1260b6a05c1f036a2e7a5829799fc7df2d87eac3e7aee55df461b040c36f5b5c61781059a0a67fd871d32642e44120331f76c2616096d04d7fa1a7db421bafbc39713d8bfba085c15b7ab64f61670f4422adb82176d5808fad4abde6fddda507b0e5ff92ba14a0d95e8f16a39d4e52c67c617eef486adcd947854373ac074ff498150c7ca1ab5da03d9d7be595000872ad6aec05667ad85e1aaaeb2050a692818d3e60d8f1628d8ba0984c657192b052d13fb717051631d67fbc83dd5dcb4d074a2fddc01aa122d95ba03643408862d758aea269c05027a1cd616c957e0db5daea529b56964db8b4f04ba01020dce8d692c3d84d9ae3e42c35e4d8adbddf7b4dd3e09e543fc980849f016e80\",\"0xf90211a04c71b4b56ed723da1c1353ec1b4c23e71dfa821664d4041c1ee1770221f507b6a031c851f261a38df9b2bece1a1cb6985bccfaa10d2bb15954b82cd2ceaad87032a08a4a3d0cc260cf0e0fef54490ce45796fdd3f522451976ca7834563c839c630fa003d074f79074566cd33a3d6a57b6ca8426ca9ea972f66b5dfde00f73287fcfcea07003d29a5bd192038600118ab5941af5c79c1f0fc6184ad564180b809c36c7c4a05f181c50402dcff567abe1c6679a8d5e3825125abca4d969c7cbf76503416813a06a85dfca80e442ef79b66162099d52eaf67718589eb794755ce57dc071a85cdaa085cba9e6937a8a5f0a7d1b5ee9eb9f03c40f89eb13d9d4e0e5fbc574c2b852faa063f93dce441a3373cfc2d1c855884682dfd8d09d1eb9844c73d88eb8d5a7cdfda0e4bc0d2597e5fd0a4cd5e76a03b657ef8959264bdeaf95c4412ebd4ff736ce44a00239290e698aa04485e0c342cfb76ccf27a3e45a161b8b1b534e0c46707b92c8a0080c3439fb84730924539797aad8d017c5f7e008314ed9086450d80ec2b0d7aba0861dbe37b9b9e0f58b6fdb83eec28045c5f7f1861530f47f78fc8a2b18a6bd8da0036697e8dc063e9086d115d468c934a01123adb3c66dcc236ee4aa8141888626a033c6f574ee79d9b1322e9ca1131a5984b33cc8881e6ac8ebd6ca36f3437cedcda07fc2855e6bb0f276202094dffe49f2b62f2366d9aba9db3ffe76d62bcdc29f0d80\",\"0xf90211a06995d919b53eefa0b097d75c2a5dee2c54109a06d3b60586327fa0086437b801a05c7d7c92f9f1e49cf27c5d97b4a96302f033d42df5b1d7c013ef05031d67e567a05278417d007913a1e7d6606fb464e7b81f6cee91b6a1d250c67b3822d9fc68d8a0fba6d9cd68fe72db07af9d99e30c32502e0afb15ee9712f6781014195444b9e1a07dca25ba23f429b5960d9feb23367e2a088e50211f280118b7f1703e6d47103fa0399eb6e0d4390688f6b28df56c7ad72d6b6cbac9066110c6a727fe35cd889e9da08ef84ddaa3b70095fb5624878289744740a9f8761ef1132ba722abc977a218ffa04296811ae184892e2d5ecc18d05fc6279d6168eb0f3abb1f97d8d0a0721c12fba05c46766c579b8a0b8a0b79b84f6cd1e5dae1c53a2988883b0385daa2cf3bdf82a01a4ba17dd1b59147a321dd374a22a0d959f1a79d70132db7f1a8b89968ff6062a0f7ffc6f3921c6bccd47c862519409e63f51d39aaa215819c664b1adb48a940b0a0dc6e636385407900a649917fb772b0972d50d197e9fd5cdb853a1c98a29e6a47a0674b224cf784c59ca937bfebbdcd8dec05ddbd57400b04f5965558a0c2d2299ca0f95ce8c921c5b17ebf74563f2496a88631aa6a697bfd9e3e22b326efa453115ea0fc133bc6b9dd098933c816660df2959074f47dfc4ab3a10fd2059a2b2e0e911aa057cac15218d6013890df78eec099144ba2000e3eea73a3498d0eb9b1f733459080\",\"0xf90211a0400aafe69a1a482277db720d12b9c0b98695f5dd78c6faf5421b3ddac50165a6a0235987542e4b37aa8e6957776c9dff11d6818797db5ad505de5e0049045c7e20a0f573b4776f8b323b7d55850300d53855cfa6fa5fe6e36ba64da6bb263fef774aa0b3a36d14d660c3492785b0f1488a2231b6d83bd51268685b95ba9267aa331fe2a0096e8c65bae8fce7d234710a1e1b8c98bd4fb2d56f8bb2eda7ef20d1cf31c7e2a059194c8bf50c2ac393c4c60a59c7ddf0c515bd9f545fc4ef212629a8b96af62aa0ffe882f4e2f1e8e49c7777f6f9b4438a9f31d4e5cefe82c96fdd3587d9a95173a00127ced7fdbdd57cd5ed8b766c9312c09e0c67a350087d22b4cc7b2d17a45479a0cfc030a250448838caa716cd2767cd1a4837b29019f474980720c94fe2ce412ea079ec358d2b4122692bf70eb73a0ddb0ff4bfeb05d503fe1acafe068e2d3d33cfa0733e2ccdc638ca3c940c566c742a1b9d58f7caaa062e8a121c07f5e3367160a8a0aa1f403798b71c67b821e6f6128cc5366bebe145ebd563714cf9972b2474814ea01b988afc628922aeed3de606a8a462093f1c0c803a563bbe178552a360bad1e1a0082741e2219024bf4e19f5b1b0643e5e885cb7dfb4cdc0a51faf5bd9f92ff9b6a03c86490fe8f0256be44b95815086d95cb62fdbc3ede63ca08d12d68f274b7fc5a03a81565e860ac32921ed4c9f4e0ace3b341c342abd030d4955f2d1e64dd81d2b80\",\"0xf8f1a0bd9a0d9559513a6c7bf427816142d254d5a9049e9ff385f3514b50cb828951fc808080a07d37353f509c9bdc99635bd75fde71a6ef99271154ac4ffd5c437e0b951d5eaca029e3beec2f52c99a1fa73251ed64486f2766af3dcb950900679f7fd740badfdaa09b348c93803521a41bd2a754e3ea5435bb2663724cdfb70a87984458b53f03dea0904e696aceac8c89e2825e0dae8add52a9b46faef2ffbabb932e8bc1267e48ba80a0935dedba6ec5fb5b89285993c5f1be0cb77492e63e11bb38b5aca18011699eb8a06b52f587932dfb669f6cbefe35b251c6d8e6b5e8a2e1c1a7c2a452a4f2917b0d808080808080\"],\"address\":\"0x7f0d15c7faae65896648c8273b6d7e43f58fa842\",\"balance\":\"0x0\",\"codeHash\":\"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\",\"nonce\":\"0x0\",\"storageHash\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"storageProof\":[{\"key\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"proof\":[],\"value\":\"0x00\"]")] + ResultWrapper eth_getProof( + [JsonRpcParameter(ExampleValue = + "[\"0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842\",[ \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\" ],\"latest\"]")] + Address accountAddress, UInt256[] hashRate, BlockParameter blockParameter); + + [JsonRpcMethod(IsImplemented = true, Description = "Retrieves Accounts via Address and Blocknumber", + IsSharable = true)] + ResultWrapper eth_getAccount( + [JsonRpcParameter(ExampleValue = "[\"0xaa00000000000000000000000000000000000000\", \"latest\"]")] + Address accountAddress, BlockParameter? blockParameter = null); +} diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs index 97c2cd043a3..c6aecb92f80 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs @@ -11,7 +11,7 @@ namespace Nethermind.Optimism; -public class OptimismEthModuleFactory : ModuleFactoryBase +public class OptimismEthModuleFactory : ModuleFactoryBase { private readonly ModuleFactoryBase _ethModuleFactory; private readonly BasicJsonRpcClient? _sequencerRpcClient; @@ -32,7 +32,7 @@ public OptimismEthModuleFactory(ModuleFactoryBase ethModuleFactor _sealer = sealer; } - public override IEthRpcModule Create() + public override IOptimismEthRpcModule Create() { return new OptimismEthRpcModule(_ethModuleFactory.Create(), _sequencerRpcClient, _blockchainBridge, _accountStateProvider, _ecdsa, _sealer); diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs index 2246e8fc29a..37b66448a88 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs @@ -1,12 +1,14 @@ // SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Collections.Generic; using System.Threading.Tasks; using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Crypto; +using Nethermind.Evm; using Nethermind.Facade; using Nethermind.Facade.Eth; using Nethermind.Facade.Filters; @@ -14,6 +16,7 @@ using Nethermind.JsonRpc; using Nethermind.JsonRpc.Client; using Nethermind.JsonRpc.Data; +using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Serialization.Rlp; using Nethermind.State.Proofs; @@ -21,7 +24,7 @@ namespace Nethermind.Optimism; -public class OptimismEthRpcModule : IEthRpcModule +public class OptimismEthRpcModule : IOptimismEthRpcModule { private readonly IEthRpcModule _ethRpcModule; private readonly IJsonRpcClient? _sequencerRpcClient; @@ -121,9 +124,10 @@ public Task> eth_getTransactionCount(Address address, Blo return _ethRpcModule.eth_getBlockTransactionCountByNumber(blockParameter); } - public ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) + public ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) { - return _ethRpcModule.eth_getBlockReceipts(blockParameter); + throw new NotImplementedException(); + // return _ethRpcModule.eth_getBlockReceipts(blockParameter); } public ResultWrapper eth_getUncleCountByBlockHash(Hash256 blockHash) @@ -226,11 +230,23 @@ public ResultWrapper eth_getTransactionByBlockNumberAndIndex( return _ethRpcModule.eth_getTransactionByBlockNumberAndIndex(blockParameter, positionIndex); } - public Task> eth_getTransactionReceipt(Hash256 txHashData) + public Task> eth_getTransactionReceipt(Hash256 txHashData) { - return _ethRpcModule.eth_getTransactionReceipt(txHashData); + (TxReceipt? receipt, TxGasInfo? gasInfo, int logIndexStart) = + _blockchainBridge.GetReceiptAndGasInfo(txHashData); + if (receipt is null || gasInfo is null) + { + return Task.FromResult(ResultWrapper.Success(null)); + } + + // SearchResult block = _blockFinder.SearchForBlock(new(receipt.BlockHash!)); + L1GasInfo l1GasInfo = new(); + + return Task.FromResult(ResultWrapper.Success( + new(txHashData, new OptimismTxReceipt(receipt), gasInfo.Value, l1GasInfo, logIndexStart))); } + public ResultWrapper eth_getUncleByBlockHashAndIndex(Hash256 blockHashData, UInt256 positionIndex) { return _ethRpcModule.eth_getUncleByBlockHashAndIndex(blockHashData, positionIndex); diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs new file mode 100644 index 00000000000..596fb9831de --- /dev/null +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core.Crypto; +using Nethermind.Evm; +using Nethermind.Int256; +using Nethermind.JsonRpc.Data; + +namespace Nethermind.Optimism; + +public class OptimismReceiptForRpc : ReceiptForRpc +{ + public OptimismReceiptForRpc(Hash256 txHash, OptimismTxReceipt receipt, TxGasInfo gasInfo, L1GasInfo l1GasInfo, int logIndexStart = 0) : base( + txHash, receipt, gasInfo, logIndexStart) + { + L1BaseFeeScalar = l1GasInfo.L1BaseFeeScalar; + L1BlobBaseFee = l1GasInfo.L1BlobBaseFee; + L1BlobBaseFeeScalar = l1GasInfo.L1BlobBaseFeeScalar; + L1Fee = l1GasInfo.L1Fee; + L1GasPrice = l1GasInfo.L1GasPrice; + L1GasUsed = l1GasInfo.L1GasUsed; + } + + public UInt256? DepositNonce; + public UInt256? DepositReceiptVersion; + + public UInt256? L1BaseFeeScalar; + public UInt256? L1BlobBaseFee; + public UInt256? L1BlobBaseFeeScalar; + public UInt256? L1Fee; + public UInt256? L1GasPrice; + public UInt256? L1GasUsed; +} diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs b/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs index 6d667c25c96..863c34cf9d4 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs @@ -4,6 +4,7 @@ using System; using Nethermind.Api; using Nethermind.Init.Steps; +using Nethermind.JsonRpc; using Nethermind.JsonRpc.Client; using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Eth; @@ -18,15 +19,17 @@ public class RegisterOptimismRpcModules : RegisterRpcModules private readonly OptimismNethermindApi _api; private readonly ILogger _logger; private readonly IOptimismConfig _config; + private readonly IJsonRpcConfig _jsonRpcConfig; public RegisterOptimismRpcModules(INethermindApi api) : base(api) { _api = (OptimismNethermindApi)api; _config = _api.Config(); _logger = _api.LogManager.GetClassLogger(); + _jsonRpcConfig = _api.Config(); } - protected override ModuleFactoryBase CreateEthModuleFactory() + protected override void RegisterEthRpcModule(IRpcModuleProvider rpcModuleProvider) { StepDependencyException.ThrowIfNull(_api.SpecHelper); StepDependencyException.ThrowIfNull(_api.SpecProvider); @@ -39,15 +42,18 @@ protected override ModuleFactoryBase CreateEthModuleFactory() _logger.Warn($"SequencerUrl is not set."); } - ModuleFactoryBase ethModuleFactory = base.CreateEthModuleFactory(); BasicJsonRpcClient? sequencerJsonRpcClient = _config.SequencerUrl is null ? null : new(new Uri(_config.SequencerUrl), _api.EthereumJsonSerializer, _api.LogManager); + ModuleFactoryBase ethModuleFactory = CreateEthModuleFactory(); ITxSigner txSigner = new WalletTxSigner(_api.Wallet, _api.SpecProvider.ChainId); TxSealer sealer = new(txSigner, _api.Timestamper); - return new OptimismEthModuleFactory(ethModuleFactory, sequencerJsonRpcClient, _api.CreateBlockchainBridge(), - _api.WorldState, _api.EthereumEcdsa, sealer); + ModuleFactoryBase optimismEthModuleFactory = new OptimismEthModuleFactory( + ethModuleFactory, sequencerJsonRpcClient, _api.CreateBlockchainBridge(), _api.WorldState, _api.EthereumEcdsa, sealer); + + rpcModuleProvider.RegisterBounded(optimismEthModuleFactory, + _jsonRpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, _jsonRpcConfig.Timeout); } } From bd6a882592a618bf20b136f3bcaa8c714c7df37b Mon Sep 17 00:00:00 2001 From: Alexey Osipov Date: Tue, 28 May 2024 17:48:05 +0300 Subject: [PATCH 2/5] Compute fields; fix spec --- src/Nethermind/Chains/base-mainnet.json | 28 ++++- src/Nethermind/Chains/base-sepolia.json | 9 +- src/Nethermind/Chains/op-mainnet.json | 18 ++- src/Nethermind/Chains/op-sepolia.json | 9 +- .../ReceiptDecoderTests.cs | 51 ++++++++ .../Nethermind.Optimism/L1BlockGasInfo.cs | 97 ++++++++++++++ .../Nethermind.Optimism/L1GasInfo.cs | 16 --- .../Nethermind.Optimism/OPL1CostHelper.cs | 48 +++---- .../Nethermind.Optimism/OptimismPlugin.cs | 2 - .../OptimismReceiptMessageDecoder.cs | 13 +- .../OptimismReceiptStorageDecoder.cs | 118 +++++++++++++----- .../Rpc/OptimismEthModuleFactory.cs | 21 +++- .../Rpc/OptimismEthRpcModule.cs | 72 +++++++++-- .../Rpc/OptimismReceiptForRpc.cs | 38 ++++-- .../Rpc/RegisterOptimismRpcModules.cs | 3 +- .../Properties/launchSettings.json | 15 ++- .../configs/base-mainnet.cfg | 23 +++- .../configs/base-sepolia.cfg | 21 +++- .../Nethermind.Runner/configs/op-mainnet.cfg | 23 +++- .../Nethermind.Runner/configs/op-sepolia.cfg | 21 +++- .../ReceiptArrayStorageDecoder.cs | 9 +- 21 files changed, 521 insertions(+), 134 deletions(-) create mode 100644 src/Nethermind/Nethermind.Optimism/L1BlockGasInfo.cs delete mode 100644 src/Nethermind/Nethermind.Optimism/L1GasInfo.cs diff --git a/src/Nethermind/Chains/base-mainnet.json b/src/Nethermind/Chains/base-mainnet.json index 431ea8ca581..c0853d933aa 100644 --- a/src/Nethermind/Chains/base-mainnet.json +++ b/src/Nethermind/Chains/base-mainnet.json @@ -6,7 +6,8 @@ "params": { "regolithTimestamp": "0x0", "bedrockBlockNumber": "0x0", - "ecotoneTimestamp": "0x65F23E01", + "canyonTimestamp": "0x65a01e91", + "ecotoneTimestamp": "0x65f23e01", "l1FeeRecipient": "0x420000000000000000000000000000000000001A", "l1BlockAddress": "0x4200000000000000000000000000000000000015" } @@ -48,11 +49,16 @@ "eip3529Transition": "0x0", "eip3541Transition": "0x0", - "eip1153TransitionTimestamp": "0x65F23E01", - "eip4788TransitionTimestamp": "0x65F23E01", - "eip4844TransitionTimestamp": "0x65F23E01", - "eip5656TransitionTimestamp": "0x65F23E01", - "eip6780TransitionTimestamp": "0x65F23E01", + "eip4895TransitionTimestamp": "0x65a01e91", + "eip3651TransitionTimestamp": "0x65a01e91", + "eip3855TransitionTimestamp": "0x65a01e91", + "eip3860TransitionTimestamp": "0x65a01e91", + + "eip1153TransitionTimestamp": "0x65f23e01", + "eip4788TransitionTimestamp": "0x65f23e01", + "eip4844TransitionTimestamp": "0x65f23e01", + "eip5656TransitionTimestamp": "0x65f23e01", + "eip6780TransitionTimestamp": "0x65f23e01", "terminalTotalDifficulty": "0" }, @@ -72,6 +78,16 @@ "baseFeePerGas": "0x3b9aca00", "gasLimit": "0x1c9c380" }, + "nodes": [ + "enode://ca2774c3c401325850b2477fd7d0f27911efbf79b1e8b335066516e2bd8c4c9e0ba9696a94b1cb030a88eac582305ff55e905e64fb77fe0edcd70a4e5296d3ec@34.65.175.185:30305", + "enode://dd751a9ef8912be1bfa7a5e34e2c3785cc5253110bd929f385e07ba7ac19929fb0e0c5d93f77827291f4da02b2232240fbc47ea7ce04c46e333e452f8656b667@34.65.107.0:30305", + "enode://c5d289b56a77b6a2342ca29956dfd07aadf45364dde8ab20d1dc4efd4d1bc6b4655d902501daea308f4d8950737a4e93a4dfedd17b49cd5760ffd127837ca965@34.65.202.239:30305", + "enode://87a32fd13bd596b2ffca97020e31aef4ddcc1bbd4b95bb633d16c1329f654f34049ed240a36b449fda5e5225d70fe40bc667f53c304b71f8e68fc9d448690b51@3.231.138.188:30301", + "enode://ca21ea8f176adb2e229ce2d700830c844af0ea941a1d8152a9513b966fe525e809c3a6c73a2c18a12b74ed6ec4380edf91662778fe0b79f6a591236e49e176f9@184.72.129.189:30301", + "enode://acf4507a211ba7c1e52cdf4eef62cdc3c32e7c9c47998954f7ba024026f9a6b2150cd3f0b734d9c78e507ab70d59ba61dfe5c45e1078c7ad0775fb251d7735a2@3.220.145.177:30301", + "enode://8a5a5006159bf079d06a04e5eceab2a1ce6e0f721875b2a9c96905336219dbe14203d38f70f3754686a6324f786c2f9852d8c0dd3adac2d080f4db35efc678c5@3.231.11.52:30301", + "enode://cdadbe835308ad3557f9a1de8db411da1a260a98f8421d62da90e71da66e55e98aaa8e90aa7ce01b408a54e4bd2253d701218081ded3dbe5efbbc7b41d7cef79@54.198.153.150:30301" + ], "accounts": { "0000000000000000000000000000000000000001": { "builtin": { diff --git a/src/Nethermind/Chains/base-sepolia.json b/src/Nethermind/Chains/base-sepolia.json index ed550dd8183..7faf0bda489 100644 --- a/src/Nethermind/Chains/base-sepolia.json +++ b/src/Nethermind/Chains/base-sepolia.json @@ -7,7 +7,7 @@ "regolithTimestamp": "0x0", "bedrockBlockNumber": "0x0", "canyonTimestamp": "0x6553a790", - "ecotoneTimestamp": "0x65D62C10", + "ecotoneTimestamp": "0x65d62c10", "l1FeeRecipient": "0x420000000000000000000000000000000000001A", "l1BlockAddress": "0x4200000000000000000000000000000000000015", "canyonBaseFeeChangeDenominator": "250", @@ -81,6 +81,13 @@ "baseFeePerGas": "0x3b9aca00", "gasLimit": "0x17d7840" }, + "nodes": [ + "enode://2bd2e657bb3c8efffb8ff6db9071d9eb7be70d7c6d7d980ff80fc93b2629675c5f750bc0a5ef27cd788c2e491b8795a7e9a4a6e72178c14acc6753c0e5d77ae4@34.65.205.244:30305", + "enode://db8e1cab24624cc62fc35dbb9e481b88a9ef0116114cd6e41034c55b5b4f18755983819252333509bd8e25f6b12aadd6465710cd2e956558faf17672cce7551f@34.65.173.88:30305", + "enode://bfda2e0110cfd0f4c9f7aa5bf5ec66e6bd18f71a2db028d36b8bf8b0d6fdb03125c1606a6017b31311d96a36f5ef7e1ad11604d7a166745e6075a715dfa67f8a@34.65.229.245:30305", + "enode://548f715f3fc388a7c917ba644a2f16270f1ede48a5d88a4d14ea287cc916068363f3092e39936f1a3e7885198bef0e5af951f1d7b1041ce8ba4010917777e71f@18.210.176.114:30301", + "enode://6f10052847a966a725c9f4adf6716f9141155b99a0fb487fea3f51498f4c2a2cb8d534e680ee678f9447db85b93ff7c74562762c3714783a7233ac448603b25f@107.21.251.55:30301" + ], "accounts": { "0000000000000000000000000000000000000001": { "balance": "0x1", diff --git a/src/Nethermind/Chains/op-mainnet.json b/src/Nethermind/Chains/op-mainnet.json index 00ef58e560b..2c04e2cc3c1 100644 --- a/src/Nethermind/Chains/op-mainnet.json +++ b/src/Nethermind/Chains/op-mainnet.json @@ -6,7 +6,8 @@ "params": { "regolithTimestamp": "0x0", "bedrockBlockNumber": "0x645C277", - "ecotoneTimestamp": "0x65F23E01", + "canyonTimestamp": "0x65a01e91", + "ecotoneTimestamp": "0x65f23e01", "l1FeeRecipient": "0x420000000000000000000000000000000000001A", "l1BlockAddress": "0x4200000000000000000000000000000000000015" } @@ -53,11 +54,16 @@ "eip3529Transition": "0x645C277", "eip3541Transition": "0x645C277", - "eip1153TransitionTimestamp": "0x65F23E01", - "eip4788TransitionTimestamp": "0x65F23E01", - "eip4844TransitionTimestamp": "0x65F23E01", - "eip5656TransitionTimestamp": "0x65F23E01", - "eip6780TransitionTimestamp": "0x65F23E01", + "eip4895TransitionTimestamp": "0x65a01e91", + "eip3651TransitionTimestamp": "0x65a01e91", + "eip3855TransitionTimestamp": "0x65a01e91", + "eip3860TransitionTimestamp": "0x65a01e91", + + "eip1153TransitionTimestamp": "0x65f23e01", + "eip4788TransitionTimestamp": "0x65f23e01", + "eip4844TransitionTimestamp": "0x65f23e01", + "eip5656TransitionTimestamp": "0x65f23e01", + "eip6780TransitionTimestamp": "0x65f23e01", "terminalTotalDifficulty": "0" }, diff --git a/src/Nethermind/Chains/op-sepolia.json b/src/Nethermind/Chains/op-sepolia.json index ebac27cbc6c..a19af876950 100644 --- a/src/Nethermind/Chains/op-sepolia.json +++ b/src/Nethermind/Chains/op-sepolia.json @@ -51,18 +51,15 @@ "eip3198Transition": "0x0", "eip3529Transition": "0x0", "eip3541Transition": "0x0", - "eip4895TransitionTimestamp": "0x6553a790", "eip3651TransitionTimestamp": "0x6553a790", "eip3855TransitionTimestamp": "0x6553a790", "eip3860TransitionTimestamp": "0x6553a790", - "eip1153TransitionTimestamp": "0x65D62C10", "eip4788TransitionTimestamp": "0x65D62C10", "eip4844TransitionTimestamp": "0x65D62C10", "eip5656TransitionTimestamp": "0x65D62C10", "eip6780TransitionTimestamp": "0x65D62C10", - "terminalTotalDifficulty": "0" }, "genesis": { @@ -83,8 +80,8 @@ }, "nodes": [ "enode://2bd2e657bb3c8efffb8ff6db9071d9eb7be70d7c6d7d980ff80fc93b2629675c5f750bc0a5ef27cd788c2e491b8795a7e9a4a6e72178c14acc6753c0e5d77ae4@34.65.205.244:30305", - "enode://db8e1cab24624cc62fc35dbb9e481b88a9ef0116114cd6e41034c55b5b4f18755983819252333509bd8e25f6b12aadd6465710cd2e956558faf17672cce7551f@34.65.173.88:30305", - "enode://bfda2e0110cfd0f4c9f7aa5bf5ec66e6bd18f71a2db028d36b8bf8b0d6fdb03125c1606a6017b31311d96a36f5ef7e1ad11604d7a166745e6075a715dfa67f8a@34.65.229.245:30305", + "enode://db8e1cab24624cc62fc35dbb9e481b88a9ef0116114cd6e41034c55b5b4f18755983819252333509bd8e25f6b12aadd6465710cd2e956558faf17672cce7551f@34.65.173.88:30305", + "enode://bfda2e0110cfd0f4c9f7aa5bf5ec66e6bd18f71a2db028d36b8bf8b0d6fdb03125c1606a6017b31311d96a36f5ef7e1ad11604d7a166745e6075a715dfa67f8a@34.65.229.245:30305", "enode://548f715f3fc388a7c917ba644a2f16270f1ede48a5d88a4d14ea287cc916068363f3092e39936f1a3e7885198bef0e5af951f1d7b1041ce8ba4010917777e71f@18.210.176.114:30301", "enode://6f10052847a966a725c9f4adf6716f9141155b99a0fb487fea3f51498f4c2a2cb8d534e680ee678f9447db85b93ff7c74562762c3714783a7233ac448603b25f@107.21.251.55:30301" ], @@ -12575,4 +12572,4 @@ "balance": "0x0" } } -} +} \ No newline at end of file diff --git a/src/Nethermind/Nethermind.Optimism.Test/ReceiptDecoderTests.cs b/src/Nethermind/Nethermind.Optimism.Test/ReceiptDecoderTests.cs index 6a7598063cd..b5c27431a2d 100644 --- a/src/Nethermind/Nethermind.Optimism.Test/ReceiptDecoderTests.cs +++ b/src/Nethermind/Nethermind.Optimism.Test/ReceiptDecoderTests.cs @@ -31,6 +31,34 @@ static OptimismTxReceipt TestNetworkEncodingRoundTrip(byte[] rlp, bool includesN return decodedReceipt; } + static OptimismTxReceipt TestStorageEncodingRoundTrip(OptimismTxReceipt decodedReceipt, bool includesNonce, bool includesVersion) + { + OptimismCompactReceiptStorageDecoder decoder = new(); + + RlpStream encodedRlp = new(decoder.GetLength(decodedReceipt, RlpBehaviors.SkipTypedWrapping)); + decoder.Encode(encodedRlp, decodedReceipt, RlpBehaviors.SkipTypedWrapping); + encodedRlp.Position = 0; + + OptimismTxReceipt decodedStorageReceipt = decoder.Decode(encodedRlp, RlpBehaviors.SkipTypedWrapping); + + Assert.Multiple(() => + { + Assert.That(decodedStorageReceipt.DepositNonce, includesNonce ? Is.Not.Null : Is.Null); + Assert.That(decodedStorageReceipt.DepositReceiptVersion, includesVersion ? Is.Not.Null : Is.Null); + }); + + Rlp.ValueDecoderContext valueDecoderCtx = new(encodedRlp.Data); + decodedStorageReceipt = decoder.Decode(ref valueDecoderCtx, RlpBehaviors.SkipTypedWrapping); + + Assert.Multiple(() => + { + Assert.That(decodedStorageReceipt.DepositNonce, includesNonce ? Is.Not.Null : Is.Null); + Assert.That(decodedStorageReceipt.DepositReceiptVersion, includesVersion ? Is.Not.Null : Is.Null); + }); + + return decodedReceipt; + } + static void TestTrieEncoding(OptimismTxReceipt decodedReceipt, bool shouldIncludeNonceAndVersionForTxTrie) { OptimismReceiptTrieDecoder trieDecoder = new(); @@ -49,6 +77,7 @@ static void TestTrieEncoding(OptimismTxReceipt decodedReceipt, bool shouldInclud } OptimismTxReceipt decodedReceipt = TestNetworkEncodingRoundTrip(rlp, includesNonce, includesVersion); + TestStorageEncodingRoundTrip(decodedReceipt, includesNonce, includesVersion); TestTrieEncoding(decodedReceipt, shouldIncludeNonceAndVersionForTxTrie); } @@ -66,6 +95,7 @@ public static IEnumerable DepositTxReceiptsSerializationTestCases { TestName = "1st OP Sepolia block receipt" }; + yield return new TestCaseData( Bytes.FromHexString("0x7ef9010c0182b729b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0830154f4"), true, @@ -75,6 +105,27 @@ public static IEnumerable DepositTxReceiptsSerializationTestCases { TestName = "Regolith receipt" }; + + yield return new TestCaseData( + Bytes.FromHexString("0x7ef903660183023676b9010000000000000000000000000000000000000000000000000000000000001000000000000000000080000000000000000001000000000000000000000000000204000200000004000000000000000000000000000000000000000000000000000100000000020000400000000000020800000000000000000000000008000000000000000000004000400000020000000001800000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000100000000000002100000000000000000000020001000100000040000000000000000000000000000000000000000000008000000f9025af9011d944200000000000000000000000000000000000010f884a0b0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead0000a000000000000000000000000072fb15f502af58765015972a85f2c58551ef3fa1b88000000000000000000000000072fb15f502af58765015972a85f2c58551ef3fa1000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000f8dc944200000000000000000000000000000000000010f863a031b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83da000000000000000000000000072fb15f502af58765015972a85f2c58551ef3fa1a000000000000000000000000072fb15f502af58765015972a85f2c58551ef3fa1b860000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000f85a944200000000000000000000000000000000000007f842a04641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133ca0c056e47e441542720e5a953ab9fcf1cc3de86fb1d3078293fb9708e6e77816938080"), + true, + false, + false + ) + { + TestName = "Regolith receipt 2" + }; + + yield return new TestCaseData( + Bytes.FromHexString("0xf901090183011711b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"), + false, + false, + false + ) + { + TestName = "Regolith receipt of a regular tx" + }; + yield return new TestCaseData( Bytes.FromHexString("7ef9010d0182ab7bb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c083b2557501"), true, diff --git a/src/Nethermind/Nethermind.Optimism/L1BlockGasInfo.cs b/src/Nethermind/Nethermind.Optimism/L1BlockGasInfo.cs new file mode 100644 index 00000000000..3c43f7ac7c3 --- /dev/null +++ b/src/Nethermind/Nethermind.Optimism/L1BlockGasInfo.cs @@ -0,0 +1,97 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; +using Nethermind.Int256; +using System; +using System.Linq; + +namespace Nethermind.Optimism; + +public readonly struct L1TxGasInfo(UInt256? l1Fee, UInt256? l1GasPrice, UInt256? l1GasUsed, string? l1FeeScalar) +{ + public UInt256? L1Fee { get; } = l1Fee; + public UInt256? L1GasPrice { get; } = l1GasPrice; + public UInt256? L1GasUsed { get; } = l1GasUsed; + public string? L1FeeScalar { get; } = l1FeeScalar; +} + +public readonly struct L1BlockGasInfo +{ + private readonly UInt256? _l1GasPrice; + private readonly UInt256 _l1BlobBaseFee; + private readonly UInt256 _l1BaseFeeScalar; + private readonly UInt256 _l1BlobBaseFeeScalar; + private readonly UInt256 _l1BaseFee; + private readonly UInt256 _overhead; + private readonly UInt256 _feeScalar; + private readonly string? _feeScalarDecimal; + private readonly bool _isEcotone; + private readonly bool _isRegolith; + + private static readonly byte[] EcotoneL1AttributesSelector = [0x44, 0x0a, 0x5e, 0x20]; + + public L1BlockGasInfo(Block block, bool isRegolith) + { + _isRegolith = isRegolith; + + if (block is not null && block.Transactions.Length > 0) + { + Transaction depositTx = block.Transactions[0]; + if (depositTx.Data is null || depositTx.Data.Value.Length < 4) + { + return; + } + + Memory data = depositTx.Data.Value; + + if (_isEcotone = data[0..4].Span.SequenceEqual(EcotoneL1AttributesSelector)) + { + if (data.Length != 164) + { + return; + } + + _l1GasPrice = new(data[36..68].Span, true); + _l1BlobBaseFee = new(data[68..100].Span, true); + _l1BaseFeeScalar = new(data[4..8].Span, true); + _l1BlobBaseFeeScalar = new(data[8..12].Span, true); + } + else + { + if (data.Length < 4 + 32 * 8) + { + return; + } + + _l1GasPrice = new(data[(4 + 32 * 2)..(4 + 32 * 3)].Span, true); + _l1BaseFee = new(data[(4 + 32 * 2)..(4 + 32 * 3)].Span, true); + _overhead = new(data[(4 + 32 * 6)..(4 + 32 * 7)].Span, true); + _feeScalar = new UInt256(data[(4 + 32 * 7)..(4 + 32 * 8)].Span, true); + _feeScalarDecimal = (((ulong)_feeScalar) / 1_000_000m).ToString(); + } + } + } + + public readonly L1TxGasInfo GetTxGasInfo(Transaction tx) + { + UInt256? l1Fee = null; + UInt256? l1GasUsed = null; + + if (_l1GasPrice is not null) + { + if (_isEcotone) + { + l1GasUsed = OPL1CostHelper.ComputeDataGas(tx, _isRegolith); + l1Fee = OPL1CostHelper.ComputeL1CostEcotone(l1GasUsed.Value, _l1GasPrice.Value, _l1BlobBaseFee, _l1BaseFeeScalar, _l1BlobBaseFeeScalar); + } + else + { + l1GasUsed = OPL1CostHelper.ComputeDataGas(tx, _isRegolith) + _overhead; + l1Fee = OPL1CostHelper.ComputeL1CostPreEcotone(l1GasUsed.Value, _l1BaseFee, _feeScalar); + } + } + + return new L1TxGasInfo(l1Fee, _l1GasPrice, l1GasUsed, _feeScalarDecimal); + } +} diff --git a/src/Nethermind/Nethermind.Optimism/L1GasInfo.cs b/src/Nethermind/Nethermind.Optimism/L1GasInfo.cs deleted file mode 100644 index 6ac141d037b..00000000000 --- a/src/Nethermind/Nethermind.Optimism/L1GasInfo.cs +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Int256; - -namespace Nethermind.Optimism; - -public class L1GasInfo -{ - public UInt256? L1BaseFeeScalar; - public UInt256? L1BlobBaseFee; - public UInt256? L1BlobBaseFeeScalar; - public UInt256? L1Fee; - public UInt256? L1GasPrice; - public UInt256? L1GasUsed; -} diff --git a/src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs b/src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs index c5116e2e502..f6f150e83d2 100644 --- a/src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs +++ b/src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs @@ -32,11 +32,18 @@ public class OPL1CostHelper(IOPConfigHelper opConfigHelper, Address l1BlockAddr) [SkipLocalsInit] public UInt256 ComputeL1Cost(Transaction tx, BlockHeader header, IWorldState worldState) { - [SkipLocalsInit] - UInt256 ComputeL1CostEcotone(IWorldState worldState, UInt256 dataGas) + if (tx.IsDeposit()) + return UInt256.Zero; + + UInt256 dataGas = ComputeDataGas(tx, _opConfigHelper.IsRegolith(header)); + if (dataGas.IsZero) + return UInt256.Zero; + + UInt256 l1BaseFee = new(worldState.Get(_l1BaseFeeSlot), true); + + if (_opConfigHelper.IsEcotone(header)) { // Ecotone formula: (dataGas) * (16 * l1BaseFee * l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar) / 16e6 - UInt256 l1BaseFee = new(worldState.Get(_l1BaseFeeSlot), true); UInt256 blobBaseFee = new(worldState.Get(_blobBaseFeeSlot), true); ReadOnlySpan scalarData = worldState.Get(_baseFeeScalarSlot); @@ -49,39 +56,38 @@ UInt256 ComputeL1CostEcotone(IWorldState worldState, UInt256 dataGas) UInt256 l1BaseFeeScalar = new(scalarData[l1BaseFeeScalarStart..l1BaseFeeScalarEnd], true); UInt256 l1BlobBaseFeeScalar = new(scalarData[l1BaseFeeScalarEnd..(l1BaseFeeScalarEnd + fieldSize)], true); - return dataGas * (precisionMultiplier * l1BaseFee * l1BaseFeeScalar + blobBaseFee * l1BlobBaseFeeScalar) / precisionDevider; + return ComputeL1CostEcotone(dataGas, l1BaseFee, blobBaseFee, l1BaseFeeScalar, l1BlobBaseFeeScalar); } - - [SkipLocalsInit] - UInt256 ComputeL1CostPreEcotone(IWorldState worldState, UInt256 dataGas) + else { // Pre-Ecotone formula: (dataGas + overhead) * l1BaseFee * scalar / 1e6 - UInt256 l1BaseFee = new(worldState.Get(_l1BaseFeeSlot), true); UInt256 overhead = new(worldState.Get(_overheadSlot), true); - UInt256 scalar = new(worldState.Get(_scalarSlot), true); + UInt256 feeScalar = new(worldState.Get(_scalarSlot), true); - return (dataGas + overhead) * l1BaseFee * scalar / basicDevider; + return ComputeL1CostPreEcotone(dataGas + overhead, l1BaseFee, feeScalar); } - - if (tx.IsDeposit()) - return UInt256.Zero; - - UInt256 dataGas = ComputeDataGas(tx, header); - if (dataGas.IsZero) - return UInt256.Zero; - - return _opConfigHelper.IsEcotone(header) ? ComputeL1CostEcotone(worldState, dataGas) : ComputeL1CostPreEcotone(worldState, dataGas); } - private UInt256 ComputeDataGas(Transaction tx, BlockHeader header) + [SkipLocalsInit] + public static UInt256 ComputeDataGas(Transaction tx, bool isRegolith) { byte[] encoded = Rlp.Encode(tx, RlpBehaviors.SkipTypedWrapping).Bytes; long zeroCount = encoded.Count(b => b == 0); long nonZeroCount = encoded.Length - zeroCount; // Add pre-EIP-3529 overhead - nonZeroCount += _opConfigHelper.IsRegolith(header) ? 0 : OptimismConstants.PreRegolithNonZeroCountOverhead; + nonZeroCount += isRegolith ? 0 : OptimismConstants.PreRegolithNonZeroCountOverhead; return (ulong)(zeroCount * GasCostOf.TxDataZero + nonZeroCount * GasCostOf.TxDataNonZeroEip2028); } + + public static UInt256 ComputeL1CostEcotone(UInt256 dataGas, UInt256 l1BaseFee, UInt256 blobBaseFee, UInt256 l1BaseFeeScalar, UInt256 l1BlobBaseFeeScalar) + { + return dataGas * (precisionMultiplier * l1BaseFee * l1BaseFeeScalar + blobBaseFee * l1BlobBaseFeeScalar) / precisionDevider; + } + + public static UInt256 ComputeL1CostPreEcotone(UInt256 dataGasWithOverhead, UInt256 l1BaseFee, UInt256 feeScalar) + { + return dataGasWithOverhead * l1BaseFee * feeScalar / basicDevider; + } } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index 996044c5905..ecf5388e502 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -26,8 +26,6 @@ using Nethermind.Serialization.Json; using Nethermind.Specs.ChainSpecStyle; using Nethermind.Serialization.Rlp; -using Nethermind.Core; -using Nethermind.JsonRpc.Modules.Eth; namespace Nethermind.Optimism; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs b/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs index b61d4ae4c5c..186fc2375d3 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismReceiptMessageDecoder.cs @@ -56,13 +56,16 @@ public OptimismTxReceipt Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = } txReceipt.Logs = entries; - if (txReceipt.TxType == TxType.DepositTx && lastCheck > rlpStream.Position) + if (lastCheck > rlpStream.Position) { - txReceipt.DepositNonce = rlpStream.DecodeUlong(); - - if (lastCheck > rlpStream.Position) + if (txReceipt.TxType == TxType.DepositTx && lastCheck > rlpStream.Position) { - txReceipt.DepositReceiptVersion = rlpStream.DecodeUlong(); + txReceipt.DepositNonce = rlpStream.DecodeUlong(); + + if (lastCheck > rlpStream.Position) + { + txReceipt.DepositReceiptVersion = rlpStream.DecodeUlong(); + } } } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismReceiptStorageDecoder.cs b/src/Nethermind/Nethermind.Optimism/OptimismReceiptStorageDecoder.cs index 036cd24bc32..38d3a9071b0 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismReceiptStorageDecoder.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismReceiptStorageDecoder.cs @@ -2,18 +2,18 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Linq; -using global::Nethermind.Core.Collections; -using global::Nethermind.Core.Crypto; -using global::Nethermind.Core; -using global::Nethermind.Serialization.Rlp; +using Nethermind.Core.Collections; +using Nethermind.Core.Crypto; +using Nethermind.Core; +using Nethermind.Serialization.Rlp; using static Nethermind.Serialization.Rlp.Rlp; namespace Nethermind.Optimism; [Decoder(RlpDecoderKey.Storage)] public class OptimismCompactReceiptStorageDecoder : - IRlpStreamDecoder, IRlpValueDecoder, IRlpObjectDecoder, IReceiptRefDecoder + IRlpStreamDecoder, IRlpValueDecoder, IRlpObjectDecoder, IReceiptRefDecoder, + IRlpStreamDecoder, IRlpValueDecoder, IRlpObjectDecoder { public OptimismTxReceipt Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { @@ -41,20 +41,24 @@ public OptimismTxReceipt Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = int sequenceLength = rlpStream.ReadSequenceLength(); int logEntriesCheck = sequenceLength + rlpStream.Position; - using ArrayPoolList logEntries = new(sequenceLength * 2 / Rlp.LengthOfAddressRlp); + using ArrayPoolList logEntries = new(sequenceLength * 2 / LengthOfAddressRlp); while (rlpStream.Position < logEntriesCheck) { logEntries.Add(CompactLogEntryDecoder.Decode(rlpStream, RlpBehaviors.AllowExtraBytes)!); } - txReceipt.Logs = logEntries.ToArray(); + txReceipt.Logs = [.. logEntries]; - if (txReceipt.TxType == TxType.DepositTx && lastCheck > rlpStream.Position) + if (lastCheck > rlpStream.Position) { - txReceipt.DepositNonce = rlpStream.DecodeUlong(); + int remainingItems = rlpStream.PeekNumberOfItemsRemaining(lastCheck); + if (remainingItems > 0) + { + txReceipt.DepositNonce = rlpStream.DecodeUlong(); + } - if (lastCheck > rlpStream.Position) + if (remainingItems > 1) { txReceipt.DepositReceiptVersion = rlpStream.DecodeUlong(); } @@ -63,7 +67,7 @@ public OptimismTxReceipt Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = bool allowExtraBytes = (rlpBehaviors & RlpBehaviors.AllowExtraBytes) != 0; if (!allowExtraBytes) { - rlpStream.Check(logEntriesCheck); + rlpStream.Check(lastCheck); } txReceipt.Bloom = new Bloom(txReceipt.Logs); @@ -71,7 +75,7 @@ public OptimismTxReceipt Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = return txReceipt; } - public OptimismTxReceipt Decode(ref Rlp.ValueDecoderContext decoderContext, + public OptimismTxReceipt Decode(ref ValueDecoderContext decoderContext, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (decoderContext.IsNextItemNull()) @@ -97,21 +101,26 @@ public OptimismTxReceipt Decode(ref Rlp.ValueDecoderContext decoderContext, txReceipt.GasUsedTotal = (long)decoderContext.DecodeUBigInt(); int sequenceLength = decoderContext.ReadSequenceLength(); + int logEntriesCheck = sequenceLength + decoderContext.Position; // Don't know the size exactly, I'll just assume its just an address and add some margin - using ArrayPoolList logEntries = new(sequenceLength * 2 / Rlp.LengthOfAddressRlp); - while (decoderContext.Position < lastCheck) + using ArrayPoolList logEntries = new(sequenceLength * 2 / LengthOfAddressRlp); + while (decoderContext.Position < logEntriesCheck) { logEntries.Add(CompactLogEntryDecoder.Decode(ref decoderContext, RlpBehaviors.AllowExtraBytes)!); } - txReceipt.Logs = logEntries.ToArray(); + txReceipt.Logs = [.. logEntries]; - if (txReceipt.TxType == TxType.DepositTx && lastCheck > decoderContext.Position) + if (lastCheck > decoderContext.Position) { - txReceipt.DepositNonce = decoderContext.DecodeULong(); + int remainingItems = decoderContext.PeekNumberOfItemsRemaining(lastCheck); + if (remainingItems > 0) + { + txReceipt.DepositNonce = decoderContext.DecodeULong(); + } - if (lastCheck > decoderContext.Position) + if (remainingItems > 1) { txReceipt.DepositReceiptVersion = decoderContext.DecodeULong(); } @@ -128,7 +137,7 @@ public OptimismTxReceipt Decode(ref Rlp.ValueDecoderContext decoderContext, return txReceipt; } - public void DecodeStructRef(scoped ref Rlp.ValueDecoderContext decoderContext, RlpBehaviors rlpBehaviors, + public void DecodeStructRef(scoped ref ValueDecoderContext decoderContext, RlpBehaviors rlpBehaviors, out TxReceiptStructRef item) { // Note: This method runs at 2.5 million times/sec on my machine @@ -140,7 +149,7 @@ public void DecodeStructRef(scoped ref Rlp.ValueDecoderContext decoderContext, R return; } - decoderContext.SkipLength(); + int lastCheck = decoderContext.ReadSequenceLength() + decoderContext.Position; ReadOnlySpan firstItem = decoderContext.DecodeByteArraySpan(); if (firstItem.Length == 1) @@ -160,16 +169,32 @@ public void DecodeStructRef(scoped ref Rlp.ValueDecoderContext decoderContext, R decoderContext.PeekPrefixAndContentLength(); int logsBytes = peekPrefixAndContentLength.ContentLength + peekPrefixAndContentLength.PrefixLength; item.LogsRlp = decoderContext.Data.Slice(decoderContext.Position, logsBytes); + + if (lastCheck > decoderContext.Position) + { + int remainingItems = decoderContext.PeekNumberOfItemsRemaining(lastCheck); + + if (remainingItems > 1) + { + decoderContext.SkipItem(); + } + + if (remainingItems > 2) + { + decoderContext.SkipItem(); + } + } + decoderContext.SkipItem(); } - public void DecodeLogEntryStructRef(scoped ref Rlp.ValueDecoderContext decoderContext, RlpBehaviors none, + public void DecodeLogEntryStructRef(scoped ref ValueDecoderContext decoderContext, RlpBehaviors none, out LogEntryStructRef current) { CompactLogEntryDecoder.DecodeLogEntryStructRef(ref decoderContext, none, out current); } - public Hash256[] DecodeTopics(Rlp.ValueDecoderContext valueDecoderContext) + public Hash256[] DecodeTopics(ValueDecoderContext valueDecoderContext) { return CompactLogEntryDecoder.DecodeTopics(valueDecoderContext); } @@ -240,18 +265,28 @@ private static (int Total, int Logs) GetContentLength(OptimismTxReceipt? item, R bool isEip658Receipts = (rlpBehaviors & RlpBehaviors.Eip658Receipts) == RlpBehaviors.Eip658Receipts; if (isEip658Receipts) { - contentLength += Rlp.LengthOf(item.StatusCode); + contentLength += LengthOf(item.StatusCode); } else { - contentLength += Rlp.LengthOf(item.PostTransactionState); + contentLength += LengthOf(item.PostTransactionState); } - contentLength += Rlp.LengthOf(item.Sender); - contentLength += Rlp.LengthOf(item.GasUsedTotal); + contentLength += LengthOf(item.Sender); + contentLength += LengthOf(item.GasUsedTotal); int logsLength = GetLogsLength(item); - contentLength += Rlp.LengthOfSequence(logsLength); + contentLength += LengthOfSequence(logsLength); + + if (item.TxType == TxType.DepositTx && item.DepositNonce is not null) + { + contentLength += LengthOf(item.DepositNonce); + + if (item.DepositReceiptVersion is not null) + { + contentLength += LengthOf(item.DepositReceiptVersion.Value); + } + } return (contentLength, logsLength); } @@ -271,6 +306,31 @@ private static int GetLogsLength(OptimismTxReceipt item) public int GetLength(OptimismTxReceipt item, RlpBehaviors rlpBehaviors) { (int Total, int Logs) length = GetContentLength(item, rlpBehaviors); - return Rlp.LengthOfSequence(length.Total); + return LengthOfSequence(length.Total); + } + + TxReceipt IRlpStreamDecoder.Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors) + { + return Decode(rlpStream, rlpBehaviors); ; + } + + public void Encode(RlpStream stream, TxReceipt item, RlpBehaviors rlpBehaviors = RlpBehaviors.None) + { + Encode(stream, (OptimismTxReceipt)item, rlpBehaviors); + } + + public int GetLength(TxReceipt item, RlpBehaviors rlpBehaviors) + { + return GetLength((OptimismTxReceipt)item, rlpBehaviors); + } + + TxReceipt IRlpValueDecoder.Decode(ref ValueDecoderContext decoderContext, RlpBehaviors rlpBehaviors) + { + return Decode(ref decoderContext, rlpBehaviors); + } + + public Rlp Encode(TxReceipt? item, RlpBehaviors rlpBehaviors = RlpBehaviors.None) + { + return Encode((OptimismTxReceipt?)item, rlpBehaviors); } } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs index c6aecb92f80..35a67406a3f 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs @@ -1,13 +1,18 @@ // SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using Nethermind.Blockchain.Filters; +using Nethermind.Blockchain.Find; +using Nethermind.Blockchain.Receipts; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Facade; using Nethermind.JsonRpc.Client; using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.TxPool; +using System; namespace Nethermind.Optimism; @@ -19,10 +24,18 @@ public class OptimismEthModuleFactory : ModuleFactoryBase private readonly IAccountStateProvider _accountStateProvider; private readonly IEthereumEcdsa _ecdsa; private readonly ITxSealer _sealer; + private readonly IBlockFinder _blockFinder; + private readonly ISpecProvider _specProvider; + private readonly IReceiptFinder _receiptFinder; + private readonly IOPConfigHelper _opConfigHelper; public OptimismEthModuleFactory(ModuleFactoryBase ethModuleFactory, BasicJsonRpcClient? sequencerRpcClient, IBlockchainBridge blockchainBridge, - IAccountStateProvider accountStateProvider, IEthereumEcdsa ecdsa, ITxSealer sealer) + IAccountStateProvider accountStateProvider, IEthereumEcdsa ecdsa, ITxSealer sealer, + IBlockFinder? blockFinder, + ISpecProvider specProvider, + IReceiptFinder? receiptFinder, + IOPConfigHelper opConfigHelper) { _ethModuleFactory = ethModuleFactory; _sequencerRpcClient = sequencerRpcClient; @@ -30,11 +43,15 @@ public OptimismEthModuleFactory(ModuleFactoryBase ethModuleFactor _accountStateProvider = accountStateProvider; _ecdsa = ecdsa; _sealer = sealer; + _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder)); + _specProvider = specProvider; + _receiptFinder = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder)); + _opConfigHelper = opConfigHelper; } public override IOptimismEthRpcModule Create() { return new OptimismEthRpcModule(_ethModuleFactory.Create(), _sequencerRpcClient, _blockchainBridge, - _accountStateProvider, _ecdsa, _sealer); + _accountStateProvider, _ecdsa, _sealer, _blockFinder, _specProvider, _receiptFinder, _opConfigHelper); } } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs index 37b66448a88..9ee9f1f04fd 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs @@ -1,12 +1,14 @@ // SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Nethermind.Blockchain.Find; +using Nethermind.Blockchain.Receipts; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Evm; using Nethermind.Facade; @@ -32,9 +34,23 @@ public class OptimismEthRpcModule : IOptimismEthRpcModule private readonly IAccountStateProvider _accountStateProvider; private readonly IEthereumEcdsa _ecdsa; private readonly ITxSealer _sealer; - - public OptimismEthRpcModule(IEthRpcModule ethRpcModule, IJsonRpcClient? sequencerRpcClient, - IBlockchainBridge blockchainBridge, IAccountStateProvider accountStateProvider, IEthereumEcdsa ecdsa, ITxSealer sealer) + private readonly IBlockFinder _blockFinder; + private readonly ISpecProvider _specProvider; + private readonly IReceiptFinder _receiptFinder; + private readonly IOPConfigHelper _opConfigHelper; + + + public OptimismEthRpcModule( + IEthRpcModule ethRpcModule, + IJsonRpcClient? sequencerRpcClient, + IBlockchainBridge blockchainBridge, + IAccountStateProvider accountStateProvider, + IEthereumEcdsa ecdsa, + ITxSealer sealer, + IBlockFinder blockFinder, + ISpecProvider specProvider, + IReceiptFinder receiptFinder, + IOPConfigHelper opConfigHelper) { _ethRpcModule = ethRpcModule; _sequencerRpcClient = sequencerRpcClient; @@ -42,6 +58,10 @@ public OptimismEthRpcModule(IEthRpcModule ethRpcModule, IJsonRpcClient? sequence _accountStateProvider = accountStateProvider; _ecdsa = ecdsa; _sealer = sealer; + _blockFinder = blockFinder; + _specProvider = specProvider; + _receiptFinder = receiptFinder; + _opConfigHelper = opConfigHelper; } public ResultWrapper eth_chainId() @@ -126,8 +146,30 @@ public Task> eth_getTransactionCount(Address address, Blo public ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) { - throw new NotImplementedException(); - // return _ethRpcModule.eth_getBlockReceipts(blockParameter); + static ResultWrapper GetBlockReceipts(IReceiptFinder receiptFinder, BlockParameter blockParameter, IBlockFinder blockFinder, ISpecProvider specProvider, IOPConfigHelper opConfigHelper) + { + SearchResult searchResult = blockFinder.SearchForBlock(blockParameter); + if (searchResult.IsError) + { + return ResultWrapper.Success(null!); + } + + Block? block = searchResult.Object!; + OptimismTxReceipt[] receipts = receiptFinder.Get(block).Cast().ToArray() ?? new OptimismTxReceipt[block.Transactions.Length]; + bool isEip1559Enabled = specProvider.GetSpec(block.Header).IsEip1559Enabled; + + L1BlockGasInfo l1BlockGasInfo = new(block, opConfigHelper.IsRegolith(block!.Header)); + + IEnumerable result = receipts + .Zip(block.Transactions, (r, t) => + { + return new OptimismReceiptForRpc(t.Hash!, r, t.GetGasInfo(isEip1559Enabled, block.Header), l1BlockGasInfo.GetTxGasInfo(t), receipts.GetBlockLogFirstIndex(r.Index)); + }); + OptimismReceiptForRpc[]? resultAsArray = result.ToArray(); + return ResultWrapper.Success(resultAsArray); + } + + return GetBlockReceipts(_receiptFinder, blockParameter, _blockFinder, _specProvider, _opConfigHelper); } public ResultWrapper eth_getUncleCountByBlockHash(Hash256 blockHash) @@ -230,23 +272,27 @@ public ResultWrapper eth_getTransactionByBlockNumberAndIndex( return _ethRpcModule.eth_getTransactionByBlockNumberAndIndex(blockParameter, positionIndex); } - public Task> eth_getTransactionReceipt(Hash256 txHashData) + public Task> eth_getTransactionReceipt(Hash256 txHash) { - (TxReceipt? receipt, TxGasInfo? gasInfo, int logIndexStart) = - _blockchainBridge.GetReceiptAndGasInfo(txHashData); + (TxReceipt? receipt, TxGasInfo? gasInfo, int logIndexStart) = _blockchainBridge.GetReceiptAndGasInfo(txHash); if (receipt is null || gasInfo is null) { return Task.FromResult(ResultWrapper.Success(null)); } - // SearchResult block = _blockFinder.SearchForBlock(new(receipt.BlockHash!)); - L1GasInfo l1GasInfo = new(); + SearchResult foundBlock = _blockFinder.SearchForBlock(new(receipt.BlockHash!)); + if (foundBlock.Object is null) + { + return Task.FromResult(ResultWrapper.Success(null)); + } + Block block = foundBlock.Object; + + L1BlockGasInfo l1GasInfo = new(block, _opConfigHelper.IsRegolith(block.Header)); return Task.FromResult(ResultWrapper.Success( - new(txHashData, new OptimismTxReceipt(receipt), gasInfo.Value, l1GasInfo, logIndexStart))); + new(txHash, (OptimismTxReceipt)receipt, gasInfo.Value, l1GasInfo.GetTxGasInfo(block.Transactions.First(tx => tx.Hash == txHash)), logIndexStart))); } - public ResultWrapper eth_getUncleByBlockHashAndIndex(Hash256 blockHashData, UInt256 positionIndex) { return _ethRpcModule.eth_getUncleByBlockHashAndIndex(blockHashData, positionIndex); diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs index 596fb9831de..2077279e73f 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs @@ -5,29 +5,47 @@ using Nethermind.Evm; using Nethermind.Int256; using Nethermind.JsonRpc.Data; +using System.Text.Json.Serialization; namespace Nethermind.Optimism; public class OptimismReceiptForRpc : ReceiptForRpc { - public OptimismReceiptForRpc(Hash256 txHash, OptimismTxReceipt receipt, TxGasInfo gasInfo, L1GasInfo l1GasInfo, int logIndexStart = 0) : base( + public OptimismReceiptForRpc(Hash256 txHash, OptimismTxReceipt receipt, TxGasInfo gasInfo, L1TxGasInfo l1GasInfo, int logIndexStart = 0) : base( txHash, receipt, gasInfo, logIndexStart) { - L1BaseFeeScalar = l1GasInfo.L1BaseFeeScalar; - L1BlobBaseFee = l1GasInfo.L1BlobBaseFee; - L1BlobBaseFeeScalar = l1GasInfo.L1BlobBaseFeeScalar; - L1Fee = l1GasInfo.L1Fee; - L1GasPrice = l1GasInfo.L1GasPrice; - L1GasUsed = l1GasInfo.L1GasUsed; + if (receipt.TxType == Core.TxType.DepositTx) + { + DepositNonce = receipt.DepositNonce; + DepositReceiptVersion = receipt.DepositReceiptVersion; + } + else + { + L1Fee = l1GasInfo.L1Fee; + L1GasUsed = l1GasInfo.L1GasUsed; + L1GasPrice = l1GasInfo.L1GasPrice; + L1FeeScalar = l1GasInfo.L1FeeScalar; + } } + // DepositTx related fields + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public UInt256? DepositNonce; + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public UInt256? DepositReceiptVersion; - public UInt256? L1BaseFeeScalar; - public UInt256? L1BlobBaseFee; - public UInt256? L1BlobBaseFeeScalar; + // Regular tx fields + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public UInt256? L1Fee; + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public UInt256? L1GasPrice; + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public UInt256? L1GasUsed; + + // Pre-ecotone field of a regular tx fields + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? L1FeeScalar; } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs b/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs index 863c34cf9d4..8c9d75ecaf9 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs @@ -3,6 +3,7 @@ using System; using Nethermind.Api; +using Nethermind.Blockchain; using Nethermind.Init.Steps; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Client; @@ -51,7 +52,7 @@ protected override void RegisterEthRpcModule(IRpcModuleProvider rpcModuleProvide TxSealer sealer = new(txSigner, _api.Timestamper); ModuleFactoryBase optimismEthModuleFactory = new OptimismEthModuleFactory( - ethModuleFactory, sequencerJsonRpcClient, _api.CreateBlockchainBridge(), _api.WorldState, _api.EthereumEcdsa, sealer); + ethModuleFactory, sequencerJsonRpcClient, _api.CreateBlockchainBridge(), _api.WorldState, _api.EthereumEcdsa, sealer, _api.BlockTree?.AsReadOnly(), _api.SpecProvider, _api.ReceiptFinder, _api.SpecHelper); rpcModuleProvider.RegisterBounded(optimismEthModuleFactory, _jsonRpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, _jsonRpcConfig.Timeout); diff --git a/src/Nethermind/Nethermind.Runner/Properties/launchSettings.json b/src/Nethermind/Nethermind.Runner/Properties/launchSettings.json index e1472d5e0ac..3db3149a77d 100644 --- a/src/Nethermind/Nethermind.Runner/Properties/launchSettings.json +++ b/src/Nethermind/Nethermind.Runner/Properties/launchSettings.json @@ -56,23 +56,30 @@ "ASPNETCORE_ENVIRONMENT": "Development" } }, + "OP Mainnet": { + "commandName": "Project", + "commandLineArgs": "-c op-mainnet -dd %NETHERMIND_DATA_DIR%", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, "OP Sepolia": { "commandName": "Project", - "commandLineArgs": "-c op-sepolia -dd %NETHERMIND_DATA_DIR% --JsonRpc.UnsecureDevNoRpcAuthentication=true", + "commandLineArgs": "-c op-sepolia -dd %NETHERMIND_DATA_DIR%", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "Base Mainnet": { "commandName": "Project", - "commandLineArgs": "-c base-mainnet -dd %NETHERMIND_DATA_DIR% --JsonRpc.UnsecureDevNoRpcAuthentication=true", + "commandLineArgs": "-c base-mainnet -dd %NETHERMIND_DATA_DIR%", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, - "Base Goerli": { + "Base Sepolia": { "commandName": "Project", - "commandLineArgs": "-c base-goerli -dd %NETHERMIND_DATA_DIR% --JsonRpc.UnsecureDevNoRpcAuthentication=true", + "commandLineArgs": "-c base-sepolia -dd %NETHERMIND_DATA_DIR%", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Nethermind/Nethermind.Runner/configs/base-mainnet.cfg b/src/Nethermind/Nethermind.Runner/configs/base-mainnet.cfg index 08a766d5999..359c438be29 100644 --- a/src/Nethermind/Nethermind.Runner/configs/base-mainnet.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/base-mainnet.cfg @@ -10,13 +10,34 @@ "BlobsSupport": "Disabled" }, "Sync": { - "NetworkingEnabled": false + "FastSync": true, + "SnapSync": true, + "AncientBodiesBarrier": 105235063, + "AncientReceiptsBarrier": 105235063, + "FastSyncCatchUpHeightDelta": "10000000000", + "PivotNumber": 14239812, + "PivotHash": "0x335a694a721f223125c0f494f44c7525ef1503a664b227a7b3478fbf8c4175b7", + "PivotTotalDifficulty": "0", + "MaxAttemptsToUpdatePivot": 0 + }, + "Discovery": { + "Discv5Enabled": true }, "JsonRpc": { "Enabled": true, "Port": 8545, "EnginePort": 8551 }, + "Pruning": { + "PruningBoundary": 1024 + }, + "Blocks": { + "SecondsPerSlot": 2, + "TargetBlockGasLimit": 60000000 + }, + "Merge": { + "Enabled": true + }, "Optimism": { "SequencerUrl": "https://mainnet-sequencer.base.org" } diff --git a/src/Nethermind/Nethermind.Runner/configs/base-sepolia.cfg b/src/Nethermind/Nethermind.Runner/configs/base-sepolia.cfg index 0c54d3a6e32..c20d5897040 100644 --- a/src/Nethermind/Nethermind.Runner/configs/base-sepolia.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/base-sepolia.cfg @@ -10,13 +10,32 @@ "BlobsSupport": "Disabled" }, "Sync": { - "NetworkingEnabled": false + "FastSync": true, + "SnapSync": true, + "FastSyncCatchUpHeightDelta": "10000000000", + "PivotNumber": 9750377, + "PivotHash": "0x71ce74cb650b24f7fc473934e97c41f3cabe6b094ac368d9d7a733f0cb514599", + "PivotTotalDifficulty": "0", + "MaxAttemptsToUpdatePivot": 0 + }, + "Discovery": { + "Discv5Enabled": true }, "JsonRpc": { "Enabled": true, "Port": 8545, "EnginePort": 8551 }, + "Pruning": { + "PruningBoundary": 1024 + }, + "Blocks": { + "SecondsPerSlot": 2, + "TargetBlockGasLimit": 45000000 + }, + "Merge": { + "Enabled": true + }, "Optimism": { "SequencerUrl": "https://sepolia-sequencer.base.org" } diff --git a/src/Nethermind/Nethermind.Runner/configs/op-mainnet.cfg b/src/Nethermind/Nethermind.Runner/configs/op-mainnet.cfg index fa124fa6708..d8f2a8fcdae 100644 --- a/src/Nethermind/Nethermind.Runner/configs/op-mainnet.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/op-mainnet.cfg @@ -11,15 +11,34 @@ "BlobsSupport": "Disabled" }, "Sync": { - "NetworkingEnabled": false, + "FastSync": true, + "SnapSync": true, "AncientBodiesBarrier": 105235063, - "AncientReceiptsBarrier": 105235063 + "AncientReceiptsBarrier": 105235063, + "FastSyncCatchUpHeightDelta": "10000000000", + "PivotNumber": 119834660, + "PivotHash": "0xcdab6080b3846cf67b50935604deccbdf0e27434fa7b454ccf2195051ecd7a10", + "PivotTotalDifficulty": "0", + "MaxAttemptsToUpdatePivot": 0 + }, + "Discovery": { + "Discv5Enabled": true }, "JsonRpc": { "Enabled": true, "Port": 8545, "EnginePort": 8551 }, + "Pruning": { + "PruningBoundary": 1024 + }, + "Blocks": { + "SecondsPerSlot": 2, + "TargetBlockGasLimit": 30000000 + }, + "Merge": { + "Enabled": true + }, "Snapshot": { "Enabled": true, "DownloadUrl": "http://optimism-snapshot.nethermind.io/op-mainnet-genesis-v2.zip", diff --git a/src/Nethermind/Nethermind.Runner/configs/op-sepolia.cfg b/src/Nethermind/Nethermind.Runner/configs/op-sepolia.cfg index 60b15102702..e2fc13f67b8 100644 --- a/src/Nethermind/Nethermind.Runner/configs/op-sepolia.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/op-sepolia.cfg @@ -10,13 +10,32 @@ "BlobsSupport": "Disabled" }, "Sync": { - "NetworkingEnabled": false + "FastSync": true, + "SnapSync": true, + "FastSyncCatchUpHeightDelta": "10000000000", + "PivotNumber": 11338054, + "PivotHash": "0xf4307e8fd758db460d57b87bd910fa932feb928932c99faa85edf5a588ede049", + "PivotTotalDifficulty": "0", + "MaxAttemptsToUpdatePivot": 0 + }, + "Discovery": { + "Discv5Enabled": true }, "JsonRpc": { "Enabled": true, "Port": 8545, "EnginePort": 8551 }, + "Pruning": { + "PruningBoundary": 1024 + }, + "Blocks": { + "SecondsPerSlot": 2, + "TargetBlockGasLimit": 30000000 + }, + "Merge": { + "Enabled": true + }, "Optimism": { "SequencerUrl": "https://sepolia-sequencer.optimism.io" } diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptArrayStorageDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptArrayStorageDecoder.cs index f176fa5e990..53d025e7277 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptArrayStorageDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptArrayStorageDecoder.cs @@ -8,7 +8,7 @@ namespace Nethermind.Serialization.Rlp; [Rlp.SkipGlobalRegistration] -public class ReceiptArrayStorageDecoder : IRlpStreamDecoder +public class ReceiptArrayStorageDecoder(bool compactEncoding = true) : IRlpStreamDecoder { public static readonly ReceiptArrayStorageDecoder Instance = new(); @@ -19,12 +19,7 @@ public class ReceiptArrayStorageDecoder : IRlpStreamDecoder private static readonly IRlpValueDecoder CompactValueDecoder = Rlp.GetValueDecoder(RlpDecoderKey.Storage); public const int CompactEncoding = 127; - private readonly bool _useCompactEncoding = true; - - public ReceiptArrayStorageDecoder(bool compactEncoding = true) - { - _useCompactEncoding = compactEncoding; - } + private readonly bool _useCompactEncoding = compactEncoding; public int GetLength(TxReceipt[] items, RlpBehaviors rlpBehaviors) { From 183daf2911a6248e046b7fa9c817ef52d93d7d34 Mon Sep 17 00:00:00 2001 From: Alexey Osipov Date: Wed, 29 May 2024 11:03:17 +0300 Subject: [PATCH 3/5] Deduplicate via generics and inheritence --- .../Modules/Eth/EthModuleFactory.cs | 3 - .../Modules/Eth/EthRpcModule.Receipts.cs | 73 ++++ .../Eth/EthRpcModule.TransactionExecutor.cs | 2 +- .../Modules/Eth/EthRpcModule.cs | 61 ++-- .../Modules/Eth/IEthRpcModule.cs | 8 +- .../Modules/RpcModuleProvider.cs | 3 +- .../InitializeBlockProducerOptimism.cs | 1 - .../OptimismBlockProcessor.cs | 3 - .../Rpc/IOptimismEthRpcModule.cs | 331 +----------------- .../Rpc/OptimismEthModuleFactory.cs | 115 +++--- .../Rpc/OptimismEthRpcModule.cs | 278 +++------------ .../Rpc/RegisterOptimismRpcModules.cs | 32 +- .../ReceiptArrayStorageDecoder.cs | 7 +- 13 files changed, 260 insertions(+), 657 deletions(-) create mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.Receipts.cs diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs index 7f174d89081..25e42fc74f2 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs @@ -8,15 +8,12 @@ using Nethermind.Core.Specs; using Nethermind.Facade; using Nethermind.Facade.Eth; -using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth.GasPrice; using Nethermind.JsonRpc.Modules.Eth.FeeHistory; using Nethermind.Logging; using Nethermind.State; using Nethermind.TxPool; using Nethermind.Wallet; -using System.Text.Json; -using System.Text.Json.Serialization; namespace Nethermind.JsonRpc.Modules.Eth { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.Receipts.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.Receipts.cs new file mode 100644 index 00000000000..05ff93613e1 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.Receipts.cs @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Threading.Tasks; +using Nethermind.Blockchain.Find; +using Nethermind.Blockchain.Receipts; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; +using Nethermind.Evm; +using Nethermind.Facade; +using Nethermind.Facade.Eth; +using Nethermind.JsonRpc.Data; +using Nethermind.JsonRpc.Modules.Eth.FeeHistory; +using Nethermind.JsonRpc.Modules.Eth.GasPrice; +using Nethermind.Logging; +using Nethermind.State; +using Nethermind.TxPool; +using Nethermind.Wallet; + +namespace Nethermind.JsonRpc.Modules.Eth; + +public class EthRpcModule : EthRpcModule, IEthRpcModule +{ + public EthRpcModule( + IJsonRpcConfig rpcConfig, + IBlockchainBridge blockchainBridge, + IBlockFinder blockFinder, + IReceiptFinder receiptFinder, + IStateReader stateReader, + ITxPool txPool, + ITxSender txSender, + IWallet wallet, + ILogManager logManager, + ISpecProvider specProvider, + IGasPriceOracle gasPriceOracle, + IEthSyncingInfo ethSyncingInfo, + IFeeHistoryOracle feeHistoryOracle) : base( + + rpcConfig, + blockchainBridge, + blockFinder, + receiptFinder, + stateReader, + txPool, + txSender, + wallet, + logManager, + specProvider, + gasPriceOracle, + ethSyncingInfo, + feeHistoryOracle) + { + } + + public override ResultWrapper eth_getTransactionReceipt(Hash256 txHash) + { + (TxReceipt? receipt, TxGasInfo? gasInfo, int logIndexStart) = _blockchainBridge.GetReceiptAndGasInfo(txHash); + if (receipt is null || gasInfo is null) + { + return ResultWrapper.Success(null); + } + + if (_logger.IsTrace) _logger.Trace($"eth_getTransactionReceipt request {txHash}, result: {txHash}"); + return ResultWrapper.Success(new(txHash, receipt, gasInfo.Value, logIndexStart)); + } + + + public override ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) + { + return _receiptFinder.GetBlockReceipts(blockParameter, _blockFinder, _specProvider); + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index afc281f7f6d..2872e683bc8 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -17,7 +17,7 @@ namespace Nethermind.JsonRpc.Modules.Eth { - public partial class EthRpcModule + public partial class EthRpcModule { private abstract class TxExecutor { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 290f3c22ab8..20d3ce13d72 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -38,23 +38,23 @@ namespace Nethermind.JsonRpc.Modules.Eth; -public partial class EthRpcModule : IEthRpcModule +public abstract partial class EthRpcModule : IEthRpcModule where TReceiptForRpc : ReceiptForRpc { - private readonly Encoding _messageEncoding = Encoding.UTF8; - private readonly IJsonRpcConfig _rpcConfig; - private readonly IBlockchainBridge _blockchainBridge; - private readonly IBlockFinder _blockFinder; - private readonly IReceiptFinder _receiptFinder; - private readonly IStateReader _stateReader; - private readonly ITxPool _txPoolBridge; - private readonly ITxSender _txSender; - private readonly IWallet _wallet; - private readonly ISpecProvider _specProvider; - private readonly ILogger _logger; - private readonly IGasPriceOracle _gasPriceOracle; - private readonly IEthSyncingInfo _ethSyncingInfo; - - private readonly IFeeHistoryOracle _feeHistoryOracle; + protected readonly Encoding _messageEncoding = Encoding.UTF8; + protected readonly IJsonRpcConfig _rpcConfig; + protected readonly IBlockchainBridge _blockchainBridge; + protected readonly IBlockFinder _blockFinder; + protected readonly IReceiptFinder _receiptFinder; + protected readonly IStateReader _stateReader; + protected readonly ITxPool _txPoolBridge; + protected readonly ITxSender _txSender; + protected readonly IWallet _wallet; + protected readonly ISpecProvider _specProvider; + protected readonly ILogger _logger; + protected readonly IGasPriceOracle _gasPriceOracle; + protected readonly IEthSyncingInfo _ethSyncingInfo; + + protected readonly IFeeHistoryOracle _feeHistoryOracle; private static bool HasStateForBlock(IBlockchainBridge blockchainBridge, BlockHeader header) { return blockchainBridge.HasStateForRoot(header.StateRoot!); @@ -193,7 +193,7 @@ public ResultWrapper eth_getStorageAt(Address address, UInt256 positionI return ResultWrapper.Success(storage.IsEmpty ? Bytes32.Zero.Unwrap() : storage!.PadLeft(32)); } - public Task> eth_getTransactionCount(Address address, BlockParameter blockParameter) + public Task> eth_getTransactionCount(Address address, BlockParameter? blockParameter) { if (blockParameter == BlockParameter.Pending) { @@ -233,11 +233,6 @@ public Task> eth_getTransactionCount(Address address, Blo : ResultWrapper.Success((UInt256)searchResult.Object!.Transactions.Length); } - public ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) - { - return _receiptFinder.GetBlockReceipts(blockParameter, _blockFinder, _specProvider); - } - public ResultWrapper eth_getUncleCountByBlockHash(Hash256 blockHash) { SearchResult searchResult = _blockFinder.SearchForBlock(new BlockParameter(blockHash)); @@ -295,14 +290,14 @@ public ResultWrapper eth_sign(Address addressData, byte[] message) return ResultWrapper.Success(sig.Bytes); } - public Task> eth_sendTransaction(TransactionForRpc rpcTx) + public virtual Task> eth_sendTransaction(TransactionForRpc rpcTx) { Transaction tx = rpcTx.ToTransactionWithDefaults(_blockchainBridge.GetChainId()); TxHandlingOptions options = rpcTx.Nonce is null ? TxHandlingOptions.ManagedNonce : TxHandlingOptions.None; return SendTx(tx, options); } - public async Task> eth_sendRawTransaction(byte[] transaction) + public virtual async Task> eth_sendRawTransaction(byte[] transaction) { try { @@ -343,7 +338,7 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); - public ResultWrapper eth_estimateGas(TransactionForRpc transactionCall, BlockParameter blockParameter) => + public ResultWrapper eth_estimateGas(TransactionForRpc transactionCall, BlockParameter? blockParameter) => new EstimateGasTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); @@ -468,18 +463,6 @@ public ResultWrapper eth_getTransactionByBlockNumberAndIndex( return ResultWrapper.Success(transactionModel); } - public Task> eth_getTransactionReceipt(Hash256 txHash) - { - (TxReceipt? receipt, TxGasInfo? gasInfo, int logIndexStart) = _blockchainBridge.GetReceiptAndGasInfo(txHash); - if (receipt is null || gasInfo is null) - { - return Task.FromResult(ResultWrapper.Success(null)); - } - - if (_logger.IsTrace) _logger.Trace($"eth_getTransactionReceipt request {txHash}, result: {txHash}"); - return Task.FromResult(ResultWrapper.Success(new(txHash, receipt, gasInfo.Value, logIndexStart))); - } - public ResultWrapper eth_getUncleByBlockHashAndIndex(Hash256 blockHash, UInt256 positionIndex) { return GetUncle(new BlockParameter(blockHash), positionIndex); @@ -730,4 +713,8 @@ private static ResultWrapper GetFailureResult(ResourceNotFound private ResultWrapper GetStateFailureResult(BlockHeader header) => ResultWrapper.Fail($"No state available for block {header.ToString(BlockHeader.Format.FullHashAndNumber)}", ErrorCodes.ResourceUnavailable, _ethSyncingInfo.SyncMode.HaveNotSyncedStateYet()); + + public abstract ResultWrapper eth_getBlockReceipts([JsonRpcParameter(ExampleValue = "latest")] BlockParameter blockParameter); + + public abstract ResultWrapper eth_getTransactionReceipt([JsonRpcParameter(ExampleValue = "[\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\"]")] Hash256 txHashData); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 11ef1e1f707..0b3e40bcd16 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -15,7 +15,9 @@ namespace Nethermind.JsonRpc.Modules.Eth { [RpcModule(ModuleType.Eth)] - public interface IEthRpcModule : IRpcModule + public interface IEthRpcModule : IEthRpcModule { } + + public interface IEthRpcModule : IRpcModule where TReceiptForRpc : ReceiptForRpc { [JsonRpcMethod(IsImplemented = true, Description = "Returns ChainID", @@ -111,7 +113,7 @@ public interface IEthRpcModule : IRpcModule [JsonRpcMethod(Description = "Get receipts from all transactions from particular block, more efficient than fetching the receipts one-by-one.", IsImplemented = true, ExampleResponse = "{\"jsonrpc\":\"2.0\",\"result\":[{\"transactionHash\":\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"transactionIndex\":\"0x0\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"cumulativeGasUsed\":\"0x5208\",\"gasUsed\":\"0x5208\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"contractAddress\":null,\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x1\",\"type\":\"0x0\"},{\"transactionHash\":\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\",\"transactionIndex\":\"0x1\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"cumulativeGasUsed\":\"0xa410\",\"gasUsed\":\"0x5208\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"contractAddress\":null,\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x1\",\"type\":\"0x0\"}],\"id\":67}")] - ResultWrapper eth_getBlockReceipts([JsonRpcParameter(ExampleValue = "latest")] BlockParameter blockParameter); + ResultWrapper eth_getBlockReceipts([JsonRpcParameter(ExampleValue = "latest")] BlockParameter blockParameter); [JsonRpcMethod(IsImplemented = true, Description = "Returns number of uncles in the block by block hash", @@ -212,7 +214,7 @@ ResultWrapper eth_getTransactionByBlockNumberAndIndex( Description = "Retrieves a transaction receipt by tx hash", IsSharable = true, ExampleResponse = "{\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"transactionIndex\":\"0x7\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"cumulativeGasUsed\":\"0x62c9d\",\"gasUsed\":\"0xe384\",\"effectiveGasPrice\":\"0x12a05f200\",\"from\":\"0x0afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"to\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"contractAddress\":null,\"logs\":[{\"removed\":false,\"logIndex\":\"0x0\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x2ac3c1d3e24b45c6c310534bc2dd84b5ed576335\",\"data\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x00000000000000000000000019e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\"]},{\"removed\":false,\"logIndex\":\"0x1\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"data\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007735940000000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0x950494fc3642fae5221b6c32e0e45765c95ebb382a04a71b160db0843e74c99f\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\"]}],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000020000000000000800000000000000000000400000000000000000000000000000000000000002000000000000000000000000008000000000000000000000000000000000000000000000002002000000000000000000000000000000000000000000812000000000000000000000000000001000000000000000000000008000400008000000000000000000000000000000000000000000000000000000000800000000000000000000002000000000000000000000000000000000000100000000000000000002000000000000000000000000010000000000000000000000400000000020000\",\"status\":\"0x1\",\"type\":\"0x0\"}")] - Task> eth_getTransactionReceipt([JsonRpcParameter(ExampleValue = "[\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\"]")] Hash256 txHashData); + ResultWrapper eth_getTransactionReceipt([JsonRpcParameter(ExampleValue = "[\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\"]")] Hash256 txHashData); [JsonRpcMethod(IsImplemented = true, Description = "Retrieves an uncle block header by block hash and uncle index", diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/RpcModuleProvider.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/RpcModuleProvider.cs index 25811ed3d4d..fdbd07c91ad 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/RpcModuleProvider.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/RpcModuleProvider.cs @@ -139,7 +139,8 @@ public void Return(string methodName, IRpcModule rpcModule) private static IDictionary GetMethodDict(Type type) { - var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); + BindingFlags methodFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; + IEnumerable methods = type.GetMethods(methodFlags).Concat(type.GetInterfaces().SelectMany(i => i.GetMethods(methodFlags))); return methods.ToDictionary( x => x.Name.Trim(), x => diff --git a/src/Nethermind/Nethermind.Optimism/InitializeBlockProducerOptimism.cs b/src/Nethermind/Nethermind.Optimism/InitializeBlockProducerOptimism.cs index d0deef60401..2c2b0d404ad 100644 --- a/src/Nethermind/Nethermind.Optimism/InitializeBlockProducerOptimism.cs +++ b/src/Nethermind/Nethermind.Optimism/InitializeBlockProducerOptimism.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System.Threading.Tasks; using Nethermind.Api; using Nethermind.Config; using Nethermind.Consensus; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismBlockProcessor.cs b/src/Nethermind/Nethermind.Optimism/OptimismBlockProcessor.cs index 4cdbb1c4150..e06cc378360 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismBlockProcessor.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismBlockProcessor.cs @@ -2,9 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using Nethermind.Blockchain; using Nethermind.Blockchain.Blocks; -using Nethermind.Blockchain.Find; using Nethermind.Blockchain.Receipts; using Nethermind.Consensus.Processing; using Nethermind.Consensus.Rewards; @@ -12,7 +10,6 @@ using Nethermind.Consensus.Withdrawals; using Nethermind.Core; using Nethermind.Core.Specs; -using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Logging; using Nethermind.State; diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs index 839dae544fa..b12ce4a013a 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs @@ -1,337 +1,10 @@ // SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System.Collections.Generic; -using System.Threading.Tasks; -using Nethermind.Blockchain.Find; -using Nethermind.Core; -using Nethermind.Core.Crypto; -using Nethermind.Facade.Eth; -using Nethermind.Facade.Filters; -using Nethermind.Int256; -using Nethermind.JsonRpc; -using Nethermind.JsonRpc.Data; -using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Eth; -using Nethermind.State.Proofs; +using Nethermind.JsonRpc.Modules; namespace Nethermind.Optimism; [RpcModule(ModuleType.Eth)] -public interface IOptimismEthRpcModule : IRpcModule -{ - [JsonRpcMethod(IsImplemented = true, - Description = "Returns ChainID", - IsSharable = true, - ExampleResponse = "0x4")] - ResultWrapper eth_chainId(); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns ETH protocol version", - IsSharable = true, - ExampleResponse = "0x41")] - ResultWrapper eth_protocolVersion(); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns syncing status", - IsSharable = true, - ExampleResponse = - "{\"isSyncing\":true,\"startingBlock\":\"0x0\",\"currentBlock\":\"0x0\",\"highestBlock\":\"0x4df8a4\"},\"id\":1}")] - ResultWrapper eth_syncing(); - - [JsonRpcMethod(IsImplemented = false, - Description = "Returns miner's coinbase", - IsSharable = true, - ExampleResponse = "0x0000000000000000000000000000000000000000")] - ResultWrapper
eth_coinbase(); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns block fee history.", - IsSharable = true, - ExampleResponse = - "{\"baseFeePerGas\": [\"0x116c1cbb03\", \"0x10c3714c06\"], \"gasUsedRatio\": [0.3487305666666667, 0.3], \"oldestBlock\": \"0xc7e5ff\", \"reward\": [[\"0x3b9aca00\",\"0x3b9aca00\"], [\"0x0\",\"0x3bb24dfa\"]]}")] - ResultWrapper eth_feeHistory(int blockCount, BlockParameter newestBlock, - double[]? rewardPercentiles = null); - - [JsonRpcMethod(IsImplemented = false, Description = "Returns full state snapshot", IsSharable = true)] - ResultWrapper eth_snapshot(); - - [JsonRpcMethod(IsImplemented = false, Description = "", IsSharable = true)] - ResultWrapper eth_maxPriorityFeePerGas(); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns miner's gas price", - IsSharable = true, - ExampleResponse = "0x4a817c800")] - ResultWrapper eth_gasPrice(); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns the base fee per blob gas in wei", - IsSharable = true, - ExampleResponse = "0x1")] - ResultWrapper eth_blobBaseFee(); - - [JsonRpcMethod(IsImplemented = false, - Description = "Returns accounts", - IsSharable = true, - ExampleResponse = "[\"0x9b96a7841d6e0b76872c85c86082959189a27342\"]")] - ResultWrapper> eth_accounts(); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns current block number", - IsSharable = true, - ExampleResponse = "0x885480")] - Task> eth_blockNumber(); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns account balance", - IsSharable = true, - ExampleResponse = "0x6c8ae945bfe6e")] - Task> eth_getBalance( - [JsonRpcParameter(ExampleValue = "[\"0x78467cada5f1883e79fcf0f3ebfa50abeec8c820\"]")] Address address, - BlockParameter? blockParameter = null); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns storage data at address. storage_index", - IsSharable = true, - ExampleResponse = "0x")] - ResultWrapper eth_getStorageAt( - [JsonRpcParameter(ExampleValue = - "[\"0x000000000000000000000000c666d239cbda32aa7ebca894b6dc598ddb881285\",\"0x2\"]")] - Address address, UInt256 positionIndex, BlockParameter? blockParameter = null); - - [JsonRpcMethod(IsImplemented = true, - Description = - "Returns account nonce (number of trnsactions from the account since genesis) at the given block number", - IsSharable = true, - ExampleResponse = "0x3e")] - Task> eth_getTransactionCount( - [JsonRpcParameter(ExampleValue = "[\"0xae3ed7a6ccdddf2914133d0669b5f02ff6fa8ad2\"]")] Address address, - BlockParameter? blockParameter = null); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns number of transactions in the block block hash", - IsSharable = true, - ExampleResponse = "0x20")] - ResultWrapper eth_getBlockTransactionCountByHash( - [JsonRpcParameter(ExampleValue = "[\"0x199c2ef63392fb67f929fe0580e11f62fa6c54b9951a624896da91375a6805b1\"]")] - Hash256 blockHash); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns number of transactions in the block by block number", - IsSharable = true, - ExampleResponse = "0x20")] - ResultWrapper eth_getBlockTransactionCountByNumber( - [JsonRpcParameter(ExampleValue = "[\"8934677\"]")] BlockParameter blockParameter); - - [JsonRpcMethod( - Description = - "Get receipts from all transactions from particular block, more efficient than fetching the receipts one-by-one.", - IsImplemented = true, - ExampleResponse = - "{\"jsonrpc\":\"2.0\",\"result\":[{\"transactionHash\":\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"transactionIndex\":\"0x0\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"cumulativeGasUsed\":\"0x5208\",\"gasUsed\":\"0x5208\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"contractAddress\":null,\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x1\",\"type\":\"0x0\"},{\"transactionHash\":\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\",\"transactionIndex\":\"0x1\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"cumulativeGasUsed\":\"0xa410\",\"gasUsed\":\"0x5208\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"contractAddress\":null,\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x1\",\"type\":\"0x0\"}],\"id\":67}")] - ResultWrapper eth_getBlockReceipts( - [JsonRpcParameter(ExampleValue = "latest")] BlockParameter blockParameter); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns number of uncles in the block by block hash", - IsSharable = true, - ExampleResponse = "0x0")] - ResultWrapper eth_getUncleCountByBlockHash( - [JsonRpcParameter(ExampleValue = "[\"0xe495c3385bb9162103bc07989d7160c38759e017c37c7d0608268bd5989d6bed \"]")] - Hash256 blockHash); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns number of uncles in the block by block number", - IsSharable = true, - ExampleResponse = "0x0")] - ResultWrapper eth_getUncleCountByBlockNumber( - [JsonRpcParameter(ExampleValue = "[\"5127400\"]")] BlockParameter blockParameter); - - [JsonRpcMethod(IsImplemented = true, Description = "Returns account code at given address and block", - IsSharable = true)] - ResultWrapper eth_getCode(Address address, BlockParameter? blockParameter = null); - - [JsonRpcMethod(IsImplemented = false, Description = "Signs a transaction", IsSharable = true)] - ResultWrapper eth_sign(Address addressData, byte[] message); - - [JsonRpcMethod(IsImplemented = true, - Description = "Send a transaction to the tx pool and broadcasting", - IsSharable = true, - ExampleResponse = "0x03783fac2efed8fbc9ad443e592ee30e61d65f471140c10ca155e937b435b760")] - Task> eth_sendTransaction( - [JsonRpcParameter(ExampleValue = - "[{\"From\": \"0xc2208fe87805279b03c1a8a78d7ee4bfdb0e48ee\", \"Gas\":\"21000\",\"GasPrice\":\"20000000000\", \"Nonce\":\"23794\", \"To\":\"0x2d44c0e097f6cd0f514edac633d82e01280b4a5c\"}]")] - TransactionForRpc rpcTx); - - [JsonRpcMethod(IsImplemented = true, - Description = "Send a raw transaction to the tx pool and broadcasting", - IsSharable = true, - ExampleResponse = "0x7a5a94d5b5e3ce017ce2c2022f02ec5db10611c43695c3256861bdb19317ab0e" - )] - Task> eth_sendRawTransaction( - [JsonRpcParameter(ExampleValue = - "[\"0xf86380843b9aca0082520894b943b13292086848d8180d75c73361107920bb1a80802ea0385656b91b8f1f5139e9ba3449b946a446c9cfe7adb91b180ddc22c33b17ac4da01fe821879d386b140fd8080dcaaa98b8c709c5025c8c4dea1334609ebac41b6c\"]")] - byte[] transaction); - - [JsonRpcMethod(IsImplemented = true, - Description = "Executes a tx call (does not create a transaction)", - IsSharable = false, - ExampleResponse = "0x")] - ResultWrapper eth_call( - [JsonRpcParameter(ExampleValue = - "[{\"from\":\"0x0001020304050607080910111213141516171819\",\"gasPrice\":\"0x100000\", \"data\": \"0x70a082310000000000000000000000006c1f09f6271fbe133db38db9c9280307f5d22160\", \"to\": \"0x0d8775f648430679a709e98d2b0cb6250d2887ef\"}]")] - TransactionForRpc transactionCall, BlockParameter? blockParameter = null); - - [JsonRpcMethod(IsImplemented = true, - Description = "Executes a tx call and returns gas used (does not create a transaction)", - IsSharable = false, - ExampleResponse = "0x")] - ResultWrapper eth_estimateGas( - [JsonRpcParameter(ExampleValue = - "[\"{\"from\": \"0x0001020304050607080910111213141516171819\", \"gasPrice\": \"1048576\", \"to\": \"0x0d8775f648430679a709e98d2b0cb6250d2887ef\"}\"]")] - TransactionForRpc transactionCall, BlockParameter? blockParameter = null); - - [JsonRpcMethod(IsImplemented = true, - Description = - "Creates an [EIP2930](https://eips.ethereum.org/EIPS/eip-2930) type AccessList for the given transaction", - EdgeCaseHint = - "If your transaction has code executed, then you can generate transaction access list with eth_createAccessList. If you send it with your transaction then it will lower your gas cost on Ethereum", - IsSharable = false, - ExampleResponse = - "{\"accessList\":[{\"address\":\"0xfffffffffffffffffffffffffffffffffffffffe\",\"storageKeys\":[\"0x0000000000000000000000000000000000000000000000000000000000000001\",\"0x0000000000000000000000000000000000000000000000000000000000000002\"]},{\"address\":\"0x76e68a8696537e4141926f3e528733af9e237d69\",\"storageKeys\":[]}],\"gasUsed\":\"0xf71b\"}")] - ResultWrapper eth_createAccessList( - [JsonRpcParameter(Description = "Transaction's details", ExampleValue = "[\"{\"type\":\"0x1\"]")] - TransactionForRpc transactionCall, - [JsonRpcParameter(Description = "(optional)")] - BlockParameter? blockParameter = null, - [JsonRpcParameter(Description = "(optional)")] - bool optimize = true); - - [JsonRpcMethod(IsImplemented = true, - Description = "Retrieves a block by hash", - IsSharable = true, - ExampleResponse = - "{\"author\":\"0x0000000000000000000000000000000000000000\",\"difficulty\":\"0x1\",\"extraData\":\"0x000000000000436f6e73656e5379732048797065726c656467657220426573754d3f7b71165a8266fcc569c96b6fcf9971ee4a8df59eeec4dcced0df8d778733429988e21d0124918859f988be9debf4b25fb5282ea41a2fc15f827f446ec93200\",\"gasLimit\":\"0x1c9c364\",\"gasUsed\":\"0x3aa87\",\"hash\":\"0xf33507f93a046dbdbb80dee5f47b84283297f6c53f1b665adc3cb6fe4138aa84\",\"logsBloom\":\"0x00000000000020000000000008000060000000000000000000000000000000000000000000000000201000020008000000000000000000000100000000200020000000000000000000000008000000000000000010000000000000000000000000000000000000000000080000000000000000000000002000000010000000000000000000000000000000000000000000040000001000000000000000020000020400000000000000000000000000000000000000000000000000010000000000000002080000000000000000020000000000000000000000000000000000000010020000000000000000000000000100000000000000000000010000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x4e3d79\",\"parentHash\":\"0x01dba3a7eb61dc6dba3f9663c8fb632f76f60a476f57df74c3e5bd9d0a246339\",\"receiptsRoot\":\"0x70f3bd929735d8edeb953cd30a27e703e7dd3ec4af32cb74fe8ac302f9e7fb87\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x754\",\"stateRoot\":\"0x71af7e25302d1baa4c988c267450eb2c7fa20938fac377809c8d77f8ff8108ac\",\"totalDifficulty\":\"0x726275\",\"timestamp\":\"0x60ec1218\",\"baseFeePerGas\":\"0x7\",\"transactions\":[\"0xa65d391d8149ed0906fab923e870d2bc7f6d27c2be10fe1bcfc6f02869b38ef3\",\"0x369a89354041b7a8cb40edce51c36ebb0ee6ffa4d8056f5a658d90f3bbe1a81a\",\"0xf857daf60d03381b9a6ecb341b62798b424d20dc05763858e13955dd866b489d\"],\"transactionsRoot\":\"0x90115f8dc10c08e748675f52f3904615729a014461ca80d72c60239bf75ee209\",\"uncles\":[]}")] - ResultWrapper eth_getBlockByHash( - [JsonRpcParameter(ExampleValue = "[\"0xf33507f93a046dbdbb80dee5f47b84283297f6c53f1b665adc3cb6fe4138aa84\"]")] - Hash256 blockHash, bool returnFullTransactionObjects = false); - - [JsonRpcMethod(IsImplemented = true, - Description = "Retrieves a block by number", - IsSharable = true, - ExampleResponse = - "{\"author\":\"0x0000000000000000000000000000000000000000\",\"difficulty\":\"0x1\",\"extraData\":\"0x000000000000436f6e73656e5379732048797065726c656467657220426573754d3f7b71165a8266fcc569c96b6fcf9971ee4a8df59eeec4dcced0df8d778733429988e21d0124918859f988be9debf4b25fb5282ea41a2fc15f827f446ec93200\",\"gasLimit\":\"0x1c9c364\",\"gasUsed\":\"0x3aa87\",\"hash\":\"0xf33507f93a046dbdbb80dee5f47b84283297f6c53f1b665adc3cb6fe4138aa84\",\"logsBloom\":\"0x00000000000020000000000008000060000000000000000000000000000000000000000000000000201000020008000000000000000000000100000000200020000000000000000000000008000000000000000010000000000000000000000000000000000000000000080000000000000000000000002000000010000000000000000000000000000000000000000000040000001000000000000000020000020400000000000000000000000000000000000000000000000000010000000000000002080000000000000000020000000000000000000000000000000000000010020000000000000000000000000100000000000000000000010000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000000\",\"number\":\"0x4e3d79\",\"parentHash\":\"0x01dba3a7eb61dc6dba3f9663c8fb632f76f60a476f57df74c3e5bd9d0a246339\",\"receiptsRoot\":\"0x70f3bd929735d8edeb953cd30a27e703e7dd3ec4af32cb74fe8ac302f9e7fb87\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x754\",\"stateRoot\":\"0x71af7e25302d1baa4c988c267450eb2c7fa20938fac377809c8d77f8ff8108ac\",\"totalDifficulty\":\"0x726275\",\"timestamp\":\"0x60ec1218\",\"baseFeePerGas\":\"0x7\",\"transactions\":[\"0xa65d391d8149ed0906fab923e870d2bc7f6d27c2be10fe1bcfc6f02869b38ef3\",\"0x369a89354041b7a8cb40edce51c36ebb0ee6ffa4d8056f5a658d90f3bbe1a81a\",\"0xf857daf60d03381b9a6ecb341b62798b424d20dc05763858e13955dd866b489d\"],\"transactionsRoot\":\"0x90115f8dc10c08e748675f52f3904615729a014461ca80d72c60239bf75ee209\",\"uncles\":[]}")] - ResultWrapper eth_getBlockByNumber( - [JsonRpcParameter(ExampleValue = "[\"5127545\"]")] BlockParameter blockParameter, - bool returnFullTransactionObjects = false); - - [JsonRpcMethod(IsImplemented = true, - Description = "Retrieves a transaction by hash", - IsSharable = true, - ExampleResponse = - "{\"hash\":\"0xabca23910646013d608ec671de099447ab60b2b7159ad8319c3c088e8d9ea0fa\",\"nonce\":\"0x1a\",\"blockHash\":\"0xcb6756f69e0469acd5e5bb77966be580786ec2c11de85c9ddfd75257010e34f8\",\"blockNumber\":\"0x4dfbc7\",\"transactionIndex\":\"0xb\",\"from\":\"0xe1e7ab1c643dbe5b24739fdf2a5c7c193b54dd99\",\"to\":\"0x0b10e304088b2ba2b2acfd2f72573faad31a13a5\",\"value\":\"0x0\",\"gasPrice\":\"0x2540be400\",\"gas\":\"0xb4a4\",\"data\":\"0x095ea7b300000000000000000000000092c1576845703089cf6c0788379ed81f75f45dd500000000000000000000000000000000000000000000000000000002540be400\",\"input\":\"0x095ea7b300000000000000000000000092c1576845703089cf6c0788379ed81f75f45dd500000000000000000000000000000000000000000000000000000002540be400\",\"type\":\"0x0\",\"v\":\"0x2d\",\"s\":\"0x496d72d435ead8a8a9a865b14d6a102c1a9f848681d050dbbf11c522c612235\",\"r\":\"0xc8350e831203fecc8bff41f5cf858ac1d121e4b4d9e59c1137cc9440516ca9fd\"}")] - Task> eth_getTransactionByHash( - [JsonRpcParameter(ExampleValue = "\"0xabca23910646013d608ec671de099447ab60b2b7159ad8319c3c088e8d9ea0fa\"")] - Hash256 transactionHash); - - [JsonRpcMethod(IsImplemented = true, - Description = "Returns the pending transactions list", - IsSharable = true, - ExampleResponse = "[]")] - ResultWrapper eth_pendingTransactions(); - - [JsonRpcMethod(IsImplemented = true, - Description = "Retrieves a transaction by block hash and index", - IsSharable = true, - ExampleResponse = - "{\"hash\":\"0xb87ec4c8cb36a06f49cdd93c2e9f63e0b7db9af07a605c8bcf1fbe705162344e\",\"nonce\":\"0x5d\",\"blockHash\":\"0xfe47fb3539ccce9d19a032473effdd6ce19e3c921bbae2746152ccf82ceef48e\",\"blockNumber\":\"0x4dfc90\",\"transactionIndex\":\"0x2\",\"from\":\"0xaa9a0f962e433755c843175488fe088fccf8526f\",\"to\":\"0x074b24cef703f17fe123fa1b82081055775b7004\",\"value\":\"0x0\",\"gasPrice\":\"0x2540be401\",\"gas\":\"0x130ab\",\"data\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"input\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"type\":\"0x0\",\"v\":\"0x2e\",\"s\":\"0x696f6db060a6dd30435a7f592506ba3213f81cf4704e211a1a45a99f8984189a\",\"r\":\"0x7e07076186e38b68cb7e4f68a04258a5744c5a2ad1a7153456ee662a07902954\"}")] - ResultWrapper eth_getTransactionByBlockHashAndIndex( - [JsonRpcParameter(ExampleValue = - "[\"0xfe47fb3539ccce9d19a032473effdd6ce19e3c921bbae2746152ccf82ceef48e\",\"0x2\"]")] - Hash256 blockHash, UInt256 positionIndex); - - [JsonRpcMethod(IsImplemented = true, - Description = "Retrieves a transaction by block number and index", - IsSharable = true, - ExampleResponse = - "{\"hash\":\"0xfd320a4949990929f64b52041c58a74c8ce13289b3d6853bd8073b0580aa031a\",\"nonce\":\"0x5b\",\"blockHash\":\"0xd779e1a5ce8f34544d66d219bb3e5331a7b280fae89a36d7d52813a23e1ca1e3\",\"blockNumber\":\"0x4dfdd8\",\"transactionIndex\":\"0x8\",\"from\":\"0xadb540569e2db497bd973c141b0b63be98461e40\",\"to\":\"0x074b24cef703f17fe123fa1b82081055775b7004\",\"value\":\"0x0\",\"gasPrice\":\"0x12a05f200\",\"gas\":\"0x927c0\",\"data\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"input\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"type\":\"0x0\",\"v\":\"0x2e\",\"s\":\"0x37b90a929884787df717c87258f0434e2f115ce2fbb4bfc230322112fa9d5bbc\",\"r\":\"0x5222eff9e16b5c3e9e8901d9c45fc8e0f9cf774e8a56546a504025ef67ceefec\"}")] - ResultWrapper eth_getTransactionByBlockNumberAndIndex( - [JsonRpcParameter(ExampleValue = "[\"5111256\",\"0x8\"]")] - BlockParameter blockParameter, UInt256 positionIndex); - - [JsonRpcMethod(IsImplemented = true, - Description = "Retrieves a transaction receipt by tx hash", - IsSharable = true, - ExampleResponse = - "{\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"transactionIndex\":\"0x7\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"cumulativeGasUsed\":\"0x62c9d\",\"gasUsed\":\"0xe384\",\"effectiveGasPrice\":\"0x12a05f200\",\"from\":\"0x0afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"to\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"contractAddress\":null,\"logs\":[{\"removed\":false,\"logIndex\":\"0x0\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x2ac3c1d3e24b45c6c310534bc2dd84b5ed576335\",\"data\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x00000000000000000000000019e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\"]},{\"removed\":false,\"logIndex\":\"0x1\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"data\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007735940000000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0x950494fc3642fae5221b6c32e0e45765c95ebb382a04a71b160db0843e74c99f\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\"]}],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000020000000000000800000000000000000000400000000000000000000000000000000000000002000000000000000000000000008000000000000000000000000000000000000000000000002002000000000000000000000000000000000000000000812000000000000000000000000000001000000000000000000000008000400008000000000000000000000000000000000000000000000000000000000800000000000000000000002000000000000000000000000000000000000100000000000000000002000000000000000000000000010000000000000000000000400000000020000\",\"status\":\"0x1\",\"type\":\"0x0\"}")] - Task> eth_getTransactionReceipt( - [JsonRpcParameter(ExampleValue = "[\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\"]")] - Hash256 txHashData); - - [JsonRpcMethod(IsImplemented = true, - Description = "Retrieves an uncle block header by block hash and uncle index", - IsSharable = true)] - ResultWrapper eth_getUncleByBlockHashAndIndex(Hash256 blockHashData, UInt256 positionIndex); - - [JsonRpcMethod(IsImplemented = true, - Description = "Retrieves an uncle block header by block number and uncle index", IsSharable = true)] - ResultWrapper eth_getUncleByBlockNumberAndIndex(BlockParameter blockParameter, UInt256 positionIndex); - - [JsonRpcMethod(IsImplemented = true, - Description = "Creates an update filter", - IsSharable = false, - ExampleResponse = "0x9")] - ResultWrapper - eth_newFilter([JsonRpcParameter(ExampleValue = "[{\"toBlock\":\"latest\"}]")] Filter filter); - - [JsonRpcMethod(IsImplemented = true, - Description = "Creates an update filter", - IsSharable = false, - ExampleResponse = "0x0")] - ResultWrapper eth_newBlockFilter(); - - [JsonRpcMethod(IsImplemented = true, - Description = "Creates an update filter", - IsSharable = false, - ExampleResponse = "0x1")] - ResultWrapper eth_newPendingTransactionFilter(); - - [JsonRpcMethod(IsImplemented = true, - Description = "Creates an update filter", - IsSharable = false)] - ResultWrapper eth_uninstallFilter(UInt256 filterId); - - [JsonRpcMethod(IsImplemented = true, - Description = "Reads filter changes", - IsSharable = true, - ExampleResponse = "[]")] - ResultWrapper> eth_getFilterChanges( - [JsonRpcParameter(ExampleValue = "[\"0x9\"]")] UInt256 filterId); - - [JsonRpcMethod(IsImplemented = true, - Description = "Reads filter changes", - IsSharable = true, - ExampleResponse = "[]")] - ResultWrapper> eth_getFilterLogs( - [JsonRpcParameter(ExampleValue = "[\"0x9\"]")] UInt256 filterId); - - [JsonRpcMethod(IsImplemented = true, Description = "Reads logs", IsSharable = false)] - ResultWrapper> eth_getLogs(Filter filter); - - [JsonRpcMethod(Description = "https://github.com/ethereum/EIPs/issues/1186", - IsImplemented = true, - IsSharable = true, - ExampleResponse = - " \"accountProof\": [\"0xf90211a0446f43a2d3e433732c75bcf3519f4844e0441a4d39b31395ee9a65700c30d3b4a0b9720db63afe9909418fb6e02c9d9f225310856549cc1b66b486041f2d867250a046e6e560e52d4fe0d2f6609f489ba85f18ad1655fee18452588dc08388fbd711a01e68f36c91bd15cbf65587d6db2a7cbd6635907291e77dd80152161da9a28a48a0d2178a1891c26ccaa2d2cec82c231a0640a26a1f5e07c7b5493761bdb3aa94e5a0fa909327d406980a2e602eadd3f56cf8dc89320d4662340962e9cac2beee3d8da0a0fc71e7dec6320a993b4b65b2f82544910d0a4a7c6f8c5a1ebaa38357d259e3a0680161dec84c5f1c8d5e2a585c9708b1b6fbc2dc664a432e045d99f5e7d89259a0f76a745765be58d46d795c44d3900a4a05b6396530244d50822616c8bbb11e19a0594824352d58f5caff819c8df9581b6a41d0e94eb584ed0431d48b48f320bb5ca0e762eb52b2bcacd728fac605de6229dc83588001ecddcd3b454b64c393ee69eda0d319cf1021af0a8535e4916c3404c84917957d73d0711f71fd6456b4533993bba0878240238a894e6fa798671ac3792563c6666a7c7fba8066d090b65d6a7aa701a03c03fdb4d8f4b241442814cbab24ddb42b75c78874f92fedc162b65d0820fc4da06a3318509aa9ff009b9acb9b348f197a134a46a46295714f436d4fbb19057e69a04139df1b6e0a59b093b35f34f9e5e890bc06832e63b366d768dc29e8638b828480\",\"0xf90211a023459f17e04fba3d19c6993f5be413969842fdbdc85d234a91b2f6b08a38be87a0153060eafecbff55ef0794802ef722b6c66698141cdc0610352d3a426976adeba0bd642b7c5111a1fd09da33feb6df031dc352b6cb20fbbe5ebe3eb328db233bd4a0705bff29e05c7ef69c07fecaa5db2457b2f124befc82f9fe6b0e54c8e35632eba03c1b4ffc076434de97050d2351c24689cfaefaa6cf8dc398dd3b8ce365e652c1a0a1ebf845ea0eb252e2a2e5c422ccd74878a3733144dfd62bcaad34758cc98652a01e4184586f5bdbb17ba74fd87539f02378c7adcef99f1538108f9555520e32d6a0b8acdfd5b644fa2c9a54f68039a3af4c6562c1e7f91ea9e63bda5a849f1260b6a05c1f036a2e7a5829799fc7df2d87eac3e7aee55df461b040c36f5b5c61781059a0a67fd871d32642e44120331f76c2616096d04d7fa1a7db421bafbc39713d8bfba085c15b7ab64f61670f4422adb82176d5808fad4abde6fddda507b0e5ff92ba14a0d95e8f16a39d4e52c67c617eef486adcd947854373ac074ff498150c7ca1ab5da03d9d7be595000872ad6aec05667ad85e1aaaeb2050a692818d3e60d8f1628d8ba0984c657192b052d13fb717051631d67fbc83dd5dcb4d074a2fddc01aa122d95ba03643408862d758aea269c05027a1cd616c957e0db5daea529b56964db8b4f04ba01020dce8d692c3d84d9ae3e42c35e4d8adbddf7b4dd3e09e543fc980849f016e80\",\"0xf90211a04c71b4b56ed723da1c1353ec1b4c23e71dfa821664d4041c1ee1770221f507b6a031c851f261a38df9b2bece1a1cb6985bccfaa10d2bb15954b82cd2ceaad87032a08a4a3d0cc260cf0e0fef54490ce45796fdd3f522451976ca7834563c839c630fa003d074f79074566cd33a3d6a57b6ca8426ca9ea972f66b5dfde00f73287fcfcea07003d29a5bd192038600118ab5941af5c79c1f0fc6184ad564180b809c36c7c4a05f181c50402dcff567abe1c6679a8d5e3825125abca4d969c7cbf76503416813a06a85dfca80e442ef79b66162099d52eaf67718589eb794755ce57dc071a85cdaa085cba9e6937a8a5f0a7d1b5ee9eb9f03c40f89eb13d9d4e0e5fbc574c2b852faa063f93dce441a3373cfc2d1c855884682dfd8d09d1eb9844c73d88eb8d5a7cdfda0e4bc0d2597e5fd0a4cd5e76a03b657ef8959264bdeaf95c4412ebd4ff736ce44a00239290e698aa04485e0c342cfb76ccf27a3e45a161b8b1b534e0c46707b92c8a0080c3439fb84730924539797aad8d017c5f7e008314ed9086450d80ec2b0d7aba0861dbe37b9b9e0f58b6fdb83eec28045c5f7f1861530f47f78fc8a2b18a6bd8da0036697e8dc063e9086d115d468c934a01123adb3c66dcc236ee4aa8141888626a033c6f574ee79d9b1322e9ca1131a5984b33cc8881e6ac8ebd6ca36f3437cedcda07fc2855e6bb0f276202094dffe49f2b62f2366d9aba9db3ffe76d62bcdc29f0d80\",\"0xf90211a06995d919b53eefa0b097d75c2a5dee2c54109a06d3b60586327fa0086437b801a05c7d7c92f9f1e49cf27c5d97b4a96302f033d42df5b1d7c013ef05031d67e567a05278417d007913a1e7d6606fb464e7b81f6cee91b6a1d250c67b3822d9fc68d8a0fba6d9cd68fe72db07af9d99e30c32502e0afb15ee9712f6781014195444b9e1a07dca25ba23f429b5960d9feb23367e2a088e50211f280118b7f1703e6d47103fa0399eb6e0d4390688f6b28df56c7ad72d6b6cbac9066110c6a727fe35cd889e9da08ef84ddaa3b70095fb5624878289744740a9f8761ef1132ba722abc977a218ffa04296811ae184892e2d5ecc18d05fc6279d6168eb0f3abb1f97d8d0a0721c12fba05c46766c579b8a0b8a0b79b84f6cd1e5dae1c53a2988883b0385daa2cf3bdf82a01a4ba17dd1b59147a321dd374a22a0d959f1a79d70132db7f1a8b89968ff6062a0f7ffc6f3921c6bccd47c862519409e63f51d39aaa215819c664b1adb48a940b0a0dc6e636385407900a649917fb772b0972d50d197e9fd5cdb853a1c98a29e6a47a0674b224cf784c59ca937bfebbdcd8dec05ddbd57400b04f5965558a0c2d2299ca0f95ce8c921c5b17ebf74563f2496a88631aa6a697bfd9e3e22b326efa453115ea0fc133bc6b9dd098933c816660df2959074f47dfc4ab3a10fd2059a2b2e0e911aa057cac15218d6013890df78eec099144ba2000e3eea73a3498d0eb9b1f733459080\",\"0xf90211a0400aafe69a1a482277db720d12b9c0b98695f5dd78c6faf5421b3ddac50165a6a0235987542e4b37aa8e6957776c9dff11d6818797db5ad505de5e0049045c7e20a0f573b4776f8b323b7d55850300d53855cfa6fa5fe6e36ba64da6bb263fef774aa0b3a36d14d660c3492785b0f1488a2231b6d83bd51268685b95ba9267aa331fe2a0096e8c65bae8fce7d234710a1e1b8c98bd4fb2d56f8bb2eda7ef20d1cf31c7e2a059194c8bf50c2ac393c4c60a59c7ddf0c515bd9f545fc4ef212629a8b96af62aa0ffe882f4e2f1e8e49c7777f6f9b4438a9f31d4e5cefe82c96fdd3587d9a95173a00127ced7fdbdd57cd5ed8b766c9312c09e0c67a350087d22b4cc7b2d17a45479a0cfc030a250448838caa716cd2767cd1a4837b29019f474980720c94fe2ce412ea079ec358d2b4122692bf70eb73a0ddb0ff4bfeb05d503fe1acafe068e2d3d33cfa0733e2ccdc638ca3c940c566c742a1b9d58f7caaa062e8a121c07f5e3367160a8a0aa1f403798b71c67b821e6f6128cc5366bebe145ebd563714cf9972b2474814ea01b988afc628922aeed3de606a8a462093f1c0c803a563bbe178552a360bad1e1a0082741e2219024bf4e19f5b1b0643e5e885cb7dfb4cdc0a51faf5bd9f92ff9b6a03c86490fe8f0256be44b95815086d95cb62fdbc3ede63ca08d12d68f274b7fc5a03a81565e860ac32921ed4c9f4e0ace3b341c342abd030d4955f2d1e64dd81d2b80\",\"0xf8f1a0bd9a0d9559513a6c7bf427816142d254d5a9049e9ff385f3514b50cb828951fc808080a07d37353f509c9bdc99635bd75fde71a6ef99271154ac4ffd5c437e0b951d5eaca029e3beec2f52c99a1fa73251ed64486f2766af3dcb950900679f7fd740badfdaa09b348c93803521a41bd2a754e3ea5435bb2663724cdfb70a87984458b53f03dea0904e696aceac8c89e2825e0dae8add52a9b46faef2ffbabb932e8bc1267e48ba80a0935dedba6ec5fb5b89285993c5f1be0cb77492e63e11bb38b5aca18011699eb8a06b52f587932dfb669f6cbefe35b251c6d8e6b5e8a2e1c1a7c2a452a4f2917b0d808080808080\"],\"address\":\"0x7f0d15c7faae65896648c8273b6d7e43f58fa842\",\"balance\":\"0x0\",\"codeHash\":\"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\",\"nonce\":\"0x0\",\"storageHash\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"storageProof\":[{\"key\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"proof\":[],\"value\":\"0x00\"]")] - ResultWrapper eth_getProof( - [JsonRpcParameter(ExampleValue = - "[\"0x7F0d15C7FAae65896648C8273B6d7E43f58Fa842\",[ \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\" ],\"latest\"]")] - Address accountAddress, UInt256[] hashRate, BlockParameter blockParameter); - - [JsonRpcMethod(IsImplemented = true, Description = "Retrieves Accounts via Address and Blocknumber", - IsSharable = true)] - ResultWrapper eth_getAccount( - [JsonRpcParameter(ExampleValue = "[\"0xaa00000000000000000000000000000000000000\", \"latest\"]")] - Address accountAddress, BlockParameter? blockParameter = null); -} +public interface IOptimismEthRpcModule : IEthRpcModule { } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs index 35a67406a3f..6d45fe82bdd 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs @@ -1,57 +1,90 @@ // SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using Nethermind.Blockchain.Filters; -using Nethermind.Blockchain.Find; +using System; using Nethermind.Blockchain.Receipts; -using Nethermind.Core; using Nethermind.Core.Specs; -using Nethermind.Crypto; using Nethermind.Facade; -using Nethermind.JsonRpc.Client; -using Nethermind.JsonRpc.Modules; -using Nethermind.JsonRpc.Modules.Eth; +using Nethermind.Facade.Eth; +using Nethermind.JsonRpc.Modules.Eth.GasPrice; +using Nethermind.JsonRpc.Modules.Eth.FeeHistory; +using Nethermind.Logging; +using Nethermind.State; using Nethermind.TxPool; -using System; +using Nethermind.Wallet; +using Nethermind.JsonRpc; +using Nethermind.JsonRpc.Modules; +using Nethermind.Blockchain.Find; +using Nethermind.Core; +using Nethermind.Crypto; +using Nethermind.JsonRpc.Client; namespace Nethermind.Optimism; -public class OptimismEthModuleFactory : ModuleFactoryBase -{ - private readonly ModuleFactoryBase _ethModuleFactory; - private readonly BasicJsonRpcClient? _sequencerRpcClient; - private readonly IBlockchainBridge _blockchainBridge; - private readonly IAccountStateProvider _accountStateProvider; - private readonly IEthereumEcdsa _ecdsa; - private readonly ITxSealer _sealer; - private readonly IBlockFinder _blockFinder; - private readonly ISpecProvider _specProvider; - private readonly IReceiptFinder _receiptFinder; - private readonly IOPConfigHelper _opConfigHelper; - - public OptimismEthModuleFactory(ModuleFactoryBase ethModuleFactory, - BasicJsonRpcClient? sequencerRpcClient, IBlockchainBridge blockchainBridge, - IAccountStateProvider accountStateProvider, IEthereumEcdsa ecdsa, ITxSealer sealer, - IBlockFinder? blockFinder, +public class OptimismEthModuleFactory( + IJsonRpcConfig rpcConfig, + IBlockchainBridgeFactory blockchainBridgeFactory, + IBlockFinder blockFinder, + IReceiptFinder receiptFinder, + IStateReader stateReader, + ITxPool txPool, + ITxSender txSender, + IWallet wallet, + ILogManager logManager, ISpecProvider specProvider, - IReceiptFinder? receiptFinder, - IOPConfigHelper opConfigHelper) - { - _ethModuleFactory = ethModuleFactory; - _sequencerRpcClient = sequencerRpcClient; - _blockchainBridge = blockchainBridge; - _accountStateProvider = accountStateProvider; - _ecdsa = ecdsa; - _sealer = sealer; - _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder)); - _specProvider = specProvider; - _receiptFinder = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder)); - _opConfigHelper = opConfigHelper; - } + IGasPriceOracle gasPriceOracle, + IEthSyncingInfo ethSyncingInfo, + IFeeHistoryOracle feeHistoryOracle, + + IJsonRpcClient? sequencerRpcClient, + IAccountStateProvider accountStateProvider, + IEthereumEcdsa ecdsa, + ITxSealer sealer, + IOPConfigHelper opConfigHelper + ) + : ModuleFactoryBase +{ + private readonly ILogManager _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager)); + private readonly IStateReader _stateReader = stateReader ?? throw new ArgumentNullException(nameof(stateReader)); + private readonly IBlockchainBridgeFactory _blockchainBridgeFactory = blockchainBridgeFactory ?? throw new ArgumentNullException(nameof(blockchainBridgeFactory)); + private readonly ITxPool _txPool = txPool ?? throw new ArgumentNullException(nameof(txPool)); + private readonly ITxSender _txSender = txSender ?? throw new ArgumentNullException(nameof(txSender)); + private readonly IWallet _wallet = wallet ?? throw new ArgumentNullException(nameof(wallet)); + private readonly IJsonRpcConfig _rpcConfig = rpcConfig ?? throw new ArgumentNullException(nameof(rpcConfig)); + private readonly ISpecProvider _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); + private readonly IGasPriceOracle _gasPriceOracle = gasPriceOracle ?? throw new ArgumentNullException(nameof(gasPriceOracle)); + private readonly IEthSyncingInfo _ethSyncingInfo = ethSyncingInfo ?? throw new ArgumentNullException(nameof(ethSyncingInfo)); + private readonly IFeeHistoryOracle _feeHistoryOracle = feeHistoryOracle ?? throw new ArgumentNullException(nameof(feeHistoryOracle)); + private readonly IJsonRpcClient? _sequencerRpcClient = sequencerRpcClient ?? throw new ArgumentNullException(nameof(sequencerRpcClient)); + private readonly IAccountStateProvider _accountStateProvider = accountStateProvider ?? throw new ArgumentNullException(nameof(accountStateProvider)); + private readonly IEthereumEcdsa _ecdsa = ecdsa ?? throw new ArgumentNullException(nameof(ecdsa)); + private readonly ITxSealer _sealer = sealer ?? throw new ArgumentNullException(nameof(sealer)); + private readonly IBlockFinder _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder)); + private readonly IReceiptFinder _receiptFinder = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder)); + private readonly IOPConfigHelper _opConfigHelper = opConfigHelper ?? throw new ArgumentNullException(nameof(opConfigHelper)); public override IOptimismEthRpcModule Create() { - return new OptimismEthRpcModule(_ethModuleFactory.Create(), _sequencerRpcClient, _blockchainBridge, - _accountStateProvider, _ecdsa, _sealer, _blockFinder, _specProvider, _receiptFinder, _opConfigHelper); + return new OptimismEthRpcModule( + _rpcConfig, + _blockchainBridgeFactory.CreateBlockchainBridge(), + _blockFinder, + _receiptFinder, + _stateReader, + _txPool, + _txSender, + _wallet, + _logManager, + _specProvider, + _gasPriceOracle, + _ethSyncingInfo, + _feeHistoryOracle, + + _sequencerRpcClient, + _accountStateProvider, + _ecdsa, + _sealer, + _opConfigHelper + ); } } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs index 9ee9f1f04fd..3618db4f22f 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs @@ -13,145 +13,78 @@ using Nethermind.Evm; using Nethermind.Facade; using Nethermind.Facade.Eth; -using Nethermind.Facade.Filters; -using Nethermind.Int256; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Client; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Eth; +using Nethermind.JsonRpc.Modules.Eth.FeeHistory; +using Nethermind.JsonRpc.Modules.Eth.GasPrice; +using Nethermind.Logging; using Nethermind.Serialization.Rlp; -using Nethermind.State.Proofs; +using Nethermind.State; using Nethermind.TxPool; +using Nethermind.Wallet; namespace Nethermind.Optimism; -public class OptimismEthRpcModule : IOptimismEthRpcModule +public class OptimismEthRpcModule : EthRpcModule, IOptimismEthRpcModule { - private readonly IEthRpcModule _ethRpcModule; private readonly IJsonRpcClient? _sequencerRpcClient; - private readonly IBlockchainBridge _blockchainBridge; private readonly IAccountStateProvider _accountStateProvider; private readonly IEthereumEcdsa _ecdsa; private readonly ITxSealer _sealer; - private readonly IBlockFinder _blockFinder; - private readonly ISpecProvider _specProvider; - private readonly IReceiptFinder _receiptFinder; private readonly IOPConfigHelper _opConfigHelper; - public OptimismEthRpcModule( - IEthRpcModule ethRpcModule, - IJsonRpcClient? sequencerRpcClient, + IJsonRpcConfig rpcConfig, IBlockchainBridge blockchainBridge, + IBlockFinder blockFinder, + IReceiptFinder receiptFinder, + IStateReader stateReader, + ITxPool txPool, + ITxSender txSender, + IWallet wallet, + ILogManager logManager, + ISpecProvider specProvider, + IGasPriceOracle gasPriceOracle, + IEthSyncingInfo ethSyncingInfo, + IFeeHistoryOracle feeHistoryOracle, + + IJsonRpcClient? sequencerRpcClient, IAccountStateProvider accountStateProvider, IEthereumEcdsa ecdsa, ITxSealer sealer, - IBlockFinder blockFinder, - ISpecProvider specProvider, - IReceiptFinder receiptFinder, - IOPConfigHelper opConfigHelper) + IOPConfigHelper opConfigHelper) : base( + rpcConfig, + blockchainBridge, + blockFinder, + receiptFinder, + stateReader, + txPool, + txSender, + wallet, + logManager, + specProvider, + gasPriceOracle, + ethSyncingInfo, + feeHistoryOracle) { - _ethRpcModule = ethRpcModule; _sequencerRpcClient = sequencerRpcClient; - _blockchainBridge = blockchainBridge; _accountStateProvider = accountStateProvider; _ecdsa = ecdsa; _sealer = sealer; - _blockFinder = blockFinder; - _specProvider = specProvider; - _receiptFinder = receiptFinder; _opConfigHelper = opConfigHelper; } - public ResultWrapper eth_chainId() - { - return _ethRpcModule.eth_chainId(); - } - - public ResultWrapper eth_protocolVersion() + public override ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) { - return _ethRpcModule.eth_protocolVersion(); - } - - public ResultWrapper eth_syncing() - { - return _ethRpcModule.eth_syncing(); - } - - public ResultWrapper
eth_coinbase() - { - return _ethRpcModule.eth_coinbase(); - } - - public ResultWrapper eth_feeHistory(int blockCount, BlockParameter newestBlock, double[]? rewardPercentiles = null) - { - return _ethRpcModule.eth_feeHistory(blockCount, newestBlock, rewardPercentiles); - } - - public ResultWrapper eth_snapshot() - { - return _ethRpcModule.eth_snapshot(); - } - - public ResultWrapper eth_maxPriorityFeePerGas() - { - return _ethRpcModule.eth_maxPriorityFeePerGas(); - } - - public ResultWrapper eth_gasPrice() - { - return _ethRpcModule.eth_gasPrice(); - } - - public ResultWrapper eth_blobBaseFee() - { - return _ethRpcModule.eth_blobBaseFee(); - } - - public ResultWrapper> eth_accounts() - { - return _ethRpcModule.eth_accounts(); - } - - public Task> eth_blockNumber() - { - return _ethRpcModule.eth_blockNumber(); - } - - public Task> eth_getBalance(Address address, BlockParameter? blockParameter = null) - { - return _ethRpcModule.eth_getBalance(address, blockParameter); - } - - public ResultWrapper eth_getStorageAt(Address address, UInt256 positionIndex, BlockParameter? blockParameter = null) - { - return _ethRpcModule.eth_getStorageAt(address, positionIndex, blockParameter); - } - - public Task> eth_getTransactionCount(Address address, BlockParameter? blockParameter = null) - { - return _ethRpcModule.eth_getTransactionCount(address, blockParameter); - } - - public ResultWrapper eth_getBlockTransactionCountByHash(Hash256 blockHash) - { - return _ethRpcModule.eth_getBlockTransactionCountByHash(blockHash); - } - - public ResultWrapper eth_getBlockTransactionCountByNumber(BlockParameter blockParameter) - { - return _ethRpcModule.eth_getBlockTransactionCountByNumber(blockParameter); - } - - public ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) - { - static ResultWrapper GetBlockReceipts(IReceiptFinder receiptFinder, BlockParameter blockParameter, IBlockFinder blockFinder, ISpecProvider specProvider, IOPConfigHelper opConfigHelper) + static ResultWrapper GetBlockReceipts(IReceiptFinder receiptFinder, BlockParameter blockParameter, IBlockFinder blockFinder, ISpecProvider specProvider, IOPConfigHelper opConfigHelper) { SearchResult searchResult = blockFinder.SearchForBlock(blockParameter); if (searchResult.IsError) { - return ResultWrapper.Success(null!); + return ResultWrapper.Success(null); } Block? block = searchResult.Object!; @@ -166,33 +99,13 @@ public Task> eth_getTransactionCount(Address address, Blo return new OptimismReceiptForRpc(t.Hash!, r, t.GetGasInfo(isEip1559Enabled, block.Header), l1BlockGasInfo.GetTxGasInfo(t), receipts.GetBlockLogFirstIndex(r.Index)); }); OptimismReceiptForRpc[]? resultAsArray = result.ToArray(); - return ResultWrapper.Success(resultAsArray); + return ResultWrapper.Success(resultAsArray); } return GetBlockReceipts(_receiptFinder, blockParameter, _blockFinder, _specProvider, _opConfigHelper); } - public ResultWrapper eth_getUncleCountByBlockHash(Hash256 blockHash) - { - return _ethRpcModule.eth_getUncleCountByBlockHash(blockHash); - } - - public ResultWrapper eth_getUncleCountByBlockNumber(BlockParameter blockParameter) - { - return _ethRpcModule.eth_getUncleCountByBlockNumber(blockParameter); - } - - public ResultWrapper eth_getCode(Address address, BlockParameter? blockParameter = null) - { - return _ethRpcModule.eth_getCode(address, blockParameter); - } - - public ResultWrapper eth_sign(Address addressData, byte[] message) - { - return _ethRpcModule.eth_sign(addressData, message); - } - - public async Task> eth_sendTransaction(TransactionForRpc rpcTx) + public override async Task> eth_sendTransaction(TransactionForRpc rpcTx) { Transaction tx = rpcTx.ToTransactionWithDefaults(_blockchainBridge.GetChainId()); tx.SenderAddress ??= _ecdsa.RecoverAddress(tx); @@ -212,7 +125,7 @@ public async Task> eth_sendTransaction(TransactionForRpc return await eth_sendRawTransaction(Rlp.Encode(tx, RlpBehaviors.SkipTypedWrapping).Bytes); } - public async Task> eth_sendRawTransaction(byte[] transaction) + public override async Task> eth_sendRawTransaction(byte[] transaction) { if (_sequencerRpcClient is null) { @@ -226,125 +139,24 @@ public async Task> eth_sendRawTransaction(byte[] transact return ResultWrapper.Success(result); } - public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockParameter? blockParameter = null) - { - return _ethRpcModule.eth_call(transactionCall, blockParameter); - } - - public ResultWrapper eth_estimateGas(TransactionForRpc transactionCall, BlockParameter? blockParameter = null) - { - return _ethRpcModule.eth_estimateGas(transactionCall, blockParameter); - } - - public ResultWrapper eth_createAccessList(TransactionForRpc transactionCall, BlockParameter? blockParameter = null, - bool optimize = true) - { - return _ethRpcModule.eth_createAccessList(transactionCall, blockParameter, optimize); - } - - public ResultWrapper eth_getBlockByHash(Hash256 blockHash, bool returnFullTransactionObjects = false) - { - return _ethRpcModule.eth_getBlockByHash(blockHash, returnFullTransactionObjects); - } - - public ResultWrapper eth_getBlockByNumber(BlockParameter blockParameter, bool returnFullTransactionObjects = false) - { - return _ethRpcModule.eth_getBlockByNumber(blockParameter, returnFullTransactionObjects); - } - - public Task> eth_getTransactionByHash(Hash256 transactionHash) - { - return _ethRpcModule.eth_getTransactionByHash(transactionHash); - } - - public ResultWrapper eth_pendingTransactions() - { - return _ethRpcModule.eth_pendingTransactions(); - } - - public ResultWrapper eth_getTransactionByBlockHashAndIndex(Hash256 blockHash, UInt256 positionIndex) - { - return _ethRpcModule.eth_getTransactionByBlockHashAndIndex(blockHash, positionIndex); - } - - public ResultWrapper eth_getTransactionByBlockNumberAndIndex(BlockParameter blockParameter, UInt256 positionIndex) - { - return _ethRpcModule.eth_getTransactionByBlockNumberAndIndex(blockParameter, positionIndex); - } - - public Task> eth_getTransactionReceipt(Hash256 txHash) + public override ResultWrapper eth_getTransactionReceipt(Hash256 txHash) { (TxReceipt? receipt, TxGasInfo? gasInfo, int logIndexStart) = _blockchainBridge.GetReceiptAndGasInfo(txHash); if (receipt is null || gasInfo is null) { - return Task.FromResult(ResultWrapper.Success(null)); + return ResultWrapper.Success(null); } SearchResult foundBlock = _blockFinder.SearchForBlock(new(receipt.BlockHash!)); if (foundBlock.Object is null) { - return Task.FromResult(ResultWrapper.Success(null)); + return ResultWrapper.Success(null); } Block block = foundBlock.Object; L1BlockGasInfo l1GasInfo = new(block, _opConfigHelper.IsRegolith(block.Header)); - return Task.FromResult(ResultWrapper.Success( - new(txHash, (OptimismTxReceipt)receipt, gasInfo.Value, l1GasInfo.GetTxGasInfo(block.Transactions.First(tx => tx.Hash == txHash)), logIndexStart))); - } - - public ResultWrapper eth_getUncleByBlockHashAndIndex(Hash256 blockHashData, UInt256 positionIndex) - { - return _ethRpcModule.eth_getUncleByBlockHashAndIndex(blockHashData, positionIndex); - } - - public ResultWrapper eth_getUncleByBlockNumberAndIndex(BlockParameter blockParameter, UInt256 positionIndex) - { - return _ethRpcModule.eth_getUncleByBlockNumberAndIndex(blockParameter, positionIndex); - } - - public ResultWrapper eth_newFilter(Filter filter) - { - return _ethRpcModule.eth_newFilter(filter); - } - - public ResultWrapper eth_newBlockFilter() - { - return _ethRpcModule.eth_newBlockFilter(); - } - - public ResultWrapper eth_newPendingTransactionFilter() - { - return _ethRpcModule.eth_newPendingTransactionFilter(); - } - - public ResultWrapper eth_uninstallFilter(UInt256 filterId) - { - return _ethRpcModule.eth_uninstallFilter(filterId); - } - - public ResultWrapper> eth_getFilterChanges(UInt256 filterId) - { - return _ethRpcModule.eth_getFilterChanges(filterId); - } - - public ResultWrapper> eth_getFilterLogs(UInt256 filterId) - { - return _ethRpcModule.eth_getFilterLogs(filterId); - } - - public ResultWrapper> eth_getLogs(Filter filter) - { - return _ethRpcModule.eth_getLogs(filter); - } - - public ResultWrapper eth_getProof(Address accountAddress, UInt256[] hashRate, BlockParameter blockParameter) - { - return _ethRpcModule.eth_getProof(accountAddress, hashRate, blockParameter); - } - - public ResultWrapper eth_getAccount(Address accountAddress, BlockParameter? blockParameter = null) - { - return _ethRpcModule.eth_getAccount(accountAddress, blockParameter); + return ResultWrapper.Success( + new(txHash, (OptimismTxReceipt)receipt, gasInfo.Value, l1GasInfo.GetTxGasInfo(block.Transactions.First(tx => tx.Hash == txHash)), logIndexStart)); } } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs b/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs index 8c9d75ecaf9..ef449b940b1 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs @@ -9,6 +9,7 @@ using Nethermind.JsonRpc.Client; using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Eth; +using Nethermind.JsonRpc.Modules.Eth.FeeHistory; using Nethermind.Logging; using Nethermind.TxPool; using Nethermind.Wallet; @@ -32,6 +33,14 @@ public RegisterOptimismRpcModules(INethermindApi api) : base(api) protected override void RegisterEthRpcModule(IRpcModuleProvider rpcModuleProvider) { + StepDependencyException.ThrowIfNull(_api.BlockTree); + StepDependencyException.ThrowIfNull(_api.ReceiptStorage); + StepDependencyException.ThrowIfNull(_api.StateReader); + StepDependencyException.ThrowIfNull(_api.TxPool); + StepDependencyException.ThrowIfNull(_api.TxSender); + StepDependencyException.ThrowIfNull(_api.Wallet); + StepDependencyException.ThrowIfNull(_api.EthSyncingInfo); + StepDependencyException.ThrowIfNull(_api.GasPriceOracle); StepDependencyException.ThrowIfNull(_api.SpecHelper); StepDependencyException.ThrowIfNull(_api.SpecProvider); StepDependencyException.ThrowIfNull(_api.WorldState); @@ -51,8 +60,29 @@ protected override void RegisterEthRpcModule(IRpcModuleProvider rpcModuleProvide ITxSigner txSigner = new WalletTxSigner(_api.Wallet, _api.SpecProvider.ChainId); TxSealer sealer = new(txSigner, _api.Timestamper); + var feeHistoryOracle = new FeeHistoryOracle(_api.BlockTree, _api.ReceiptStorage, _api.SpecProvider); + _api.DisposeStack.Push(feeHistoryOracle); + ModuleFactoryBase optimismEthModuleFactory = new OptimismEthModuleFactory( - ethModuleFactory, sequencerJsonRpcClient, _api.CreateBlockchainBridge(), _api.WorldState, _api.EthereumEcdsa, sealer, _api.BlockTree?.AsReadOnly(), _api.SpecProvider, _api.ReceiptFinder, _api.SpecHelper); + _jsonRpcConfig, + _api, + _api.BlockTree.AsReadOnly(), + _api.ReceiptStorage, + _api.StateReader, + _api.TxPool, + _api.TxSender, + _api.Wallet, + _api.LogManager, + _api.SpecProvider, + _api.GasPriceOracle, + _api.EthSyncingInfo, + feeHistoryOracle, + + sequencerJsonRpcClient, + _api.WorldState, + _api.EthereumEcdsa, + sealer, + _api.SpecHelper); rpcModuleProvider.RegisterBounded(optimismEthModuleFactory, _jsonRpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, _jsonRpcConfig.Timeout); diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptArrayStorageDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptArrayStorageDecoder.cs index 53d025e7277..f2d7c8051e1 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptArrayStorageDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptArrayStorageDecoder.cs @@ -19,7 +19,6 @@ public class ReceiptArrayStorageDecoder(bool compactEncoding = true) : IRlpStrea private static readonly IRlpValueDecoder CompactValueDecoder = Rlp.GetValueDecoder(RlpDecoderKey.Storage); public const int CompactEncoding = 127; - private readonly bool _useCompactEncoding = compactEncoding; public int GetLength(TxReceipt[] items, RlpBehaviors rlpBehaviors) { @@ -29,7 +28,7 @@ public int GetLength(TxReceipt[] items, RlpBehaviors rlpBehaviors) } int bufferLength = Rlp.LengthOfSequence(GetContentLength(items, rlpBehaviors)); - if (_useCompactEncoding && (rlpBehaviors & RlpBehaviors.Storage) != 0) + if (compactEncoding && (rlpBehaviors & RlpBehaviors.Storage) != 0) { bufferLength++; } @@ -38,7 +37,7 @@ public int GetLength(TxReceipt[] items, RlpBehaviors rlpBehaviors) private int GetContentLength(TxReceipt[] items, RlpBehaviors rlpBehaviors) { - if (_useCompactEncoding && (rlpBehaviors & RlpBehaviors.Storage) != 0) + if (compactEncoding && (rlpBehaviors & RlpBehaviors.Storage) != 0) { int totalLength = 0; for (int i = 0; i < items.Length; i++) @@ -81,7 +80,7 @@ public void Encode(RlpStream stream, TxReceipt[] items, RlpBehaviors rlpBehavior return; } - if (_useCompactEncoding && (rlpBehaviors & RlpBehaviors.Storage) != 0) + if (compactEncoding && (rlpBehaviors & RlpBehaviors.Storage) != 0) { int totalLength = GetContentLength(items, rlpBehaviors); stream.WriteByte(CompactEncoding); From bbe17a334a41091bf2ef5a324b7312c31deff07a Mon Sep 17 00:00:00 2001 From: Alexey Osipov Date: Thu, 30 May 2024 12:52:21 +0300 Subject: [PATCH 4/5] Replace generics with new --- .../Modules/Eth/EthRpcModule.Receipts.cs | 73 --------------- .../Eth/EthRpcModule.TransactionExecutor.cs | 2 +- .../Modules/Eth/EthRpcModule.cs | 91 +++++++++---------- .../Modules/Eth/IEthRpcModule.cs | 8 +- .../Modules/RpcModuleProvider.cs | 6 +- .../Rpc/IOptimismEthRpcModule.cs | 18 +++- .../Rpc/OptimismEthRpcModule.cs | 13 ++- 7 files changed, 76 insertions(+), 135 deletions(-) delete mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.Receipts.cs diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.Receipts.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.Receipts.cs deleted file mode 100644 index 05ff93613e1..00000000000 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.Receipts.cs +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System.Threading.Tasks; -using Nethermind.Blockchain.Find; -using Nethermind.Blockchain.Receipts; -using Nethermind.Core; -using Nethermind.Core.Crypto; -using Nethermind.Core.Specs; -using Nethermind.Evm; -using Nethermind.Facade; -using Nethermind.Facade.Eth; -using Nethermind.JsonRpc.Data; -using Nethermind.JsonRpc.Modules.Eth.FeeHistory; -using Nethermind.JsonRpc.Modules.Eth.GasPrice; -using Nethermind.Logging; -using Nethermind.State; -using Nethermind.TxPool; -using Nethermind.Wallet; - -namespace Nethermind.JsonRpc.Modules.Eth; - -public class EthRpcModule : EthRpcModule, IEthRpcModule -{ - public EthRpcModule( - IJsonRpcConfig rpcConfig, - IBlockchainBridge blockchainBridge, - IBlockFinder blockFinder, - IReceiptFinder receiptFinder, - IStateReader stateReader, - ITxPool txPool, - ITxSender txSender, - IWallet wallet, - ILogManager logManager, - ISpecProvider specProvider, - IGasPriceOracle gasPriceOracle, - IEthSyncingInfo ethSyncingInfo, - IFeeHistoryOracle feeHistoryOracle) : base( - - rpcConfig, - blockchainBridge, - blockFinder, - receiptFinder, - stateReader, - txPool, - txSender, - wallet, - logManager, - specProvider, - gasPriceOracle, - ethSyncingInfo, - feeHistoryOracle) - { - } - - public override ResultWrapper eth_getTransactionReceipt(Hash256 txHash) - { - (TxReceipt? receipt, TxGasInfo? gasInfo, int logIndexStart) = _blockchainBridge.GetReceiptAndGasInfo(txHash); - if (receipt is null || gasInfo is null) - { - return ResultWrapper.Success(null); - } - - if (_logger.IsTrace) _logger.Trace($"eth_getTransactionReceipt request {txHash}, result: {txHash}"); - return ResultWrapper.Success(new(txHash, receipt, gasInfo.Value, logIndexStart)); - } - - - public override ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) - { - return _receiptFinder.GetBlockReceipts(blockParameter, _blockFinder, _specProvider); - } -} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 2872e683bc8..afc281f7f6d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -17,7 +17,7 @@ namespace Nethermind.JsonRpc.Modules.Eth { - public partial class EthRpcModule + public partial class EthRpcModule { private abstract class TxExecutor { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 20d3ce13d72..1e46576047f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -38,58 +38,41 @@ namespace Nethermind.JsonRpc.Modules.Eth; -public abstract partial class EthRpcModule : IEthRpcModule where TReceiptForRpc : ReceiptForRpc +public partial class EthRpcModule( + IJsonRpcConfig rpcConfig, + IBlockchainBridge blockchainBridge, + IBlockFinder blockFinder, + IReceiptFinder receiptFinder, + IStateReader stateReader, + ITxPool txPool, + ITxSender txSender, + IWallet wallet, + ILogManager logManager, + ISpecProvider specProvider, + IGasPriceOracle gasPriceOracle, + IEthSyncingInfo ethSyncingInfo, + IFeeHistoryOracle feeHistoryOracle) : IEthRpcModule { protected readonly Encoding _messageEncoding = Encoding.UTF8; - protected readonly IJsonRpcConfig _rpcConfig; - protected readonly IBlockchainBridge _blockchainBridge; - protected readonly IBlockFinder _blockFinder; - protected readonly IReceiptFinder _receiptFinder; - protected readonly IStateReader _stateReader; - protected readonly ITxPool _txPoolBridge; - protected readonly ITxSender _txSender; - protected readonly IWallet _wallet; - protected readonly ISpecProvider _specProvider; - protected readonly ILogger _logger; - protected readonly IGasPriceOracle _gasPriceOracle; - protected readonly IEthSyncingInfo _ethSyncingInfo; - - protected readonly IFeeHistoryOracle _feeHistoryOracle; + protected readonly IJsonRpcConfig _rpcConfig = rpcConfig ?? throw new ArgumentNullException(nameof(rpcConfig)); + protected readonly IBlockchainBridge _blockchainBridge = blockchainBridge ?? throw new ArgumentNullException(nameof(blockchainBridge)); + 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 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)); + protected readonly ILogger _logger = logManager.GetClassLogger(); + protected readonly IGasPriceOracle _gasPriceOracle = gasPriceOracle ?? throw new ArgumentNullException(nameof(gasPriceOracle)); + protected readonly IEthSyncingInfo _ethSyncingInfo = ethSyncingInfo ?? throw new ArgumentNullException(nameof(ethSyncingInfo)); + protected readonly IFeeHistoryOracle _feeHistoryOracle = feeHistoryOracle ?? throw new ArgumentNullException(nameof(feeHistoryOracle)); + private static bool HasStateForBlock(IBlockchainBridge blockchainBridge, BlockHeader header) { return blockchainBridge.HasStateForRoot(header.StateRoot!); } - public EthRpcModule( - IJsonRpcConfig rpcConfig, - IBlockchainBridge blockchainBridge, - IBlockFinder blockFinder, - IReceiptFinder receiptFinder, - IStateReader stateReader, - ITxPool txPool, - ITxSender txSender, - IWallet wallet, - ILogManager logManager, - ISpecProvider specProvider, - IGasPriceOracle gasPriceOracle, - IEthSyncingInfo ethSyncingInfo, - IFeeHistoryOracle feeHistoryOracle) - { - _logger = logManager.GetClassLogger(); - _rpcConfig = rpcConfig ?? throw new ArgumentNullException(nameof(rpcConfig)); - _blockchainBridge = blockchainBridge ?? throw new ArgumentNullException(nameof(blockchainBridge)); - _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder)); - _receiptFinder = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder)); - _stateReader = stateReader ?? throw new ArgumentNullException(nameof(stateReader)); - _txPoolBridge = txPool ?? throw new ArgumentNullException(nameof(txPool)); - _txSender = txSender ?? throw new ArgumentNullException(nameof(txSender)); - _wallet = wallet ?? throw new ArgumentNullException(nameof(wallet)); - _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); - _gasPriceOracle = gasPriceOracle ?? throw new ArgumentNullException(nameof(gasPriceOracle)); - _ethSyncingInfo = ethSyncingInfo ?? throw new ArgumentNullException(nameof(ethSyncingInfo)); - _feeHistoryOracle = feeHistoryOracle ?? throw new ArgumentNullException(nameof(feeHistoryOracle)); - } - public ResultWrapper eth_protocolVersion() { int highestVersion = P2PProtocolInfoProvider.GetHighestVersionOfEthProtocol(); @@ -714,7 +697,21 @@ private static ResultWrapper GetFailureResult(ResourceNotFound private ResultWrapper GetStateFailureResult(BlockHeader header) => ResultWrapper.Fail($"No state available for block {header.ToString(BlockHeader.Format.FullHashAndNumber)}", ErrorCodes.ResourceUnavailable, _ethSyncingInfo.SyncMode.HaveNotSyncedStateYet()); - public abstract ResultWrapper eth_getBlockReceipts([JsonRpcParameter(ExampleValue = "latest")] BlockParameter blockParameter); + public ResultWrapper eth_getTransactionReceipt(Hash256 txHash) + { + (TxReceipt? receipt, TxGasInfo? gasInfo, int logIndexStart) = _blockchainBridge.GetReceiptAndGasInfo(txHash); + if (receipt is null || gasInfo is null) + { + return ResultWrapper.Success(null); + } - public abstract ResultWrapper eth_getTransactionReceipt([JsonRpcParameter(ExampleValue = "[\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\"]")] Hash256 txHashData); + if (_logger.IsTrace) _logger.Trace($"eth_getTransactionReceipt request {txHash}, result: {txHash}"); + return ResultWrapper.Success(new(txHash, receipt, gasInfo.Value, logIndexStart)); + } + + + public ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) + { + return _receiptFinder.GetBlockReceipts(blockParameter, _blockFinder, _specProvider); + } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 0b3e40bcd16..7b42b8ddf38 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -15,9 +15,7 @@ namespace Nethermind.JsonRpc.Modules.Eth { [RpcModule(ModuleType.Eth)] - public interface IEthRpcModule : IEthRpcModule { } - - public interface IEthRpcModule : IRpcModule where TReceiptForRpc : ReceiptForRpc + public interface IEthRpcModule : IRpcModule { [JsonRpcMethod(IsImplemented = true, Description = "Returns ChainID", @@ -113,7 +111,7 @@ public interface IEthRpcModule : IRpcModule where TReceiptForRpc [JsonRpcMethod(Description = "Get receipts from all transactions from particular block, more efficient than fetching the receipts one-by-one.", IsImplemented = true, ExampleResponse = "{\"jsonrpc\":\"2.0\",\"result\":[{\"transactionHash\":\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"transactionIndex\":\"0x0\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"cumulativeGasUsed\":\"0x5208\",\"gasUsed\":\"0x5208\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"contractAddress\":null,\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x1\",\"type\":\"0x0\"},{\"transactionHash\":\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\",\"transactionIndex\":\"0x1\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"cumulativeGasUsed\":\"0xa410\",\"gasUsed\":\"0x5208\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"contractAddress\":null,\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x1\",\"type\":\"0x0\"}],\"id\":67}")] - ResultWrapper eth_getBlockReceipts([JsonRpcParameter(ExampleValue = "latest")] BlockParameter blockParameter); + ResultWrapper eth_getBlockReceipts([JsonRpcParameter(ExampleValue = "latest")] BlockParameter blockParameter); [JsonRpcMethod(IsImplemented = true, Description = "Returns number of uncles in the block by block hash", @@ -214,7 +212,7 @@ ResultWrapper eth_getTransactionByBlockNumberAndIndex( Description = "Retrieves a transaction receipt by tx hash", IsSharable = true, ExampleResponse = "{\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"transactionIndex\":\"0x7\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"cumulativeGasUsed\":\"0x62c9d\",\"gasUsed\":\"0xe384\",\"effectiveGasPrice\":\"0x12a05f200\",\"from\":\"0x0afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"to\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"contractAddress\":null,\"logs\":[{\"removed\":false,\"logIndex\":\"0x0\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x2ac3c1d3e24b45c6c310534bc2dd84b5ed576335\",\"data\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x00000000000000000000000019e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\"]},{\"removed\":false,\"logIndex\":\"0x1\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"data\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007735940000000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0x950494fc3642fae5221b6c32e0e45765c95ebb382a04a71b160db0843e74c99f\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\"]}],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000020000000000000800000000000000000000400000000000000000000000000000000000000002000000000000000000000000008000000000000000000000000000000000000000000000002002000000000000000000000000000000000000000000812000000000000000000000000000001000000000000000000000008000400008000000000000000000000000000000000000000000000000000000000800000000000000000000002000000000000000000000000000000000000100000000000000000002000000000000000000000000010000000000000000000000400000000020000\",\"status\":\"0x1\",\"type\":\"0x0\"}")] - ResultWrapper eth_getTransactionReceipt([JsonRpcParameter(ExampleValue = "[\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\"]")] Hash256 txHashData); + ResultWrapper eth_getTransactionReceipt([JsonRpcParameter(ExampleValue = "[\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\"]")] Hash256 txHashData); [JsonRpcMethod(IsImplemented = true, Description = "Retrieves an uncle block header by block hash and uncle index", diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/RpcModuleProvider.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/RpcModuleProvider.cs index fdbd07c91ad..a4c11d06a26 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/RpcModuleProvider.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/RpcModuleProvider.cs @@ -140,7 +140,11 @@ public void Return(string methodName, IRpcModule rpcModule) private static IDictionary GetMethodDict(Type type) { BindingFlags methodFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; - IEnumerable methods = type.GetMethods(methodFlags).Concat(type.GetInterfaces().SelectMany(i => i.GetMethods(methodFlags))); + + IEnumerable methods = type.GetMethods(methodFlags) + .Concat(type.GetInterfaces().SelectMany(i => i.GetMethods(methodFlags))) + .DistinctBy(x => x.Name); + return methods.ToDictionary( x => x.Name.Trim(), x => diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs index b12ce4a013a..9f95e620733 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs @@ -3,8 +3,24 @@ using Nethermind.JsonRpc.Modules.Eth; using Nethermind.JsonRpc.Modules; +using Nethermind.Core.Crypto; +using Nethermind.JsonRpc; +using Nethermind.Blockchain.Find; namespace Nethermind.Optimism; [RpcModule(ModuleType.Eth)] -public interface IOptimismEthRpcModule : IEthRpcModule { } +public interface IOptimismEthRpcModule : IEthRpcModule +{ + [JsonRpcMethod(Description = "Get receipts from all transactions from particular block, more efficient than fetching the receipts one-by-one.", + IsImplemented = true, + ExampleResponse = "{\"jsonrpc\":\"2.0\",\"result\":[{\"transactionHash\":\"0x681c2b6f99e37fd6fe6046db8b51ec3460d699cacd6a376143fd5842ac50621f\",\"transactionIndex\":\"0x0\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"cumulativeGasUsed\":\"0x5208\",\"gasUsed\":\"0x5208\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"contractAddress\":null,\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x1\",\"type\":\"0x0\"},{\"transactionHash\":\"0x7126cf20a0ad8bd51634837d9049615c34c1bff5e1a54e5663f7e23109bff48b\",\"transactionIndex\":\"0x1\",\"blockHash\":\"0x29f141925d2d8e357ae5b6040c97aa12d7ac6dfcbe2b20e7b616d8907ac8e1f3\",\"blockNumber\":\"0x3\",\"cumulativeGasUsed\":\"0xa410\",\"gasUsed\":\"0x5208\",\"effectiveGasPrice\":\"0x1\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"contractAddress\":null,\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"status\":\"0x1\",\"type\":\"0x0\"}],\"id\":67}")] + new ResultWrapper eth_getBlockReceipts([JsonRpcParameter(ExampleValue = "latest")] BlockParameter blockParameter); + + + [JsonRpcMethod(IsImplemented = true, + Description = "Retrieves a transaction receipt by tx hash", + IsSharable = true, + ExampleResponse = "{\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"transactionIndex\":\"0x7\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"cumulativeGasUsed\":\"0x62c9d\",\"gasUsed\":\"0xe384\",\"effectiveGasPrice\":\"0x12a05f200\",\"from\":\"0x0afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"to\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"contractAddress\":null,\"logs\":[{\"removed\":false,\"logIndex\":\"0x0\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x2ac3c1d3e24b45c6c310534bc2dd84b5ed576335\",\"data\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x00000000000000000000000019e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\"]},{\"removed\":false,\"logIndex\":\"0x1\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"data\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007735940000000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0x950494fc3642fae5221b6c32e0e45765c95ebb382a04a71b160db0843e74c99f\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\"]}],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000020000000000000800000000000000000000400000000000000000000000000000000000000002000000000000000000000000008000000000000000000000000000000000000000000000002002000000000000000000000000000000000000000000812000000000000000000000000000001000000000000000000000008000400008000000000000000000000000000000000000000000000000000000000800000000000000000000002000000000000000000000000000000000000100000000000000000002000000000000000000000000010000000000000000000000400000000020000\",\"status\":\"0x1\",\"type\":\"0x0\"}")] + new ResultWrapper eth_getTransactionReceipt([JsonRpcParameter(ExampleValue = "[\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\"]")] Hash256 txHashData); +} diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs index 3618db4f22f..7f42d0d76ca 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs @@ -28,7 +28,7 @@ namespace Nethermind.Optimism; -public class OptimismEthRpcModule : EthRpcModule, IOptimismEthRpcModule +public class OptimismEthRpcModule : EthRpcModule, IOptimismEthRpcModule { private readonly IJsonRpcClient? _sequencerRpcClient; private readonly IAccountStateProvider _accountStateProvider; @@ -77,7 +77,7 @@ public OptimismEthRpcModule( _opConfigHelper = opConfigHelper; } - public override ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) + public new ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) { static ResultWrapper GetBlockReceipts(IReceiptFinder receiptFinder, BlockParameter blockParameter, IBlockFinder blockFinder, ISpecProvider specProvider, IOPConfigHelper opConfigHelper) { @@ -93,13 +93,12 @@ public OptimismEthRpcModule( L1BlockGasInfo l1BlockGasInfo = new(block, opConfigHelper.IsRegolith(block!.Header)); - IEnumerable result = receipts + OptimismReceiptForRpc[]? result = [.. receipts .Zip(block.Transactions, (r, t) => { return new OptimismReceiptForRpc(t.Hash!, r, t.GetGasInfo(isEip1559Enabled, block.Header), l1BlockGasInfo.GetTxGasInfo(t), receipts.GetBlockLogFirstIndex(r.Index)); - }); - OptimismReceiptForRpc[]? resultAsArray = result.ToArray(); - return ResultWrapper.Success(resultAsArray); + })]; + return ResultWrapper.Success(result); } return GetBlockReceipts(_receiptFinder, blockParameter, _blockFinder, _specProvider, _opConfigHelper); @@ -139,7 +138,7 @@ public override async Task> eth_sendRawTransaction(byte[] return ResultWrapper.Success(result); } - public override ResultWrapper eth_getTransactionReceipt(Hash256 txHash) + public new ResultWrapper eth_getTransactionReceipt(Hash256 txHash) { (TxReceipt? receipt, TxGasInfo? gasInfo, int logIndexStart) = _blockchainBridge.GetReceiptAndGasInfo(txHash); if (receipt is null || gasInfo is null) From bd5fb98fdcf371e11620ebf73964db31ebb20d72 Mon Sep 17 00:00:00 2001 From: Alexey Osipov Date: Fri, 31 May 2024 11:59:24 +0300 Subject: [PATCH 5/5] Use OP tx processor in trace RPC; improve project structure --- .../AuRaContractGasLimitOverrideTests.cs | 3 +- .../Contract/TxPriorityContractTests.cs | 3 +- .../Transactions/TxCertifierFilterTests.cs | 3 +- .../Transactions/TxPermissionFilterTest.cs | 5 +- .../Processing/ReadOnlyChainProcessingEnv.cs | 16 ++-- .../Processing/ReadOnlyTxProcessingEnv.cs | 86 +++++++++-------- .../Steps/RegisterRpcModules.cs | 40 +++++--- .../Steps/StepInitializationException.cs | 2 +- .../Modules/Trace/ParityStyleTracerTests.cs | 6 +- .../Modules/TraceRpcModuleTests.cs | 2 +- .../Modules/Trace/TraceModuleFactory.cs | 92 ++++++++----------- .../Modules/Trace/TraceRpcModule.cs | 9 +- .../Create2DeployerContractRewriter.cs | 10 +- .../DepositTxExtensions.cs | 1 - ...ConfigHelper.cs => IOptimismSpecHelper.cs} | 2 +- .../InitializeBlockProducerOptimism.cs | 1 - .../InitializeBlockchainOptimism.cs | 6 +- .../Nethermind.Optimism/OPConfigHelper.cs | 28 ++---- .../Nethermind.Optimism/OPL1CostHelper.cs | 12 +-- .../OptimismBlockProcessor.cs | 4 +- .../OptimismBlockProducerEnvFactory.cs | 71 ++++++-------- .../OptimismBlockReceiptTracer.cs | 8 +- .../OptimismNethermindApi.cs | 2 +- .../OptimismPayloadPreparationService.cs | 1 + .../OptimismPayloadTxSource.cs | 1 + .../Nethermind.Optimism/OptimismPlugin.cs | 1 + .../OptimismPostMergeBlockProducer.cs | 1 + .../OptimismReadOnlyTxProcessingEnv.cs | 38 ++++++++ .../OptimismTransactionProcessor.cs | 33 +++---- .../OptimismTxPoolTxSource.cs | 1 + .../ReadOnlyChainProcessingEnv.cs | 54 +++++++++++ .../{ => Rpc}/IOptimismEngineRpcModule.cs | 2 +- .../Rpc/IOptimismEthRpcModule.cs | 2 +- .../{ => Rpc}/OptimismEngineRpcModule.cs | 2 +- .../Rpc/OptimismEthModuleFactory.cs | 8 +- .../Rpc/OptimismEthRpcModule.cs | 17 ++-- .../{ => Rpc}/OptimismPayloadAttributes.cs | 6 +- .../Rpc/OptimismReceiptForRpc.cs | 2 +- .../Rpc/OptimismTraceModuleFactory.cs | 58 ++++++++++++ .../Rpc/RegisterOptimismRpcModules.cs | 33 ++++++- 40 files changed, 412 insertions(+), 260 deletions(-) rename src/Nethermind/Nethermind.Optimism/{IOPConfigHelper.cs => IOptimismSpecHelper.cs} (92%) create mode 100644 src/Nethermind/Nethermind.Optimism/OptimismReadOnlyTxProcessingEnv.cs create mode 100644 src/Nethermind/Nethermind.Optimism/ReadOnlyChainProcessingEnv.cs rename src/Nethermind/Nethermind.Optimism/{ => Rpc}/IOptimismEngineRpcModule.cs (99%) rename src/Nethermind/Nethermind.Optimism/{ => Rpc}/OptimismEngineRpcModule.cs (98%) rename src/Nethermind/Nethermind.Optimism/{ => Rpc}/OptimismPayloadAttributes.cs (97%) create mode 100644 src/Nethermind/Nethermind.Optimism/Rpc/OptimismTraceModuleFactory.cs diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs index 2fc2439574b..7df3df7dcca 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/AuRaContractGasLimitOverrideTests.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using FluentAssertions; using Nethermind.Abi; +using Nethermind.Blockchain; using Nethermind.Consensus; using Nethermind.Consensus.AuRa; using Nethermind.Consensus.AuRa.Contracts; @@ -85,7 +86,7 @@ protected override BlockProcessor CreateBlockProcessor() BlockGasLimitContract gasLimitContract = new(AbiEncoder.Instance, blockGasLimitContractTransition.Value, blockGasLimitContractTransition.Key, new ReadOnlyTxProcessingEnv( WorldStateManager, - BlockTree, SpecProvider, LimboLogs.Instance)); + BlockTree.AsReadOnly(), SpecProvider, LimboLogs.Instance)); GasLimitOverrideCache = new AuRaContractGasLimitOverride.Cache(); GasLimitCalculator = new AuRaContractGasLimitOverride(new[] { gasLimitContract }, GasLimitOverrideCache, false, new FollowOtherMiners(SpecProvider), LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs index 276671dab2a..1caa20bf3a9 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using FluentAssertions; using Nethermind.Abi; +using Nethermind.Blockchain; using Nethermind.Blockchain.Data; using Nethermind.Consensus.AuRa.Contracts; using Nethermind.Consensus.AuRa.Contracts.DataStore; @@ -254,7 +255,7 @@ protected override TxPoolTxSource CreateTxPoolTxSource() TxPoolTxSource txPoolTxSource = base.CreateTxPoolTxSource(); TxPriorityContract = new TxPriorityContract(AbiEncoder.Instance, TestItem.AddressA, - new ReadOnlyTxProcessingEnv(WorldStateManager, BlockTree, SpecProvider, LimboLogs.Instance)); + new ReadOnlyTxProcessingEnv(WorldStateManager, BlockTree.AsReadOnly(), SpecProvider, LimboLogs.Instance)); Priorities = new DictionaryContractDataStore( new TxPriorityContract.DestinationSortedListContractDataStoreCollection(), diff --git a/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxCertifierFilterTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxCertifierFilterTests.cs index 594d365cb23..00a2894d175 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxCertifierFilterTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxCertifierFilterTests.cs @@ -6,6 +6,7 @@ using FluentAssertions; using Nethermind.Abi; using Nethermind.AuRa.Test.Contract; +using Nethermind.Blockchain; using Nethermind.Consensus.AuRa; using Nethermind.Consensus.AuRa.Contracts; using Nethermind.Consensus.AuRa.Transactions; @@ -138,7 +139,7 @@ protected override BlockProcessor CreateBlockProcessor() AbiEncoder abiEncoder = AbiEncoder.Instance; ReadOnlyTransactionProcessorSource = new ReadOnlyTxProcessingEnv( WorldStateManager, - BlockTree, SpecProvider, + BlockTree.AsReadOnly(), SpecProvider, LimboLogs.Instance); RegisterContract = new RegisterContract(abiEncoder, ChainSpec.Parameters.Registrar, ReadOnlyTransactionProcessorSource); CertifierContract = new CertifierContract( diff --git a/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxPermissionFilterTest.cs b/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxPermissionFilterTest.cs index 2a43f1bd7ab..e18f723dbf9 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxPermissionFilterTest.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Transactions/TxPermissionFilterTest.cs @@ -8,6 +8,7 @@ using FluentAssertions; using Nethermind.Abi; using Nethermind.AuRa.Test.Contract; +using Nethermind.Blockchain; using Nethermind.Consensus.AuRa; using Nethermind.Consensus.AuRa.Contracts; using Nethermind.Consensus.AuRa.Transactions; @@ -277,12 +278,12 @@ protected override BlockProcessor CreateBlockProcessor() IReadOnlyTrieStore trieStore = new TrieStore(DbProvider.StateDb, LimboLogs.Instance).AsReadOnly(); IReadOnlyTxProcessorSource txProcessorSource = new ReadOnlyTxProcessingEnv( WorldStateManager, - BlockTree, + BlockTree.AsReadOnly(), SpecProvider, LimboLogs.Instance); VersionedTransactionPermissionContract transactionPermissionContract = new(AbiEncoder.Instance, _contractAddress, 1, - new ReadOnlyTxProcessingEnv(WorldStateManager, BlockTree, SpecProvider, LimboLogs.Instance), TransactionPermissionContractVersions, LimboLogs.Instance, SpecProvider); + new ReadOnlyTxProcessingEnv(WorldStateManager, BlockTree.AsReadOnly(), SpecProvider, LimboLogs.Instance), TransactionPermissionContractVersions, LimboLogs.Instance, SpecProvider); TxPermissionFilterCache = new PermissionBasedTxFilter.Cache(); PermissionBasedTxFilter = new PermissionBasedTxFilter(transactionPermissionContract, TxPermissionFilterCache, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs index ee64bb8cf92..ba2071ce683 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs @@ -7,7 +7,6 @@ using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; using Nethermind.Core.Specs; -using Nethermind.Db; using Nethermind.Logging; using Nethermind.State; @@ -41,7 +40,16 @@ public ReadOnlyChainProcessingEnv( IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor = blockTransactionsExecutor ?? new BlockProcessor.BlockValidationTransactionsExecutor(_txEnv.TransactionProcessor, StateProvider); - BlockProcessor = new BlockProcessor( + BlockProcessor = CreateBlockProcessor(txEnv, blockValidator, rewardCalculator, receiptStorage, specProvider, logManager, transactionsExecutor); + + _blockProcessingQueue = new BlockchainProcessor(_txEnv.BlockTree, BlockProcessor, recoveryStep, _txEnv.StateReader, logManager, BlockchainProcessor.Options.NoReceipts); + BlockProcessingQueue = _blockProcessingQueue; + ChainProcessor = new OneTimeChainProcessor(txEnv.StateProvider, _blockProcessingQueue); + } + + protected virtual IBlockProcessor CreateBlockProcessor(ReadOnlyTxProcessingEnv txEnv, IBlockValidator blockValidator, IRewardCalculator rewardCalculator, IReceiptStorage receiptStorage, ISpecProvider specProvider, ILogManager logManager, IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor) + { + return new BlockProcessor( specProvider, blockValidator, rewardCalculator, @@ -50,10 +58,6 @@ public ReadOnlyChainProcessingEnv( receiptStorage, new BlockhashStore(txEnv.BlockTree, specProvider, StateProvider), logManager); - - _blockProcessingQueue = new BlockchainProcessor(_txEnv.BlockTree, BlockProcessor, recoveryStep, _txEnv.StateReader, logManager, BlockchainProcessor.Options.NoReceipts); - BlockProcessingQueue = _blockProcessingQueue; - ChainProcessor = new OneTimeChainProcessor(txEnv.StateProvider, _blockProcessingQueue); } public void Dispose() diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index 15b581e9207..fadbb5cd495 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -12,52 +12,48 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedAutoPropertyAccessor.Global -namespace Nethermind.Consensus.Processing +namespace Nethermind.Consensus.Processing; + +public class ReadOnlyTxProcessingEnv : IReadOnlyTxProcessorSource { - public class ReadOnlyTxProcessingEnv : IReadOnlyTxProcessorSource + protected readonly ISpecProvider _specProvider; + protected readonly ILogManager? _logManager; + + public IStateReader StateReader { get; } + public IWorldState StateProvider { get; } + public ITransactionProcessor TransactionProcessor { get; set; } + public IBlockTree BlockTree { get; } + + public ReadOnlyTxProcessingEnv( + IWorldStateManager? worldStateManager, + IReadOnlyBlockTree? readOnlyBlockTree, + ISpecProvider? specProvider, + ILogManager? logManager, + PreBlockCaches? preBlockCaches = null) + { + ArgumentNullException.ThrowIfNull(worldStateManager); + ArgumentNullException.ThrowIfNull(readOnlyBlockTree); + ArgumentNullException.ThrowIfNull(specProvider); + + StateReader = worldStateManager.GlobalStateReader; + StateProvider = worldStateManager.CreateResettableWorldState(preBlockCaches); + BlockTree = readOnlyBlockTree; + _specProvider = specProvider; + _logManager = logManager; + TransactionProcessor = CreateTransactionProcessor(); + } + + protected virtual TransactionProcessor CreateTransactionProcessor() + { + BlockhashProvider blockhashProvider = new(BlockTree, _specProvider, StateProvider, _logManager); + VirtualMachine virtualMachine = new(blockhashProvider, _specProvider, _logManager); + return new TransactionProcessor(_specProvider, StateProvider, virtualMachine, _logManager); + } + + public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) => new ReadOnlyTransactionProcessor(TransactionProcessor, StateProvider, stateRoot); + + public void Reset() { - public IStateReader StateReader { get; } - public IWorldState StateProvider { get; } - public ITransactionProcessor TransactionProcessor { get; set; } - public IBlockTree BlockTree { get; } - public IBlockhashProvider BlockhashProvider { get; } - public IVirtualMachine Machine { get; } - public ISpecProvider SpecProvider { get; } - - public ReadOnlyTxProcessingEnv( - IWorldStateManager worldStateManager, - IBlockTree? blockTree, - ISpecProvider? specProvider, - ILogManager? logManager) - : this(worldStateManager, blockTree?.AsReadOnly(), specProvider, logManager) - { - } - - public ReadOnlyTxProcessingEnv( - IWorldStateManager worldStateManager, - IReadOnlyBlockTree? readOnlyBlockTree, - ISpecProvider? specProvider, - ILogManager? logManager, - PreBlockCaches? preBlockCaches = null) - { - ArgumentNullException.ThrowIfNull(specProvider); - ArgumentNullException.ThrowIfNull(worldStateManager); - SpecProvider = specProvider; - StateReader = worldStateManager.GlobalStateReader; - StateProvider = worldStateManager.CreateResettableWorldState(preBlockCaches); - - BlockTree = readOnlyBlockTree ?? throw new ArgumentNullException(nameof(readOnlyBlockTree)); - BlockhashProvider = new BlockhashProvider(BlockTree, specProvider, StateProvider, logManager); - - Machine = new VirtualMachine(BlockhashProvider, specProvider, logManager); - TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, Machine, logManager); - } - - public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) => new ReadOnlyTransactionProcessor(TransactionProcessor, StateProvider, stateRoot); - - public void Reset() - { - StateProvider.Reset(); - } + StateProvider.Reset(); } } diff --git a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs index 673bf3eb88c..4c2939de9c4 100644 --- a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs +++ b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs @@ -114,18 +114,7 @@ public virtual async Task Execute(CancellationToken cancellationToken) _api.LogManager); rpcModuleProvider.RegisterBoundedByCpuCount(debugModuleFactory, _jsonRpcConfig.Timeout); - TraceModuleFactory traceModuleFactory = new( - _api.WorldStateManager, - _api.BlockTree, - _jsonRpcConfig, - _api.BlockPreprocessor, - _api.RewardCalculatorSource, - _api.ReceiptStorage, - _api.SpecProvider, - _api.PoSSwitcher, - _api.LogManager); - - rpcModuleProvider.RegisterBoundedByCpuCount(traceModuleFactory, _jsonRpcConfig.Timeout); + RegisterTraceRpcModule(rpcModuleProvider); StepDependencyException.ThrowIfNull(_api.EthereumEcdsa); @@ -249,4 +238,31 @@ protected virtual void RegisterEthRpcModule(IRpcModuleProvider rpcModuleProvider rpcModuleProvider.RegisterBounded(ethModuleFactory, _jsonRpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, _jsonRpcConfig.Timeout); } + + protected ModuleFactoryBase CreateTraceModuleFactory() + { + StepDependencyException.ThrowIfNull(_api.WorldStateManager); + StepDependencyException.ThrowIfNull(_api.BlockTree); + StepDependencyException.ThrowIfNull(_api.RewardCalculatorSource); + StepDependencyException.ThrowIfNull(_api.ReceiptStorage); + StepDependencyException.ThrowIfNull(_api.SpecProvider); + + return new TraceModuleFactory( + _api.WorldStateManager, + _api.BlockTree, + _jsonRpcConfig, + _api.BlockPreprocessor, + _api.RewardCalculatorSource, + _api.ReceiptStorage, + _api.SpecProvider, + _api.PoSSwitcher, + _api.LogManager); + } + + protected virtual void RegisterTraceRpcModule(IRpcModuleProvider rpcModuleProvider) + { + ModuleFactoryBase traceModuleFactory = CreateTraceModuleFactory(); + + rpcModuleProvider.RegisterBoundedByCpuCount(traceModuleFactory, _jsonRpcConfig.Timeout); + } } diff --git a/src/Nethermind/Nethermind.Init/Steps/StepInitializationException.cs b/src/Nethermind/Nethermind.Init/Steps/StepInitializationException.cs index 33840679e7b..8fe0e62a4f3 100644 --- a/src/Nethermind/Nethermind.Init/Steps/StepInitializationException.cs +++ b/src/Nethermind/Nethermind.Init/Steps/StepInitializationException.cs @@ -18,7 +18,7 @@ public StepDependencyException(string message) { } - public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression("argument")] string? paramName = null) + public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) { if (argument is not null) return; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs index f811731191c..54e8d292a82 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs @@ -93,7 +93,7 @@ public void Setup() [Test] public void Can_trace_raw_parity_style() { - TraceRpcModule traceRpcModule = new(NullReceiptStorage.Instance, _tracer, _blockTree, _jsonRpcConfig, MainnetSpecProvider.Instance, LimboLogs.Instance, _stateReader); + TraceRpcModule traceRpcModule = new(NullReceiptStorage.Instance, _tracer, _blockTree, _jsonRpcConfig, _stateReader); ResultWrapper result = traceRpcModule.trace_rawTransaction(Bytes.FromHexString("f889808609184e72a00082271094000000000000000000000000000000000000000080a47f74657374320000000000000000000000000000000000000000000000000000006000571ca08a8bbf888cfa37bbf0bb965423625641fc956967b81d12e23709cead01446075a01ce999b56a8a88504be365442ea61239198e23d1fce7d00fcfc5cd3b44b7215f"), new[] { "trace" }); Assert.NotNull(result.Data); } @@ -101,7 +101,7 @@ public void Can_trace_raw_parity_style() [Test] public void Can_trace_raw_parity_style_berlin_tx() { - TraceRpcModule traceRpcModule = new(NullReceiptStorage.Instance, _tracer, _blockTree, _jsonRpcConfig, MainnetSpecProvider.Instance, LimboLogs.Instance, _stateReader); + TraceRpcModule traceRpcModule = new(NullReceiptStorage.Instance, _tracer, _blockTree, _jsonRpcConfig, _stateReader); ResultWrapper result = traceRpcModule.trace_rawTransaction(Bytes.FromHexString("01f85b821e8e8204d7847735940083030d408080853a60005500c080a0f43e70c79190701347517e283ef63753f6143a5225cbb500b14d98eadfb7616ba070893923d8a1fc97499f426524f9e82f8e0322dfac7c3d7e8a9eee515f0bcdc4"), new[] { "trace" }); Assert.NotNull(result.Data); } @@ -114,7 +114,7 @@ public void Should_return_correct_block_reward(bool isPostMerge) _blockTree!.SuggestBlock(block).Should().Be(AddBlockResult.Added); _poSSwitcher!.IsPostMerge(Arg.Any()).Returns(isPostMerge); - TraceRpcModule traceRpcModule = new(NullReceiptStorage.Instance, _tracer, _blockTree, _jsonRpcConfig, MainnetSpecProvider.Instance, LimboLogs.Instance, _stateReader); + TraceRpcModule traceRpcModule = new(NullReceiptStorage.Instance, _tracer, _blockTree, _jsonRpcConfig, _stateReader); ParityTxTraceFromStore[] result = traceRpcModule.trace_block(new BlockParameter(block.Number)).Data.ToArray(); if (isPostMerge) { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs index 0e499183eb8..115afc9123f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs @@ -72,7 +72,7 @@ public async Task Build(ISpecProvider? specProvider = null, bool isAura = false) ReadOnlyChainProcessingEnv executeProcessingEnv = CreateChainProcessingEnv(executeBlockTransactionsExecutor); Tracer tracer = new(txProcessingEnv.StateProvider, traceProcessingEnv.ChainProcessor, executeProcessingEnv.ChainProcessor); - TraceRpcModule = new TraceRpcModule(receiptFinder, tracer, Blockchain.BlockFinder, JsonRpcConfig, MainnetSpecProvider.Instance, LimboLogs.Instance, txProcessingEnv.StateReader); + TraceRpcModule = new TraceRpcModule(receiptFinder, tracer, Blockchain.BlockFinder, JsonRpcConfig, txProcessingEnv.StateReader); for (int i = 1; i < 10; i++) { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceModuleFactory.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceModuleFactory.cs index 9d34f031e44..551967408fb 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceModuleFactory.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceModuleFactory.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; - using Nethermind.Blockchain; using Nethermind.Blockchain.Receipts; using Nethermind.Consensus; @@ -17,56 +16,32 @@ using Nethermind.State; using Nethermind.Trie.Pruning; -namespace Nethermind.JsonRpc.Modules.Trace -{ - public class TraceModuleFactory : ModuleFactoryBase - { - private readonly IWorldStateManager _worldStateManager; - private readonly IReadOnlyBlockTree _blockTree; - private readonly IJsonRpcConfig _jsonRpcConfig; - private readonly IReceiptStorage _receiptStorage; - private readonly ISpecProvider _specProvider; - private readonly ILogManager _logManager; - private readonly IBlockPreprocessorStep _recoveryStep; - private readonly IRewardCalculatorSource _rewardCalculatorSource; - private readonly IPoSSwitcher _poSSwitcher; - - public TraceModuleFactory( - IWorldStateManager worldStateManager, - IBlockTree blockTree, - IJsonRpcConfig jsonRpcConfig, - IBlockPreprocessorStep recoveryStep, - IRewardCalculatorSource rewardCalculatorSource, - IReceiptStorage receiptFinder, - ISpecProvider specProvider, - IPoSSwitcher poSSwitcher, - ILogManager logManager) - { - _worldStateManager = worldStateManager; - _blockTree = blockTree.AsReadOnly(); - _jsonRpcConfig = jsonRpcConfig ?? throw new ArgumentNullException(nameof(jsonRpcConfig)); - _recoveryStep = recoveryStep ?? throw new ArgumentNullException(nameof(recoveryStep)); - _rewardCalculatorSource = rewardCalculatorSource ?? throw new ArgumentNullException(nameof(rewardCalculatorSource)); - _receiptStorage = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder)); - _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); - _poSSwitcher = poSSwitcher ?? throw new ArgumentNullException(nameof(poSSwitcher)); - _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager)); - logManager.GetClassLogger(); - } - - public override ITraceRpcModule Create() - { - ReadOnlyTxProcessingEnv txProcessingEnv = - new(_worldStateManager, _blockTree, _specProvider, _logManager); +namespace Nethermind.JsonRpc.Modules.Trace; - IRewardCalculator rewardCalculator = - new MergeRpcRewardCalculator(_rewardCalculatorSource.Get(txProcessingEnv.TransactionProcessor), - _poSSwitcher); +public class TraceModuleFactory( + IWorldStateManager worldStateManager, + IBlockTree blockTree, + IJsonRpcConfig jsonRpcConfig, + IBlockPreprocessorStep recoveryStep, + IRewardCalculatorSource rewardCalculatorSource, + IReceiptStorage receiptFinder, + ISpecProvider specProvider, + IPoSSwitcher poSSwitcher, + ILogManager logManager) : ModuleFactoryBase +{ + protected readonly IWorldStateManager _worldStateManager = worldStateManager; + protected readonly IReadOnlyBlockTree _blockTree = blockTree.AsReadOnly(); + protected readonly IJsonRpcConfig _jsonRpcConfig = jsonRpcConfig ?? throw new ArgumentNullException(nameof(jsonRpcConfig)); + protected readonly IReceiptStorage _receiptStorage = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder)); + protected readonly ISpecProvider _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); + protected readonly ILogManager _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager)); + protected readonly IBlockPreprocessorStep _recoveryStep = recoveryStep ?? throw new ArgumentNullException(nameof(recoveryStep)); + protected readonly IRewardCalculatorSource _rewardCalculatorSource = rewardCalculatorSource ?? throw new ArgumentNullException(nameof(rewardCalculatorSource)); + protected readonly IPoSSwitcher _poSSwitcher = poSSwitcher ?? throw new ArgumentNullException(nameof(poSSwitcher)); - RpcBlockTransactionsExecutor rpcBlockTransactionsExecutor = new(txProcessingEnv.TransactionProcessor, txProcessingEnv.StateProvider); - BlockProcessor.BlockValidationTransactionsExecutor executeBlockTransactionsExecutor = new(txProcessingEnv.TransactionProcessor, txProcessingEnv.StateProvider); + protected virtual ReadOnlyTxProcessingEnv CreateTxProcessingEnv() => new(_worldStateManager, _blockTree, _specProvider, _logManager); - ReadOnlyChainProcessingEnv CreateChainProcessingEnv(IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor) => new( + protected virtual ReadOnlyChainProcessingEnv CreateChainProcessingEnv(IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor, ReadOnlyTxProcessingEnv txProcessingEnv, IRewardCalculator rewardCalculator) => new( txProcessingEnv, Always.Valid, _recoveryStep, @@ -76,12 +51,23 @@ public override ITraceRpcModule Create() _logManager, transactionsExecutor); - ReadOnlyChainProcessingEnv traceProcessingEnv = CreateChainProcessingEnv(rpcBlockTransactionsExecutor); - ReadOnlyChainProcessingEnv executeProcessingEnv = CreateChainProcessingEnv(executeBlockTransactionsExecutor); + public override ITraceRpcModule Create() + { + ReadOnlyTxProcessingEnv txProcessingEnv = CreateTxProcessingEnv(); + + IRewardCalculator rewardCalculator = + new MergeRpcRewardCalculator(_rewardCalculatorSource.Get(txProcessingEnv.TransactionProcessor), + _poSSwitcher); + + RpcBlockTransactionsExecutor rpcBlockTransactionsExecutor = new(txProcessingEnv.TransactionProcessor, txProcessingEnv.StateProvider); + BlockProcessor.BlockValidationTransactionsExecutor executeBlockTransactionsExecutor = new(txProcessingEnv.TransactionProcessor, txProcessingEnv.StateProvider); - Tracer tracer = new(txProcessingEnv.StateProvider, traceProcessingEnv.ChainProcessor, executeProcessingEnv.ChainProcessor); + ReadOnlyChainProcessingEnv traceProcessingEnv = CreateChainProcessingEnv(rpcBlockTransactionsExecutor, txProcessingEnv, rewardCalculator); + ReadOnlyChainProcessingEnv executeProcessingEnv = CreateChainProcessingEnv(executeBlockTransactionsExecutor, txProcessingEnv, rewardCalculator); - return new TraceRpcModule(_receiptStorage, tracer, _blockTree, _jsonRpcConfig, _specProvider, _logManager, txProcessingEnv.StateReader); - } + Tracer tracer = new(txProcessingEnv.StateProvider, traceProcessingEnv.ChainProcessor, executeProcessingEnv.ChainProcessor); + + return new TraceRpcModule(_receiptStorage, tracer, _blockTree, _jsonRpcConfig, txProcessingEnv.StateReader); } + } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs index 903fb1b1bfc..dce79316b4d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs @@ -39,24 +39,19 @@ public class TraceRpcModule : ITraceRpcModule private readonly IBlockFinder _blockFinder; private readonly TxDecoder _txDecoder = new(); private readonly IJsonRpcConfig _jsonRpcConfig; - private readonly ILogManager _logManager; - private readonly ILogger _logger; - private readonly ISpecProvider _specProvider; private readonly TimeSpan _cancellationTokenTimeout; private readonly IStateReader _stateReader; - public TraceRpcModule(IReceiptFinder? receiptFinder, ITracer? tracer, IBlockFinder? blockFinder, IJsonRpcConfig? jsonRpcConfig, ISpecProvider? specProvider, ILogManager? logManager, IStateReader stateReader) + public TraceRpcModule(IReceiptFinder? receiptFinder, ITracer? tracer, IBlockFinder? blockFinder, IJsonRpcConfig? jsonRpcConfig, IStateReader stateReader) { _receiptFinder = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder)); _tracer = tracer ?? throw new ArgumentNullException(nameof(tracer)); _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder)); _jsonRpcConfig = jsonRpcConfig ?? throw new ArgumentNullException(nameof(jsonRpcConfig)); - _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); - _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager)); _stateReader = stateReader ?? throw new ArgumentNullException(nameof(stateReader)); - _logger = logManager.GetClassLogger(); _cancellationTokenTimeout = TimeSpan.FromMilliseconds(_jsonRpcConfig.Timeout); } + public static ParityTraceTypes GetParityTypes(string[] types) => types.Select(s => FastEnum.Parse(s, true)).Aggregate((t1, t2) => t1 | t2); diff --git a/src/Nethermind/Nethermind.Optimism/Create2DeployerContractRewriter.cs b/src/Nethermind/Nethermind.Optimism/Create2DeployerContractRewriter.cs index 3510481d6a2..fc7a1714d5a 100644 --- a/src/Nethermind/Nethermind.Optimism/Create2DeployerContractRewriter.cs +++ b/src/Nethermind/Nethermind.Optimism/Create2DeployerContractRewriter.cs @@ -11,13 +11,13 @@ namespace Nethermind.Optimism; public class Create2DeployerContractRewriter { - private readonly IOPConfigHelper _opConfigHelper; + private readonly IOptimismSpecHelper _opSpecHelper; private readonly ISpecProvider _specProvider; private readonly IBlockTree _blockTree; - public Create2DeployerContractRewriter(IOPConfigHelper opConfigHelper, ISpecProvider specProvider, IBlockTree blockTree) + public Create2DeployerContractRewriter(IOptimismSpecHelper opSpecHelper, ISpecProvider specProvider, IBlockTree blockTree) { - _opConfigHelper = opConfigHelper; + _opSpecHelper = opSpecHelper; _specProvider = specProvider; _blockTree = blockTree; } @@ -26,9 +26,9 @@ public void RewriteContract(BlockHeader header, IWorldState worldState) { IReleaseSpec spec = _specProvider.GetSpec(header); BlockHeader? parent = _blockTree.FindParent(header, BlockTreeLookupOptions.None)?.Header; - if ((parent is null || !_opConfigHelper.IsCanyon(parent)) && _opConfigHelper.IsCanyon(header)) + if ((parent is null || !_opSpecHelper.IsCanyon(parent)) && _opSpecHelper.IsCanyon(header)) { - worldState.InsertCode(_opConfigHelper.Create2DeployerAddress!, _opConfigHelper.Create2DeployerCode, spec); + worldState.InsertCode(_opSpecHelper.Create2DeployerAddress!, _opSpecHelper.Create2DeployerCode, spec); } } } diff --git a/src/Nethermind/Nethermind.Optimism/DepositTxExtensions.cs b/src/Nethermind/Nethermind.Optimism/DepositTxExtensions.cs index 2130699aada..5c908bb730d 100644 --- a/src/Nethermind/Nethermind.Optimism/DepositTxExtensions.cs +++ b/src/Nethermind/Nethermind.Optimism/DepositTxExtensions.cs @@ -7,7 +7,6 @@ namespace Nethermind.Optimism; public static class DepositTxExtensions { - public static bool IsDeposit(this Transaction tx) { return tx.Type == TxType.DepositTx; diff --git a/src/Nethermind/Nethermind.Optimism/IOPConfigHelper.cs b/src/Nethermind/Nethermind.Optimism/IOptimismSpecHelper.cs similarity index 92% rename from src/Nethermind/Nethermind.Optimism/IOPConfigHelper.cs rename to src/Nethermind/Nethermind.Optimism/IOptimismSpecHelper.cs index 4320ef70bfc..4e571fae53b 100644 --- a/src/Nethermind/Nethermind.Optimism/IOPConfigHelper.cs +++ b/src/Nethermind/Nethermind.Optimism/IOptimismSpecHelper.cs @@ -5,7 +5,7 @@ namespace Nethermind.Optimism; -public interface IOPConfigHelper +public interface IOptimismSpecHelper { Address L1FeeReceiver { get; } diff --git a/src/Nethermind/Nethermind.Optimism/InitializeBlockProducerOptimism.cs b/src/Nethermind/Nethermind.Optimism/InitializeBlockProducerOptimism.cs index 2c2b0d404ad..06111a6445e 100644 --- a/src/Nethermind/Nethermind.Optimism/InitializeBlockProducerOptimism.cs +++ b/src/Nethermind/Nethermind.Optimism/InitializeBlockProducerOptimism.cs @@ -34,7 +34,6 @@ protected override IBlockProducer BuildProducer() _api.BlockProducerEnvFactory = new OptimismBlockProducerEnvFactory( _api.WorldStateManager, - _api.ChainSpec, _api.BlockTree, _api.SpecProvider, _api.BlockValidator, diff --git a/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs b/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs index 93cf3e46194..edf205a9767 100644 --- a/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs +++ b/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs @@ -6,9 +6,11 @@ using Nethermind.Blockchain.Blocks; using Nethermind.Blockchain.Services; using Nethermind.Config; +using Nethermind.Consensus.AuRa.Withdrawals; using Nethermind.Consensus.Processing; using Nethermind.Consensus.Producers; using Nethermind.Consensus.Validators; +using Nethermind.Consensus.Withdrawals; using Nethermind.Evm; using Nethermind.Evm.TransactionProcessing; using Nethermind.Init.Steps; @@ -40,6 +42,7 @@ protected override ITransactionProcessor CreateTransactionProcessor() if (_api.SpecProvider is null) throw new StepDependencyException(nameof(_api.SpecProvider)); if (_api.SpecHelper is null) throw new StepDependencyException(nameof(_api.SpecHelper)); if (_api.L1CostHelper is null) throw new StepDependencyException(nameof(_api.L1CostHelper)); + if (_api.WorldState is null) throw new StepDependencyException(nameof(_api.WorldState)); VirtualMachine virtualMachine = CreateVirtualMachine(); @@ -105,7 +108,8 @@ protected override BlockProcessor CreateBlockProcessor() new BlockhashStore(_api.BlockTree, _api.SpecProvider, _api.WorldState), _api.LogManager, _api.SpecHelper, - contractRewriter); + contractRewriter, + new BlockProductionWithdrawalProcessor(new NullWithdrawalProcessor())); } protected override IUnclesValidator CreateUnclesValidator() => Always.Valid; diff --git a/src/Nethermind/Nethermind.Optimism/OPConfigHelper.cs b/src/Nethermind/Nethermind.Optimism/OPConfigHelper.cs index 57549e96fbe..07a21bec088 100644 --- a/src/Nethermind/Nethermind.Optimism/OPConfigHelper.cs +++ b/src/Nethermind/Nethermind.Optimism/OPConfigHelper.cs @@ -6,26 +6,14 @@ namespace Nethermind.Optimism; -public class OPSpecHelper : IOPConfigHelper +public class OptimismSpecHelper(OptimismParameters parameters) : IOptimismSpecHelper { - private readonly ulong _regolithTimestamp; - private readonly long _bedrockBlockNumber; - private readonly ulong? _canyonTimestamp; - private readonly ulong? _ecotoneTimestamp; + private readonly long _bedrockBlockNumber = parameters.BedrockBlockNumber; + private readonly ulong _regolithTimestamp = parameters.RegolithTimestamp; + private readonly ulong? _canyonTimestamp = parameters.CanyonTimestamp; + private readonly ulong? _ecotoneTimestamp = parameters.EcotoneTimestamp; - public Address L1FeeReceiver { get; init; } - - public OPSpecHelper(OptimismParameters parameters) - { - _regolithTimestamp = parameters.RegolithTimestamp; - _bedrockBlockNumber = parameters.BedrockBlockNumber; - _canyonTimestamp = parameters.CanyonTimestamp; - _ecotoneTimestamp = parameters.EcotoneTimestamp; - - L1FeeReceiver = parameters.L1FeeRecipient; - Create2DeployerCode = parameters.Create2DeployerCode; - Create2DeployerAddress = parameters.Create2DeployerAddress; - } + public Address L1FeeReceiver { get; init; } = parameters.L1FeeRecipient; public bool IsRegolith(BlockHeader header) { @@ -47,6 +35,6 @@ public bool IsEcotone(BlockHeader header) return header.Timestamp >= _ecotoneTimestamp; } - public Address? Create2DeployerAddress { get; } - public byte[]? Create2DeployerCode { get; } + public Address? Create2DeployerAddress { get; } = parameters.Create2DeployerAddress; + public byte[]? Create2DeployerCode { get; } = parameters.Create2DeployerCode; } diff --git a/src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs b/src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs index f6f150e83d2..29d2fa259af 100644 --- a/src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs +++ b/src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs @@ -12,9 +12,9 @@ namespace Nethermind.Optimism; -public class OPL1CostHelper(IOPConfigHelper opConfigHelper, Address l1BlockAddr) : IL1CostHelper +public class OPL1CostHelper(IOptimismSpecHelper opSpecHelper, Address l1BlockAddr) : IL1CostHelper { - private readonly IOPConfigHelper _opConfigHelper = opConfigHelper; + private readonly IOptimismSpecHelper _opSpecHelper = opSpecHelper; private readonly StorageCell _l1BaseFeeSlot = new(l1BlockAddr, new UInt256(1)); private readonly StorageCell _overheadSlot = new(l1BlockAddr, new UInt256(5)); @@ -35,15 +35,14 @@ public UInt256 ComputeL1Cost(Transaction tx, BlockHeader header, IWorldState wor if (tx.IsDeposit()) return UInt256.Zero; - UInt256 dataGas = ComputeDataGas(tx, _opConfigHelper.IsRegolith(header)); + UInt256 dataGas = ComputeDataGas(tx, _opSpecHelper.IsRegolith(header)); if (dataGas.IsZero) return UInt256.Zero; UInt256 l1BaseFee = new(worldState.Get(_l1BaseFeeSlot), true); - if (_opConfigHelper.IsEcotone(header)) + if (_opSpecHelper.IsEcotone(header)) { - // Ecotone formula: (dataGas) * (16 * l1BaseFee * l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar) / 16e6 UInt256 blobBaseFee = new(worldState.Get(_blobBaseFeeSlot), true); ReadOnlySpan scalarData = worldState.Get(_baseFeeScalarSlot); @@ -60,7 +59,6 @@ public UInt256 ComputeL1Cost(Transaction tx, BlockHeader header, IWorldState wor } else { - // Pre-Ecotone formula: (dataGas + overhead) * l1BaseFee * scalar / 1e6 UInt256 overhead = new(worldState.Get(_overheadSlot), true); UInt256 feeScalar = new(worldState.Get(_scalarSlot), true); @@ -81,11 +79,13 @@ public static UInt256 ComputeDataGas(Transaction tx, bool isRegolith) return (ulong)(zeroCount * GasCostOf.TxDataZero + nonZeroCount * GasCostOf.TxDataNonZeroEip2028); } + // Ecotone formula: (dataGas) * (16 * l1BaseFee * l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar) / 16e6 public static UInt256 ComputeL1CostEcotone(UInt256 dataGas, UInt256 l1BaseFee, UInt256 blobBaseFee, UInt256 l1BaseFeeScalar, UInt256 l1BlobBaseFeeScalar) { return dataGas * (precisionMultiplier * l1BaseFee * l1BaseFeeScalar + blobBaseFee * l1BlobBaseFeeScalar) / precisionDevider; } + // Pre-Ecotone formula: (dataGas + overhead) * l1BaseFee * scalar / 1e6 public static UInt256 ComputeL1CostPreEcotone(UInt256 dataGasWithOverhead, UInt256 l1BaseFee, UInt256 feeScalar) { return dataGasWithOverhead * l1BaseFee * feeScalar / basicDevider; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismBlockProcessor.cs b/src/Nethermind/Nethermind.Optimism/OptimismBlockProcessor.cs index e06cc378360..854f5b1491b 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismBlockProcessor.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismBlockProcessor.cs @@ -29,7 +29,7 @@ public OptimismBlockProcessor( IReceiptStorage? receiptStorage, IBlockhashStore? blockhashStore, ILogManager? logManager, - IOPConfigHelper opConfigHelper, + IOptimismSpecHelper opSpecHelper, Create2DeployerContractRewriter contractRewriter, IWithdrawalProcessor? withdrawalProcessor = null) : base(specProvider, blockValidator, rewardCalculator, blockTransactionsExecutor, @@ -37,7 +37,7 @@ public OptimismBlockProcessor( { ArgumentNullException.ThrowIfNull(stateProvider); _contractRewriter = contractRewriter; - ReceiptsTracer = new OptimismBlockReceiptTracer(opConfigHelper, stateProvider); + ReceiptsTracer = new OptimismBlockReceiptTracer(opSpecHelper, stateProvider); } protected override TxReceipt[] ProcessBlock(Block block, IBlockTracer blockTracer, ProcessingOptions options) diff --git a/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs b/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs index ade9f8fb8a8..68581ebc710 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs @@ -14,53 +14,40 @@ using Nethermind.Consensus.Withdrawals; using Nethermind.Core.Specs; using Nethermind.Logging; -using Nethermind.Specs.ChainSpecStyle; using Nethermind.State; using Nethermind.TxPool; namespace Nethermind.Optimism; -public class OptimismBlockProducerEnvFactory : BlockProducerEnvFactory +public class OptimismBlockProducerEnvFactory( + IWorldStateManager worldStateManager, + IBlockTree blockTree, + ISpecProvider specProvider, + IBlockValidator blockValidator, + IRewardCalculatorSource rewardCalculatorSource, + IReceiptStorage receiptStorage, + IBlockPreprocessorStep blockPreprocessorStep, + ITxPool txPool, + ITransactionComparerProvider transactionComparerProvider, + IBlocksConfig blocksConfig, + OptimismSpecHelper specHelper, + OPL1CostHelper l1CostHelper, + ILogManager logManager) : BlockProducerEnvFactory( + worldStateManager, + blockTree, + specProvider, + blockValidator, + rewardCalculatorSource, + receiptStorage, + blockPreprocessorStep, + txPool, + transactionComparerProvider, + blocksConfig, + logManager) { - private readonly ChainSpec _chainSpec; - private readonly OPSpecHelper _specHelper; - private readonly OPL1CostHelper _l1CostHelper; - - public OptimismBlockProducerEnvFactory( - IWorldStateManager worldStateManager, - ChainSpec chainSpec, - IBlockTree blockTree, - ISpecProvider specProvider, - IBlockValidator blockValidator, - IRewardCalculatorSource rewardCalculatorSource, - IReceiptStorage receiptStorage, - IBlockPreprocessorStep blockPreprocessorStep, - ITxPool txPool, - ITransactionComparerProvider transactionComparerProvider, - IBlocksConfig blocksConfig, - OPSpecHelper specHelper, - OPL1CostHelper l1CostHelper, - ILogManager logManager) : base(worldStateManager, - blockTree, specProvider, blockValidator, - rewardCalculatorSource, receiptStorage, blockPreprocessorStep, - txPool, transactionComparerProvider, blocksConfig, logManager) - { - _specHelper = specHelper; - _l1CostHelper = l1CostHelper; - _chainSpec = chainSpec; - TransactionsExecutorFactory = new OptimismTransactionsExecutorFactory(specProvider, logManager); - } - protected override ReadOnlyTxProcessingEnv CreateReadonlyTxProcessingEnv(IWorldStateManager worldStateManager, - ReadOnlyBlockTree readOnlyBlockTree) - { - ReadOnlyTxProcessingEnv result = new(worldStateManager, - readOnlyBlockTree, _specProvider, _logManager); - result.TransactionProcessor = - new OptimismTransactionProcessor(_specProvider, result.StateProvider, result.Machine, _logManager, _l1CostHelper, _specHelper); - - return result; - } + ReadOnlyBlockTree readOnlyBlockTree) => + new OptimismReadOnlyTxProcessingEnv(worldStateManager, readOnlyBlockTree, _specProvider, _logManager, l1CostHelper, specHelper); protected override ITxSource CreateTxSourceForProducer(ITxSource? additionalTxSource, ReadOnlyTxProcessingEnv processingEnv, @@ -90,8 +77,8 @@ protected override BlockProcessor CreateBlockProcessor( receiptStorage, new BlockhashStore(_blockTree, specProvider, readOnlyTxProcessingEnv.StateProvider), logManager, - _specHelper, - new Create2DeployerContractRewriter(_specHelper, _specProvider, _blockTree), + specHelper, + new Create2DeployerContractRewriter(specHelper, _specProvider, _blockTree), new BlockProductionWithdrawalProcessor(new WithdrawalProcessor(readOnlyTxProcessingEnv.StateProvider, logManager))); } } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs b/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs index 7f43df08c32..aab105b9090 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs @@ -11,12 +11,12 @@ namespace Nethermind.Optimism; public class OptimismBlockReceiptTracer : BlockReceiptsTracer { - private readonly IOPConfigHelper _opConfigHelper; + private readonly IOptimismSpecHelper _opSpecHelper; private readonly IWorldState _worldState; - public OptimismBlockReceiptTracer(IOPConfigHelper opConfigHelper, IWorldState worldState) + public OptimismBlockReceiptTracer(IOptimismSpecHelper opSpecHelper, IWorldState worldState) { - _opConfigHelper = opConfigHelper; + _opSpecHelper = opSpecHelper; _worldState = worldState; } @@ -35,7 +35,7 @@ public OptimismBlockReceiptTracer(IOPConfigHelper opConfigHelper, IWorldState wo { depositNonce--; } - if (_opConfigHelper.IsCanyon(header)) + if (_opSpecHelper.IsCanyon(header)) { version = 1; } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs b/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs index 9f39d63b1ff..8e1e8f4002d 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs @@ -22,5 +22,5 @@ public OptimismNethermindApi( public IInvalidChainTracker? InvalidChainTracker { get; set; } public OPL1CostHelper? L1CostHelper { get; set; } - public OPSpecHelper? SpecHelper { get; set; } + public OptimismSpecHelper? SpecHelper { get; set; } } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPayloadPreparationService.cs b/src/Nethermind/Nethermind.Optimism/OptimismPayloadPreparationService.cs index 71187bba01a..35fd2e3abb2 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPayloadPreparationService.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPayloadPreparationService.cs @@ -8,6 +8,7 @@ using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Merge.Plugin.BlockProduction; +using Nethermind.Optimism.Rpc; namespace Nethermind.Optimism; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPayloadTxSource.cs b/src/Nethermind/Nethermind.Optimism/OptimismPayloadTxSource.cs index 77f3c9ca35f..53b23ea2695 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPayloadTxSource.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPayloadTxSource.cs @@ -6,6 +6,7 @@ using Nethermind.Consensus.Producers; using Nethermind.Consensus.Transactions; using Nethermind.Core; +using Nethermind.Optimism.Rpc; namespace Nethermind.Optimism; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index ecf5388e502..997d05beb7c 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -26,6 +26,7 @@ using Nethermind.Serialization.Json; using Nethermind.Specs.ChainSpecStyle; using Nethermind.Serialization.Rlp; +using Nethermind.Optimism.Rpc; namespace Nethermind.Optimism; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPostMergeBlockProducer.cs b/src/Nethermind/Nethermind.Optimism/OptimismPostMergeBlockProducer.cs index 2f1e53c562b..93df8a49f9c 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPostMergeBlockProducer.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPostMergeBlockProducer.cs @@ -13,6 +13,7 @@ using Nethermind.Core.Specs; using Nethermind.Logging; using Nethermind.Merge.Plugin.BlockProduction; +using Nethermind.Optimism.Rpc; using Nethermind.State; namespace Nethermind.Optimism; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Optimism/OptimismReadOnlyTxProcessingEnv.cs new file mode 100644 index 00000000000..ad5fba0d750 --- /dev/null +++ b/src/Nethermind/Nethermind.Optimism/OptimismReadOnlyTxProcessingEnv.cs @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Blockchain; +using Nethermind.Consensus.Processing; +using Nethermind.Core.Specs; +using Nethermind.Evm; +using Nethermind.Evm.TransactionProcessing; +using Nethermind.Logging; +using Nethermind.State; +using System; + +namespace Nethermind.Optimism; + +public class OptimismReadOnlyTxProcessingEnv( + IWorldStateManager worldStateManager, + IReadOnlyBlockTree readOnlyBlockTree, + ISpecProvider specProvider, + ILogManager logManager, + IL1CostHelper l1CostHelper, + IOptimismSpecHelper opSpecHelper, + PreBlockCaches? preBlockCaches = null) : ReadOnlyTxProcessingEnv( + worldStateManager, + readOnlyBlockTree, + specProvider, + logManager, + preBlockCaches + ) +{ + protected override TransactionProcessor CreateTransactionProcessor() + { + ArgumentNullException.ThrowIfNull(_logManager); + + BlockhashProvider blockhashProvider = new(BlockTree, _specProvider, StateProvider, _logManager); + VirtualMachine virtualMachine = new(blockhashProvider, _specProvider, _logManager); + return new OptimismTransactionProcessor(_specProvider, StateProvider, virtualMachine, _logManager, l1CostHelper, opSpecHelper); + } +} diff --git a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs index 4322fa58f32..ccf02547435 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs @@ -13,23 +13,14 @@ namespace Nethermind.Optimism; -public class OptimismTransactionProcessor : TransactionProcessor +public class OptimismTransactionProcessor( + ISpecProvider specProvider, + IWorldState worldState, + IVirtualMachine virtualMachine, + ILogManager logManager, + IL1CostHelper l1CostHelper, + IOptimismSpecHelper opSpecHelper) : TransactionProcessor(specProvider, worldState, virtualMachine, logManager) { - private readonly IL1CostHelper _l1CostHelper; - private readonly IOPConfigHelper _opConfigHelper; - - public OptimismTransactionProcessor( - ISpecProvider? specProvider, - IWorldState? worldState, - IVirtualMachine? virtualMachine, - ILogManager? logManager, - IL1CostHelper l1CostHelper, - IOPConfigHelper opConfigHelper) : base(specProvider, worldState, virtualMachine, logManager) - { - _l1CostHelper = l1CostHelper; - _opConfigHelper = opConfigHelper; - } - private UInt256? _currentTxL1Cost; protected override TransactionResult Execute(Transaction tx, in BlockExecutionContext blCtx, ITxTracer tracer, ExecutionOptions opts) @@ -108,7 +99,7 @@ protected override TransactionResult BuyGas(Transaction tx, BlockHeader header, return "insufficient sender balance"; } - UInt256 l1Cost = _currentTxL1Cost ??= _l1CostHelper.ComputeL1Cost(tx, header, WorldState); + UInt256 l1Cost = _currentTxL1Cost ??= l1CostHelper.ComputeL1Cost(tx, header, WorldState); if (UInt256.SubtractUnderflow(balanceLeft, l1Cost, out balanceLeft)) { TraceLogInvalidTx(tx, $"INSUFFICIENT_SENDER_BALANCE: ({tx.SenderAddress})_BALANCE = {senderBalance}"); @@ -158,10 +149,10 @@ protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec // Skip coinbase payments for deposit tx in Regolith base.PayFees(tx, header, spec, tracer, substate, spentGas, premiumPerGas, statusCode); - if (_opConfigHelper.IsBedrock(header)) + if (opSpecHelper.IsBedrock(header)) { - UInt256 l1Cost = _currentTxL1Cost ??= _l1CostHelper.ComputeL1Cost(tx, header, WorldState); - WorldState.AddToBalanceAndCreateIfNotExists(_opConfigHelper.L1FeeReceiver, l1Cost, spec); + UInt256 l1Cost = _currentTxL1Cost ??= l1CostHelper.ComputeL1Cost(tx, header, WorldState); + WorldState.AddToBalanceAndCreateIfNotExists(opSpecHelper.L1FeeReceiver, l1Cost, spec); } } } @@ -171,7 +162,7 @@ protected override long Refund(Transaction tx, BlockHeader header, IReleaseSpec { // if deposit: skip refunds, skip tipping coinbase // Regolith changes this behaviour to report the actual gasUsed instead of always reporting all gas used. - if (tx.IsDeposit() && !_opConfigHelper.IsRegolith(header)) + if (tx.IsDeposit() && !opSpecHelper.IsRegolith(header)) { // Record deposits as using all their gas // System Transactions are special & are not recorded as using any gas (anywhere) diff --git a/src/Nethermind/Nethermind.Optimism/OptimismTxPoolTxSource.cs b/src/Nethermind/Nethermind.Optimism/OptimismTxPoolTxSource.cs index b91f085b892..7334e9448b4 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismTxPoolTxSource.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismTxPoolTxSource.cs @@ -6,6 +6,7 @@ using Nethermind.Consensus.Producers; using Nethermind.Consensus.Transactions; using Nethermind.Core; +using Nethermind.Optimism.Rpc; namespace Nethermind.Optimism; diff --git a/src/Nethermind/Nethermind.Optimism/ReadOnlyChainProcessingEnv.cs b/src/Nethermind/Nethermind.Optimism/ReadOnlyChainProcessingEnv.cs new file mode 100644 index 00000000000..8c97a784c81 --- /dev/null +++ b/src/Nethermind/Nethermind.Optimism/ReadOnlyChainProcessingEnv.cs @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Blockchain.Blocks; +using Nethermind.Blockchain.Receipts; +using Nethermind.Consensus.Processing; +using Nethermind.Consensus.Rewards; +using Nethermind.Consensus.Validators; +using Nethermind.Consensus.Withdrawals; +using Nethermind.Core.Specs; +using Nethermind.Logging; + +namespace Nethermind.Optimism; + +/// +/// Not thread safe. +/// +public class OptimismReadOnlyChainProcessingEnv( + ReadOnlyTxProcessingEnv txEnv, + IBlockValidator blockValidator, + IBlockPreprocessorStep recoveryStep, + IRewardCalculator rewardCalculator, + IReceiptStorage receiptStorage, + ISpecProvider specProvider, + ILogManager logManager, + IOptimismSpecHelper opSpecHelper, + Create2DeployerContractRewriter contractRewriter, + IWithdrawalProcessor? withdrawalProcessor, + IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) : ReadOnlyChainProcessingEnv( + txEnv, + blockValidator, + recoveryStep, + rewardCalculator, + receiptStorage, + specProvider, + logManager, + blockTransactionsExecutor) +{ + protected override IBlockProcessor CreateBlockProcessor(ReadOnlyTxProcessingEnv txEnv, IBlockValidator blockValidator, IRewardCalculator rewardCalculator, IReceiptStorage receiptStorage, ISpecProvider specProvider, ILogManager logManager, IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor) + { + return new OptimismBlockProcessor( + specProvider, + blockValidator, + rewardCalculator, + transactionsExecutor, + StateProvider, + receiptStorage, + new BlockhashStore(txEnv.BlockTree, specProvider, StateProvider), + logManager, + opSpecHelper, + contractRewriter, + withdrawalProcessor); + } +} diff --git a/src/Nethermind/Nethermind.Optimism/IOptimismEngineRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEngineRpcModule.cs similarity index 99% rename from src/Nethermind/Nethermind.Optimism/IOptimismEngineRpcModule.cs rename to src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEngineRpcModule.cs index 08b1ee5f25f..a4fff0ee437 100644 --- a/src/Nethermind/Nethermind.Optimism/IOptimismEngineRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEngineRpcModule.cs @@ -7,7 +7,7 @@ using Nethermind.JsonRpc.Modules; using Nethermind.Merge.Plugin.Data; -namespace Nethermind.Optimism; +namespace Nethermind.Optimism.Rpc; [RpcModule(ModuleType.Engine)] diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs index 9f95e620733..963fbe27a4b 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs @@ -7,7 +7,7 @@ using Nethermind.JsonRpc; using Nethermind.Blockchain.Find; -namespace Nethermind.Optimism; +namespace Nethermind.Optimism.Rpc; [RpcModule(ModuleType.Eth)] public interface IOptimismEthRpcModule : IEthRpcModule diff --git a/src/Nethermind/Nethermind.Optimism/OptimismEngineRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEngineRpcModule.cs similarity index 98% rename from src/Nethermind/Nethermind.Optimism/OptimismEngineRpcModule.cs rename to src/Nethermind/Nethermind.Optimism/Rpc/OptimismEngineRpcModule.cs index 79e063eb4b6..92aba891d7b 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismEngineRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEngineRpcModule.cs @@ -7,7 +7,7 @@ using Nethermind.Merge.Plugin; using Nethermind.Merge.Plugin.Data; -namespace Nethermind.Optimism; +namespace Nethermind.Optimism.Rpc; public class OptimismEngineRpcModule : IOptimismEngineRpcModule { diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs index 6d45fe82bdd..d3e6bbd605e 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs @@ -19,7 +19,7 @@ using Nethermind.Crypto; using Nethermind.JsonRpc.Client; -namespace Nethermind.Optimism; +namespace Nethermind.Optimism.Rpc; public class OptimismEthModuleFactory( IJsonRpcConfig rpcConfig, @@ -40,7 +40,7 @@ public class OptimismEthModuleFactory( IAccountStateProvider accountStateProvider, IEthereumEcdsa ecdsa, ITxSealer sealer, - IOPConfigHelper opConfigHelper + IOptimismSpecHelper opSpecHelper ) : ModuleFactoryBase { @@ -61,7 +61,7 @@ IOPConfigHelper opConfigHelper private readonly ITxSealer _sealer = sealer ?? throw new ArgumentNullException(nameof(sealer)); private readonly IBlockFinder _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder)); private readonly IReceiptFinder _receiptFinder = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder)); - private readonly IOPConfigHelper _opConfigHelper = opConfigHelper ?? throw new ArgumentNullException(nameof(opConfigHelper)); + private readonly IOptimismSpecHelper _opSpecHelper = opSpecHelper ?? throw new ArgumentNullException(nameof(opSpecHelper)); public override IOptimismEthRpcModule Create() { @@ -84,7 +84,7 @@ public override IOptimismEthRpcModule Create() _accountStateProvider, _ecdsa, _sealer, - _opConfigHelper + _opSpecHelper ); } } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs index 7f42d0d76ca..c26ad0c5063 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Nethermind.Blockchain.Find; @@ -26,7 +25,7 @@ using Nethermind.TxPool; using Nethermind.Wallet; -namespace Nethermind.Optimism; +namespace Nethermind.Optimism.Rpc; public class OptimismEthRpcModule : EthRpcModule, IOptimismEthRpcModule { @@ -34,7 +33,7 @@ public class OptimismEthRpcModule : EthRpcModule, IOptimismEthRpcModule private readonly IAccountStateProvider _accountStateProvider; private readonly IEthereumEcdsa _ecdsa; private readonly ITxSealer _sealer; - private readonly IOPConfigHelper _opConfigHelper; + private readonly IOptimismSpecHelper _opSpecHelper; public OptimismEthRpcModule( IJsonRpcConfig rpcConfig, @@ -55,7 +54,7 @@ public OptimismEthRpcModule( IAccountStateProvider accountStateProvider, IEthereumEcdsa ecdsa, ITxSealer sealer, - IOPConfigHelper opConfigHelper) : base( + IOptimismSpecHelper opSpecHelper) : base( rpcConfig, blockchainBridge, blockFinder, @@ -74,12 +73,12 @@ public OptimismEthRpcModule( _accountStateProvider = accountStateProvider; _ecdsa = ecdsa; _sealer = sealer; - _opConfigHelper = opConfigHelper; + _opSpecHelper = opSpecHelper; } public new ResultWrapper eth_getBlockReceipts(BlockParameter blockParameter) { - static ResultWrapper GetBlockReceipts(IReceiptFinder receiptFinder, BlockParameter blockParameter, IBlockFinder blockFinder, ISpecProvider specProvider, IOPConfigHelper opConfigHelper) + static ResultWrapper GetBlockReceipts(IReceiptFinder receiptFinder, BlockParameter blockParameter, IBlockFinder blockFinder, ISpecProvider specProvider, IOptimismSpecHelper opSpecHelper) { SearchResult searchResult = blockFinder.SearchForBlock(blockParameter); if (searchResult.IsError) @@ -91,7 +90,7 @@ public OptimismEthRpcModule( OptimismTxReceipt[] receipts = receiptFinder.Get(block).Cast().ToArray() ?? new OptimismTxReceipt[block.Transactions.Length]; bool isEip1559Enabled = specProvider.GetSpec(block.Header).IsEip1559Enabled; - L1BlockGasInfo l1BlockGasInfo = new(block, opConfigHelper.IsRegolith(block!.Header)); + L1BlockGasInfo l1BlockGasInfo = new(block, opSpecHelper.IsRegolith(block!.Header)); OptimismReceiptForRpc[]? result = [.. receipts .Zip(block.Transactions, (r, t) => @@ -101,7 +100,7 @@ public OptimismEthRpcModule( return ResultWrapper.Success(result); } - return GetBlockReceipts(_receiptFinder, blockParameter, _blockFinder, _specProvider, _opConfigHelper); + return GetBlockReceipts(_receiptFinder, blockParameter, _blockFinder, _specProvider, _opSpecHelper); } public override async Task> eth_sendTransaction(TransactionForRpc rpcTx) @@ -154,7 +153,7 @@ public override async Task> eth_sendRawTransaction(byte[] Block block = foundBlock.Object; - L1BlockGasInfo l1GasInfo = new(block, _opConfigHelper.IsRegolith(block.Header)); + L1BlockGasInfo l1GasInfo = new(block, _opSpecHelper.IsRegolith(block.Header)); return ResultWrapper.Success( new(txHash, (OptimismTxReceipt)receipt, gasInfo.Value, l1GasInfo.GetTxGasInfo(block.Transactions.First(tx => tx.Hash == txHash)), logIndexStart)); } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPayloadAttributes.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismPayloadAttributes.cs similarity index 97% rename from src/Nethermind/Nethermind.Optimism/OptimismPayloadAttributes.cs rename to src/Nethermind/Nethermind.Optimism/Rpc/OptimismPayloadAttributes.cs index f1727be019c..8db3156fcae 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPayloadAttributes.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismPayloadAttributes.cs @@ -12,7 +12,7 @@ using Nethermind.Core.Specs; using Nethermind.Serialization.Rlp; -namespace Nethermind.Optimism; +namespace Nethermind.Optimism.Rpc; public class OptimismPayloadAttributes : PayloadAttributes { @@ -69,7 +69,7 @@ protected override int ComputePayloadIdMembersSize() => protected override int WritePayloadIdMembers(BlockHeader parentHeader, Span inputSpan) { - int offset = base.WritePayloadIdMembers(parentHeader, inputSpan); + var offset = base.WritePayloadIdMembers(parentHeader, inputSpan); inputSpan[offset] = NoTxPool ? (byte)1 : (byte)0; offset += 1; @@ -122,9 +122,7 @@ public override string ToString() .Append($"{nameof(Transactions)}: {Transactions?.Length ?? 0}"); if (Withdrawals is not null) - { sb.Append($", {nameof(Withdrawals)} count: {Withdrawals.Length}"); - } sb.Append('}'); return sb.ToString(); diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs index 2077279e73f..d902059872b 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismReceiptForRpc.cs @@ -7,7 +7,7 @@ using Nethermind.JsonRpc.Data; using System.Text.Json.Serialization; -namespace Nethermind.Optimism; +namespace Nethermind.Optimism.Rpc; public class OptimismReceiptForRpc : ReceiptForRpc { diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismTraceModuleFactory.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismTraceModuleFactory.cs new file mode 100644 index 00000000000..c6b8326ed4d --- /dev/null +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismTraceModuleFactory.cs @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Blockchain; +using Nethermind.Blockchain.Receipts; +using Nethermind.Consensus; +using Nethermind.Consensus.Processing; +using Nethermind.Consensus.Rewards; +using Nethermind.Consensus.Validators; +using Nethermind.Consensus.Withdrawals; +using Nethermind.Core.Specs; +using Nethermind.JsonRpc; +using Nethermind.JsonRpc.Modules.Trace; +using Nethermind.Logging; +using Nethermind.State; + +namespace Nethermind.Optimism.Rpc; + +public class OptimismTraceModuleFactory( + IWorldStateManager worldStateManager, + IBlockTree blockTree, + IJsonRpcConfig jsonRpcConfig, + IBlockPreprocessorStep recoveryStep, + IRewardCalculatorSource rewardCalculatorSource, + IReceiptStorage receiptFinder, + ISpecProvider specProvider, + IPoSSwitcher poSSwitcher, + ILogManager logManager, + IL1CostHelper l1CostHelper, + IOptimismSpecHelper opSpecHelper, + Create2DeployerContractRewriter contractRewriter, + IWithdrawalProcessor withdrawalProcessor) : TraceModuleFactory( + worldStateManager, + blockTree, + jsonRpcConfig, + recoveryStep, + rewardCalculatorSource, + receiptFinder, + specProvider, + poSSwitcher, + logManager) +{ + protected override ReadOnlyTxProcessingEnv CreateTxProcessingEnv() => + new OptimismReadOnlyTxProcessingEnv(_worldStateManager, _blockTree, _specProvider, _logManager, l1CostHelper, opSpecHelper); + + protected override ReadOnlyChainProcessingEnv CreateChainProcessingEnv(IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor, ReadOnlyTxProcessingEnv txProcessingEnv, IRewardCalculator rewardCalculator) => new OptimismReadOnlyChainProcessingEnv( + txProcessingEnv, + Always.Valid, + _recoveryStep, + rewardCalculator, + _receiptStorage, + _specProvider, + _logManager, + opSpecHelper, + contractRewriter, + withdrawalProcessor, + transactionsExecutor); +} diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs b/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs index ef449b940b1..c72ad28a6c6 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs @@ -4,6 +4,8 @@ using System; using Nethermind.Api; using Nethermind.Blockchain; +using Nethermind.Consensus.AuRa.Withdrawals; +using Nethermind.Consensus.Withdrawals; using Nethermind.Init.Steps; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Client; @@ -14,7 +16,7 @@ using Nethermind.TxPool; using Nethermind.Wallet; -namespace Nethermind.Optimism; +namespace Nethermind.Optimism.Rpc; public class RegisterOptimismRpcModules : RegisterRpcModules { @@ -87,4 +89,33 @@ protected override void RegisterEthRpcModule(IRpcModuleProvider rpcModuleProvide rpcModuleProvider.RegisterBounded(optimismEthModuleFactory, _jsonRpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, _jsonRpcConfig.Timeout); } + + protected override void RegisterTraceRpcModule(IRpcModuleProvider rpcModuleProvider) + { + StepDependencyException.ThrowIfNull(_api.WorldStateManager); + StepDependencyException.ThrowIfNull(_api.BlockTree); + StepDependencyException.ThrowIfNull(_api.ReceiptStorage); + StepDependencyException.ThrowIfNull(_api.RewardCalculatorSource); + StepDependencyException.ThrowIfNull(_api.SpecProvider); + StepDependencyException.ThrowIfNull(_api.WorldState); + StepDependencyException.ThrowIfNull(_api.L1CostHelper); + StepDependencyException.ThrowIfNull(_api.SpecHelper); + + OptimismTraceModuleFactory traceModuleFactory = new( + _api.WorldStateManager, + _api.BlockTree, + _jsonRpcConfig, + _api.BlockPreprocessor, + _api.RewardCalculatorSource, + _api.ReceiptStorage, + _api.SpecProvider, + _api.PoSSwitcher, + _api.LogManager, + _api.L1CostHelper, + _api.SpecHelper, + new Create2DeployerContractRewriter(_api.SpecHelper, _api.SpecProvider, _api.BlockTree), + new BlockProductionWithdrawalProcessor(new NullWithdrawalProcessor())); + + rpcModuleProvider.RegisterBoundedByCpuCount(traceModuleFactory, _jsonRpcConfig.Timeout); + } }