From e0743341ab93573375ae0966a31815369988d0e8 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 3 Apr 2023 13:01:14 +0100 Subject: [PATCH 001/213] Added frontend request receiving part Types from https://github.com/ethereum/execution-apis/pull/383/files#diff-a16a053e97d76abc119872eec30d015697dd307f4b3437b7ba4e74c4c6ae9dfeR1 are implemented --- .../Nethermind.Cli/Modules/EthCliModule.cs | 9 +++++ .../Proxy/EthJsonRpcClientProxy.cs | 9 +++++ .../Proxy/IEthJsonRpcClientProxy.cs | 4 +++ .../Proxy/Models/MultiCall/AccountOverride.cs | 33 +++++++++++++++++++ .../Models/MultiCall/AccountOverrideType.cs | 10 ++++++ .../Proxy/Models/MultiCall/BlockOverride.cs | 19 +++++++++++ .../Proxy/Models/MultiCall/Error.cs | 11 +++++++ .../Proxy/Models/MultiCall/Log.cs | 17 ++++++++++ .../MultiCallBlockStateCallsModel.cs | 11 +++++++ .../Models/MultiCall/MultiCallResultModel.cs | 32 ++++++++++++++++++ .../Proxy/Models/MultiCall/ResultType.cs | 11 +++++++ .../Modules/Eth/EthRpcModule.cs | 9 +++++ .../Modules/Eth/EthRpcModuleProxy.cs | 7 ++++ .../Modules/Eth/IEthRpcModule.cs | 15 +++++++++ 14 files changed, 197 insertions(+) create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverrideType.cs create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallResultModel.cs create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/ResultType.cs diff --git a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs index 656ac2129bd..2612275ae24 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs @@ -49,6 +49,15 @@ public JsValue GetProof(string address, string[] storageKeys, string? blockParam return NodeManager.Post("eth_call", tx, blockParameter ?? "latest").Result; } + //TODO: add tests + [CliFunction("eth", "multicall")] + public JsValue MultiCall(ulong version, object[] blockCalls, string? blockParameter = null) + { + return NodeManager.PostJint("eth_multicall", version, blockCalls, blockParameter ?? "latest").Result; + } + + + [CliFunction("eth", "getBlockByHash")] public JsValue GetBlockByHash(string hash, bool returnFullTransactionObjects) { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index db64a36898a..90ff839d578 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -7,6 +7,8 @@ using Nethermind.Core.Crypto; using Nethermind.Int256; using Nethermind.Facade.Proxy.Models; +using System.Transactions; +using Nethermind.Facade.Proxy.Models.MultiCall; namespace Nethermind.Facade.Proxy { @@ -38,6 +40,13 @@ public Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_call), transaction, MapBlockParameter(blockParameter)); + public Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, + BlockParameterModel blockParameter = null) + { + var data = blockCalls; + return _proxy.SendAsync(nameof(eth_multicall), version, blockCalls, MapBlockParameter(blockParameter)); + } + public Task> eth_getCode(Address address, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_getCode), address, MapBlockParameter(blockParameter)); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs index 9bd8e5adeeb..cd52b73b88a 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs @@ -6,6 +6,7 @@ using Nethermind.Core.Crypto; using Nethermind.Int256; using Nethermind.Facade.Proxy.Models; +using Nethermind.Facade.Proxy.Models.MultiCall; namespace Nethermind.Facade.Proxy { @@ -17,6 +18,9 @@ public interface IEthJsonRpcClientProxy Task> eth_getTransactionCount(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionReceipt(Keccak transactionHash); Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null); + + //TODO:add tests + Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameterModel blockParameter = null); Task> eth_getCode(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionByHash(Keccak transactionHash); Task> eth_pendingTransactions(); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs new file mode 100644 index 00000000000..e111816889d --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; +using Nethermind.Int256; +using Nethermind.State.Snap; + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public class AccountOverride +{ + public AccountOverrideType Type + { + get => State != null ? AccountOverrideType.AccountOverrideState : AccountOverrideType.AccountOverrideStateDiff; + } + + public bool IsState => Type == AccountOverrideType.AccountOverrideState; + public bool IsStateDiff => Type == AccountOverrideType.AccountOverrideStateDiff; + + /// AccountOverrideState and AccountOverrideStateDiff base + public Address Address { get; set; } + public UInt256 Nonce { get; set; } + + public UInt256 Balance { get; set; } + public byte[] Code { get; set; } + + //Storage for AccountOverrideState + public PathWithAccount? State { get; set; } + + //Storage difference for AccountOverrideStateDiff + public PathWithAccount? StateDiff { get; set; } + +} diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverrideType.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverrideType.cs new file mode 100644 index 00000000000..9af644688c0 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverrideType.cs @@ -0,0 +1,10 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public enum AccountOverrideType +{ + AccountOverrideState, + AccountOverrideStateDiff +} diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs new file mode 100644 index 00000000000..56a18dd30b4 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Int256; + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public class BlockOverride +{ + public Keccak PrevRandao { get; set; } = Keccak.Zero; + public UInt256 Number { get; set; } + public UInt256 Time { get; set; } + public UInt64 GasLimit { get; set; } + public Address FeeRecipient { get; set; } + public UInt256 BaseFee { get; set; } +} diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs new file mode 100644 index 00000000000..1c7656e97fe --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public class Error +{ + public int Code { get; set; } + public string Message { get; set; } + public string Data { get; set; } +} diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs new file mode 100644 index 00000000000..3c0d477cb11 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; +using Nethermind.Core.Crypto; + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public class Log +{ + public ulong LogIndex { get; set; } + public Keccak BlockHash { get; set; } + public ulong BlockNumber { get; set; } + public Address Address { get; set; } + public byte[] Data { get; set; } + public Keccak[] Topics { get; set; } +} diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs new file mode 100644 index 00000000000..5cda1bad8b9 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public class MultiCallBlockStateCallsModel +{ + public BlockOverride BlockOverride { get; set; } + public AccountOverride[] StateOverrides { get; set; } + public CallTransactionModel[] Calls { get; set; } +} diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallResultModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallResultModel.cs new file mode 100644 index 00000000000..07b5d52367b --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallResultModel.cs @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public class MultiCallResultModel +{ + public ResultType Type + { + get + { + if (Logs != null) + { + return ResultType.Success; + } + + if (Return != null && Error != null) + { + return ResultType.Failure; + } + return ResultType.Invalid; + } + } + + public string Status { get; set; } + public byte[]? Return { get; set; } + public ulong? GasUsed { get; set; } + + public Error? Error { get; set; } + public Log[]? Logs { get; set; } + +} diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/ResultType.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/ResultType.cs new file mode 100644 index 00000000000..42788b77621 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/ResultType.cs @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public enum ResultType +{ + Failure, + Success, + Invalid +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 23163672fc0..ce28dc4a714 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -18,6 +18,7 @@ using Nethermind.Facade; using Nethermind.Facade.Eth; using Nethermind.Facade.Filters; +using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth.FeeHistory; @@ -366,6 +367,14 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); + public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, + BlockParameter? blockParameter = null) + { + var data = blockCalls; + + throw new NotImplementedException(); + } + public ResultWrapper eth_estimateGas(TransactionForRpc transactionCall, BlockParameter blockParameter) => new EstimateGasTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs index c4bfa1fcbc8..115c24c752a 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs @@ -12,6 +12,7 @@ using Nethermind.Facade.Filters; using Nethermind.Facade.Proxy; using Nethermind.Facade.Proxy.Models; +using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.Serialization.Rlp; @@ -156,6 +157,12 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa throw new NotSupportedException(); } + public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, + BlockParameter? blockParameter = null) + { + throw new NotImplementedException(); + } + public ResultWrapper eth_estimateGas( TransactionForRpc transactionCall, BlockParameter? blockParameter = null) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index bf844a5d701..8918daf75a4 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -8,6 +8,9 @@ using Nethermind.Core.Crypto; using Nethermind.Facade.Eth; using Nethermind.Facade.Filters; +using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models; +using Nethermind.Facade.Proxy; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.State.Proofs; @@ -148,6 +151,18 @@ public interface IEthRpcModule : IRpcModule 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 (does not create a transaction)", + IsSharable = false, + ExampleResponse = "0x")] + ResultWrapper eth_multicall( + ulong version, + [JsonRpcParameter(ExampleValue = "[{\"stateOverrides\":[{\"nonce\":\"0x1\", \"address\": \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\", \"balance\": \"0xde0b6b3a7640000\", \"state\": {\"0x2292f0db49e1af24fbcac7f32b7537f334244455ad0ed0b46a78202982e7b70d\": \"0xde0b6b3a7640000\", \"0x0x877bd4632ef8c8ddc43b67e5a4511d939eadb612553c8a060670e05ebb1bb83c\": \"0xde0b6b3a7640000\"}}],\"calls\":[{\"from\":\"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"to\":\"0x6b175474e89094c44da98b954eedeac495271d0f\",\"data\":\"0x18160ddd\"}]}]")] + MultiCallBlockStateCallsModel[] blockCalls, + BlockParameter? blockParameter = null); + + [JsonRpcMethod(IsImplemented = true, Description = "Executes a tx call and returns gas used (does not create a transaction)", IsSharable = false, From c19c6be7481be12459e5c323fe7c372f0fac0108 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 8 May 2023 07:03:25 +0100 Subject: [PATCH 002/213] Implementation of in memory chain fork Unit tests fail on StateProvider not seeing account for "write" in generated DB, while providing its info details of RPC calls. --- .../Blockchain/TestBlockchain.cs | 12 +- src/Nethermind/Nethermind.Db/ReadOnlyDb.cs | 5 +- .../Proxy/EthJsonRpcClientProxy.cs | 1 - .../Proxy/Models/MultiCall/AccountOverride.cs | 5 +- .../Modules/Eth/EthRpcMulticallTests.cs | 157 ++++++++ .../Eth/EthModule.TransactionExecutor.cs | 33 ++ .../Modules/Eth/EthRpcModule.cs | 9 +- .../Modules/Eth/EthRpcModuleProxy.cs | 2 +- .../Modules/Eth/IEthRpcModule.cs | 2 +- .../Eth/Multicall/MultiCallBlockchainFork.cs | 357 ++++++++++++++++++ 10 files changed, 568 insertions(+), 15 deletions(-) create mode 100644 src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs create mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index 80b4e93ed7b..7cedc35e3a0 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -8,6 +8,7 @@ using Nethermind.Blockchain; using Nethermind.Blockchain.Find; using Nethermind.Blockchain.Receipts; +using Nethermind.Blockchain.Synchronization; using Nethermind.Config; using Nethermind.Consensus; using Nethermind.Consensus.Comparers; @@ -136,10 +137,13 @@ protected virtual async Task Build(ISpecProvider? specProvider = ReadOnlyTrieStore = TrieStore.AsReadOnly(StateDb); StateReader = new StateReader(ReadOnlyTrieStore, CodeDb, LogManager); - IDb blockDb = new MemDb(); - IDb headerDb = new MemDb(); - IDb blockInfoDb = new MemDb(); - BlockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), SpecProvider, NullBloomStorage.Instance, LimboLogs.Instance); + IDb blockDb = DbProvider.BlocksDb; + IDb headerDb = DbProvider.HeadersDb; + IDb blockInfoDb = DbProvider.BlockInfosDb; + IDb metadataDb = DbProvider.MetadataDb; + SyncConfig syncConfig = new(); + BlockTree = new BlockTree(blockDb, headerDb, blockInfoDb, metadataDb, new ChainLevelInfoRepository(blockInfoDb), + SpecProvider, NullBloomStorage.Instance, syncConfig, LimboLogs.Instance); ReadOnlyState = new ChainHeadReadOnlyStateProvider(BlockTree, StateReader); TransactionComparerProvider = new TransactionComparerProvider(SpecProvider, BlockTree); TxPool = CreateTxPool(); diff --git a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs index c3776e1f861..e701774a698 100644 --- a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs +++ b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Nethermind.Core; namespace Nethermind.Db @@ -60,9 +61,9 @@ public KeyValuePair[] this[byte[][] keys] } } - public IEnumerable> GetAll(bool ordered = false) => _memDb.GetAll(); + public IEnumerable> GetAll(bool ordered = false) => _memDb.GetAll().Union(_wrappedDb.GetAll()); - public IEnumerable GetAllValues(bool ordered = false) => _memDb.GetAllValues(); + public IEnumerable GetAllValues(bool ordered = false) => _memDb.GetAllValues().Union(_wrappedDb.GetAllValues()); public IBatch StartBatch() { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index 90ff839d578..18618e08ee1 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -43,7 +43,6 @@ public Task> eth_call(CallTransactionModel transaction, public Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameterModel blockParameter = null) { - var data = blockCalls; return _proxy.SendAsync(nameof(eth_multicall), version, blockCalls, MapBlockParameter(blockParameter)); } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs index e111816889d..27f9c1b3d3d 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.Collections.Generic; using Nethermind.Core; using Nethermind.Int256; using Nethermind.State.Snap; @@ -25,9 +26,9 @@ public AccountOverrideType Type public byte[] Code { get; set; } //Storage for AccountOverrideState - public PathWithAccount? State { get; set; } + public Dictionary? State { get; set; } //Storage difference for AccountOverrideStateDiff - public PathWithAccount? StateDiff { get; set; } + public Dictionary? StateDiff { get; set; } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs new file mode 100644 index 00000000000..81d82f6fcb4 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -0,0 +1,157 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using FluentAssertions; +using Nethermind.Blockchain.Find; +using Nethermind.Core.Crypto; +using Nethermind.Core; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Core.Test.Builders; +using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Int256; +using Nethermind.JsonRpc.Modules.Eth.Multicall; +using Nethermind.Specs; +using Nethermind.Specs.Forks; +using Nethermind.State; +using NUnit.Framework; +using Nethermind.Blockchain; + +namespace Nethermind.JsonRpc.Test.Modules.Eth; + +public class EthRpcMulticallTests +{ + private static Task CreateChain(IReleaseSpec? releaseSpec = null, + UInt256? initialBaseFeePerGas = null) + { + TestRpcBlockchain testMevRpcBlockchain = new(); + TestSpecProvider testSpecProvider = releaseSpec is not null + ? new TestSpecProvider(releaseSpec) + : new TestSpecProvider(London.Instance); + return TestRpcBlockchain.ForTest(testMevRpcBlockchain).Build(testSpecProvider); + } + + private static void allocateAccounts(MultiCallBlockStateCallsModel requestBlockOne, IStateProvider _stateProvider, + IReleaseSpec latestBlockSpec, ISpecProvider _specProvider, IStorageProvider _storageProvider) + { + foreach (var accountOverride in requestBlockOne.StateOverrides) + { + var address = accountOverride.Address; + var acc = _stateProvider.GetAccount(address); + if (acc == null) + { + _stateProvider.CreateAccount(address, accountOverride.Balance, accountOverride.Nonce); + acc = _stateProvider.GetAccount(address); + } + + var t = acc.Balance; + _stateProvider.SubtractFromBalance(address, 666, latestBlockSpec); + + if (acc != null) + { + if (accountOverride.Code is not null) + { + Keccak codeHash = _stateProvider.UpdateCode(accountOverride.Code); + _stateProvider.UpdateCodeHash(address, codeHash, + latestBlockSpec, true); + } + } + + + if (accountOverride.State is not null) + { + foreach (KeyValuePair storage in accountOverride.State) + { + _storageProvider.Set(new StorageCell(address, storage.Key), + storage.Value.WithoutLeadingZeros().ToArray()); + } + } + + if (accountOverride.StateDiff is not null) + { + foreach (KeyValuePair storage in accountOverride.StateDiff) + { + _storageProvider.Set(new StorageCell(address, storage.Key), + storage.Value.WithoutLeadingZeros().ToArray()); + } + } + } + } + + /// + /// This test verifies that a temporary forked blockchain updates the user balance and block number + /// independently of the main chain, ensuring the main chain remains intact. + /// + [Test] + public async Task Test_eth_multicall() + { + var chain = await CreateChain(); + + var requestBlockOne = new MultiCallBlockStateCallsModel(); + requestBlockOne.StateOverrides = new[] { + new AccountOverride() + { + Address = TestItem.AddressA, + Balance = UInt256.One + } + }; + + var blockNumberBefore = chain.BlockFinder.Head.Number; + var userBalanceBefore = await chain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); + userBalanceBefore.Result.ResultType.Should().Be(Core.ResultType.Success); + + //Force persistancy of head block in main chain + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + + var tt = chain.TrieStore; + + using (var tmpChain =new MultiCallBlockchainFork(chain.DbProvider, chain.SpecProvider)) + { + //Check if tmpChain initialised + Assert.AreEqual(chain.BlockTree.BestKnownNumber, tmpChain.BlockTree.BestKnownNumber); + Assert.AreEqual(chain.BlockFinder.BestPersistedState, tmpChain.BlockFinder.BestPersistedState); + Assert.AreEqual(chain.BlockFinder.Head.Number, tmpChain.BlockFinder.Head.Number); + + //Check if tmpChain RPC initialised + var userBalanceBefore_fromTmp = + await tmpChain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); + userBalanceBefore_fromTmp.Result.ResultType.Should().Be(Core.ResultType.Success); + + //Check if tmpChain shows same values as main one + var num_real = userBalanceBefore.Data.Value; + var num_tmp = userBalanceBefore_fromTmp.Data.Value; + Assert.AreEqual(userBalanceBefore_fromTmp.Data, userBalanceBefore.Data); + + var processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, storageProvider) => + { + allocateAccounts(requestBlockOne, stateProvider, currentSpec, specProvider, + storageProvider); + }); + + //Check block has been added to chain as main + Assert.True(processed); + + //Check block has updated values in tmp chain + var userBalanceResult_fromTm = + await tmpChain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); + userBalanceResult_fromTm.Result.ResultType.Should().Be(Core.ResultType.Success); + Assert.AreNotEqual(userBalanceResult_fromTm.Data, userBalanceBefore.Data); + + //Check block has not updated values in the main chain + var userBalanceResult = await chain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); + userBalanceResult.Result.ResultType.Should().Be(Core.ResultType.Success); + Assert.AreEqual(userBalanceResult.Data, userBalanceBefore.Data); //Main chain is intact + Assert.AreNotEqual(userBalanceResult.Data, userBalanceResult_fromTm.Data); // Balance was changed + Assert.AreNotEqual(chain.BlockFinder.Head.Number, tmpChain.LatestBlock.Number); // Block number changed + } + + GC.Collect(); + GC.WaitForFullGCComplete(); + + Assert.Equals(chain.BlockFinder.Head.Number, + blockNumberBefore); // tmp chain is disposed, main chain block number is still the same + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index 21bd58a7fb1..02530d1ba76 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -9,8 +9,10 @@ using Nethermind.Core.Extensions; using Nethermind.Evm; using Nethermind.Facade; +using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; +using Nethermind.Specs; using Nethermind.Specs.Forks; namespace Nethermind.JsonRpc.Modules.Eth @@ -82,6 +84,37 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, Transacti } } + private class MultiCallTxExecutor + { + public MultiCallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) + { + + } + + public ResultWrapper Execute(ulong version, MultiCallBlockStateCallsModel[] blockCalls, + BlockParameter? blockParameter) + { + + + throw new NotImplementedException(); + + /* + BlockchainBridge.CallOutput result = _blockchainBridge.Call(header, tx, token); + + if (result.Error is null) + { + return ResultWrapper.Success(result.OutputData.ToHexString(true)); + } + + return result.InputError + ? GetInputError(result) + : ResultWrapper.Fail("VM execution error.", ErrorCodes.ExecutionError, result.Error); + */ + } + + + } + private class EstimateGasTxExecutor : TxExecutor { public EstimateGasTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index ce28dc4a714..46c188ad471 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -367,13 +367,14 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); - public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, + public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null) { - var data = blockCalls; - - throw new NotImplementedException(); + return new MultiCallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) + .Execute(version, blockCalls, blockParameter); } + + public ResultWrapper eth_estimateGas(TransactionForRpc transactionCall, BlockParameter blockParameter) => new EstimateGasTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs index 115c24c752a..7c43c7b6d55 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs @@ -157,7 +157,7 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa throw new NotSupportedException(); } - public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, + public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null) { throw new NotImplementedException(); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 8918daf75a4..f155e6df0c8 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -156,7 +156,7 @@ public interface IEthRpcModule : IRpcModule Description = "Executes a tx call (does not create a transaction)", IsSharable = false, ExampleResponse = "0x")] - ResultWrapper eth_multicall( + ResultWrapper eth_multicall( ulong version, [JsonRpcParameter(ExampleValue = "[{\"stateOverrides\":[{\"nonce\":\"0x1\", \"address\": \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\", \"balance\": \"0xde0b6b3a7640000\", \"state\": {\"0x2292f0db49e1af24fbcac7f32b7537f334244455ad0ed0b46a78202982e7b70d\": \"0xde0b6b3a7640000\", \"0x0x877bd4632ef8c8ddc43b67e5a4511d939eadb612553c8a060670e05ebb1bb83c\": \"0xde0b6b3a7640000\"}}],\"calls\":[{\"from\":\"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"to\":\"0x6b175474e89094c44da98b954eedeac495271d0f\",\"data\":\"0x18160ddd\"}]}]")] MultiCallBlockStateCallsModel[] blockCalls, diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs new file mode 100644 index 00000000000..c178d813f17 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -0,0 +1,357 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Linq; +using System.Threading.Tasks; +using Jint.Parser; +using Nethermind.Blockchain; +using Nethermind.Blockchain.Filters; +using Nethermind.Blockchain.Find; +using Nethermind.Blockchain.Receipts; +using Nethermind.Blockchain.Synchronization; +using Nethermind.Config; +using Nethermind.Consensus; +using Nethermind.Consensus.Comparers; +using Nethermind.Consensus.Processing; +using Nethermind.Consensus.Rewards; +using Nethermind.Consensus.Validators; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; +using Nethermind.Crypto; +using Nethermind.Db; +using Nethermind.Db.Blooms; +using Nethermind.Evm; +using Nethermind.Evm.Tracing; +using Nethermind.Evm.TransactionProcessing; +using Nethermind.Facade; +using Nethermind.Facade.Eth; +using Nethermind.JsonRpc.Modules.Eth.FeeHistory; +using Nethermind.JsonRpc.Modules.Eth.GasPrice; +using Nethermind.Logging; +using Nethermind.State; +using Nethermind.State.Repositories; +using Nethermind.Trie.Pruning; +using Nethermind.TxPool; +using Nethermind.Wallet; + +namespace Nethermind.JsonRpc.Modules.Eth.Multicall; + +/// +/// The MultiCallBlockchainFork class enables the creation of temporary in-memory blockchain instances, +/// based on a base chain's state. It's useful for simulating transactions, testing, +/// and executing smart contracts without affecting the base chain. The class offers RPC, +/// StateProvider, and StorageProvider utilities for swift chain data manipulation +/// and supports multi-block chain simulations using CreateBlock/FinaliseBlock pair manually or ForgeChainBlock method. +/// +public class MultiCallBlockchainFork : IDisposable +{ + private BlockchainProcessor ChainProcessor { get; set; } + + public StateProvider StateProvider { get; internal set; } + public StorageProvider StorageProvider { get; internal set; } + public ISpecProvider SpecProvider { get; internal set; } + public IBlockTree BlockTree { get; set; } + public IBlockFinder BlockFinder + { + get => BlockTree; + } + public Block? LatestBlock { get => BlockFinder.Head; } + + public EthRpcModule EthRpcModule { get; internal set; } + public IReleaseSpec CurrentSpec { get => SpecProvider.GetSpec(LatestBlock!.Header); } + + /// + /// Creates a MultiCallBlockchainFork instance with the following steps: + /// 1. Initialize MultiCallBlockchainFork object + /// 2. Create read-only in-memory databases + /// 3. Set spec provider + /// 4. Set up log manager + /// 5. Establish EthereumEcdsa + /// 6. Configure TrieStore, StateProvider, and StorageProvider + /// 7. Prepare state reader + /// 8. Instantiate BlockTree + /// 9. Launch read-only state provider + /// 10. Create transaction comparer provider and transaction pool + /// 11. Start receipt storage + /// 12. Initialize virtual machine + /// 13. Initialize transaction processor and block preprocessor step + /// 14. Initialize header and block validators + /// 15. Initialize block processor + /// 16. Initialize and start chain processor + /// 17. Create and initialize temp database provider for RPC calls + /// 18. Initialize filter store and manager + /// 19. Set up read-only processing environment + /// 20. Initialize Bloom storage and log finder + /// 21. Set up timestamper, blockchain bridge, and gas price oracle + /// 22. Configure fee history oracle and sync config + /// 23. Initialize nonce manager, wallet, and transaction signer + /// 24. Create transaction sealer and sender + /// 25. Set up EthRpcModule + /// + /// Current state database + /// Current Block database + /// Current Header database + /// Current Block information database + /// Current Code database + /// Specification provider (optional) + /// MultiCallBlockchainFork instance + public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProvider) + { + //Init BlockChain + //Writable inMemory DBs on with access to the data of existing ones (will not modify existing data) + if (oldDbProvider == null) + { + throw new ArgumentNullException(); + } + + var oldStack = oldDbProvider.StateDb.GetAllValues().ToList(); + IDb inMemStateDb = new ReadOnlyDb(oldDbProvider.StateDb, true); + IDb inMemBlockDb = new ReadOnlyDb(oldDbProvider.BlocksDb, true); + IDb inMemHeaderDb = new ReadOnlyDb(oldDbProvider.HeadersDb, true); + IDb inMemBlockInfoDb = new ReadOnlyDb(oldDbProvider.BlockInfosDb, true); + IDb inMemCodeDb = new ReadOnlyDb(oldDbProvider.CodeDb, true); + IDb inMemMetadataDb = new ReadOnlyDb(oldDbProvider.MetadataDb, true); + + DbProvider dbProvider = new(DbModeHint.Mem); + DbProvider = dbProvider; + + dbProvider.RegisterDb(DbNames.State, inMemStateDb); + dbProvider.RegisterDb(DbNames.Blocks, inMemBlockDb); + dbProvider.RegisterDb(DbNames.Headers, inMemHeaderDb); + dbProvider.RegisterDb(DbNames.BlockInfos, inMemBlockInfoDb); + dbProvider.RegisterDb(DbNames.Code, inMemCodeDb); + dbProvider.RegisterDb(DbNames.Metadata, inMemMetadataDb); + + SpecProvider = specProvider; + + ILogManager logManager = SimpleConsoleLogManager.Instance; + + var newStack = inMemStateDb.GetAllValues().ToList(); + TrieStore trieStore = new(inMemStateDb, logManager); + StateProvider = new(trieStore, inMemCodeDb, logManager); + StorageProvider = new(trieStore, StateProvider, logManager); + + IReadOnlyTrieStore readOnlyTrieStore = trieStore.AsReadOnly(inMemStateDb); + StateReader stateReader = new(readOnlyTrieStore, inMemCodeDb, logManager); + SyncConfig syncConfig = new(); + BlockTree = new BlockTree(inMemBlockDb, + inMemHeaderDb, + inMemBlockInfoDb, + inMemMetadataDb, + new ChainLevelInfoRepository(inMemBlockInfoDb), + SpecProvider, + NullBloomStorage.Instance, + syncConfig, + LimboLogs.Instance); + + ChainHeadReadOnlyStateProvider readOnlyState = new(BlockTree, stateReader); + + TransactionComparerProvider transactionComparerProvider = new(SpecProvider, BlockTree); + + EthereumEcdsa ethereumEcdsa = new(SpecProvider.ChainId, logManager); + + Nethermind.TxPool.TxPool txPool = new( + ethereumEcdsa, + new ChainHeadInfoProvider( + SpecProvider, + BlockTree, + readOnlyState), + new TxPoolConfig(), + new TxValidator(SpecProvider.ChainId), + logManager, + transactionComparerProvider.GetDefaultComparer()); + + InMemoryReceiptStorage receiptStorage = new(); + + VirtualMachine virtualMachine = new( + new BlockhashProvider(BlockTree, logManager), + SpecProvider, + logManager); + + TransactionProcessor txProcessor = new(SpecProvider, StateProvider, StorageProvider, virtualMachine, logManager); + RecoverSignatures blockPreprocessorStep = new(ethereumEcdsa, txPool, SpecProvider, logManager); + + HeaderValidator headerValidator = new( + BlockTree, + Always.Valid, + SpecProvider, + logManager); + + BlockValidator blockValidator = new(new TxValidator(SpecProvider.ChainId), + headerValidator, + Always.Valid, + SpecProvider, + logManager); + + BlockProcessor blockProcessor = new(SpecProvider, + blockValidator, + NoBlockRewards.Instance, + new BlockProcessor.BlockValidationTransactionsExecutor(txProcessor, StateProvider), + StateProvider, + StorageProvider, + receiptStorage, + NullWitnessCollector.Instance, + logManager); + + ChainProcessor = new( + BlockTree, + blockProcessor, + blockPreprocessorStep, + stateReader, + logManager, + BlockchainProcessor.Options.Default); + ChainProcessor.Start(); + + //Init RPC + IFilterStore filterStore = new FilterStore(); + IFilterManager filterManager = + new FilterManager(filterStore, blockProcessor, txPool, LimboLogs.Instance); + ReadOnlyTxProcessingEnv processingEnv = new( + new ReadOnlyDbProvider(DbProvider, false), + new TrieStore(DbProvider.StateDb, LimboLogs.Instance).AsReadOnly(), + new ReadOnlyBlockTree(BlockTree), + SpecProvider, + LimboLogs.Instance); + + BloomStorage bloomStorage = + new(new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory()); + ReceiptsRecovery receiptsRecovery = + new(new EthereumEcdsa(SpecProvider.ChainId, LimboLogs.Instance), SpecProvider); + IReceiptFinder receiptFinder = receiptStorage; + LogFinder logFinder = new(BlockTree, receiptStorage, receiptStorage, bloomStorage, + LimboLogs.Instance, receiptsRecovery); + ITimestamper timestamper = Timestamper.Default; + + + BlockchainBridge bridge = new(processingEnv, + txPool, + receiptFinder, + filterStore, + filterManager, + ethereumEcdsa, + timestamper, + logFinder, + SpecProvider, + new BlocksConfig(), + false); + + GasPriceOracle gasPriceOracle = new(BlockFinder, SpecProvider, logManager); + FeeHistoryOracle feeHistoryOracle = + new(BlockFinder, receiptStorage, SpecProvider); + IChainHeadInfoProvider chainHeadInfoProvider = + new ChainHeadInfoProvider(SpecProvider, BlockTree, stateReader); + NonceManager nonceManager = new(chainHeadInfoProvider.AccountStateProvider); + NullWallet? wallet = NullWallet.Instance; // May be use one from API directly? + ITxSigner txSigner = new WalletTxSigner(wallet, SpecProvider.ChainId); + TxSealer txSealer = new(txSigner, timestamper); + TxPoolSender txSender = new(txPool, txSealer, nonceManager, ethereumEcdsa); + + EthRpcModule = new EthRpcModule( + new JsonRpcConfig(), + bridge, + BlockFinder, + stateReader, + txPool, + txSender, + wallet, + receiptFinder, + LimboLogs.Instance, + SpecProvider, + gasPriceOracle, + new EthSyncingInfo(BlockTree, receiptStorage, syncConfig, logManager), + feeHistoryOracle); + + } + + public IDbProvider DbProvider { get; set; } + + //Create a new block next to current LatestBlock (BlockFinder.Head) + public Block CreateBlock() + { + var parent = LatestBlock?.Header; + if (parent == null) + throw new Exception("Existing header expected"); + Keccak? headerHash = parent.Hash; + + + BlockHeader blockHeader = new( + parent.Hash, + Keccak.OfAnEmptySequenceRlp, + Address.Zero, + parent.Difficulty, parent.Number + 1, + parent.GasLimit, + parent.Timestamp + 1, + Array.Empty()); + + + return new Block(blockHeader); + } + + //Process Block and UpdateMainChain with it + public bool FinalizeBlock(Block CurrentBlock) + { + StorageProvider.Commit(); + StorageProvider.CommitTrees(CurrentBlock.Number); + StateProvider.CommitTree(CurrentBlock.Number); + CurrentBlock.Header.StateRoot = StateProvider.StateRoot; + CurrentBlock.Header.Hash = CurrentBlock.Header.CalculateHash(); + + AddBlockResult res = BlockTree.SuggestBlock(CurrentBlock, BlockTreeSuggestOptions.ForceSetAsMain); + if (res != AddBlockResult.Added) return false; + + Block? current = ChainProcessor.Process(CurrentBlock!, ProcessingOptions.None, NullBlockTracer.Instance); //TODo: Maybe Trace!! + if (current == null) return false; + + BlockTree.UpdateMainChain(new[] { current }, true); + return true; + } + + /// + /// Forges a new block in the temp blockchain using the provided action to manipulate state, release spec, spec provider, and storage provider. + /// + /// An action representing the modifications to the blockchain state and storage. + public bool ForgeChainBlock(Action action) + { + //Prepare a block + var newBlock = CreateBlock(); + var tt = StateProvider.StateRoot; + var ttt = newBlock.Header.StateRoot; + //newBlock.Header.s + //Actual stuff + action(StateProvider, + CurrentSpec, + SpecProvider, + StorageProvider); + + //Add block + bool results = FinalizeBlock(newBlock); + return results; + } + + //For using scope guard + #region IDisposable + + private bool _disposed; + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + _disposed = true; + DbProvider?.Dispose(); + } + } + + ~MultiCallBlockchainFork() + { + Dispose(false); + } + #endregion +} From f9e99ac10b4c4216dfc0d232a61258c1f6647c8d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 8 May 2023 12:40:17 +0100 Subject: [PATCH 003/213] Keeping up with master merge --- .github/workflows/build-secp256k1-libs.yml | 77 -- Dockerfile.secp256k1 | 19 - src/Nethermind/Chains/shandong.json | 928 ------------------ src/Nethermind/Chains/withdrawals_devnet.json | 892 ----------------- .../Chains/withdrawals_hivetests.json | 200 ---- src/Nethermind/Chains/withdrawals_test.json | 69 -- src/Nethermind/Chains/zhejiang.json | 896 ----------------- .../Eip3651Tests.cs | 28 - .../Eip3855Tests.cs | 26 - .../Eip3860Tests.cs | 26 - .../WithdrawalsTests.cs | 26 - .../LoadLocalTestsStrategy.cs | 49 - .../Contract.ConstantContract.cs | 98 -- .../Nethermind.Abi.Contracts/Contract.cs | 194 ---- 14 files changed, 3528 deletions(-) delete mode 100644 .github/workflows/build-secp256k1-libs.yml delete mode 100644 Dockerfile.secp256k1 delete mode 100644 src/Nethermind/Chains/shandong.json delete mode 100644 src/Nethermind/Chains/withdrawals_devnet.json delete mode 100644 src/Nethermind/Chains/withdrawals_hivetests.json delete mode 100644 src/Nethermind/Chains/withdrawals_test.json delete mode 100644 src/Nethermind/Chains/zhejiang.json delete mode 100644 src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3651Tests.cs delete mode 100644 src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3855Tests.cs delete mode 100644 src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3860Tests.cs delete mode 100644 src/Nethermind/Ethereum.Blockchain.Block.Test/WithdrawalsTests.cs delete mode 100644 src/Nethermind/Ethereum.Test.Base/LoadLocalTestsStrategy.cs delete mode 100644 src/Nethermind/Nethermind.Abi.Contracts/Contract.ConstantContract.cs delete mode 100644 src/Nethermind/Nethermind.Abi.Contracts/Contract.cs diff --git a/.github/workflows/build-secp256k1-libs.yml b/.github/workflows/build-secp256k1-libs.yml deleted file mode 100644 index 5af2957957c..00000000000 --- a/.github/workflows/build-secp256k1-libs.yml +++ /dev/null @@ -1,77 +0,0 @@ -name: '[BUILD] Secp256k1 Libraries' - -on: - workflow_dispatch: - -jobs: - build-secp256k1: - name: Building Secp256k1 - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [windows-latest, macOS-latest, ubuntu-latest] - steps: - - name: Cloning secp256k1 repository - run: | - git clone https://github.com/NethermindEth/secp256k1 - - name: Building secp256k1 for Linux - if: matrix.os == 'ubuntu-latest' - run: | - sudo apt-get install autoconf libtool - cd secp256k1/ - ./autogen.sh - ./configure --enable-module-recovery --enable-experimental --enable-module-ecdh --enable-shared --with-bignum=no - make -j8 - strip .libs/libsecp256k1.so - - uses: actions/upload-artifact@v1 - name: Uploading Linux artifact - if: matrix.os == 'ubuntu-latest' - with: - name: linux_artifact_secp256k1 - path: secp256k1/.libs/libsecp256k1.so - - name: Building secp256k1 for OSX - if: matrix.os == 'macOS-latest' - run: | - brew install automake - brew install libtool - brew install gmp - cd secp256k1/ - ./autogen.sh - ./configure --enable-module-recovery --enable-experimental --enable-module-ecdh --enable-shared --with-bignum=no - make -j8 - - uses: actions/upload-artifact@v1 - name: Uploading Darwin artifact - if: matrix.os == 'macOS-latest' - with: - name: darwin_artifact_secp256k1 - path: secp256k1/.libs/libsecp256k1.dylib - - uses: msys2/setup-msys2@v2 - if: matrix.os == 'windows-latest' - with: - update: true - install: autoconf libtool make automake gcc mingw-w64-x86_64-gcc base-devel - name: Setting up msys2 for Windows - - run: | - cat <> run.sh - mv secp256k1 64bit - cd 64bit - ./autogen.sh - echo "LDFLAGS = -no-undefined" >> Makefile.am - ./configure --host=x86_64-w64-mingw32 --enable-module-recovery --enable-experimental --enable-module-ecdh --enable-shared --with-bignum=no - make -j8 - strip .libs/libsecp256k1-0.dll - mv .libs/libsecp256k1-0.dll .libs/secp256k1.dll - EOT - if: matrix.os == 'windows-latest' - name: Creating script for secp256k1 build - shell: bash - - run: ./run.sh - if: matrix.os == 'windows-latest' - shell: msys2 {0} - name: Running secp256k1 build for Windows x64 - - uses: actions/upload-artifact@v1 - name: Uploading Windows artifact - if: matrix.os == 'windows-latest' - with: - name: windows_artifact_secp256k1 - path: 64bit/.libs/secp256k1.dll diff --git a/Dockerfile.secp256k1 b/Dockerfile.secp256k1 deleted file mode 100644 index 516b468cbe5..00000000000 --- a/Dockerfile.secp256k1 +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -# SPDX-License-Identifier: LGPL-3.0-only - -FROM debian@sha256:acf7795dc91df17e10effee064bd229580a9c34213b4dba578d64768af5d8c51 AS secp256k1 -WORKDIR /source - -RUN apt-get update && apt-get install -y git autoconf automake libtool build-essential - -RUN git clone https://github.com/NethermindEth/secp256k1 . && \ - ./autogen.sh && \ - ./configure --enable-module-recovery --enable-experimental --enable-module-ecdh --enable-shared --with-bignum=no && \ - make -j16 - -RUN strip .libs/libsecp256k1.so - - -FROM debian@sha256:acf7795dc91df17e10effee064bd229580a9c34213b4dba578d64768af5d8c51 AS libsecp256k1 -WORKDIR /nethermind -COPY --from=secp256k1 /source/.libs/libsecp256k1.so . diff --git a/src/Nethermind/Chains/shandong.json b/src/Nethermind/Chains/shandong.json deleted file mode 100644 index c0815117d48..00000000000 --- a/src/Nethermind/Chains/shandong.json +++ /dev/null @@ -1,928 +0,0 @@ -{ - "name": "shandong", - "engine": { - "Ethash": { - "params": { - "minimumDifficulty": "0x20000", - "difficultyBoundDivisor": "0x800", - "durationLimit": "0xd", - "blockReward": { - "0x0": "0x1BC16D674EC80000" - }, - "homesteadTransition": "0x0", - "eip100bTransition": "0x0", - "difficultyBombDelays": {} - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x400", - "registrar": "0x0000000000000000000000000000000000000000", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID": "0x00146A2E", - "MergeForkIdTransition": "0x0", - "maxCodeSize": "0x6000", - "maxCodeSizeTransition": "0x0", - "eip150Transition": "0x0", - "eip158Transition": "0x0", - "eip160Transition": "0x0", - "eip161abcTransition": "0x0", - "eip161dTransition": "0x0", - "eip155Transition": "0x0", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0", - "eip145Transition": "0x0", - "eip1014Transition": "0x0", - "eip1052Transition": "0x0", - "eip1283Transition": "0x0", - "eip1283DisableTransition": "0x0", - "eip152Transition": "0x0", - "eip1108Transition": "0x0", - "eip1344Transition": "0x0", - "eip1884Transition": "0x0", - "eip2028Transition": "0x0", - "eip2200Transition": "0x0", - "eip2565Transition": "0x0", - "eip2929Transition": "0x0", - "eip2930Transition": "0x0", - "eip1559Transition": "0x0", - "eip3198Transition": "0x0", - "eip3529Transition": "0x0", - "eip3541Transition": "0x0", - "eip3540TransitionTimestamp": "0x0", - "eip3651TransitionTimestamp": "0x0", - "eip3670TransitionTimestamp": "0x0", - "eip3855TransitionTimestamp": "0x0", - "eip3860TransitionTimestamp": "0x0", - "eip4895TransitionTimestamp": "0x0", - "terminalTotalDifficulty": "0x0" - }, - "genesis": { - "seal": { - "ethereum": { - "nonce": "0x1234", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x01", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x63585F88", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "", - "gasLimit": "0x400000" - }, - "accounts": { - "0x0000000000000000000000000000000000000000": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000001": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000003": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000004": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000005": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000006": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000007": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000008": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000009": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000010": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000011": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000012": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000013": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000014": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000015": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000016": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000017": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000018": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000019": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000020": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000021": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000022": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000023": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000024": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000025": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000026": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000027": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000028": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000029": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000030": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000031": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000032": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000033": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000034": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000035": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000036": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000037": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000038": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000039": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000040": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000041": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000042": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000043": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000044": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000045": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000046": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000047": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000048": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000049": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000050": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000051": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000052": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000053": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000054": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000055": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000056": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000057": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000058": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000059": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000060": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000061": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000062": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000063": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000064": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000065": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000066": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000067": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000068": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000069": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000070": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000071": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000072": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000073": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000074": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000075": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000076": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000077": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000078": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000079": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000080": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000081": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000082": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000083": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000084": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000085": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000086": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000087": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000088": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000089": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000090": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000091": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000092": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000093": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000094": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000095": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000096": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000097": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000098": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000099": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009f": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000aa": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ab": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ac": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ad": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ae": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000af": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ba": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000be": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bf": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ca": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ce": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cf": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000da": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000db": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000dc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000dd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000de": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000df": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ea": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000eb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ec": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ed": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ee": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ef": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fa": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fe": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ff": { - "balance": "1" - }, - "0x4242424242424242424242424242424242424242": { - "balance": "0", - "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", - "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", - "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", - "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", - "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", - "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", - "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", - "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", - "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", - "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", - "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", - "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", - "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", - "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", - "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", - "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", - "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", - "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", - "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", - "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", - "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", - "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", - "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", - "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", - "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", - "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", - "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", - "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", - "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", - "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" - } - }, - "0xf97e180c050e5Ab072211Ad2C213Eb5AEE4DF134": { - "balance": "10000000000000000000000000" - }, - "0x2cA5F489CC1Fd1CEC24747B64E8dE0F4A6A850E1": { - "balance": "10000000000000000000000000" - }, - "0x7203bd333a874D9d329050ecE393820fCD501eaA": { - "balance": "10000000000000000000000000" - }, - "0xA51918aA40D78Ff8be939bf0E8404252875c6aDF": { - "balance": "10000000000000000000000000" - }, - "0xAA81078e6b2121dd7A846690DFdD6b10d7658d8B": { - "balance": "10000000000000000000000000" - }, - "0xFA2d31D8f21c1D1633E9BEB641dF77D21D63ccDd": { - "balance": "10000000000000000000000000" - }, - "0xf751C9c6d60614226fE57D2cAD6e10C856a2ddA3": { - "balance": "10000000000000000000000000" - }, - "0x9cD16887f6A808AEaa65D3c840f059EeA4ca1319": { - "balance": "10000000000000000000000000" - }, - "0x2E07043584F11BFF0AC39c927665DF6c6ebaffFB": { - "balance": "10000000000000000000000000" - }, - "0x806ce45534bb07a2CAd3a84c53611a2b3DdE316A": { - "balance": "10000000000000000000000000" - }, - "0x97C9B168C5E14d5D369B6D88E9776E5B7b11dcC1": { - "balance": "10000000000000000000000000" - } - }, - "nodes": [ - "enode://11e43515d6258ab2bd814b25a50c911c155a46a27e9be8ce6ea68e293ec13aa4cd6740418baf9abf1e79ba9252c497d66aa4a293c94ef8168d0e7c211ef73690@46.101.126.45:30303", - "enode://95b683a66aba396551bafff688644fc6dc1bada2de78491f89b268ebdcf3d88dfc9942a9f2833ecc3887d49dfb4e96851c2f5eb0adde41847cc356f15ac4ac67@178.128.206.76:30303", - "enode://bcd3eeabca8ff3a1c3b19384e064cc79fda547939324e0699d030041a8960a1d68f1e19141d19305e79675be50434521d024352a5eae00da8ace7933abf20fdf@142.93.160.7:30303", - "enode://6a65c7e62360e1fcc98c88cf8dd8e9492d2e95372f5d7b742b73ab8f82e849bae196bd18b79bc9502b204cef7bf64b589147700368d877c32a76f9c4fd7dd941@104.248.21.4:30303", - "enode://2ae5ef4b4c338e4ee15a347aba8e60bcb451ca19d26f8d67e731bb5f2972ad6ce867ec85f9942a5efe349470106b21c49a9aeb5b00b91063e35f1c1643c0930c@104.248.251.20:30303", - "enode://85ecd8fcab723a33ee68e5f8530c9d264bd601899dc74af7f020bc2f8e0d0ad8ec5c5324364f127c77ddab607bc16e1c5fbae2c675b6d94a79a24222e7e4766e@164.92.174.56:30303", - "enode://24951d3b76f20aed18e32096941d572b98518c9e4dace6b7d0b1f34292dfc5ee7d295453b955be4d2967c6ce1948c11513cd70d76dbee8d3034ddb40d63f5517@142.93.173.170:30303", - "enode://73e2396ac78c462287edd22957096890ca1995a4995c51a1fe24accbe931209fb0fc5359fc1043a0edad3fc53ba64fba5262255c70a03e5fca86f924c261ad4f@178.128.203.243:30303" - ] -} diff --git a/src/Nethermind/Chains/withdrawals_devnet.json b/src/Nethermind/Chains/withdrawals_devnet.json deleted file mode 100644 index a32c2d50d1b..00000000000 --- a/src/Nethermind/Chains/withdrawals_devnet.json +++ /dev/null @@ -1,892 +0,0 @@ -{ - "name": "Testnet", - "engine": { - "Ethash": {} - }, - "params": { - "gasLimitBoundDivisor": "0x400", - "registrar": "0x0000000000000000000000000000000000000000", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0xffff", - "minGasLimit": "0x1388", - "networkID": "0x1469cd", - "MergeForkIdTransition": "0x0", - "maxCodeSize": "0x6000", - "maxCodeSizeTransition": "0x0", - "eip150Transition": "0x0", - "eip158Transition": "0x0", - "eip160Transition": "0x0", - "eip161abcTransition": "0x0", - "eip161dTransition": "0x0", - "eip155Transition": "0x0", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0", - "eip145Transition": "0x0", - "eip1014Transition": "0x0", - "eip1052Transition": "0x0", - "eip1283Transition": "0x0", - "eip1283DisableTransition": "0x0", - "eip152Transition": "0x0", - "eip1108Transition": "0x0", - "eip1344Transition": "0x0", - "eip1884Transition": "0x0", - "eip2028Transition": "0x0", - "eip2200Transition": "0x0", - "eip2565Transition": "0x0", - "eip2929Transition": "0x0", - "eip2930Transition": "0x0", - "eip1559Transition": "0x0", - "eip3198Transition": "0x0", - "eip3529Transition": "0x0", - "eip3541Transition": "0x0", - "eip4895TransitionTimestamp": "0x63a474ec", - "eip3855TransitionTimestamp": "0x63a474ec", - "eip3651TransitionTimestamp": "0x63a474ec", - "eip3860TransitionTimestamp": "0x63a474ec", - "terminalTotalDifficulty": "0x0" - }, - "genesis": { - "seal": { - "ethereum": { - "nonce": "0x1234", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x01", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x63a438b0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "", - "gasLimit": "0x400000" - }, - "accounts": { - "0x0000000000000000000000000000000000000000": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000001": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000003": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000004": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000005": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000006": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000007": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000008": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000009": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000010": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000011": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000012": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000013": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000014": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000015": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000016": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000017": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000018": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000019": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000020": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000021": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000022": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000023": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000024": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000025": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000026": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000027": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000028": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000029": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000030": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000031": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000032": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000033": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000034": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000035": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000036": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000037": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000038": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000039": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000040": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000041": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000042": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000043": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000044": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000045": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000046": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000047": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000048": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000049": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000050": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000051": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000052": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000053": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000054": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000055": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000056": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000057": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000058": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000059": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000060": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000061": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000062": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000063": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000064": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000065": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000066": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000067": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000068": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000069": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000070": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000071": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000072": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000073": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000074": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000075": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000076": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000077": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000078": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000079": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000080": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000081": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000082": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000083": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000084": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000085": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000086": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000087": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000088": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000089": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000090": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000091": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000092": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000093": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000094": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000095": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000096": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000097": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000098": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000099": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009f": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000aa": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ab": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ac": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ad": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ae": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000af": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ba": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000be": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bf": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ca": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ce": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cf": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000da": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000db": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000dc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000dd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000de": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000df": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ea": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000eb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ec": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ed": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ee": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ef": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fa": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fe": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ff": { - "balance": "1" - }, - "0x4242424242424242424242424242424242424242": { - "balance": "0", - "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", - "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", - "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", - "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", - "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", - "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", - "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", - "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", - "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", - "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", - "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", - "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", - "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", - "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", - "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", - "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", - "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", - "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", - "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", - "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", - "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", - "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", - "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", - "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", - "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", - "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", - "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", - "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", - "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", - "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" - } - }, - "0x7bB4e40fC0Fc4cbA645b63717D996c394388D9b2": { - "balance": "1000000000000000000000000000" - }, - "0x368aA5d08abc4d62F0Ca81C045B41209449Ce1FD": { - "balance": "1000000000000000000000000000" - }, - "0x088f7C908A13417Ef367Cb89097CC11837e526Cb": { - "balance": "1000000000000000000000000000" - }, - "0x5Ef957B844bf9D340099ffeF89765D2826132c9E": { - "balance": "1000000000000000000000000000" - }, - "0x9Ebb4D26aF2a100419ea2a97d9Ff58e54897214B": { - "balance": "1000000000000000000000000000" - }, - "0xF8870c504B1BcF903A1b7B93c6f2c36e7dD306fF": { - "balance": "1000000000000000000000000000" - } - }, - "nodes": ["enode://d0411c2d31fdae12a532a8ab62f63670ca6d9cfdc3d56b9540c5d56ce6e0a63df36521bd824ced629ff4658ad081ac3bb000d4a58de6ac347b308aeb25294151@134.122.93.43:30303", - "enode://7ecb84ee11e49957d588f24f00d85fd65df6d4834c53b335e6aad5deff2d872be63611c8cb89bf0a371c3e5fcb094cb46e0f572c320d3710ce53152a5e4a55aa@178.128.203.61:30303", - "enode://b3d5a13f72271bccacfd9e9d42c19e9bfb2e5e6aec892cb74e99457047b3aa0c5922b301a7f597f7ca9de117c02ac08580256797db671d8b2f4c86d1e1bf6772@46.101.129.227:30303"] -} diff --git a/src/Nethermind/Chains/withdrawals_hivetests.json b/src/Nethermind/Chains/withdrawals_hivetests.json deleted file mode 100644 index 0425dd6e993..00000000000 --- a/src/Nethermind/Chains/withdrawals_hivetests.json +++ /dev/null @@ -1,200 +0,0 @@ -{ - "version": "1", - "engine": { - "clique": { - "params": { - "period": 1, - "epoch": 30000, - "blockReward": "0x0" - } - } - }, - "params": { - "eip150Transition": "0x0", - "eip160Transition": "0x0", - "eip161abcTransition": "0x0", - "eip161dTransition": "0x0", - "eip155Transition": "0x0", - "maxCodeSizeTransition": "0x0", - "maxCodeSize": 24576, - "maximumExtraDataSize": "0x400", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0", - "eip145Transition": "0x0", - "eip1014Transition": "0x0", - "eip1052Transition": "0x0", - "eip1283Transition": "0x0", - "eip1283DisableTransition": "0x0", - "eip152Transition": "0x0", - "eip1108Transition": "0x0", - "eip1344Transition": "0x0", - "eip1884Transition": "0x0", - "eip2028Transition": "0x0", - "eip2200Transition": "0x0", - "eip2565Transition": "0x0", - "eip2718Transition": "0x0", - "eip2929Transition": "0x0", - "eip2930Transition": "0x0", - "eip1559Transition": "0x0", - "eip3238Transition": "0x0", - "eip3529Transition": "0x0", - "eip3541Transition": "0x0", - "eip3198Transition": "0x0", - "eip4895TransitionTimestamp": "0x1235", - "networkID": "0x7", - "chainID": "0x7" - }, - "genesis": { - "seal": { - "ethereum": { - "nonce": "0x0000000000000000" - } - }, - "difficulty": "0x30000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x1234", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x2fefd8" - }, - "accounts": { - "0xcf49fda3be353c69b41ed96333cd24302da4556f": { - "balance": "0x123450000000000000000" - }, - "0x0161e041aad467a890839d5b08b138c1e6373072": { - "balance": "0x123450000000000000000" - }, - "0x87da6a8c6e9eff15d703fc2773e32f6af8dbe301": { - "balance": "0x123450000000000000000" - }, - "0xb97de4b8c857e4f6bc354f226dc3249aaee49209": { - "balance": "0x123450000000000000000" - }, - "0xc5065c9eeebe6df2c2284d046bfc906501846c51": { - "balance": "0x123450000000000000000" - }, - "0x0000000000000000000000000000000000000314": { - "balance": "0x0", - "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a223e05d1461006a578063abd1a0cf1461008d578063abfced1d146100d4578063e05c914a14610110578063e6768b451461014c575b610000565b346100005761007761019d565b6040518082815260200191505060405180910390f35b34610000576100be600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506101a3565b6040518082815260200191505060405180910390f35b346100005761010e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101ed565b005b346100005761014a600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610236565b005b346100005761017960048080359060200190919080359060200190919080359060200190919050506103c4565b60405180848152602001838152602001828152602001935050505060405180910390f35b60005481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5050565b7f6031a8d62d7c95988fa262657cd92107d90ed96e08d8f867d32f26edfe85502260405180905060405180910390a17f47e2689743f14e97f7dcfa5eec10ba1dff02f83b3d1d4b9c07b206cbbda66450826040518082815260200191505060405180910390a1817fa48a6b249a5084126c3da369fbc9b16827ead8cb5cdc094b717d3f1dcd995e2960405180905060405180910390a27f7890603b316f3509577afd111710f9ebeefa15e12f72347d9dffd0d65ae3bade81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18073ffffffffffffffffffffffffffffffffffffffff167f7efef9ea3f60ddc038e50cccec621f86a0195894dc0520482abf8b5c6b659e4160405180905060405180910390a28181604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a05b5050565b6000600060008585859250925092505b935093509390505600a165627a7a72305820aaf842d0d0c35c45622c5263cbb54813d2974d3999c8c38551d7c613ea2bc1170029", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x1234", - "0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9": "0x01" - } - }, - "0x0000000000000000000000000000000000000315": { - "balance": "0x9999999999999999999999999999999", - "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef2769ca1461003e575b610000565b3461000057610078600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061007a565b005b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f1935050505015610106578173ffffffffffffffffffffffffffffffffffffffff167f30a3c50752f2552dcc2b93f5b96866280816a986c0c0408cb6778b9fa198288f826040518082815260200191505060405180910390a25b5b50505600a165627a7a72305820637991fabcc8abad4294bf2bb615db78fbec4edff1635a2647d3894e2daf6a610029" - }, - "0x0000000000000000000000000000000000000316": { - "balance": "0x0", - "code": "0x444355" - }, - "0x0000000000000000000000000000000000000317": { - "balance": "0x0", - "code": "0x600160003555" - }, - "0x0000000000000000000000000000000000000001": { - "builtin": { - "name": "ecrecover", - "pricing": { - "linear": { - "base": 3000, - "word": 0 - } - } - } - }, - "0x0000000000000000000000000000000000000002": { - "builtin": { - "name": "sha256", - "pricing": { - "linear": { - "base": 60, - "word": 12 - } - } - } - }, - "0x0000000000000000000000000000000000000003": { - "builtin": { - "name": "ripemd160", - "pricing": { - "linear": { - "base": 600, - "word": 120 - } - } - } - }, - "0x0000000000000000000000000000000000000004": { - "builtin": { - "name": "identity", - "pricing": { - "linear": { - "base": 15, - "word": 3 - } - } - } - }, - "0x0000000000000000000000000000000000000005": { - "builtin": { - "name": "modexp", - "activate_at": "0x0", - "pricing": { - "modexp": { - "divisor": 20 - } - } - } - }, - "0x0000000000000000000000000000000000000006": { - "builtin": { - "name": "alt_bn128_add", - "activate_at": "0x0", - "pricing": { - "linear": { - "base": 500, - "word": 0 - } - } - } - }, - "0x0000000000000000000000000000000000000007": { - "builtin": { - "name": "alt_bn128_mul", - "activate_at": "0x0", - "pricing": { - "linear": { - "base": 40000, - "word": 0 - } - } - } - }, - "0x0000000000000000000000000000000000000008": { - "builtin": { - "name": "alt_bn128_pairing", - "activate_at": "0x0", - "pricing": { - "alt_bn128_pairing": { - "base": 100000, - "pair": 80000 - } - } - } - }, - "0x0000000000000000000000000000000000000009": { - "builtin": { - "name": "blake2_f", - "activate_at": "0x0", - "pricing": { - "blake2_f": { - "gas_per_round": 1 - } - } - } - } - } -} diff --git a/src/Nethermind/Chains/withdrawals_test.json b/src/Nethermind/Chains/withdrawals_test.json deleted file mode 100644 index 752c3a16496..00000000000 --- a/src/Nethermind/Chains/withdrawals_test.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "TheMerge_Devnet", - "engine": { - "clique": { - "params": { - "period": 5, - "epoch": 30000 - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID": 1, - "eip150Transition": "0x0", - "eip155Transition": "0x0", - "eip158Transition": "0x0", - "eip160Transition": "0x0", - "eip161abcTransition": "0x0", - "eip161dTransition": "0x0", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0", - "eip145Transition": "0x0", - "eip1014Transition": "0x0", - "eip1052Transition": "0x0", - "eip1283Transition": "0x0", - "eip1283DisableTransition": "0x0", - "eip152Transition": "0x0", - "eip1108Transition": "0x0", - "eip1344Transition": "0x0", - "eip1884Transition": "0x0", - "eip2028Transition": "0x0", - "eip2200Transition": "0x0", - "eip2565Transition": "0x0", - "eip2929Transition": "0x0", - "eip2930Transition": "0x0", - "eip1559Transition": "0x0", - "eip3198Transition": "0x0", - "eip3529Transition": "0x0", - "eip3541Transition": "0x0", - "eip4895TransitionTimestamp": "0x0", - "terminalTotalDifficulty": "0x0" - }, - "genesis": { - "seal": { - "ethereum": { - "nonce": "0x42", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x400000000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData":"0x0000000000000000000000000000000000000000000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit":"0x1C9C380", - "baseFeePerGas":"0x7" - }, - "accounts": { - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": - { - "balance":"0x6d6172697573766477000000" - } - } -} diff --git a/src/Nethermind/Chains/zhejiang.json b/src/Nethermind/Chains/zhejiang.json deleted file mode 100644 index e5e369b7e3a..00000000000 --- a/src/Nethermind/Chains/zhejiang.json +++ /dev/null @@ -1,896 +0,0 @@ -{ - "name": "Testnet", - "engine": { - "Ethash": {} - }, - "params": { - "gasLimitBoundDivisor": "0x400", - "registrar": "0x0000000000000000000000000000000000000000", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0xffff", - "minGasLimit": "0x1388", - "networkID": "0x1469cb", - "MergeForkIdTransition": "0x0", - "maxCodeSize": "0x6000", - "maxCodeSizeTransition": "0x0", - "eip150Transition": "0x0", - "eip158Transition": "0x0", - "eip160Transition": "0x0", - "eip161abcTransition": "0x0", - "eip161dTransition": "0x0", - "eip155Transition": "0x0", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0", - "eip145Transition": "0x0", - "eip1014Transition": "0x0", - "eip1052Transition": "0x0", - "eip1283Transition": "0x0", - "eip1283DisableTransition": "0x0", - "eip152Transition": "0x0", - "eip1108Transition": "0x0", - "eip1344Transition": "0x0", - "eip1884Transition": "0x0", - "eip2028Transition": "0x0", - "eip2200Transition": "0x0", - "eip2565Transition": "0x0", - "eip2929Transition": "0x0", - "eip2930Transition": "0x0", - "eip1559Transition": "0x0", - "eip3198Transition": "0x0", - "eip3529Transition": "0x0", - "eip3541Transition": "0x0", - "eip4895TransitionTimestamp": "0x63e26770", - "eip3855TransitionTimestamp": "0x63e26770", - "eip3651TransitionTimestamp": "0x63e26770", - "eip3860TransitionTimestamp": "0x63e26770", - "terminalTotalDifficulty": "0x0" - }, - "genesis": { - "seal": { - "ethereum": { - "nonce": "0x1234", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x01", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x63da7df8", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "", - "gasLimit": "0x17D7840" - }, - "accounts": { - "0x0000000000000000000000000000000000000000": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000001": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000003": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000004": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000005": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000006": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000007": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000008": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000009": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000010": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000011": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000012": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000013": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000014": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000015": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000016": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000017": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000018": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000019": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000020": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000021": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000022": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000023": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000024": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000025": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000026": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000027": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000028": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000029": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000030": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000031": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000032": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000033": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000034": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000035": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000036": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000037": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000038": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000039": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000040": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000041": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000042": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000043": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000044": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000045": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000046": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000047": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000048": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000049": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000050": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000051": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000052": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000053": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000054": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000055": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000056": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000057": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000058": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000059": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000060": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000061": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000062": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000063": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000064": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000065": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000066": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000067": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000068": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000069": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000070": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000071": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000072": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000073": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000074": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000075": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000076": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000077": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000078": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000079": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000080": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000081": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000082": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000083": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000084": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000085": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000086": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000087": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000088": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000089": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000090": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000091": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000092": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000093": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000094": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000095": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000096": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000097": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000098": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000099": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009f": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000aa": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ab": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ac": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ad": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ae": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000af": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ba": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000be": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bf": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ca": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ce": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cf": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000da": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000db": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000dc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000dd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000de": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000df": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ea": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000eb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ec": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ed": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ee": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ef": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fa": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fe": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ff": { - "balance": "1" - }, - "0x4242424242424242424242424242424242424242": { - "balance": "0", - "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", - "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", - "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", - "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", - "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", - "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", - "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", - "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", - "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", - "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", - "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", - "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", - "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", - "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", - "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", - "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", - "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", - "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", - "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", - "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", - "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", - "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", - "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", - "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", - "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", - "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", - "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", - "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", - "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", - "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" - } - }, - "0x3E951C9f69a06Bc3AD71fF7358DbC56bEd94b9F2": { - "balance": "1000000000000000000000000000" - }, - "0xe228C30d4e5245f967ac21726d5412dA27aD071C": { - "balance": "1000000000000000000000000000" - }, - "0xD59Ce7Ccc6454a2D2C2e06bbcf71D0Beb33480eD": { - "balance": "1000000000000000000000000000" - }, - "0x1CF4D54414eF51b41f9B2238c57102ab2e61D1F2": { - "balance": "1000000000000000000000000000" - }, - "0x249bE3fDEd872338C733cF3975af9736bdCb9D4D": { - "balance": "1000000000000000000000000000" - }, - "0x3fCd1bff94513712f8cD63d1eD66776A67D5F78e": { - "balance": "1000000000000000000000000000" - } - }, - "nodes": [ - "enode://691c66d0ce351633b2ef8b4e4ef7db9966915ca0937415bd2b408df22923f274873b4d4438929e029a13a680140223dcf701cabe22df7d8870044321022dfefa@64.225.78.1:30303", - "enode://89347b9461727ee1849256d78e84d5c86cc3b4c6c5347650093982b726d71f3d08027e280b399b7b6604ceeda863283dcfe1a01e93728b4883114e9f8c7cc8ef@146.190.238.212:30303", - "enode://c2892072efe247f21ed7ebea6637ade38512a0ae7c5cffa1bf0786d5e3be1e7f40ff71252a21b36aa9de54e49edbcfc6962a98032adadfa29c8524262e484ad3@165.232.84.160:30303", - "enode://71e862580d3177a99e9837bd9e9c13c83bde63d3dba1d5cea18e89eb2a17786bbd47a8e7ae690e4d29763b55c205af13965efcaf6105d58e118a5a8ed2b0f6d0@68.183.13.170:30303", - "enode://2f6cf7f774e4507e7c1b70815f9c0ccd6515ee1170c991ce3137002c6ba9c671af38920f5b8ab8a215b62b3b50388030548f1d826cb6c2b30c0f59472804a045@161.35.147.98:30303" - ] -} diff --git a/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3651Tests.cs b/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3651Tests.cs deleted file mode 100644 index 71ad0e0313e..00000000000 --- a/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3651Tests.cs +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Ethereum.Test.Base; -using FluentAssertions; -using NUnit.Framework; - -namespace Ethereum.Blockchain.Block.Test; - -[TestFixture] -[Parallelizable(ParallelScope.All)] -public class Eip3651Tests : BlockchainTestBase -{ - [TestCaseSource(nameof(LoadTests))] - public async Task Test(BlockchainTest test) - { - await RunTest(test); - } - - public static IEnumerable LoadTests() - { - var loader = new TestsSourceLoader(new LoadLocalTestsStrategy(), "eip3651"); - return (IEnumerable)loader.LoadTests(); - } -} diff --git a/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3855Tests.cs b/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3855Tests.cs deleted file mode 100644 index 8c4cf906106..00000000000 --- a/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3855Tests.cs +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System.Collections.Generic; -using System.Threading.Tasks; -using Ethereum.Test.Base; -using NUnit.Framework; - -namespace Ethereum.Blockchain.Block.Test; - -[TestFixture] -[Parallelizable(ParallelScope.All)] -public class Eip3855Tests : BlockchainTestBase -{ - [TestCaseSource(nameof(LoadTests))] - public async Task Test(BlockchainTest test) - { - await RunTest(test); - } - - public static IEnumerable LoadTests() - { - var loader = new TestsSourceLoader(new LoadLocalTestsStrategy(), "eip3855"); - return (IEnumerable)loader.LoadTests(); - } -} diff --git a/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3860Tests.cs b/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3860Tests.cs deleted file mode 100644 index 7d03036a8fa..00000000000 --- a/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3860Tests.cs +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System.Collections.Generic; -using System.Threading.Tasks; -using Ethereum.Test.Base; -using NUnit.Framework; - -namespace Ethereum.Blockchain.Block.Test; - -[TestFixture] -[Parallelizable(ParallelScope.All)] -public class Eip3860Tests : BlockchainTestBase -{ - [TestCaseSource(nameof(LoadTests))] - public async Task Test(BlockchainTest test) - { - await RunTest(test); - } - - public static IEnumerable LoadTests() - { - var loader = new TestsSourceLoader(new LoadLocalTestsStrategy(), "eip3860"); - return (IEnumerable)loader.LoadTests(); - } -} diff --git a/src/Nethermind/Ethereum.Blockchain.Block.Test/WithdrawalsTests.cs b/src/Nethermind/Ethereum.Blockchain.Block.Test/WithdrawalsTests.cs deleted file mode 100644 index e976066d8b0..00000000000 --- a/src/Nethermind/Ethereum.Blockchain.Block.Test/WithdrawalsTests.cs +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System.Collections.Generic; -using System.Threading.Tasks; -using Ethereum.Test.Base; -using NUnit.Framework; - -namespace Ethereum.Blockchain.Block.Test; - -[TestFixture] -[Parallelizable(ParallelScope.All)] -public class WithdrawalsTests : BlockchainTestBase -{ - [TestCaseSource(nameof(LoadTests))] - public async Task Test(BlockchainTest test) - { - await RunTest(test); - } - - public static IEnumerable LoadTests() - { - var loader = new TestsSourceLoader(new LoadLocalTestsStrategy(), "withdrawals"); - return (IEnumerable)loader.LoadTests(); - } -} diff --git a/src/Nethermind/Ethereum.Test.Base/LoadLocalTestsStrategy.cs b/src/Nethermind/Ethereum.Test.Base/LoadLocalTestsStrategy.cs deleted file mode 100644 index 8f2f33d3c1a..00000000000 --- a/src/Nethermind/Ethereum.Test.Base/LoadLocalTestsStrategy.cs +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Collections.Generic; -using System.IO; -using Ethereum.Test.Base.Interfaces; - -namespace Ethereum.Test.Base; - -// Loads tests from src/ethereum-tests -public class LoadLocalTestsStrategy : ITestLoadStrategy -{ - public IEnumerable Load(string testDirectoryName, string wildcard = null) - { - List testsByName = new(); - IEnumerable testFiles = Directory.EnumerateFiles(GetLocalTestsDirectory() + testDirectoryName); - - foreach (string testFile in testFiles) - { - FileTestsSource fileTestsSource = new(testFile, wildcard); - try - { - var tests = fileTestsSource.LoadBlockchainTests(); - foreach (BlockchainTest blockchainTest in tests) - { - blockchainTest.Category = testDirectoryName; - } - - testsByName.AddRange(tests); - } - catch (Exception e) - { - testsByName.Add(new BlockchainTest { Name = testFile, LoadFailure = $"Failed to load: {e}" }); - } - } - - return testsByName; - } - - private string GetLocalTestsDirectory() - { - char pathSeparator = Path.AltDirectorySeparatorChar; - string currentDirectory = AppDomain.CurrentDomain.BaseDirectory; - - return currentDirectory.Remove(currentDirectory.LastIndexOf("src")) + $"src{pathSeparator}ethereum-tests{pathSeparator}"; - } - -} diff --git a/src/Nethermind/Nethermind.Abi.Contracts/Contract.ConstantContract.cs b/src/Nethermind/Nethermind.Abi.Contracts/Contract.ConstantContract.cs deleted file mode 100644 index a243d6851a9..00000000000 --- a/src/Nethermind/Nethermind.Abi.Contracts/Contract.ConstantContract.cs +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using Nethermind.Abi; -using Nethermind.Core; -using Nethermind.Core.Crypto; -using Nethermind.Evm; -using Nethermind.State; - -namespace Nethermind.Consensus.AuRa.Contracts -{ - public partial class Contract - { - /// - /// Gets constant version of the contract. Allowing to call contract methods without state modification. - /// - /// Source of readonly to call transactions. - /// Constant version of the contract. - protected ConstantContract GetConstant(IReadOnlyTransactionProcessorSource readOnlyReadOnlyTransactionProcessorSource) => - new ConstantContract(this, readOnlyReadOnlyTransactionProcessorSource); - - /// - /// Constant version of the contract. Allows to call contract methods without state modification. - /// - protected class ConstantContract - { - private readonly Contract _contract; - private readonly IReadOnlyTransactionProcessorSource _readOnlyReadOnlyTransactionProcessorSource; - - public ConstantContract(Contract contract, IReadOnlyTransactionProcessorSource readOnlyReadOnlyTransactionProcessorSource) - { - _contract = contract; - _readOnlyReadOnlyTransactionProcessorSource = readOnlyReadOnlyTransactionProcessorSource ?? throw new ArgumentNullException(nameof(readOnlyReadOnlyTransactionProcessorSource)); - } - - private byte[] Call(BlockHeader parentHeader, Transaction transaction) - { - using var readOnlyTransactionProcessor = _readOnlyReadOnlyTransactionProcessorSource.Get(GetState(parentHeader)); - return CallCore(readOnlyTransactionProcessor, parentHeader, transaction, true); - } - - private object[] Call(BlockHeader parentHeader, AbiFunctionDescription function, Address sender, params object[] arguments) - { - var result = CallRaw(parentHeader, function, sender, arguments); - var objects = _contract.AbiEncoder.Decode(function.GetReturnInfo(), result); - return objects; - } - - /// - /// - /// - /// - /// - /// - /// - /// - /// - public T Call(BlockHeader parentHeader, AbiFunctionDescription function, Address sender, params object[] arguments) - { - return (T)Call(parentHeader, function, sender, arguments)[0]; - } - - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public (T1, T2) Call(BlockHeader parentHeader, AbiFunctionDescription function, Address sender, params object[] arguments) - { - var objects = Call(parentHeader, function, sender, arguments); - return ((T1)objects[0], (T2)objects[1]); - } - - /// - /// - /// - /// - /// - /// - /// - /// - public byte[] CallRaw(BlockHeader parentHeader, AbiFunctionDescription function, Address sender, params object[] arguments) - { - var transaction = _contract.GenerateTransaction(function, sender, arguments); - var result = Call(parentHeader, transaction); - return result; - } - - private Keccak GetState(BlockHeader parentHeader) => parentHeader?.StateRoot ?? Keccak.EmptyTreeHash; - } - } -} diff --git a/src/Nethermind/Nethermind.Abi.Contracts/Contract.cs b/src/Nethermind/Nethermind.Abi.Contracts/Contract.cs deleted file mode 100644 index e31e2382d45..00000000000 --- a/src/Nethermind/Nethermind.Abi.Contracts/Contract.cs +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using Nethermind.Abi; -using Nethermind.Core; -using Nethermind.Crypto; -using Nethermind.Dirichlet.Numerics; -using Nethermind.Evm; -using Nethermind.Evm.Tracing; -using Nethermind.Specs.Forks; -using Nethermind.State; - -namespace Nethermind.Consensus.AuRa.Contracts -{ - /// - /// Base class for contracts that will be interacted by the node engine. - /// - /// - /// This class is intended to be inherited and concrete contract class should provide contract specific methods to be able for the node to use the contract. - /// - /// There are 3 main ways a node can interact with contract: - /// 1. It can that will be added to a block. - /// 2. It can contract and modify current state of execution. - /// 3. It can constant contract. This by design doesn't modify current state. It is designed as read-only operation that will allow the node to make decisions how it should operate. - /// - public abstract partial class Contract - { - /// - /// Default gas limit of transactions generated from contract. - /// - public const long DefaultContractGasLimit = 1_600_000L; - - private readonly ITransactionProcessor _transactionProcessor; - protected IAbiEncoder AbiEncoder { get; } - protected Address ContractAddress { get; } - - /// - /// Creates contract - /// - /// Transaction processor on which all should be run on. - /// Binary interface encoder/decoder. - /// Address where contract is deployed. - protected Contract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress) - { - _transactionProcessor = transactionProcessor ?? throw new ArgumentNullException(nameof(transactionProcessor)); - AbiEncoder = abiEncoder ?? throw new ArgumentNullException(nameof(abiEncoder)); - ContractAddress = contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)); - } - - private Transaction GenerateTransaction(byte[] transactionData, Address sender, long gasLimit = DefaultContractGasLimit) where T : Transaction, new() - { - var transaction = new T() - { - Value = UInt256.Zero, - Data = transactionData, - To = ContractAddress, - SenderAddress = sender ?? Address.SystemUser, - GasLimit = gasLimit, - GasPrice = UInt256.Zero, - }; - - transaction.Hash = transaction.CalculateHash(); - - return transaction; - } - - /// - /// Generates transaction. - /// That transaction can be added to a produced block or broadcasted - if is used as . - /// That transaction can be used in if is used as . - /// - /// Function in contract that is called by the transaction. - /// Sender of the transaction - caller of the function. - /// Arguments to the function. - /// Type of . - /// Transaction. - protected Transaction GenerateTransaction(AbiFunctionDescription function, Address sender, params object[] arguments) where T : Transaction, new() - => GenerateTransaction(AbiEncoder.Encode(function.GetCallInfo(), arguments), sender); - - private byte[] Call(BlockHeader header, Transaction transaction) => CallCore(_transactionProcessor, header, transaction); - - /// - /// Calls the function in contract, state modification is allowed. - /// - /// Header in which context the call is done. - /// Function in contract that is being called. - /// Sender of the transaction - caller of the function. - /// Arguments to the function. - /// Deserialized return value of the based on its definition. - protected object[] Call(BlockHeader header, AbiFunctionDescription function, Address sender, params object[] arguments) - { - var transaction = GenerateTransaction(function, sender, arguments); - var result = Call(header, transaction); - var objects = AbiEncoder.Decode(function.GetReturnInfo(), result); - return objects; - } - - /// - /// Helper method that actually does the actual call to . - /// - /// Actual transaction processor to be called upon. - /// Header in which context the call is done. - /// Transaction to be executed. - /// Is it restore call. - /// Bytes with result. - /// Thrown when there is an exception during execution or is . - private static byte[] CallCore(ITransactionProcessor transactionProcessor, BlockHeader header, Transaction transaction, bool callAndRestore = false) - { - bool failure; - - CallOutputTracer tracer = new CallOutputTracer(); - - try - { - if (callAndRestore) - { - transactionProcessor.CallAndRestore(transaction, header, tracer); - } - else - { - transactionProcessor.Execute(transaction, header, tracer); - } - - failure = tracer.StatusCode != StatusCode.Success; - } - catch (Exception e) - { - throw new AuRaException($"System call returned an exception '{e.Message}' at block {header.Number}.", e); - } - - if (failure) - { - throw new AuRaException($"System call returned error '{tracer.Error}' at block {header.Number}."); - } - else - { - return tracer.ReturnValue; - } - } - - private bool TryCall(BlockHeader header, Transaction transaction, out byte[] result) - { - CallOutputTracer tracer = new CallOutputTracer(); - - try - { - _transactionProcessor.Execute(transaction, header, tracer); - result = tracer.ReturnValue; - return tracer.StatusCode == StatusCode.Success; - } - catch (Exception) - { - result = null; - return false; - } - } - - /// - /// Same as but returns false instead of throwing . - /// - /// Header in which context the call is done. - /// Function in contract that is being called. - /// Sender of the transaction - caller of the function. - /// Deserialized return value of the based on its definition. - /// Arguments to the function. - /// true if function was otherwise false. - protected bool TryCall(BlockHeader header, AbiFunctionDescription function, Address sender, out object[] result, params object[] arguments) - { - var transaction = GenerateTransaction(function, sender, arguments); - if (TryCall(header, transaction, out var bytes)) - { - result = AbiEncoder.Decode(function.GetReturnInfo(), bytes); - return true; - } - - result = null; - return false; - } - - /// - /// Creates account if its not in current state. - /// - /// State provider. - protected void EnsureSystemAccount(IStateProvider stateProvider) - { - if (!stateProvider.AccountExists(Address.SystemUser)) - { - stateProvider.CreateAccount(Address.SystemUser, UInt256.Zero); - stateProvider.Commit(Homestead.Instance); - } - } - } -} From cd6af2cb9fe348724bf4df39a6561f6ea89238b5 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 8 May 2023 12:42:06 +0100 Subject: [PATCH 004/213] merging master --- .github/workflows/build-secp256k1-libs.yml | 77 ++ Dockerfile.secp256k1 | 19 + src/Nethermind/Chains/shandong.json | 928 ++++++++++++++++++ src/Nethermind/Chains/withdrawals_devnet.json | 892 +++++++++++++++++ .../Chains/withdrawals_hivetests.json | 200 ++++ src/Nethermind/Chains/withdrawals_test.json | 69 ++ src/Nethermind/Chains/zhejiang.json | 896 +++++++++++++++++ .../Eip3651Tests.cs | 28 + .../Eip3855Tests.cs | 26 + .../Eip3860Tests.cs | 26 + .../WithdrawalsTests.cs | 26 + .../LoadLocalTestsStrategy.cs | 49 + .../Contract.ConstantContract.cs | 98 ++ .../Nethermind.Abi.Contracts/Contract.cs | 194 ++++ 14 files changed, 3528 insertions(+) create mode 100644 .github/workflows/build-secp256k1-libs.yml create mode 100644 Dockerfile.secp256k1 create mode 100644 src/Nethermind/Chains/shandong.json create mode 100644 src/Nethermind/Chains/withdrawals_devnet.json create mode 100644 src/Nethermind/Chains/withdrawals_hivetests.json create mode 100644 src/Nethermind/Chains/withdrawals_test.json create mode 100644 src/Nethermind/Chains/zhejiang.json create mode 100644 src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3651Tests.cs create mode 100644 src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3855Tests.cs create mode 100644 src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3860Tests.cs create mode 100644 src/Nethermind/Ethereum.Blockchain.Block.Test/WithdrawalsTests.cs create mode 100644 src/Nethermind/Ethereum.Test.Base/LoadLocalTestsStrategy.cs create mode 100644 src/Nethermind/Nethermind.Abi.Contracts/Contract.ConstantContract.cs create mode 100644 src/Nethermind/Nethermind.Abi.Contracts/Contract.cs diff --git a/.github/workflows/build-secp256k1-libs.yml b/.github/workflows/build-secp256k1-libs.yml new file mode 100644 index 00000000000..5af2957957c --- /dev/null +++ b/.github/workflows/build-secp256k1-libs.yml @@ -0,0 +1,77 @@ +name: '[BUILD] Secp256k1 Libraries' + +on: + workflow_dispatch: + +jobs: + build-secp256k1: + name: Building Secp256k1 + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest, macOS-latest, ubuntu-latest] + steps: + - name: Cloning secp256k1 repository + run: | + git clone https://github.com/NethermindEth/secp256k1 + - name: Building secp256k1 for Linux + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get install autoconf libtool + cd secp256k1/ + ./autogen.sh + ./configure --enable-module-recovery --enable-experimental --enable-module-ecdh --enable-shared --with-bignum=no + make -j8 + strip .libs/libsecp256k1.so + - uses: actions/upload-artifact@v1 + name: Uploading Linux artifact + if: matrix.os == 'ubuntu-latest' + with: + name: linux_artifact_secp256k1 + path: secp256k1/.libs/libsecp256k1.so + - name: Building secp256k1 for OSX + if: matrix.os == 'macOS-latest' + run: | + brew install automake + brew install libtool + brew install gmp + cd secp256k1/ + ./autogen.sh + ./configure --enable-module-recovery --enable-experimental --enable-module-ecdh --enable-shared --with-bignum=no + make -j8 + - uses: actions/upload-artifact@v1 + name: Uploading Darwin artifact + if: matrix.os == 'macOS-latest' + with: + name: darwin_artifact_secp256k1 + path: secp256k1/.libs/libsecp256k1.dylib + - uses: msys2/setup-msys2@v2 + if: matrix.os == 'windows-latest' + with: + update: true + install: autoconf libtool make automake gcc mingw-w64-x86_64-gcc base-devel + name: Setting up msys2 for Windows + - run: | + cat <> run.sh + mv secp256k1 64bit + cd 64bit + ./autogen.sh + echo "LDFLAGS = -no-undefined" >> Makefile.am + ./configure --host=x86_64-w64-mingw32 --enable-module-recovery --enable-experimental --enable-module-ecdh --enable-shared --with-bignum=no + make -j8 + strip .libs/libsecp256k1-0.dll + mv .libs/libsecp256k1-0.dll .libs/secp256k1.dll + EOT + if: matrix.os == 'windows-latest' + name: Creating script for secp256k1 build + shell: bash + - run: ./run.sh + if: matrix.os == 'windows-latest' + shell: msys2 {0} + name: Running secp256k1 build for Windows x64 + - uses: actions/upload-artifact@v1 + name: Uploading Windows artifact + if: matrix.os == 'windows-latest' + with: + name: windows_artifact_secp256k1 + path: 64bit/.libs/secp256k1.dll diff --git a/Dockerfile.secp256k1 b/Dockerfile.secp256k1 new file mode 100644 index 00000000000..516b468cbe5 --- /dev/null +++ b/Dockerfile.secp256k1 @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +# SPDX-License-Identifier: LGPL-3.0-only + +FROM debian@sha256:acf7795dc91df17e10effee064bd229580a9c34213b4dba578d64768af5d8c51 AS secp256k1 +WORKDIR /source + +RUN apt-get update && apt-get install -y git autoconf automake libtool build-essential + +RUN git clone https://github.com/NethermindEth/secp256k1 . && \ + ./autogen.sh && \ + ./configure --enable-module-recovery --enable-experimental --enable-module-ecdh --enable-shared --with-bignum=no && \ + make -j16 + +RUN strip .libs/libsecp256k1.so + + +FROM debian@sha256:acf7795dc91df17e10effee064bd229580a9c34213b4dba578d64768af5d8c51 AS libsecp256k1 +WORKDIR /nethermind +COPY --from=secp256k1 /source/.libs/libsecp256k1.so . diff --git a/src/Nethermind/Chains/shandong.json b/src/Nethermind/Chains/shandong.json new file mode 100644 index 00000000000..c0815117d48 --- /dev/null +++ b/src/Nethermind/Chains/shandong.json @@ -0,0 +1,928 @@ +{ + "name": "shandong", + "engine": { + "Ethash": { + "params": { + "minimumDifficulty": "0x20000", + "difficultyBoundDivisor": "0x800", + "durationLimit": "0xd", + "blockReward": { + "0x0": "0x1BC16D674EC80000" + }, + "homesteadTransition": "0x0", + "eip100bTransition": "0x0", + "difficultyBombDelays": {} + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x400", + "registrar": "0x0000000000000000000000000000000000000000", + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID": "0x00146A2E", + "MergeForkIdTransition": "0x0", + "maxCodeSize": "0x6000", + "maxCodeSizeTransition": "0x0", + "eip150Transition": "0x0", + "eip158Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip155Transition": "0x0", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "eip145Transition": "0x0", + "eip1014Transition": "0x0", + "eip1052Transition": "0x0", + "eip1283Transition": "0x0", + "eip1283DisableTransition": "0x0", + "eip152Transition": "0x0", + "eip1108Transition": "0x0", + "eip1344Transition": "0x0", + "eip1884Transition": "0x0", + "eip2028Transition": "0x0", + "eip2200Transition": "0x0", + "eip2565Transition": "0x0", + "eip2929Transition": "0x0", + "eip2930Transition": "0x0", + "eip1559Transition": "0x0", + "eip3198Transition": "0x0", + "eip3529Transition": "0x0", + "eip3541Transition": "0x0", + "eip3540TransitionTimestamp": "0x0", + "eip3651TransitionTimestamp": "0x0", + "eip3670TransitionTimestamp": "0x0", + "eip3855TransitionTimestamp": "0x0", + "eip3860TransitionTimestamp": "0x0", + "eip4895TransitionTimestamp": "0x0", + "terminalTotalDifficulty": "0x0" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x1234", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x01", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x63585F88", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "", + "gasLimit": "0x400000" + }, + "accounts": { + "0x0000000000000000000000000000000000000000": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000001": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000002": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000003": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000004": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000005": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000006": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000007": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000008": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000009": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000010": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000011": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000012": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000013": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000014": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000015": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000016": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000017": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000018": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000019": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000020": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000021": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000022": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000023": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000024": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000025": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000026": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000027": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000028": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000029": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000030": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000031": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000032": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000033": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000034": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000035": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000036": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000037": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000038": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000039": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000040": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000041": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000042": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000043": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000044": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000045": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000046": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000047": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000048": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000049": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000050": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000051": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000052": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000053": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000054": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000055": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000056": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000057": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000058": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000059": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000060": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000061": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000062": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000063": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000064": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000065": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000066": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000067": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000068": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000069": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000070": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000071": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000072": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000073": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000074": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000075": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000076": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000077": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000078": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000079": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000080": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000081": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000082": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000083": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000084": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000085": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000086": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000087": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000088": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000089": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000090": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000091": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000092": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000093": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000094": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000095": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000096": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000097": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000098": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000099": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009f": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000aa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ab": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ac": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ad": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ae": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000af": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ba": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000be": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ca": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ce": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000da": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000db": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000de": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000df": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ea": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000eb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ec": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ed": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ee": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ef": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fe": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ff": { + "balance": "1" + }, + "0x4242424242424242424242424242424242424242": { + "balance": "0", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + } + }, + "0xf97e180c050e5Ab072211Ad2C213Eb5AEE4DF134": { + "balance": "10000000000000000000000000" + }, + "0x2cA5F489CC1Fd1CEC24747B64E8dE0F4A6A850E1": { + "balance": "10000000000000000000000000" + }, + "0x7203bd333a874D9d329050ecE393820fCD501eaA": { + "balance": "10000000000000000000000000" + }, + "0xA51918aA40D78Ff8be939bf0E8404252875c6aDF": { + "balance": "10000000000000000000000000" + }, + "0xAA81078e6b2121dd7A846690DFdD6b10d7658d8B": { + "balance": "10000000000000000000000000" + }, + "0xFA2d31D8f21c1D1633E9BEB641dF77D21D63ccDd": { + "balance": "10000000000000000000000000" + }, + "0xf751C9c6d60614226fE57D2cAD6e10C856a2ddA3": { + "balance": "10000000000000000000000000" + }, + "0x9cD16887f6A808AEaa65D3c840f059EeA4ca1319": { + "balance": "10000000000000000000000000" + }, + "0x2E07043584F11BFF0AC39c927665DF6c6ebaffFB": { + "balance": "10000000000000000000000000" + }, + "0x806ce45534bb07a2CAd3a84c53611a2b3DdE316A": { + "balance": "10000000000000000000000000" + }, + "0x97C9B168C5E14d5D369B6D88E9776E5B7b11dcC1": { + "balance": "10000000000000000000000000" + } + }, + "nodes": [ + "enode://11e43515d6258ab2bd814b25a50c911c155a46a27e9be8ce6ea68e293ec13aa4cd6740418baf9abf1e79ba9252c497d66aa4a293c94ef8168d0e7c211ef73690@46.101.126.45:30303", + "enode://95b683a66aba396551bafff688644fc6dc1bada2de78491f89b268ebdcf3d88dfc9942a9f2833ecc3887d49dfb4e96851c2f5eb0adde41847cc356f15ac4ac67@178.128.206.76:30303", + "enode://bcd3eeabca8ff3a1c3b19384e064cc79fda547939324e0699d030041a8960a1d68f1e19141d19305e79675be50434521d024352a5eae00da8ace7933abf20fdf@142.93.160.7:30303", + "enode://6a65c7e62360e1fcc98c88cf8dd8e9492d2e95372f5d7b742b73ab8f82e849bae196bd18b79bc9502b204cef7bf64b589147700368d877c32a76f9c4fd7dd941@104.248.21.4:30303", + "enode://2ae5ef4b4c338e4ee15a347aba8e60bcb451ca19d26f8d67e731bb5f2972ad6ce867ec85f9942a5efe349470106b21c49a9aeb5b00b91063e35f1c1643c0930c@104.248.251.20:30303", + "enode://85ecd8fcab723a33ee68e5f8530c9d264bd601899dc74af7f020bc2f8e0d0ad8ec5c5324364f127c77ddab607bc16e1c5fbae2c675b6d94a79a24222e7e4766e@164.92.174.56:30303", + "enode://24951d3b76f20aed18e32096941d572b98518c9e4dace6b7d0b1f34292dfc5ee7d295453b955be4d2967c6ce1948c11513cd70d76dbee8d3034ddb40d63f5517@142.93.173.170:30303", + "enode://73e2396ac78c462287edd22957096890ca1995a4995c51a1fe24accbe931209fb0fc5359fc1043a0edad3fc53ba64fba5262255c70a03e5fca86f924c261ad4f@178.128.203.243:30303" + ] +} diff --git a/src/Nethermind/Chains/withdrawals_devnet.json b/src/Nethermind/Chains/withdrawals_devnet.json new file mode 100644 index 00000000000..a32c2d50d1b --- /dev/null +++ b/src/Nethermind/Chains/withdrawals_devnet.json @@ -0,0 +1,892 @@ +{ + "name": "Testnet", + "engine": { + "Ethash": {} + }, + "params": { + "gasLimitBoundDivisor": "0x400", + "registrar": "0x0000000000000000000000000000000000000000", + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0xffff", + "minGasLimit": "0x1388", + "networkID": "0x1469cd", + "MergeForkIdTransition": "0x0", + "maxCodeSize": "0x6000", + "maxCodeSizeTransition": "0x0", + "eip150Transition": "0x0", + "eip158Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip155Transition": "0x0", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "eip145Transition": "0x0", + "eip1014Transition": "0x0", + "eip1052Transition": "0x0", + "eip1283Transition": "0x0", + "eip1283DisableTransition": "0x0", + "eip152Transition": "0x0", + "eip1108Transition": "0x0", + "eip1344Transition": "0x0", + "eip1884Transition": "0x0", + "eip2028Transition": "0x0", + "eip2200Transition": "0x0", + "eip2565Transition": "0x0", + "eip2929Transition": "0x0", + "eip2930Transition": "0x0", + "eip1559Transition": "0x0", + "eip3198Transition": "0x0", + "eip3529Transition": "0x0", + "eip3541Transition": "0x0", + "eip4895TransitionTimestamp": "0x63a474ec", + "eip3855TransitionTimestamp": "0x63a474ec", + "eip3651TransitionTimestamp": "0x63a474ec", + "eip3860TransitionTimestamp": "0x63a474ec", + "terminalTotalDifficulty": "0x0" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x1234", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x01", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x63a438b0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "", + "gasLimit": "0x400000" + }, + "accounts": { + "0x0000000000000000000000000000000000000000": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000001": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000002": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000003": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000004": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000005": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000006": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000007": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000008": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000009": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000010": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000011": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000012": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000013": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000014": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000015": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000016": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000017": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000018": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000019": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000020": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000021": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000022": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000023": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000024": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000025": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000026": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000027": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000028": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000029": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000030": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000031": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000032": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000033": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000034": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000035": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000036": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000037": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000038": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000039": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000040": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000041": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000042": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000043": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000044": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000045": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000046": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000047": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000048": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000049": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000050": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000051": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000052": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000053": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000054": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000055": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000056": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000057": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000058": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000059": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000060": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000061": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000062": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000063": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000064": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000065": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000066": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000067": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000068": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000069": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000070": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000071": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000072": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000073": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000074": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000075": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000076": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000077": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000078": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000079": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000080": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000081": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000082": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000083": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000084": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000085": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000086": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000087": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000088": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000089": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000090": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000091": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000092": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000093": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000094": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000095": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000096": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000097": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000098": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000099": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009f": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000aa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ab": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ac": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ad": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ae": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000af": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ba": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000be": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ca": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ce": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000da": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000db": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000de": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000df": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ea": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000eb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ec": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ed": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ee": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ef": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fe": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ff": { + "balance": "1" + }, + "0x4242424242424242424242424242424242424242": { + "balance": "0", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + } + }, + "0x7bB4e40fC0Fc4cbA645b63717D996c394388D9b2": { + "balance": "1000000000000000000000000000" + }, + "0x368aA5d08abc4d62F0Ca81C045B41209449Ce1FD": { + "balance": "1000000000000000000000000000" + }, + "0x088f7C908A13417Ef367Cb89097CC11837e526Cb": { + "balance": "1000000000000000000000000000" + }, + "0x5Ef957B844bf9D340099ffeF89765D2826132c9E": { + "balance": "1000000000000000000000000000" + }, + "0x9Ebb4D26aF2a100419ea2a97d9Ff58e54897214B": { + "balance": "1000000000000000000000000000" + }, + "0xF8870c504B1BcF903A1b7B93c6f2c36e7dD306fF": { + "balance": "1000000000000000000000000000" + } + }, + "nodes": ["enode://d0411c2d31fdae12a532a8ab62f63670ca6d9cfdc3d56b9540c5d56ce6e0a63df36521bd824ced629ff4658ad081ac3bb000d4a58de6ac347b308aeb25294151@134.122.93.43:30303", + "enode://7ecb84ee11e49957d588f24f00d85fd65df6d4834c53b335e6aad5deff2d872be63611c8cb89bf0a371c3e5fcb094cb46e0f572c320d3710ce53152a5e4a55aa@178.128.203.61:30303", + "enode://b3d5a13f72271bccacfd9e9d42c19e9bfb2e5e6aec892cb74e99457047b3aa0c5922b301a7f597f7ca9de117c02ac08580256797db671d8b2f4c86d1e1bf6772@46.101.129.227:30303"] +} diff --git a/src/Nethermind/Chains/withdrawals_hivetests.json b/src/Nethermind/Chains/withdrawals_hivetests.json new file mode 100644 index 00000000000..0425dd6e993 --- /dev/null +++ b/src/Nethermind/Chains/withdrawals_hivetests.json @@ -0,0 +1,200 @@ +{ + "version": "1", + "engine": { + "clique": { + "params": { + "period": 1, + "epoch": 30000, + "blockReward": "0x0" + } + } + }, + "params": { + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip155Transition": "0x0", + "maxCodeSizeTransition": "0x0", + "maxCodeSize": 24576, + "maximumExtraDataSize": "0x400", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "eip145Transition": "0x0", + "eip1014Transition": "0x0", + "eip1052Transition": "0x0", + "eip1283Transition": "0x0", + "eip1283DisableTransition": "0x0", + "eip152Transition": "0x0", + "eip1108Transition": "0x0", + "eip1344Transition": "0x0", + "eip1884Transition": "0x0", + "eip2028Transition": "0x0", + "eip2200Transition": "0x0", + "eip2565Transition": "0x0", + "eip2718Transition": "0x0", + "eip2929Transition": "0x0", + "eip2930Transition": "0x0", + "eip1559Transition": "0x0", + "eip3238Transition": "0x0", + "eip3529Transition": "0x0", + "eip3541Transition": "0x0", + "eip3198Transition": "0x0", + "eip4895TransitionTimestamp": "0x1235", + "networkID": "0x7", + "chainID": "0x7" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000000" + } + }, + "difficulty": "0x30000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x1234", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0x2fefd8" + }, + "accounts": { + "0xcf49fda3be353c69b41ed96333cd24302da4556f": { + "balance": "0x123450000000000000000" + }, + "0x0161e041aad467a890839d5b08b138c1e6373072": { + "balance": "0x123450000000000000000" + }, + "0x87da6a8c6e9eff15d703fc2773e32f6af8dbe301": { + "balance": "0x123450000000000000000" + }, + "0xb97de4b8c857e4f6bc354f226dc3249aaee49209": { + "balance": "0x123450000000000000000" + }, + "0xc5065c9eeebe6df2c2284d046bfc906501846c51": { + "balance": "0x123450000000000000000" + }, + "0x0000000000000000000000000000000000000314": { + "balance": "0x0", + "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a223e05d1461006a578063abd1a0cf1461008d578063abfced1d146100d4578063e05c914a14610110578063e6768b451461014c575b610000565b346100005761007761019d565b6040518082815260200191505060405180910390f35b34610000576100be600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506101a3565b6040518082815260200191505060405180910390f35b346100005761010e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101ed565b005b346100005761014a600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610236565b005b346100005761017960048080359060200190919080359060200190919080359060200190919050506103c4565b60405180848152602001838152602001828152602001935050505060405180910390f35b60005481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5050565b7f6031a8d62d7c95988fa262657cd92107d90ed96e08d8f867d32f26edfe85502260405180905060405180910390a17f47e2689743f14e97f7dcfa5eec10ba1dff02f83b3d1d4b9c07b206cbbda66450826040518082815260200191505060405180910390a1817fa48a6b249a5084126c3da369fbc9b16827ead8cb5cdc094b717d3f1dcd995e2960405180905060405180910390a27f7890603b316f3509577afd111710f9ebeefa15e12f72347d9dffd0d65ae3bade81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18073ffffffffffffffffffffffffffffffffffffffff167f7efef9ea3f60ddc038e50cccec621f86a0195894dc0520482abf8b5c6b659e4160405180905060405180910390a28181604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a05b5050565b6000600060008585859250925092505b935093509390505600a165627a7a72305820aaf842d0d0c35c45622c5263cbb54813d2974d3999c8c38551d7c613ea2bc1170029", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x1234", + "0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9": "0x01" + } + }, + "0x0000000000000000000000000000000000000315": { + "balance": "0x9999999999999999999999999999999", + "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef2769ca1461003e575b610000565b3461000057610078600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061007a565b005b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f1935050505015610106578173ffffffffffffffffffffffffffffffffffffffff167f30a3c50752f2552dcc2b93f5b96866280816a986c0c0408cb6778b9fa198288f826040518082815260200191505060405180910390a25b5b50505600a165627a7a72305820637991fabcc8abad4294bf2bb615db78fbec4edff1635a2647d3894e2daf6a610029" + }, + "0x0000000000000000000000000000000000000316": { + "balance": "0x0", + "code": "0x444355" + }, + "0x0000000000000000000000000000000000000317": { + "balance": "0x0", + "code": "0x600160003555" + }, + "0x0000000000000000000000000000000000000001": { + "builtin": { + "name": "ecrecover", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000002": { + "builtin": { + "name": "sha256", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0x0000000000000000000000000000000000000003": { + "builtin": { + "name": "ripemd160", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0x0000000000000000000000000000000000000004": { + "builtin": { + "name": "identity", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + }, + "0x0000000000000000000000000000000000000005": { + "builtin": { + "name": "modexp", + "activate_at": "0x0", + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0x0000000000000000000000000000000000000006": { + "builtin": { + "name": "alt_bn128_add", + "activate_at": "0x0", + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000007": { + "builtin": { + "name": "alt_bn128_mul", + "activate_at": "0x0", + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } + }, + "0x0000000000000000000000000000000000000008": { + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": "0x0", + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000 + } + } + } + }, + "0x0000000000000000000000000000000000000009": { + "builtin": { + "name": "blake2_f", + "activate_at": "0x0", + "pricing": { + "blake2_f": { + "gas_per_round": 1 + } + } + } + } + } +} diff --git a/src/Nethermind/Chains/withdrawals_test.json b/src/Nethermind/Chains/withdrawals_test.json new file mode 100644 index 00000000000..752c3a16496 --- /dev/null +++ b/src/Nethermind/Chains/withdrawals_test.json @@ -0,0 +1,69 @@ +{ + "name": "TheMerge_Devnet", + "engine": { + "clique": { + "params": { + "period": 5, + "epoch": 30000 + } + } + }, + "params": { + "gasLimitBoundDivisor": "0x400", + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID": 1, + "eip150Transition": "0x0", + "eip155Transition": "0x0", + "eip158Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "eip145Transition": "0x0", + "eip1014Transition": "0x0", + "eip1052Transition": "0x0", + "eip1283Transition": "0x0", + "eip1283DisableTransition": "0x0", + "eip152Transition": "0x0", + "eip1108Transition": "0x0", + "eip1344Transition": "0x0", + "eip1884Transition": "0x0", + "eip2028Transition": "0x0", + "eip2200Transition": "0x0", + "eip2565Transition": "0x0", + "eip2929Transition": "0x0", + "eip2930Transition": "0x0", + "eip1559Transition": "0x0", + "eip3198Transition": "0x0", + "eip3529Transition": "0x0", + "eip3541Transition": "0x0", + "eip4895TransitionTimestamp": "0x0", + "terminalTotalDifficulty": "0x0" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x42", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData":"0x0000000000000000000000000000000000000000000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit":"0x1C9C380", + "baseFeePerGas":"0x7" + }, + "accounts": { + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": + { + "balance":"0x6d6172697573766477000000" + } + } +} diff --git a/src/Nethermind/Chains/zhejiang.json b/src/Nethermind/Chains/zhejiang.json new file mode 100644 index 00000000000..e5e369b7e3a --- /dev/null +++ b/src/Nethermind/Chains/zhejiang.json @@ -0,0 +1,896 @@ +{ + "name": "Testnet", + "engine": { + "Ethash": {} + }, + "params": { + "gasLimitBoundDivisor": "0x400", + "registrar": "0x0000000000000000000000000000000000000000", + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0xffff", + "minGasLimit": "0x1388", + "networkID": "0x1469cb", + "MergeForkIdTransition": "0x0", + "maxCodeSize": "0x6000", + "maxCodeSizeTransition": "0x0", + "eip150Transition": "0x0", + "eip158Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip155Transition": "0x0", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "eip145Transition": "0x0", + "eip1014Transition": "0x0", + "eip1052Transition": "0x0", + "eip1283Transition": "0x0", + "eip1283DisableTransition": "0x0", + "eip152Transition": "0x0", + "eip1108Transition": "0x0", + "eip1344Transition": "0x0", + "eip1884Transition": "0x0", + "eip2028Transition": "0x0", + "eip2200Transition": "0x0", + "eip2565Transition": "0x0", + "eip2929Transition": "0x0", + "eip2930Transition": "0x0", + "eip1559Transition": "0x0", + "eip3198Transition": "0x0", + "eip3529Transition": "0x0", + "eip3541Transition": "0x0", + "eip4895TransitionTimestamp": "0x63e26770", + "eip3855TransitionTimestamp": "0x63e26770", + "eip3651TransitionTimestamp": "0x63e26770", + "eip3860TransitionTimestamp": "0x63e26770", + "terminalTotalDifficulty": "0x0" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x1234", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x01", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x63da7df8", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "", + "gasLimit": "0x17D7840" + }, + "accounts": { + "0x0000000000000000000000000000000000000000": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000001": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000002": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000003": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000004": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000005": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000006": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000007": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000008": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000009": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000010": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000011": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000012": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000013": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000014": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000015": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000016": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000017": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000018": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000019": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000020": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000021": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000022": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000023": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000024": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000025": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000026": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000027": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000028": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000029": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000030": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000031": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000032": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000033": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000034": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000035": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000036": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000037": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000038": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000039": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000040": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000041": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000042": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000043": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000044": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000045": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000046": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000047": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000048": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000049": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000050": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000051": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000052": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000053": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000054": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000055": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000056": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000057": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000058": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000059": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000060": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000061": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000062": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000063": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000064": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000065": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000066": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000067": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000068": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000069": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000070": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000071": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000072": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000073": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000074": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000075": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000076": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000077": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000078": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000079": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000080": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000081": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000082": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000083": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000084": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000085": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000086": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000087": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000088": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000089": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000090": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000091": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000092": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000093": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000094": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000095": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000096": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000097": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000098": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000099": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009f": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000aa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ab": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ac": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ad": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ae": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000af": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ba": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000be": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ca": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ce": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000da": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000db": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000de": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000df": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ea": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000eb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ec": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ed": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ee": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ef": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fe": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ff": { + "balance": "1" + }, + "0x4242424242424242424242424242424242424242": { + "balance": "0", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + } + }, + "0x3E951C9f69a06Bc3AD71fF7358DbC56bEd94b9F2": { + "balance": "1000000000000000000000000000" + }, + "0xe228C30d4e5245f967ac21726d5412dA27aD071C": { + "balance": "1000000000000000000000000000" + }, + "0xD59Ce7Ccc6454a2D2C2e06bbcf71D0Beb33480eD": { + "balance": "1000000000000000000000000000" + }, + "0x1CF4D54414eF51b41f9B2238c57102ab2e61D1F2": { + "balance": "1000000000000000000000000000" + }, + "0x249bE3fDEd872338C733cF3975af9736bdCb9D4D": { + "balance": "1000000000000000000000000000" + }, + "0x3fCd1bff94513712f8cD63d1eD66776A67D5F78e": { + "balance": "1000000000000000000000000000" + } + }, + "nodes": [ + "enode://691c66d0ce351633b2ef8b4e4ef7db9966915ca0937415bd2b408df22923f274873b4d4438929e029a13a680140223dcf701cabe22df7d8870044321022dfefa@64.225.78.1:30303", + "enode://89347b9461727ee1849256d78e84d5c86cc3b4c6c5347650093982b726d71f3d08027e280b399b7b6604ceeda863283dcfe1a01e93728b4883114e9f8c7cc8ef@146.190.238.212:30303", + "enode://c2892072efe247f21ed7ebea6637ade38512a0ae7c5cffa1bf0786d5e3be1e7f40ff71252a21b36aa9de54e49edbcfc6962a98032adadfa29c8524262e484ad3@165.232.84.160:30303", + "enode://71e862580d3177a99e9837bd9e9c13c83bde63d3dba1d5cea18e89eb2a17786bbd47a8e7ae690e4d29763b55c205af13965efcaf6105d58e118a5a8ed2b0f6d0@68.183.13.170:30303", + "enode://2f6cf7f774e4507e7c1b70815f9c0ccd6515ee1170c991ce3137002c6ba9c671af38920f5b8ab8a215b62b3b50388030548f1d826cb6c2b30c0f59472804a045@161.35.147.98:30303" + ] +} diff --git a/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3651Tests.cs b/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3651Tests.cs new file mode 100644 index 00000000000..71ad0e0313e --- /dev/null +++ b/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3651Tests.cs @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Ethereum.Test.Base; +using FluentAssertions; +using NUnit.Framework; + +namespace Ethereum.Blockchain.Block.Test; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class Eip3651Tests : BlockchainTestBase +{ + [TestCaseSource(nameof(LoadTests))] + public async Task Test(BlockchainTest test) + { + await RunTest(test); + } + + public static IEnumerable LoadTests() + { + var loader = new TestsSourceLoader(new LoadLocalTestsStrategy(), "eip3651"); + return (IEnumerable)loader.LoadTests(); + } +} diff --git a/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3855Tests.cs b/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3855Tests.cs new file mode 100644 index 00000000000..8c4cf906106 --- /dev/null +++ b/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3855Tests.cs @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using System.Threading.Tasks; +using Ethereum.Test.Base; +using NUnit.Framework; + +namespace Ethereum.Blockchain.Block.Test; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class Eip3855Tests : BlockchainTestBase +{ + [TestCaseSource(nameof(LoadTests))] + public async Task Test(BlockchainTest test) + { + await RunTest(test); + } + + public static IEnumerable LoadTests() + { + var loader = new TestsSourceLoader(new LoadLocalTestsStrategy(), "eip3855"); + return (IEnumerable)loader.LoadTests(); + } +} diff --git a/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3860Tests.cs b/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3860Tests.cs new file mode 100644 index 00000000000..7d03036a8fa --- /dev/null +++ b/src/Nethermind/Ethereum.Blockchain.Block.Test/Eip3860Tests.cs @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using System.Threading.Tasks; +using Ethereum.Test.Base; +using NUnit.Framework; + +namespace Ethereum.Blockchain.Block.Test; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class Eip3860Tests : BlockchainTestBase +{ + [TestCaseSource(nameof(LoadTests))] + public async Task Test(BlockchainTest test) + { + await RunTest(test); + } + + public static IEnumerable LoadTests() + { + var loader = new TestsSourceLoader(new LoadLocalTestsStrategy(), "eip3860"); + return (IEnumerable)loader.LoadTests(); + } +} diff --git a/src/Nethermind/Ethereum.Blockchain.Block.Test/WithdrawalsTests.cs b/src/Nethermind/Ethereum.Blockchain.Block.Test/WithdrawalsTests.cs new file mode 100644 index 00000000000..e976066d8b0 --- /dev/null +++ b/src/Nethermind/Ethereum.Blockchain.Block.Test/WithdrawalsTests.cs @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using System.Threading.Tasks; +using Ethereum.Test.Base; +using NUnit.Framework; + +namespace Ethereum.Blockchain.Block.Test; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class WithdrawalsTests : BlockchainTestBase +{ + [TestCaseSource(nameof(LoadTests))] + public async Task Test(BlockchainTest test) + { + await RunTest(test); + } + + public static IEnumerable LoadTests() + { + var loader = new TestsSourceLoader(new LoadLocalTestsStrategy(), "withdrawals"); + return (IEnumerable)loader.LoadTests(); + } +} diff --git a/src/Nethermind/Ethereum.Test.Base/LoadLocalTestsStrategy.cs b/src/Nethermind/Ethereum.Test.Base/LoadLocalTestsStrategy.cs new file mode 100644 index 00000000000..8f2f33d3c1a --- /dev/null +++ b/src/Nethermind/Ethereum.Test.Base/LoadLocalTestsStrategy.cs @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using System.IO; +using Ethereum.Test.Base.Interfaces; + +namespace Ethereum.Test.Base; + +// Loads tests from src/ethereum-tests +public class LoadLocalTestsStrategy : ITestLoadStrategy +{ + public IEnumerable Load(string testDirectoryName, string wildcard = null) + { + List testsByName = new(); + IEnumerable testFiles = Directory.EnumerateFiles(GetLocalTestsDirectory() + testDirectoryName); + + foreach (string testFile in testFiles) + { + FileTestsSource fileTestsSource = new(testFile, wildcard); + try + { + var tests = fileTestsSource.LoadBlockchainTests(); + foreach (BlockchainTest blockchainTest in tests) + { + blockchainTest.Category = testDirectoryName; + } + + testsByName.AddRange(tests); + } + catch (Exception e) + { + testsByName.Add(new BlockchainTest { Name = testFile, LoadFailure = $"Failed to load: {e}" }); + } + } + + return testsByName; + } + + private string GetLocalTestsDirectory() + { + char pathSeparator = Path.AltDirectorySeparatorChar; + string currentDirectory = AppDomain.CurrentDomain.BaseDirectory; + + return currentDirectory.Remove(currentDirectory.LastIndexOf("src")) + $"src{pathSeparator}ethereum-tests{pathSeparator}"; + } + +} diff --git a/src/Nethermind/Nethermind.Abi.Contracts/Contract.ConstantContract.cs b/src/Nethermind/Nethermind.Abi.Contracts/Contract.ConstantContract.cs new file mode 100644 index 00000000000..a243d6851a9 --- /dev/null +++ b/src/Nethermind/Nethermind.Abi.Contracts/Contract.ConstantContract.cs @@ -0,0 +1,98 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Abi; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Evm; +using Nethermind.State; + +namespace Nethermind.Consensus.AuRa.Contracts +{ + public partial class Contract + { + /// + /// Gets constant version of the contract. Allowing to call contract methods without state modification. + /// + /// Source of readonly to call transactions. + /// Constant version of the contract. + protected ConstantContract GetConstant(IReadOnlyTransactionProcessorSource readOnlyReadOnlyTransactionProcessorSource) => + new ConstantContract(this, readOnlyReadOnlyTransactionProcessorSource); + + /// + /// Constant version of the contract. Allows to call contract methods without state modification. + /// + protected class ConstantContract + { + private readonly Contract _contract; + private readonly IReadOnlyTransactionProcessorSource _readOnlyReadOnlyTransactionProcessorSource; + + public ConstantContract(Contract contract, IReadOnlyTransactionProcessorSource readOnlyReadOnlyTransactionProcessorSource) + { + _contract = contract; + _readOnlyReadOnlyTransactionProcessorSource = readOnlyReadOnlyTransactionProcessorSource ?? throw new ArgumentNullException(nameof(readOnlyReadOnlyTransactionProcessorSource)); + } + + private byte[] Call(BlockHeader parentHeader, Transaction transaction) + { + using var readOnlyTransactionProcessor = _readOnlyReadOnlyTransactionProcessorSource.Get(GetState(parentHeader)); + return CallCore(readOnlyTransactionProcessor, parentHeader, transaction, true); + } + + private object[] Call(BlockHeader parentHeader, AbiFunctionDescription function, Address sender, params object[] arguments) + { + var result = CallRaw(parentHeader, function, sender, arguments); + var objects = _contract.AbiEncoder.Decode(function.GetReturnInfo(), result); + return objects; + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + public T Call(BlockHeader parentHeader, AbiFunctionDescription function, Address sender, params object[] arguments) + { + return (T)Call(parentHeader, function, sender, arguments)[0]; + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public (T1, T2) Call(BlockHeader parentHeader, AbiFunctionDescription function, Address sender, params object[] arguments) + { + var objects = Call(parentHeader, function, sender, arguments); + return ((T1)objects[0], (T2)objects[1]); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public byte[] CallRaw(BlockHeader parentHeader, AbiFunctionDescription function, Address sender, params object[] arguments) + { + var transaction = _contract.GenerateTransaction(function, sender, arguments); + var result = Call(parentHeader, transaction); + return result; + } + + private Keccak GetState(BlockHeader parentHeader) => parentHeader?.StateRoot ?? Keccak.EmptyTreeHash; + } + } +} diff --git a/src/Nethermind/Nethermind.Abi.Contracts/Contract.cs b/src/Nethermind/Nethermind.Abi.Contracts/Contract.cs new file mode 100644 index 00000000000..e31e2382d45 --- /dev/null +++ b/src/Nethermind/Nethermind.Abi.Contracts/Contract.cs @@ -0,0 +1,194 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Abi; +using Nethermind.Core; +using Nethermind.Crypto; +using Nethermind.Dirichlet.Numerics; +using Nethermind.Evm; +using Nethermind.Evm.Tracing; +using Nethermind.Specs.Forks; +using Nethermind.State; + +namespace Nethermind.Consensus.AuRa.Contracts +{ + /// + /// Base class for contracts that will be interacted by the node engine. + /// + /// + /// This class is intended to be inherited and concrete contract class should provide contract specific methods to be able for the node to use the contract. + /// + /// There are 3 main ways a node can interact with contract: + /// 1. It can that will be added to a block. + /// 2. It can contract and modify current state of execution. + /// 3. It can constant contract. This by design doesn't modify current state. It is designed as read-only operation that will allow the node to make decisions how it should operate. + /// + public abstract partial class Contract + { + /// + /// Default gas limit of transactions generated from contract. + /// + public const long DefaultContractGasLimit = 1_600_000L; + + private readonly ITransactionProcessor _transactionProcessor; + protected IAbiEncoder AbiEncoder { get; } + protected Address ContractAddress { get; } + + /// + /// Creates contract + /// + /// Transaction processor on which all should be run on. + /// Binary interface encoder/decoder. + /// Address where contract is deployed. + protected Contract(ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress) + { + _transactionProcessor = transactionProcessor ?? throw new ArgumentNullException(nameof(transactionProcessor)); + AbiEncoder = abiEncoder ?? throw new ArgumentNullException(nameof(abiEncoder)); + ContractAddress = contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)); + } + + private Transaction GenerateTransaction(byte[] transactionData, Address sender, long gasLimit = DefaultContractGasLimit) where T : Transaction, new() + { + var transaction = new T() + { + Value = UInt256.Zero, + Data = transactionData, + To = ContractAddress, + SenderAddress = sender ?? Address.SystemUser, + GasLimit = gasLimit, + GasPrice = UInt256.Zero, + }; + + transaction.Hash = transaction.CalculateHash(); + + return transaction; + } + + /// + /// Generates transaction. + /// That transaction can be added to a produced block or broadcasted - if is used as . + /// That transaction can be used in if is used as . + /// + /// Function in contract that is called by the transaction. + /// Sender of the transaction - caller of the function. + /// Arguments to the function. + /// Type of . + /// Transaction. + protected Transaction GenerateTransaction(AbiFunctionDescription function, Address sender, params object[] arguments) where T : Transaction, new() + => GenerateTransaction(AbiEncoder.Encode(function.GetCallInfo(), arguments), sender); + + private byte[] Call(BlockHeader header, Transaction transaction) => CallCore(_transactionProcessor, header, transaction); + + /// + /// Calls the function in contract, state modification is allowed. + /// + /// Header in which context the call is done. + /// Function in contract that is being called. + /// Sender of the transaction - caller of the function. + /// Arguments to the function. + /// Deserialized return value of the based on its definition. + protected object[] Call(BlockHeader header, AbiFunctionDescription function, Address sender, params object[] arguments) + { + var transaction = GenerateTransaction(function, sender, arguments); + var result = Call(header, transaction); + var objects = AbiEncoder.Decode(function.GetReturnInfo(), result); + return objects; + } + + /// + /// Helper method that actually does the actual call to . + /// + /// Actual transaction processor to be called upon. + /// Header in which context the call is done. + /// Transaction to be executed. + /// Is it restore call. + /// Bytes with result. + /// Thrown when there is an exception during execution or is . + private static byte[] CallCore(ITransactionProcessor transactionProcessor, BlockHeader header, Transaction transaction, bool callAndRestore = false) + { + bool failure; + + CallOutputTracer tracer = new CallOutputTracer(); + + try + { + if (callAndRestore) + { + transactionProcessor.CallAndRestore(transaction, header, tracer); + } + else + { + transactionProcessor.Execute(transaction, header, tracer); + } + + failure = tracer.StatusCode != StatusCode.Success; + } + catch (Exception e) + { + throw new AuRaException($"System call returned an exception '{e.Message}' at block {header.Number}.", e); + } + + if (failure) + { + throw new AuRaException($"System call returned error '{tracer.Error}' at block {header.Number}."); + } + else + { + return tracer.ReturnValue; + } + } + + private bool TryCall(BlockHeader header, Transaction transaction, out byte[] result) + { + CallOutputTracer tracer = new CallOutputTracer(); + + try + { + _transactionProcessor.Execute(transaction, header, tracer); + result = tracer.ReturnValue; + return tracer.StatusCode == StatusCode.Success; + } + catch (Exception) + { + result = null; + return false; + } + } + + /// + /// Same as but returns false instead of throwing . + /// + /// Header in which context the call is done. + /// Function in contract that is being called. + /// Sender of the transaction - caller of the function. + /// Deserialized return value of the based on its definition. + /// Arguments to the function. + /// true if function was otherwise false. + protected bool TryCall(BlockHeader header, AbiFunctionDescription function, Address sender, out object[] result, params object[] arguments) + { + var transaction = GenerateTransaction(function, sender, arguments); + if (TryCall(header, transaction, out var bytes)) + { + result = AbiEncoder.Decode(function.GetReturnInfo(), bytes); + return true; + } + + result = null; + return false; + } + + /// + /// Creates account if its not in current state. + /// + /// State provider. + protected void EnsureSystemAccount(IStateProvider stateProvider) + { + if (!stateProvider.AccountExists(Address.SystemUser)) + { + stateProvider.CreateAccount(Address.SystemUser, UInt256.Zero); + stateProvider.Commit(Homestead.Instance); + } + } + } +} From 8a44bad0299c433f0d118a1d85d23edf83b9ac6a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 15 May 2023 13:24:25 +0100 Subject: [PATCH 005/213] Chain push updates Fixes block pushing tests --- .../Validators/BlockValidator.cs | 2 +- .../Modules/Eth/EthRpcMulticallTests.cs | 9 +- .../Eth/Multicall/MultiCallBlockchainFork.cs | 214 +++++++++++------- 3 files changed, 143 insertions(+), 82 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs index 1a14417d415..4e935aa1ce4 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs @@ -110,7 +110,7 @@ public bool ValidateSuggestedBlock(Block block) /// List of tx receipts from the processed block (required only for better diagnostics when the receipt root is invalid). /// Block received from the network - unchanged. /// true if the is valid; otherwise, false. - public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) + public virtual bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) { bool isValid = processedBlock.Header.Hash == suggestedBlock.Header.Hash; if (!isValid) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs index 81d82f6fcb4..4cf35f58596 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -18,7 +18,6 @@ using Nethermind.Specs.Forks; using Nethermind.State; using NUnit.Framework; -using Nethermind.Blockchain; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -50,6 +49,10 @@ private static void allocateAccounts(MultiCallBlockStateCallsModel requestBlockO var t = acc.Balance; _stateProvider.SubtractFromBalance(address, 666, latestBlockSpec); + _stateProvider.Commit(latestBlockSpec); + _storageProvider.Commit(); + + if (acc != null) { if (accountOverride.Code is not null) @@ -138,6 +141,8 @@ public async Task Test_eth_multicall() var userBalanceResult_fromTm = await tmpChain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); userBalanceResult_fromTm.Result.ResultType.Should().Be(Core.ResultType.Success); + var tval = tmpChain.StateProvider.GetBalance(TestItem.AddressA); + Assert.AreNotEqual(userBalanceResult_fromTm.Data, userBalanceBefore.Data); //Check block has not updated values in the main chain @@ -151,7 +156,7 @@ public async Task Test_eth_multicall() GC.Collect(); GC.WaitForFullGCComplete(); - Assert.Equals(chain.BlockFinder.Head.Number, + Assert.AreEqual(chain.BlockFinder.Head.Number, blockNumberBefore); // tmp chain is disposed, main chain block number is still the same } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index c178d813f17..164a8d01c60 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -2,9 +2,8 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; -using Jint.Parser; using Nethermind.Blockchain; using Nethermind.Blockchain.Filters; using Nethermind.Blockchain.Find; @@ -27,6 +26,7 @@ using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; using Nethermind.Facade.Eth; +using Nethermind.Int256; using Nethermind.JsonRpc.Modules.Eth.FeeHistory; using Nethermind.JsonRpc.Modules.Eth.GasPrice; using Nethermind.Logging; @@ -38,57 +38,92 @@ namespace Nethermind.JsonRpc.Modules.Eth.Multicall; +public class SimplifiedBlockValidator : BlockValidator +{ + public override bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) + { + if (processedBlock.Header.StateRoot != suggestedBlock.Header.StateRoot) + { + //Note we mutate suggested block here to allow eth_multicall enforced State Root change + //and still pass validation + suggestedBlock.Header.StateRoot = processedBlock.Header.StateRoot; + suggestedBlock.Header.Hash = suggestedBlock.Header.CalculateHash(); + } + + bool isValid = processedBlock.Header.Hash == suggestedBlock.Header.Hash; + + if (processedBlock.Header.GasUsed != suggestedBlock.Header.GasUsed) isValid = false; + + if (processedBlock.Header.Bloom != suggestedBlock.Header.Bloom) isValid = false; + + if (processedBlock.Header.ReceiptsRoot != suggestedBlock.Header.ReceiptsRoot) isValid = false; + + + for (int i = 0; i < processedBlock.Transactions.Length; i++) + if (receipts[i].Error is not null && receipts[i].GasUsed == 0 && receipts[i].Error == "invalid") + isValid = false; + + return isValid; + } + + public SimplifiedBlockValidator(ITxValidator? txValidator, + IHeaderValidator? headerValidator, + IUnclesValidator? unclesValidator, + ISpecProvider? specProvider, + ILogManager? logManager) : base(txValidator, headerValidator, unclesValidator, specProvider, logManager) + { + } +} + /// -/// The MultiCallBlockchainFork class enables the creation of temporary in-memory blockchain instances, -/// based on a base chain's state. It's useful for simulating transactions, testing, -/// and executing smart contracts without affecting the base chain. The class offers RPC, -/// StateProvider, and StorageProvider utilities for swift chain data manipulation -/// and supports multi-block chain simulations using CreateBlock/FinaliseBlock pair manually or ForgeChainBlock method. +/// The MultiCallBlockchainFork class enables the creation of temporary in-memory blockchain instances, +/// based on a base chain's state. It's useful for simulating transactions, testing, +/// and executing smart contracts without affecting the base chain. The class offers RPC, +/// StateProvider, and StorageProvider utilities for swift chain data manipulation +/// and supports multi-block chain simulations using CreateBlock/FinaliseBlock pair manually or ForgeChainBlock method. /// public class MultiCallBlockchainFork : IDisposable { - private BlockchainProcessor ChainProcessor { get; set; } + private BlockchainProcessor ChainProcessor { get; } + private BlockProcessor BlockProcessor { get; } public StateProvider StateProvider { get; internal set; } public StorageProvider StorageProvider { get; internal set; } public ISpecProvider SpecProvider { get; internal set; } - public IBlockTree BlockTree { get; set; } - public IBlockFinder BlockFinder - { - get => BlockTree; - } - public Block? LatestBlock { get => BlockFinder.Head; } + public IBlockTree BlockTree { get; internal set; } + public IBlockFinder BlockFinder => BlockTree; + public Block? LatestBlock => BlockFinder.Head; public EthRpcModule EthRpcModule { get; internal set; } - public IReleaseSpec CurrentSpec { get => SpecProvider.GetSpec(LatestBlock!.Header); } + public IReleaseSpec CurrentSpec => SpecProvider.GetSpec(LatestBlock!.Header); /// - /// Creates a MultiCallBlockchainFork instance with the following steps: - /// 1. Initialize MultiCallBlockchainFork object - /// 2. Create read-only in-memory databases - /// 3. Set spec provider - /// 4. Set up log manager - /// 5. Establish EthereumEcdsa - /// 6. Configure TrieStore, StateProvider, and StorageProvider - /// 7. Prepare state reader - /// 8. Instantiate BlockTree - /// 9. Launch read-only state provider - /// 10. Create transaction comparer provider and transaction pool - /// 11. Start receipt storage - /// 12. Initialize virtual machine - /// 13. Initialize transaction processor and block preprocessor step - /// 14. Initialize header and block validators - /// 15. Initialize block processor - /// 16. Initialize and start chain processor - /// 17. Create and initialize temp database provider for RPC calls - /// 18. Initialize filter store and manager - /// 19. Set up read-only processing environment - /// 20. Initialize Bloom storage and log finder - /// 21. Set up timestamper, blockchain bridge, and gas price oracle - /// 22. Configure fee history oracle and sync config - /// 23. Initialize nonce manager, wallet, and transaction signer - /// 24. Create transaction sealer and sender - /// 25. Set up EthRpcModule + /// Creates a MultiCallBlockchainFork instance with the following steps: + /// 1. Initialize MultiCallBlockchainFork object + /// 2. Create read-only in-memory databases + /// 3. Set spec provider + /// 4. Set up log manager + /// 5. Establish EthereumEcdsa + /// 6. Configure TrieStore, StateProvider, and StorageProvider + /// 7. Prepare state reader + /// 8. Instantiate BlockTree + /// 9. Launch read-only state provider + /// 10. Create transaction comparer provider and transaction pool + /// 11. Start receipt storage + /// 12. Initialize virtual machine + /// 13. Initialize transaction processor and block preprocessor step + /// 14. Initialize header and block validators + /// 15. Initialize block processor + /// 16. Initialize and start chain processor + /// 17. Create and initialize temp database provider for RPC calls + /// 18. Initialize filter store and manager + /// 19. Set up read-only processing environment + /// 20. Initialize Bloom storage and log finder + /// 21. Set up timestamper, blockchain bridge, and gas price oracle + /// 22. Configure fee history oracle and sync config + /// 23. Initialize nonce manager, wallet, and transaction signer + /// 24. Create transaction sealer and sender + /// 25. Set up EthRpcModule /// /// Current state database /// Current Block database @@ -101,12 +136,9 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv { //Init BlockChain //Writable inMemory DBs on with access to the data of existing ones (will not modify existing data) - if (oldDbProvider == null) - { - throw new ArgumentNullException(); - } + if (oldDbProvider == null) throw new ArgumentNullException(); - var oldStack = oldDbProvider.StateDb.GetAllValues().ToList(); + List? oldStack = oldDbProvider.StateDb.GetAllValues().ToList(); IDb inMemStateDb = new ReadOnlyDb(oldDbProvider.StateDb, true); IDb inMemBlockDb = new ReadOnlyDb(oldDbProvider.BlocksDb, true); IDb inMemHeaderDb = new ReadOnlyDb(oldDbProvider.HeadersDb, true); @@ -128,10 +160,10 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv ILogManager logManager = SimpleConsoleLogManager.Instance; - var newStack = inMemStateDb.GetAllValues().ToList(); + List? newStack = inMemStateDb.GetAllValues().ToList(); TrieStore trieStore = new(inMemStateDb, logManager); - StateProvider = new(trieStore, inMemCodeDb, logManager); - StorageProvider = new(trieStore, StateProvider, logManager); + StateProvider = new StateProvider(trieStore, inMemCodeDb, logManager); + StorageProvider = new StorageProvider(trieStore, StateProvider, logManager); IReadOnlyTrieStore readOnlyTrieStore = trieStore.AsReadOnly(inMemStateDb); StateReader stateReader = new(readOnlyTrieStore, inMemCodeDb, logManager); @@ -146,6 +178,8 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv syncConfig, LimboLogs.Instance); + StateProvider.StateRoot = BlockTree.Head.StateRoot; + ChainHeadReadOnlyStateProvider readOnlyState = new(BlockTree, stateReader); TransactionComparerProvider transactionComparerProvider = new(SpecProvider, BlockTree); @@ -170,7 +204,8 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv SpecProvider, logManager); - TransactionProcessor txProcessor = new(SpecProvider, StateProvider, StorageProvider, virtualMachine, logManager); + TransactionProcessor txProcessor = + new(SpecProvider, StateProvider, StorageProvider, virtualMachine, logManager); RecoverSignatures blockPreprocessorStep = new(ethereumEcdsa, txPool, SpecProvider, logManager); HeaderValidator headerValidator = new( @@ -179,13 +214,13 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv SpecProvider, logManager); - BlockValidator blockValidator = new(new TxValidator(SpecProvider.ChainId), + SimplifiedBlockValidator blockValidator = new(new TxValidator(SpecProvider.ChainId), headerValidator, Always.Valid, SpecProvider, logManager); - BlockProcessor blockProcessor = new(SpecProvider, + BlockProcessor = new BlockProcessor(SpecProvider, blockValidator, NoBlockRewards.Instance, new BlockProcessor.BlockValidationTransactionsExecutor(txProcessor, StateProvider), @@ -195,9 +230,9 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv NullWitnessCollector.Instance, logManager); - ChainProcessor = new( + ChainProcessor = new BlockchainProcessor( BlockTree, - blockProcessor, + BlockProcessor, blockPreprocessorStep, stateReader, logManager, @@ -207,7 +242,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv //Init RPC IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = - new FilterManager(filterStore, blockProcessor, txPool, LimboLogs.Instance); + new FilterManager(filterStore, BlockProcessor, txPool, LimboLogs.Instance); ReadOnlyTxProcessingEnv processingEnv = new( new ReadOnlyDbProvider(DbProvider, false), new TrieStore(DbProvider.StateDb, LimboLogs.Instance).AsReadOnly(), @@ -262,65 +297,83 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv gasPriceOracle, new EthSyncingInfo(BlockTree, receiptStorage, syncConfig, logManager), feeHistoryOracle); - } - public IDbProvider DbProvider { get; set; } + public IDbProvider DbProvider { get; internal set; } //Create a new block next to current LatestBlock (BlockFinder.Head) public Block CreateBlock() { - var parent = LatestBlock?.Header; + BlockHeader? parent = LatestBlock?.Header; if (parent == null) throw new Exception("Existing header expected"); - Keccak? headerHash = parent.Hash; - BlockHeader blockHeader = new( parent.Hash, Keccak.OfAnEmptySequenceRlp, Address.Zero, - parent.Difficulty, parent.Number + 1, + UInt256.Zero, + parent.Number + 1, parent.GasLimit, parent.Timestamp + 1, Array.Empty()); + UInt256 difficulty = ConstantDifficulty.One.Calculate(blockHeader, parent); + blockHeader.Difficulty = difficulty; + blockHeader.TotalDifficulty = parent.TotalDifficulty + difficulty; + blockHeader.BaseFeePerGas = BaseFeeCalculator.Calculate(parent, SpecProvider.GetSpec(blockHeader)); + + blockHeader.ReceiptsRoot = Keccak.EmptyTreeHash; + blockHeader.TxRoot = Keccak.EmptyTreeHash; + blockHeader.Bloom = Bloom.Empty; - return new Block(blockHeader); + Block? block = new Block(blockHeader, Array.Empty(), Array.Empty()); + + block = ChainProcessor.Process(block, + ProcessingOptions.ProducingBlock, + NullBlockTracer.Instance); + + return block; } //Process Block and UpdateMainChain with it - public bool FinalizeBlock(Block CurrentBlock) + public bool FinalizeBlock(Block currentBlock) { StorageProvider.Commit(); - StorageProvider.CommitTrees(CurrentBlock.Number); - StateProvider.CommitTree(CurrentBlock.Number); - CurrentBlock.Header.StateRoot = StateProvider.StateRoot; - CurrentBlock.Header.Hash = CurrentBlock.Header.CalculateHash(); + StateProvider.Commit(SpecProvider.GetSpec(currentBlock.Header)); + StorageProvider.CommitTrees(currentBlock.Number); + StateProvider.CommitTree(currentBlock.Number); + StateProvider.RecalculateStateRoot(); - AddBlockResult res = BlockTree.SuggestBlock(CurrentBlock, BlockTreeSuggestOptions.ForceSetAsMain); + currentBlock.Header.StateRoot = StateProvider.StateRoot; + currentBlock.Header.IsPostMerge = true; //ToDo: Seal if necessary before merge 192 BPB + currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); + + AddBlockResult res = BlockTree.SuggestBlock(currentBlock, BlockTreeSuggestOptions.ForceSetAsMain); if (res != AddBlockResult.Added) return false; - Block? current = ChainProcessor.Process(CurrentBlock!, ProcessingOptions.None, NullBlockTracer.Instance); //TODo: Maybe Trace!! - if (current == null) return false; + //ChainProcessor uses parent.StateRoot with the Process, it gets bad on InitBranch due to _state/storage resets + Block[]? blocks = BlockProcessor.Process(currentBlock.StateRoot, + new List { currentBlock! }, + ProcessingOptions.ForceProcessing, + new BlockReceiptsTracer()); + + BlockTree.UpdateMainChain(blocks, true, true); - BlockTree.UpdateMainChain(new[] { current }, true); return true; } /// - /// Forges a new block in the temp blockchain using the provided action to manipulate state, release spec, spec provider, and storage provider. + /// Forges a new block in the temp blockchain using the provided action to manipulate state, release spec, spec + /// provider, and storage provider. /// /// An action representing the modifications to the blockchain state and storage. - public bool ForgeChainBlock(Action action) + public bool ForgeChainBlock(Action action) { //Prepare a block - var newBlock = CreateBlock(); - var tt = StateProvider.StateRoot; - var ttt = newBlock.Header.StateRoot; - //newBlock.Header.s - //Actual stuff + Block? newBlock = CreateBlock(); + action(StateProvider, CurrentSpec, SpecProvider, @@ -332,9 +385,11 @@ public bool ForgeChainBlock(Action Date: Mon, 15 May 2023 15:34:39 +0100 Subject: [PATCH 006/213] Update for IWorldState --- src/Nethermind/Nethermind.Db/ReadOnlyDb.cs | 2 +- .../Modules/Eth/EthRpcMulticallTests.cs | 20 +++++------ .../Eth/Multicall/MultiCallBlockchainFork.cs | 35 ++++++++----------- 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs index 1a1643e86d3..dc218d30165 100644 --- a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs +++ b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs @@ -96,7 +96,7 @@ public virtual void ClearTempChanges() _memDb.Clear(); } - public Span GetSpan(ReadOnlySpan key) => _memDb.Get(key).AsSpan(); + public Span GetSpan(ReadOnlySpan key) => Get(key).AsSpan(); public void PutSpan(ReadOnlySpan keyBytes, ReadOnlySpan value) { if (!_createInMemWriteStore) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs index 4cf35f58596..204bab5eec6 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -33,8 +33,8 @@ private static Task CreateChain(IReleaseSpec? releaseSpec = n return TestRpcBlockchain.ForTest(testMevRpcBlockchain).Build(testSpecProvider); } - private static void allocateAccounts(MultiCallBlockStateCallsModel requestBlockOne, IStateProvider _stateProvider, - IReleaseSpec latestBlockSpec, ISpecProvider _specProvider, IStorageProvider _storageProvider) + private static void allocateAccounts(MultiCallBlockStateCallsModel requestBlockOne, IWorldState _stateProvider, + IReleaseSpec latestBlockSpec, ISpecProvider _specProvider) { foreach (var accountOverride in requestBlockOne.StateOverrides) { @@ -50,15 +50,14 @@ private static void allocateAccounts(MultiCallBlockStateCallsModel requestBlockO _stateProvider.SubtractFromBalance(address, 666, latestBlockSpec); _stateProvider.Commit(latestBlockSpec); - _storageProvider.Commit(); + // _storageProvider.Commit(); if (acc != null) { if (accountOverride.Code is not null) { - Keccak codeHash = _stateProvider.UpdateCode(accountOverride.Code); - _stateProvider.UpdateCodeHash(address, codeHash, + _stateProvider.InsertCode(address, accountOverride.Code, latestBlockSpec, true); } } @@ -68,7 +67,7 @@ private static void allocateAccounts(MultiCallBlockStateCallsModel requestBlockO { foreach (KeyValuePair storage in accountOverride.State) { - _storageProvider.Set(new StorageCell(address, storage.Key), + _stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.WithoutLeadingZeros().ToArray()); } } @@ -77,7 +76,7 @@ private static void allocateAccounts(MultiCallBlockStateCallsModel requestBlockO { foreach (KeyValuePair storage in accountOverride.StateDiff) { - _storageProvider.Set(new StorageCell(address, storage.Key), + _stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.WithoutLeadingZeros().ToArray()); } } @@ -107,10 +106,10 @@ public async Task Test_eth_multicall() userBalanceBefore.Result.ResultType.Should().Be(Core.ResultType.Success); //Force persistancy of head block in main chain + chain.BlockTree.UpdateMainChain(new []{chain.BlockFinder.Head}, true, true ); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); var tt = chain.TrieStore; - using (var tmpChain =new MultiCallBlockchainFork(chain.DbProvider, chain.SpecProvider)) { //Check if tmpChain initialised @@ -128,10 +127,9 @@ public async Task Test_eth_multicall() var num_tmp = userBalanceBefore_fromTmp.Data.Value; Assert.AreEqual(userBalanceBefore_fromTmp.Data, userBalanceBefore.Data); - var processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, storageProvider) => + var processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider) => { - allocateAccounts(requestBlockOne, stateProvider, currentSpec, specProvider, - storageProvider); + allocateAccounts(requestBlockOne, stateProvider, currentSpec, specProvider); }); //Check block has been added to chain as main diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index 164a8d01c60..41f6c706621 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -32,6 +32,7 @@ using Nethermind.Logging; using Nethermind.State; using Nethermind.State.Repositories; +using Nethermind.Synchronization.ParallelSync; using Nethermind.Trie.Pruning; using Nethermind.TxPool; using Nethermind.Wallet; @@ -87,8 +88,7 @@ public class MultiCallBlockchainFork : IDisposable private BlockchainProcessor ChainProcessor { get; } private BlockProcessor BlockProcessor { get; } - public StateProvider StateProvider { get; internal set; } - public StorageProvider StorageProvider { get; internal set; } + public IWorldState StateProvider { get; internal set; } public ISpecProvider SpecProvider { get; internal set; } public IBlockTree BlockTree { get; internal set; } public IBlockFinder BlockFinder => BlockTree; @@ -137,7 +137,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv //Init BlockChain //Writable inMemory DBs on with access to the data of existing ones (will not modify existing data) if (oldDbProvider == null) throw new ArgumentNullException(); - + List? oldStack = oldDbProvider.StateDb.GetAllValues().ToList(); IDb inMemStateDb = new ReadOnlyDb(oldDbProvider.StateDb, true); IDb inMemBlockDb = new ReadOnlyDb(oldDbProvider.BlocksDb, true); @@ -160,19 +160,17 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv ILogManager logManager = SimpleConsoleLogManager.Instance; - List? newStack = inMemStateDb.GetAllValues().ToList(); TrieStore trieStore = new(inMemStateDb, logManager); - StateProvider = new StateProvider(trieStore, inMemCodeDb, logManager); - StorageProvider = new StorageProvider(trieStore, StateProvider, logManager); + StateProvider = new WorldState(trieStore, inMemCodeDb, logManager); IReadOnlyTrieStore readOnlyTrieStore = trieStore.AsReadOnly(inMemStateDb); StateReader stateReader = new(readOnlyTrieStore, inMemCodeDb, logManager); SyncConfig syncConfig = new(); - BlockTree = new BlockTree(inMemBlockDb, - inMemHeaderDb, - inMemBlockInfoDb, - inMemMetadataDb, - new ChainLevelInfoRepository(inMemBlockInfoDb), + BlockTree = new BlockTree(DbProvider.BlocksDb, + DbProvider.HeadersDb, + DbProvider.BlockInfosDb, + DbProvider.MetadataDb, + new ChainLevelInfoRepository(DbProvider.BlockInfosDb), SpecProvider, NullBloomStorage.Instance, syncConfig, @@ -205,7 +203,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv logManager); TransactionProcessor txProcessor = - new(SpecProvider, StateProvider, StorageProvider, virtualMachine, logManager); + new(SpecProvider, StateProvider, virtualMachine, logManager); RecoverSignatures blockPreprocessorStep = new(ethereumEcdsa, txPool, SpecProvider, logManager); HeaderValidator headerValidator = new( @@ -225,7 +223,6 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv NoBlockRewards.Instance, new BlockProcessor.BlockValidationTransactionsExecutor(txProcessor, StateProvider), StateProvider, - StorageProvider, receiptStorage, NullWitnessCollector.Instance, logManager); @@ -295,7 +292,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv LimboLogs.Instance, SpecProvider, gasPriceOracle, - new EthSyncingInfo(BlockTree, receiptStorage, syncConfig, logManager), + new EthSyncingInfo(BlockTree, receiptStorage, syncConfig, new StaticSelector(SyncMode.All), logManager), feeHistoryOracle); } @@ -339,9 +336,7 @@ public Block CreateBlock() //Process Block and UpdateMainChain with it public bool FinalizeBlock(Block currentBlock) { - StorageProvider.Commit(); StateProvider.Commit(SpecProvider.GetSpec(currentBlock.Header)); - StorageProvider.CommitTrees(currentBlock.Number); StateProvider.CommitTree(currentBlock.Number); StateProvider.RecalculateStateRoot(); @@ -368,16 +363,16 @@ public bool FinalizeBlock(Block currentBlock) /// provider, and storage provider. /// /// An action representing the modifications to the blockchain state and storage. - public bool ForgeChainBlock(Action action) + public bool ForgeChainBlock(Action action) { //Prepare a block Block? newBlock = CreateBlock(); action(StateProvider, CurrentSpec, - SpecProvider, - StorageProvider); + SpecProvider + ); //Add block bool results = FinalizeBlock(newBlock); From 90236bf11fd212904689ccfdbbfc3b6248834f65 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 15 May 2023 15:50:53 +0100 Subject: [PATCH 007/213] fixing workflow files --- .github/workflows/sync-testnets.yml | 263 ++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 .github/workflows/sync-testnets.yml diff --git a/.github/workflows/sync-testnets.yml b/.github/workflows/sync-testnets.yml new file mode 100644 index 00000000000..d7a624786ae --- /dev/null +++ b/.github/workflows/sync-testnets.yml @@ -0,0 +1,263 @@ +name: Sync Testnets + +on: + push: + branches: ["master"] + workflow_dispatch: + +jobs: + chiado: + name: "Run sync of chiado testnet" + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Configure settings + id: settings + run: | + echo "BUILD_TIMESTAMP=$(date '+%s')" >> $GITHUB_OUTPUT + echo "COMMIT_HASH=$(git describe --always --exclude=* --abbrev=40)" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build docker image + run: docker buildx build --platform=linux/amd64 -t current_branch_image -f Dockerfile --build-arg COMMIT_HASH=${{ steps.settings.outputs.COMMIT_HASH }} --build-arg BUILD_TIMESTAMP=${{ steps.settings.outputs.BUILD_TIMESTAMP}} --load . + + - name: Setup Go environment + uses: actions/setup-go@v4.0.0 + + - name: Install Sedge environment + run: | + echo "Downloading sedge sources..." + git clone https://github.com/NethermindEth/sedge.git sedge --branch main --single-branch + echo "Sources downloaded." + cd sedge + echo "Building sedge..." + make compile + + - name: Run Sedge + working-directory: sedge + run: | + echo 'Generating sedge docker...' + ./build/sedge deps install + ./build/sedge generate --logging none -p $GITHUB_WORKSPACE/sedge \ + full-node --map-all --no-mev-boost --no-validator --network chiado \ + -c lighthouse:sigp/lighthouse:latest -e nethermind:current_branch_image \ + --el-extra-flag Sync.NonValidatorNode=true --el-extra-flag Sync.DownloadBodiesInFastSync=false \ + --el-extra-flag Sync.DownloadReceiptsInFastSync=false \ + --el-extra-flag JsonRpc.EnabledModules=[Eth,Subscribe,Trace,TxPool,Web3,Personal,Proof,Net,Parity,Health,Rpc,Debug] \ + --cl-extra-flag checkpoint-sync-url=http://139.144.26.89:4000/ + echo 'Running sedge...' + docker compose up -d + + - name: Wait for Chiado to sync + run: | + set +e + + # Check if Docker container is running + MAX_RETRIES=10 + RETRY_COUNT=0 + while [[ ! "$(docker inspect -f '{{.State.Status}}' sedge-execution-client 2>/dev/null)" =~ "running" ]] && [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do + echo "Docker container 'sedge-execution-client' is not running. Retrying in 10 seconds..." + let "RETRY_COUNT+=1" + sleep 10 + done + + if [[ ! "$(docker inspect -f '{{.State.Status}}' sedge-execution-client 2>/dev/null)" =~ "running" ]]; then + echo "Error: Docker container 'sedge-execution-client' is not running after $MAX_RETRIES attempts." + exit 404 + fi + + # Check readiness of the service + RETRY_COUNT=0 + while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do + RESPONSE=$(curl -s --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" localhost:8545) + if [[ $? -eq 0 ]] && [[ -n "$RESPONSE" ]]; then + break + else + echo "Service not ready. Retrying in 10 seconds..." + let "RETRY_COUNT+=1" + sleep 10 + fi + done + + if [[ $RETRY_COUNT -eq $MAX_RETRIES ]]; then + echo "Error: Service not ready after $MAX_RETRIES attempts." + exit 403 + fi + + SYNCING_RESULT="" + DEBUG_RESULT="" + while [[ "$SYNCING_RESULT" != "false" ]] || [[ "$DEBUG_RESULT" != *"WaitingForBlock"* ]]; do + sleep 10 + RESPONSE_SYNCING=$(curl -s --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" localhost:8545) + SYNCING_RESULT=$(echo $RESPONSE_SYNCING | jq .result) + echo "eth_syncing endpoint response: $RESPONSE_SYNCING" + + RESPONSE_DEBUG=$(curl -s --data '{"method":"debug_getSyncStage","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" localhost:8545) + DEBUG_RESULT=$(echo $RESPONSE_DEBUG | jq -r .result) + echo "debug_getSyncStage endpoint response: $RESPONSE_DEBUG" + + done + echo "Sedge is synced." + + - name: Display Docker logs + working-directory: sedge + run: docker compose logs + + - name: Verify health of a node + working-directory: sedge + run: | + set +e + + dockerLogs=$(docker compose logs execution 2>/dev/null) + + validLines=$(echo "$dockerLogs" | grep -E "Valid. Result of a new payload:") + countValid=$(if [ -z "$validLines" ]; then echo 0; else echo "$validLines" | wc -l; fi) + if [ $countValid -lt 1 ]; then + echo "Error: No lines found for 'Valid. Result of a new payload:' - probably node is not progressing well." + exit 20 + fi + + invalidLines=$(echo "$dockerLogs" | grep -E "Invalid|Exception") + countInvalid=$(if [ -z "$invalidLines" ]; then echo 0; else echo "$invalidLines" | wc -l; fi) + if [ $countInvalid -gt 0 ]; then + echo "Error: Lines found for 'Invalid' or 'Exception'" + echo "$invalidLines" + exit 30 + fi + + # If the script reaches this point, it means there were valid lines and no invalid lines. + echo "Valid lines:" + echo "$validLines" + + sepolia: + name: "Run sync of sepolia testnet" + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Configure settings + id: settings + run: | + echo "BUILD_TIMESTAMP=$(date '+%s')" >> $GITHUB_OUTPUT + echo "COMMIT_HASH=$(git describe --always --exclude=* --abbrev=40)" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build docker image + run: docker buildx build --platform=linux/amd64 -t current_branch_image -f Dockerfile --build-arg COMMIT_HASH=${{ steps.settings.outputs.COMMIT_HASH }} --build-arg BUILD_TIMESTAMP=${{ steps.settings.outputs.BUILD_TIMESTAMP}} --load . + + - name: Setup Go environment + uses: actions/setup-go@v4.0.0 + + - name: Install Sedge environment + run: | + echo "Downloading sedge sources..." + git clone https://github.com/NethermindEth/sedge.git sedge --branch main --single-branch + echo "Sources downloaded." + cd sedge + echo "Building sedge..." + make compile + + - name: Run Sedge + working-directory: sedge + run: | + echo 'Generating sedge docker...' + ./build/sedge deps install + ./build/sedge generate --logging none -p $GITHUB_WORKSPACE/sedge \ + full-node --map-all --no-mev-boost --no-validator --network sepolia \ + -c lighthouse:sigp/lighthouse:latest -e nethermind:current_branch_image \ + --el-extra-flag Sync.NonValidatorNode=true --el-extra-flag Sync.DownloadBodiesInFastSync=false \ + --el-extra-flag Sync.DownloadReceiptsInFastSync=false \ + --el-extra-flag JsonRpc.EnabledModules=[Eth,Subscribe,Trace,TxPool,Web3,Personal,Proof,Net,Parity,Health,Rpc,Debug] \ + --cl-extra-flag checkpoint-sync-url=https://beaconstate-sepolia.chainsafe.io + echo 'Running sedge...' + docker compose up -d + + - name: Wait for Sepolia to sync + run: | + set +e + + # Check if Docker container is running + MAX_RETRIES=10 + RETRY_COUNT=0 + while [[ ! "$(docker inspect -f '{{.State.Status}}' sedge-execution-client 2>/dev/null)" =~ "running" ]] && [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do + echo "Docker container 'sedge-execution-client' is not running. Retrying in 10 seconds..." + let "RETRY_COUNT+=1" + sleep 10 + done + + if [[ ! "$(docker inspect -f '{{.State.Status}}' sedge-execution-client 2>/dev/null)" =~ "running" ]]; then + echo "Error: Docker container 'sedge-execution-client' is not running after $MAX_RETRIES attempts." + exit 404 + fi + + # Check readiness of the service + RETRY_COUNT=0 + while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do + RESPONSE=$(curl -s --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" localhost:8545) + if [[ $? -eq 0 ]] && [[ -n "$RESPONSE" ]]; then + break + else + echo "Service not ready. Retrying in 10 seconds..." + let "RETRY_COUNT+=1" + sleep 10 + fi + done + + if [[ $RETRY_COUNT -eq $MAX_RETRIES ]]; then + echo "Error: Service not ready after $MAX_RETRIES attempts." + exit 403 + fi + + SYNCING_RESULT="" + DEBUG_RESULT="" + while [[ "$SYNCING_RESULT" != "false" ]] || [[ "$DEBUG_RESULT" != *"WaitingForBlock"* ]]; do + sleep 10 + RESPONSE_SYNCING=$(curl -s --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" localhost:8545) + SYNCING_RESULT=$(echo $RESPONSE_SYNCING | jq .result) + echo "eth_syncing endpoint response: $RESPONSE_SYNCING" + + RESPONSE_DEBUG=$(curl -s --data '{"method":"debug_getSyncStage","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" localhost:8545) + DEBUG_RESULT=$(echo $RESPONSE_DEBUG | jq -r .result) + echo "debug_getSyncStage endpoint response: $RESPONSE_DEBUG" + + done + echo "Sedge is synced." + + - name: Display Docker logs + working-directory: sedge + run: docker compose logs + + - name: Verify health of a node + working-directory: sedge + run: | + set +e + + dockerLogs=$(docker compose logs execution 2>/dev/null) + + validLines=$(echo "$dockerLogs" | grep -E "Valid. Result of a new payload:") + countValid=$(if [ -z "$validLines" ]; then echo 0; else echo "$validLines" | wc -l; fi) + if [ $countValid -lt 1 ]; then + echo "Error: No lines found for 'Valid. Result of a new payload:' - probably node is not progressing well." + exit 20 + fi + + invalidLines=$(echo "$dockerLogs" | grep -E "Invalid|Exception") + countInvalid=$(if [ -z "$invalidLines" ]; then echo 0; else echo "$invalidLines" | wc -l; fi) + if [ $countInvalid -gt 0 ]; then + echo "Error: Lines found for 'Invalid' or 'Exception'" + echo "$invalidLines" + exit 30 + fi + + # If the script reaches this point, it means there were valid lines and no invalid lines. + echo "Valid lines:" + echo "$validLines" From ad3a8524f5f728a27c3a7462b2d18d323acf3c55 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 15 May 2023 15:54:08 +0100 Subject: [PATCH 008/213] removing files not present in master --- src/ethereum-tests | 1 - 1 file changed, 1 deletion(-) delete mode 160000 src/ethereum-tests diff --git a/src/ethereum-tests b/src/ethereum-tests deleted file mode 160000 index 46f4ea3857c..00000000000 --- a/src/ethereum-tests +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 46f4ea3857c717efdb04d8810bc81fda7f71c138 From 4bf1f23c45f344e5f3a85d94712ed4a6ba709a9d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 24 May 2023 03:25:06 +0100 Subject: [PATCH 009/213] Tested Precompiles modification Demo with const EcRecover --- .../Processing/ReadOnlyTxProcessingEnv.cs | 2 +- .../Nethermind.Evm/VirtualMachine.cs | 2 +- .../Modules/Eth/EthRpcMulticallTests.cs | 321 +++++++++++++++--- .../Modules/Eth/SecureStringWrapper.cs | 52 +++ .../Eth/Multicall/MultiCallBlockValidator.cs | 35 ++ .../Eth/Multicall/MultiCallBlockchainFork.cs | 114 +++---- .../MultiCallReadOnlyTxProcessingEnv.cs | 27 ++ .../Eth/Multicall/MultiCallVirtualMachine.cs | 47 +++ .../Nethermind.Mev.Test/MevRpcModuleTests.cs | 3 +- 9 files changed, 483 insertions(+), 120 deletions(-) create mode 100644 src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/SecureStringWrapper.cs create mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs create mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs create mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index f99c5f01b12..fe44cce7305 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -25,7 +25,7 @@ public class ReadOnlyTxProcessingEnv : IReadOnlyTxProcessorSource public IBlockTree BlockTree { get; } public IReadOnlyDbProvider DbProvider { get; } public IBlockhashProvider BlockhashProvider { get; } - public IVirtualMachine Machine { get; } + public IVirtualMachine Machine { get; protected set; } public ReadOnlyTxProcessingEnv( IDbProvider? dbProvider, diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index f70bc299e41..e48fbd6aafa 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -371,7 +371,7 @@ private void RevertParityTouchBugAccount(IReleaseSpec spec) } } - public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) + public virtual CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) { if (codeSource.IsPrecompile(vmSpec)) { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs index 204bab5eec6..fd7a0fbdff5 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -5,19 +5,35 @@ using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions; +using Nethermind.Abi; +using Nethermind.Blockchain.Contracts.Json; using Nethermind.Blockchain.Find; -using Nethermind.Core.Crypto; using Nethermind.Core; +using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; +using Nethermind.Core.Test.IO; +using Nethermind.Crypto; +using Nethermind.Evm; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Evm.Precompiles; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; +using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth.Multicall; +using Nethermind.KeyStore; +using Nethermind.KeyStore.Config; +using Nethermind.Logging; +using Nethermind.Serialization.Json; using Nethermind.Specs; using Nethermind.Specs.Forks; using Nethermind.State; +using Nethermind.Trie.Pruning; +using Nethermind.TxPool; +using Nethermind.Wallet; using NUnit.Framework; +using ResultType = Nethermind.Core.ResultType; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -34,83 +50,297 @@ private static Task CreateChain(IReleaseSpec? releaseSpec = n } private static void allocateAccounts(MultiCallBlockStateCallsModel requestBlockOne, IWorldState _stateProvider, - IReleaseSpec latestBlockSpec, ISpecProvider _specProvider) + IReleaseSpec latestBlockSpec, ISpecProvider _specProvider, MultiCallVirtualMachine virtualMachine) { - foreach (var accountOverride in requestBlockOne.StateOverrides) + foreach (AccountOverride accountOverride in requestBlockOne.StateOverrides) { - var address = accountOverride.Address; - var acc = _stateProvider.GetAccount(address); + Address address = accountOverride.Address; + Account? acc = _stateProvider.GetAccount(address); if (acc == null) { _stateProvider.CreateAccount(address, accountOverride.Balance, accountOverride.Nonce); acc = _stateProvider.GetAccount(address); } - var t = acc.Balance; + UInt256 t = acc.Balance; _stateProvider.SubtractFromBalance(address, 666, latestBlockSpec); _stateProvider.Commit(latestBlockSpec); - // _storageProvider.Commit(); + // _storageProvider.Commit(); if (acc != null) - { if (accountOverride.Code is not null) - { - _stateProvider.InsertCode(address, accountOverride.Code, - latestBlockSpec, true); - } - } + virtualMachine.SetOverwrite(address, new CodeInfo(accountOverride.Code)); if (accountOverride.State is not null) { + accountOverride.State = new Dictionary(); foreach (KeyValuePair storage in accountOverride.State) - { _stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.WithoutLeadingZeros().ToArray()); - } } if (accountOverride.StateDiff is not null) { foreach (KeyValuePair storage in accountOverride.StateDiff) - { _stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.WithoutLeadingZeros().ToArray()); - } } } } + /* Compiled contract + * Call example for TestItem.AddressA + * recover 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 28 0x7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c4403 0x7e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055 + * returns address: 0xb7705aE4c6F81B66cdB323C65f4E8133690fC099 + + pragma solidity ^0.8.7; + + contract EcrecoverProxy { + function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure returns (address) { + return ecrecover(hash, v, r, s); + } + } + */ + private const string EcRecoverContractBytecode = + "608060405234801561001057600080fd5b5061028b806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c2bf17b014610030575b600080fd5b61004a6004803603810190610045919061012f565b610060565b60405161005791906101d7565b60405180910390f35b6000600185858585604051600081526020016040526040516100859493929190610210565b6020604051602081039080840390855afa1580156100a7573d6000803e3d6000fd5b505050602060405103519050949350505050565b600080fd5b6000819050919050565b6100d3816100c0565b81146100de57600080fd5b50565b6000813590506100f0816100ca565b92915050565b600060ff82169050919050565b61010c816100f6565b811461011757600080fd5b50565b60008135905061012981610103565b92915050565b60008060008060808587031215610149576101486100bb565b5b6000610157878288016100e1565b94505060206101688782880161011a565b9350506040610179878288016100e1565b925050606061018a878288016100e1565b91505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101c182610196565b9050919050565b6101d1816101b6565b82525050565b60006020820190506101ec60008301846101c8565b92915050565b6101fb816100c0565b82525050565b61020a816100f6565b82525050565b600060808201905061022560008301876101f2565b6102326020830186610201565b61023f60408301856101f2565b61024c60608301846101f2565b9594505050505056fea26469706673582212204855668ab62273dde1249722b61c57ad057ef3d17384f21233e1b7bb309db7e464736f6c63430008120033"; + + //Taken from contract compiler output metadata + private const string EcRecoverContractJsonAbi = @"[ + { + ""payable"": false, + ""inputs"": [ + { + ""internalType"": ""bytes32"", + ""name"": ""hash"", + ""type"": ""bytes32"" + }, + { + ""internalType"": ""uint8"", + ""name"": ""v"", + ""type"": ""uint8"" + }, + { + ""internalType"": ""bytes32"", + ""name"": ""r"", + ""type"": ""bytes32"" + }, + { + ""internalType"": ""bytes32"", + ""name"": ""s"", + ""type"": ""bytes32"" + } + ], + ""name"": ""recover"", + ""outputs"": [ + { + ""internalType"": ""address"", + ""name"": """", + ""type"": ""address"" + } + ], + ""stateMutability"": ""pure"", + ""type"": ""function"" + } +]"; + + + private async Task DeployEcRecoverContract(TestRpcBlockchain chain1) + { + byte[] bytecode = Bytes.FromHexString(EcRecoverContractBytecode); + Transaction tx = new() + { + Value = UInt256.Zero, + Nonce = 0, + Data = bytecode, + GasLimit = 3_000_000, + SenderAddress = TestItem.PublicKeyB.Address, + To = null, + GasPrice = 20.GWei() + }; + // calculate contract address + + ILogManager logManager = SimpleConsoleLogManager.Instance; + IKeyStoreConfig config = new KeyStoreConfig(); + config.KeyStoreDirectory = TempPath.GetTempDirectory().Path; + ISymmetricEncrypter encrypter = new AesEncrypter(config, LimboLogs.Instance); + + IWallet? wallet = new DevKeyStoreWallet( + new FileKeyStore(config, + new EthereumJsonSerializer(), encrypter, new CryptoRandom(), + LimboLogs.Instance, new PrivateKeyStoreIOSettingsProvider(config)), + LimboLogs.Instance); + + ITxSigner txSigner = new WalletTxSigner(wallet, chain1.SpecProvider.ChainId); + TxSealer txSealer = new(txSigner, chain1.Timestamper); + TxPoolSender txSender = new(chain1.TxPool, txSealer, chain1.NonceManager, chain1.EthereumEcdsa); + + //Tested Alternative, often faster + //chain.EthereumEcdsa.Sign(TestItem.PrivateKeyB, tx, true); + //tx.Hash = tx.CalculateHash(); + //await chain.AddBlock(true, tx); + //TxReceipt? createContractTxReceipt = chain.Bridge.GetReceipt(tx.Hash); + //createContractTxReceipt.ContractAddress.Should().NotBeNull($"Contract transaction {tx.Hash} was not deployed."); + + Address contractAddress1 = null; + using (SecureStringWrapper pass = new("testB")) + { + wallet.Import(TestItem.PrivateKeyB.KeyBytes, pass.SecureData); + wallet.UnlockAccount(TestItem.PublicKeyB.Address, pass.SecureData, TimeSpan.MaxValue); + (Keccak hash, AcceptTxResult? code) = await txSender.SendTransaction(tx, + TxHandlingOptions.ManagedNonce | TxHandlingOptions.PersistentBroadcast); + + code.Value.Should().Be(AcceptTxResult.Accepted); + Transaction[] txs = chain1.TxPool.GetPendingTransactions(); + + await chain1.AddBlock(true, txs); + + + TxReceipt createContractTxReceipt = null; + while (createContractTxReceipt == null) + { + await Task.Delay(100); // wait... todo enforce! + createContractTxReceipt = chain1.Bridge.GetReceipt(tx.Hash); + } + + createContractTxReceipt.ContractAddress.Should() + .NotBeNull($"Contract transaction {tx.Hash} was not deployed."); + contractAddress1 = createContractTxReceipt.ContractAddress; + } + + return contractAddress1; + } + /// - /// This test verifies that a temporary forked blockchain updates the user balance and block number - /// independently of the main chain, ensuring the main chain remains intact. + /// This test verifies that a temporary forked blockchain can updates precompiles /// [Test] - public async Task Test_eth_multicall() + public async Task Test_eth_multicall_erc() { - var chain = await CreateChain(); + byte[] GenerateTransactionData(Keccak keccak, ulong @ulong, byte[] bytes1, byte[] bytes2) + { + AbiDefinitionParser parser = new(); + AbiDefinition call = parser.Parse(EcRecoverContractJsonAbi); + AbiEncodingInfo functionInfo = call.GetFunction("recover").GetCallInfo(); + byte[] transactionData1 = AbiEncoder.Instance.Encode(functionInfo.EncodingStyle, + functionInfo.Signature, + keccak, @ulong, bytes1, bytes2); + return transactionData1; + } - var requestBlockOne = new MultiCallBlockStateCallsModel(); - requestBlockOne.StateOverrides = new[] { - new AccountOverride() + void MainChainTransaction(byte[] bytes, Address? address, TestRpcBlockchain testRpcBlockchain) + { + SystemTransaction transaction = new() { - Address = TestItem.AddressA, - Balance = UInt256.One - } - }; + Data = bytes, To = address, SenderAddress = TestItem.PublicKeyB.Address + }; + transaction.Hash = transaction.CalculateHash(); + TransactionForRpc transactionForRpc = new(transaction); + ResultWrapper mainChainResult = + testRpcBlockchain.EthRpcModule.eth_call(transactionForRpc, BlockParameter.Pending); + + byte[] mainChainResultBytes = + Bytes.FromHexString(mainChainResult.Data).SliceWithZeroPaddingEmptyOnError(12, 20); + Address mainChainRpcAddress = new(mainChainResultBytes); + Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); + } + + TestRpcBlockchain chain = await CreateChain(); + + //Empose Opcode instead of EcRecoverPrecompile, it returns const TestItem.AddressE address + byte[] code = Prepare.EvmCode + .StoreDataInMemory(0, TestItem.AddressE.ToString(false, false).PadLeft(64, '0')) + .PushData(Bytes.FromHexString("0x20")) + .PushData(Bytes.FromHexString("0x0")) + .Op(Instruction.RETURN).Done; + MultiCallBlockStateCallsModel requestMultiCall = new(); + requestMultiCall.StateOverrides = + new[] { new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code } }; + + // Step 1: Take an account + Address account = TestItem.AddressA; + // Step 2: Hash the message + Keccak messageHash = Keccak.Compute("Hello, world!"); + // Step 3: Sign the hash + Signature signature = chain.EthereumEcdsa.Sign(TestItem.PrivateKeyA, messageHash); + + ulong v = signature.V; + byte[] r = signature.R; + byte[] s = signature.S; + + Address? contractAddress = await DeployEcRecoverContract(chain); + + //Check real address + Address recoveredAddress = chain.EthereumEcdsa.RecoverAddress(signature, messageHash); + Assert.AreEqual(TestItem.AddressA, recoveredAddress); + + byte[] transactionData = GenerateTransactionData(messageHash, v, r, s); + + + MainChainTransaction(transactionData, contractAddress, chain); + + //Force persistancy of head block in main chain + chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider)) + { + foreach (AccountOverride accountOverride in requestMultiCall.StateOverrides) + if (accountOverride.Code != null) + tmpChain.VirtualMachine.SetOverwrite(accountOverride.Address, new CodeInfo(accountOverride.Code)); + + //Generate and send transaction + SystemTransaction systemTransactionForModifiedVM = new() + { + Data = transactionData, To = contractAddress, SenderAddress = TestItem.PublicKeyB.Address + }; + systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); + TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); + ResultWrapper responseFromModifiedVM = + tmpChain.EthRpcModule.eth_call(transactionForRpcOfModifiedVM, BlockParameter.Pending); + responseFromModifiedVM.ErrorCode.Should().Be(ErrorCodes.None); + + //Check results + byte[] addressBytes = Bytes.FromHexString(responseFromModifiedVM.Data) + .SliceWithZeroPaddingEmptyOnError(12, 20); + Address resultingAddress = new(addressBytes); + Assert.AreNotEqual(account, resultingAddress); + Assert.AreEqual(TestItem.AddressE, resultingAddress); + + //Note: real address can still be accessed + Address recoveredAddressOnMulticallChain = tmpChain.EthereumEcdsa.RecoverAddress(signature, messageHash); + Assert.AreEqual(TestItem.AddressA, recoveredAddressOnMulticallChain); + } + + //Check that initial VM is intact + MainChainTransaction(transactionData, contractAddress, chain); + } + + /// + /// This test verifies that a temporary forked blockchain updates the user balance and block number + /// independently of the main chain, ensuring the main chain remains intact. + /// + [Test] + public async Task Test_eth_multicall() + { + TestRpcBlockchain chain = await CreateChain(); + + MultiCallBlockStateCallsModel requestBlockOne = new(); + requestBlockOne.StateOverrides = + new[] { new AccountOverride { Address = TestItem.AddressA, Balance = UInt256.One } }; - var blockNumberBefore = chain.BlockFinder.Head.Number; - var userBalanceBefore = await chain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); - userBalanceBefore.Result.ResultType.Should().Be(Core.ResultType.Success); + long blockNumberBefore = chain.BlockFinder.Head.Number; + ResultWrapper userBalanceBefore = + await chain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); + userBalanceBefore.Result.ResultType.Should().Be(ResultType.Success); //Force persistancy of head block in main chain - chain.BlockTree.UpdateMainChain(new []{chain.BlockFinder.Head}, true, true ); + chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); - var tt = chain.TrieStore; - using (var tmpChain =new MultiCallBlockchainFork(chain.DbProvider, chain.SpecProvider)) + TrieStore tt = chain.TrieStore; + using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider)) { //Check if tmpChain initialised Assert.AreEqual(chain.BlockTree.BestKnownNumber, tmpChain.BlockTree.BestKnownNumber); @@ -118,34 +348,35 @@ public async Task Test_eth_multicall() Assert.AreEqual(chain.BlockFinder.Head.Number, tmpChain.BlockFinder.Head.Number); //Check if tmpChain RPC initialised - var userBalanceBefore_fromTmp = + ResultWrapper userBalanceBefore_fromTmp = await tmpChain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); - userBalanceBefore_fromTmp.Result.ResultType.Should().Be(Core.ResultType.Success); + userBalanceBefore_fromTmp.Result.ResultType.Should().Be(ResultType.Success); //Check if tmpChain shows same values as main one - var num_real = userBalanceBefore.Data.Value; - var num_tmp = userBalanceBefore_fromTmp.Data.Value; + UInt256 num_real = userBalanceBefore.Data.Value; + UInt256 num_tmp = userBalanceBefore_fromTmp.Data.Value; Assert.AreEqual(userBalanceBefore_fromTmp.Data, userBalanceBefore.Data); - var processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider) => + bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => { - allocateAccounts(requestBlockOne, stateProvider, currentSpec, specProvider); + allocateAccounts(requestBlockOne, stateProvider, currentSpec, specProvider, virtualMachine); }); //Check block has been added to chain as main Assert.True(processed); //Check block has updated values in tmp chain - var userBalanceResult_fromTm = + ResultWrapper userBalanceResult_fromTm = await tmpChain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); - userBalanceResult_fromTm.Result.ResultType.Should().Be(Core.ResultType.Success); - var tval = tmpChain.StateProvider.GetBalance(TestItem.AddressA); + userBalanceResult_fromTm.Result.ResultType.Should().Be(ResultType.Success); + UInt256 tval = tmpChain.StateProvider.GetBalance(TestItem.AddressA); Assert.AreNotEqual(userBalanceResult_fromTm.Data, userBalanceBefore.Data); //Check block has not updated values in the main chain - var userBalanceResult = await chain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); - userBalanceResult.Result.ResultType.Should().Be(Core.ResultType.Success); + ResultWrapper userBalanceResult = + await chain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); + userBalanceResult.Result.ResultType.Should().Be(ResultType.Success); Assert.AreEqual(userBalanceResult.Data, userBalanceBefore.Data); //Main chain is intact Assert.AreNotEqual(userBalanceResult.Data, userBalanceResult_fromTm.Data); // Balance was changed Assert.AreNotEqual(chain.BlockFinder.Head.Number, tmpChain.LatestBlock.Number); // Block number changed diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/SecureStringWrapper.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/SecureStringWrapper.cs new file mode 100644 index 00000000000..537650a69a7 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/SecureStringWrapper.cs @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Security; + +namespace Nethermind.JsonRpc.Test.Modules.Eth; + +internal sealed class SecureStringWrapper : IDisposable +{ + private bool _disposed = false; + public SecureString SecureData { get; private set; } + + public SecureStringWrapper(string data) + { + SecureData = CreateSecureString(data); + } + + private SecureString CreateSecureString(string regularString) + { + var secureString = new SecureString(); + foreach (char c in regularString) + { + secureString.AppendChar(c); + } + secureString.MakeReadOnly(); + return secureString; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + SecureData.Dispose(); + } + _disposed = true; + } + } + + ~SecureStringWrapper() + { + Dispose(false); + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs new file mode 100644 index 00000000000..f926e6584cc --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Consensus.Validators; +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Crypto; +using Nethermind.Logging; +using Nethermind.TxPool; + +namespace Nethermind.JsonRpc.Modules.Eth.Multicall; + +internal class MultiCallBlockValidator : BlockValidator +{ + public override bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) + { + if (processedBlock.Header.StateRoot != suggestedBlock.Header.StateRoot) + { + //Note we mutate suggested block here to allow eth_multicall enforced State Root change + //and still pass validation + suggestedBlock.Header.StateRoot = processedBlock.Header.StateRoot; + suggestedBlock.Header.Hash = suggestedBlock.Header.CalculateHash(); + } + + return base.ValidateProcessedBlock(processedBlock, receipts, suggestedBlock); + } + + public MultiCallBlockValidator(ITxValidator? txValidator, + IHeaderValidator? headerValidator, + IUnclesValidator? unclesValidator, + ISpecProvider? specProvider, + ILogManager? logManager) : base(txValidator, headerValidator, unclesValidator, specProvider, logManager) + { + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index 41f6c706621..7f8cf42d754 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -21,7 +21,6 @@ using Nethermind.Crypto; using Nethermind.Db; using Nethermind.Db.Blooms; -using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; @@ -39,43 +38,6 @@ namespace Nethermind.JsonRpc.Modules.Eth.Multicall; -public class SimplifiedBlockValidator : BlockValidator -{ - public override bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) - { - if (processedBlock.Header.StateRoot != suggestedBlock.Header.StateRoot) - { - //Note we mutate suggested block here to allow eth_multicall enforced State Root change - //and still pass validation - suggestedBlock.Header.StateRoot = processedBlock.Header.StateRoot; - suggestedBlock.Header.Hash = suggestedBlock.Header.CalculateHash(); - } - - bool isValid = processedBlock.Header.Hash == suggestedBlock.Header.Hash; - - if (processedBlock.Header.GasUsed != suggestedBlock.Header.GasUsed) isValid = false; - - if (processedBlock.Header.Bloom != suggestedBlock.Header.Bloom) isValid = false; - - if (processedBlock.Header.ReceiptsRoot != suggestedBlock.Header.ReceiptsRoot) isValid = false; - - - for (int i = 0; i < processedBlock.Transactions.Length; i++) - if (receipts[i].Error is not null && receipts[i].GasUsed == 0 && receipts[i].Error == "invalid") - isValid = false; - - return isValid; - } - - public SimplifiedBlockValidator(ITxValidator? txValidator, - IHeaderValidator? headerValidator, - IUnclesValidator? unclesValidator, - ISpecProvider? specProvider, - ILogManager? logManager) : base(txValidator, headerValidator, unclesValidator, specProvider, logManager) - { - } -} - /// /// The MultiCallBlockchainFork class enables the creation of temporary in-memory blockchain instances, /// based on a base chain's state. It's useful for simulating transactions, testing, @@ -85,18 +47,6 @@ public SimplifiedBlockValidator(ITxValidator? txValidator, /// public class MultiCallBlockchainFork : IDisposable { - private BlockchainProcessor ChainProcessor { get; } - private BlockProcessor BlockProcessor { get; } - - public IWorldState StateProvider { get; internal set; } - public ISpecProvider SpecProvider { get; internal set; } - public IBlockTree BlockTree { get; internal set; } - public IBlockFinder BlockFinder => BlockTree; - public Block? LatestBlock => BlockFinder.Head; - - public EthRpcModule EthRpcModule { get; internal set; } - public IReleaseSpec CurrentSpec => SpecProvider.GetSpec(LatestBlock!.Header); - /// /// Creates a MultiCallBlockchainFork instance with the following steps: /// 1. Initialize MultiCallBlockchainFork object @@ -137,7 +87,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv //Init BlockChain //Writable inMemory DBs on with access to the data of existing ones (will not modify existing data) if (oldDbProvider == null) throw new ArgumentNullException(); - + List? oldStack = oldDbProvider.StateDb.GetAllValues().ToList(); IDb inMemStateDb = new ReadOnlyDb(oldDbProvider.StateDb, true); IDb inMemBlockDb = new ReadOnlyDb(oldDbProvider.BlocksDb, true); @@ -174,7 +124,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv SpecProvider, NullBloomStorage.Instance, syncConfig, - LimboLogs.Instance); + logManager); StateProvider.StateRoot = BlockTree.Head.StateRoot; @@ -182,10 +132,10 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv TransactionComparerProvider transactionComparerProvider = new(SpecProvider, BlockTree); - EthereumEcdsa ethereumEcdsa = new(SpecProvider.ChainId, logManager); + EthereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId, logManager); Nethermind.TxPool.TxPool txPool = new( - ethereumEcdsa, + EthereumEcdsa, new ChainHeadInfoProvider( SpecProvider, BlockTree, @@ -197,14 +147,14 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv InMemoryReceiptStorage receiptStorage = new(); - VirtualMachine virtualMachine = new( + VirtualMachine = new MultiCallVirtualMachine( new BlockhashProvider(BlockTree, logManager), SpecProvider, logManager); TransactionProcessor txProcessor = - new(SpecProvider, StateProvider, virtualMachine, logManager); - RecoverSignatures blockPreprocessorStep = new(ethereumEcdsa, txPool, SpecProvider, logManager); + new(SpecProvider, StateProvider, VirtualMachine, logManager); + RecoverSignatures blockPreprocessorStep = new(EthereumEcdsa, txPool, SpecProvider, logManager); HeaderValidator headerValidator = new( BlockTree, @@ -212,7 +162,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv SpecProvider, logManager); - SimplifiedBlockValidator blockValidator = new(new TxValidator(SpecProvider.ChainId), + MultiCallBlockValidator blockValidator = new(new TxValidator(SpecProvider.ChainId), headerValidator, Always.Valid, SpecProvider, @@ -239,21 +189,23 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv //Init RPC IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = - new FilterManager(filterStore, BlockProcessor, txPool, LimboLogs.Instance); - ReadOnlyTxProcessingEnv processingEnv = new( + new FilterManager(filterStore, BlockProcessor, txPool, logManager); + + //ToDO make use of our VM!!! + MultiCallReadOnlyTxProcessingEnv processingEnv = new(VirtualMachine, new ReadOnlyDbProvider(DbProvider, false), - new TrieStore(DbProvider.StateDb, LimboLogs.Instance).AsReadOnly(), + new TrieStore(DbProvider.StateDb, logManager).AsReadOnly(), new ReadOnlyBlockTree(BlockTree), SpecProvider, - LimboLogs.Instance); + logManager); BloomStorage bloomStorage = new(new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory()); ReceiptsRecovery receiptsRecovery = - new(new EthereumEcdsa(SpecProvider.ChainId, LimboLogs.Instance), SpecProvider); + new(new EthereumEcdsa(SpecProvider.ChainId, logManager), SpecProvider); IReceiptFinder receiptFinder = receiptStorage; LogFinder logFinder = new(BlockTree, receiptStorage, receiptStorage, bloomStorage, - LimboLogs.Instance, receiptsRecovery); + logManager, receiptsRecovery); ITimestamper timestamper = Timestamper.Default; @@ -262,7 +214,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv receiptFinder, filterStore, filterManager, - ethereumEcdsa, + EthereumEcdsa, timestamper, logFinder, SpecProvider, @@ -278,10 +230,12 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv NullWallet? wallet = NullWallet.Instance; // May be use one from API directly? ITxSigner txSigner = new WalletTxSigner(wallet, SpecProvider.ChainId); TxSealer txSealer = new(txSigner, timestamper); - TxPoolSender txSender = new(txPool, txSealer, nonceManager, ethereumEcdsa); + TxPoolSender txSender = new(txPool, txSealer, nonceManager, EthereumEcdsa); + + JsonRpcConfig? jsonRpcConfig = new(); EthRpcModule = new EthRpcModule( - new JsonRpcConfig(), + jsonRpcConfig, bridge, BlockFinder, stateReader, @@ -289,13 +243,28 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv txSender, wallet, receiptFinder, - LimboLogs.Instance, + logManager, SpecProvider, gasPriceOracle, new EthSyncingInfo(BlockTree, receiptStorage, syncConfig, new StaticSelector(SyncMode.All), logManager), feeHistoryOracle); } + private BlockchainProcessor ChainProcessor { get; } + private BlockProcessor BlockProcessor { get; } + + public IWorldState StateProvider { get; internal set; } + public ISpecProvider SpecProvider { get; internal set; } + public IBlockTree BlockTree { get; internal set; } + public IBlockFinder BlockFinder => BlockTree; + public Block? LatestBlock => BlockFinder.Head; + + public EthRpcModule EthRpcModule { get; internal set; } + + public EthereumEcdsa EthereumEcdsa { get; internal set; } + public IReleaseSpec CurrentSpec => SpecProvider.GetSpec(LatestBlock!.Header); + public MultiCallVirtualMachine VirtualMachine { get; internal set; } + public IDbProvider DbProvider { get; internal set; } //Create a new block next to current LatestBlock (BlockFinder.Head) @@ -324,7 +293,7 @@ public Block CreateBlock() blockHeader.TxRoot = Keccak.EmptyTreeHash; blockHeader.Bloom = Bloom.Empty; - Block? block = new Block(blockHeader, Array.Empty(), Array.Empty()); + Block? block = new(blockHeader, Array.Empty(), Array.Empty()); block = ChainProcessor.Process(block, ProcessingOptions.ProducingBlock, @@ -364,15 +333,16 @@ public bool FinalizeBlock(Block currentBlock) /// /// An action representing the modifications to the blockchain state and storage. public bool ForgeChainBlock(Action action) + IReleaseSpec, ISpecProvider, MultiCallVirtualMachine> action) { //Prepare a block Block? newBlock = CreateBlock(); action(StateProvider, CurrentSpec, - SpecProvider - ); + SpecProvider, + VirtualMachine + ); //Add block bool results = FinalizeBlock(newBlock); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs new file mode 100644 index 00000000000..ec9877c6e20 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Blockchain; +using Nethermind.Consensus.Processing; +using Nethermind.Core.Specs; +using Nethermind.Db; +using Nethermind.Evm.TransactionProcessing; +using Nethermind.Logging; +using Nethermind.Trie.Pruning; + +namespace Nethermind.JsonRpc.Modules.Eth.Multicall; + +internal class MultiCallReadOnlyTxProcessingEnv : ReadOnlyTxProcessingEnv +{ + public MultiCallReadOnlyTxProcessingEnv( + MultiCallVirtualMachine virtualMachine, + IReadOnlyDbProvider? readOnlyDbProvider, + IReadOnlyTrieStore? readOnlyTrieStore, + IReadOnlyBlockTree? readOnlyBlockTree, + ISpecProvider? specProvider, + ILogManager? logManager) : base(readOnlyDbProvider, readOnlyTrieStore, readOnlyBlockTree, specProvider, logManager) + { + Machine = new MultiCallVirtualMachine(virtualMachine); + TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, Machine, logManager); + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs new file mode 100644 index 00000000000..0011d05319f --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Evm; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Logging; +using Nethermind.State; + +namespace Nethermind.JsonRpc.Modules.Eth.Multicall; + +public class MultiCallVirtualMachine : VirtualMachine +{ + private readonly IBlockhashProvider? _blockhashProvider; + private readonly ISpecProvider? _specProvider; + private readonly ILogManager? _logManager; + + public MultiCallVirtualMachine(MultiCallVirtualMachine vm) : + this(vm._blockhashProvider, vm._specProvider, vm._logManager) + { + overloaded = vm.overloaded; + } + + public MultiCallVirtualMachine(IBlockhashProvider? blockhashProvider, + ISpecProvider? specProvider, ILogManager? logManager) : + base(blockhashProvider, specProvider, logManager) + { + _blockhashProvider = blockhashProvider; + _specProvider = specProvider; + _logManager = logManager; + } + + private Dictionary overloaded = new(); + + public void SetOverwrite(Address key, CodeInfo value) + { + overloaded[key] = value; + } + + public override CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) + { + return overloaded.TryGetValue(codeSource, out CodeInfo result) ? + result : base.GetCachedCodeInfo(worldState, codeSource, vmSpec); + } +} diff --git a/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.cs b/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.cs index 5341c56ec41..6781ad137db 100644 --- a/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.cs @@ -70,7 +70,8 @@ public static class Contracts public static async Task
Deploy(TestMevRpcBlockchain chain, string code, ulong nonce = 0, int value = 1) { - Transaction createContractTx = Build.A.Transaction.WithCode(Bytes.FromHexString(code)).WithGasLimit(LargeGasLimit).WithNonce(nonce).WithValue(0).SignedAndResolved(ContractCreatorPrivateKey).TestObject; + Transaction createContractTx = Build.A.Transaction.WithCode(Bytes.FromHexString(code)) + .WithGasLimit(LargeGasLimit).WithNonce(nonce).WithValue(0).SignedAndResolved(ContractCreatorPrivateKey).TestObject; // guarantee state change await chain.AddBlock(true, createContractTx); From 26aec2721bf5ce04172a266e3a5c8b181039fee2 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 24 May 2023 03:39:22 +0100 Subject: [PATCH 010/213] Fix spaces --- .../Modules/Eth/EthRpcMulticallTests.cs | 8 ++++++-- .../Modules/Eth/EthModule.TransactionExecutor.cs | 4 ++-- .../Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs index fd7a0fbdff5..79f576fe0b0 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -234,7 +234,9 @@ void MainChainTransaction(byte[] bytes, Address? address, TestRpcBlockchain test { SystemTransaction transaction = new() { - Data = bytes, To = address, SenderAddress = TestItem.PublicKeyB.Address + Data = bytes, + To = address, + SenderAddress = TestItem.PublicKeyB.Address }; transaction.Hash = transaction.CalculateHash(); TransactionForRpc transactionForRpc = new(transaction); @@ -293,7 +295,9 @@ void MainChainTransaction(byte[] bytes, Address? address, TestRpcBlockchain test //Generate and send transaction SystemTransaction systemTransactionForModifiedVM = new() { - Data = transactionData, To = contractAddress, SenderAddress = TestItem.PublicKeyB.Address + Data = transactionData, + To = contractAddress, + SenderAddress = TestItem.PublicKeyB.Address }; systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index 02530d1ba76..fc294f80ff1 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -88,7 +88,7 @@ private class MultiCallTxExecutor { public MultiCallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) { - + } public ResultWrapper Execute(ulong version, MultiCallBlockStateCallsModel[] blockCalls, @@ -112,7 +112,7 @@ public ResultWrapper Execute(ulong version, MultiCallBlock */ } - + } private class EstimateGasTxExecutor : TxExecutor diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 46c188ad471..ef4b4da3d3c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -373,8 +373,8 @@ public ResultWrapper eth_multicall(ulong version, MultiCal return new MultiCallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .Execute(version, blockCalls, blockParameter); } - - + + public ResultWrapper eth_estimateGas(TransactionForRpc transactionCall, BlockParameter blockParameter) => new EstimateGasTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) From adf729c4a246186feaa7791a07030f953100f042 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 1 Jun 2023 08:33:30 +0100 Subject: [PATCH 011/213] Eth_Multicall redirect sample and protocol update --- .../Proxy/EthJsonRpcClientProxy.cs | 12 +- .../Proxy/IEthJsonRpcClientProxy.cs | 2 +- .../Proxy/Models/MultiCall/AccountOverride.cs | 1 + .../Models/MultiCall/MultiCallBlockResult.cs | 22 ++ ...lResultModel.cs => MultiCallCallResult.cs} | 9 +- .../Steps/RegisterRpcModules.cs | 5 +- .../Modules/BoundedModulePoolTests.cs | 3 +- ...ulticallTestsPrecompilesWithRedirection.cs | 196 ++++++++++++++ .../Eth/EthMulticallTestsSimplePrecompiles.cs | 128 +++++++++ .../Modules/Eth/EthRpcMulticallTests.cs | 253 +++++------------- .../Modules/SingletonModulePoolTests.cs | 3 +- .../Modules/TestRpcBlockchain.cs | 7 +- .../Eth/EthModule.TransactionExecutor.cs | 139 +++++++++- .../Modules/Eth/EthModuleFactory.cs | 9 +- .../Modules/Eth/EthRpcModule.cs | 11 +- .../Modules/Eth/EthRpcModuleProxy.cs | 2 +- .../Modules/Eth/IEthRpcModule.cs | 2 +- .../Eth/Multicall/MultiCallBlockchainFork.cs | 5 +- .../Eth/Multicall/MultiCallVirtualMachine.cs | 19 +- 19 files changed, 610 insertions(+), 218 deletions(-) create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs rename src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/{MultiCallResultModel.cs => MultiCallCallResult.cs} (94%) create mode 100644 src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs create mode 100644 src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index 18618e08ee1..9bc2ddc9c41 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -7,7 +7,6 @@ using Nethermind.Core.Crypto; using Nethermind.Int256; using Nethermind.Facade.Proxy.Models; -using System.Transactions; using Nethermind.Facade.Proxy.Models.MultiCall; namespace Nethermind.Facade.Proxy @@ -40,11 +39,12 @@ public Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_call), transaction, MapBlockParameter(blockParameter)); - public Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, - BlockParameterModel blockParameter = null) - { - return _proxy.SendAsync(nameof(eth_multicall), version, blockCalls, MapBlockParameter(blockParameter)); - } + public Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, + BlockParameterModel blockParameter = null) => _proxy.SendAsync( + nameof(eth_multicall), + version, blockCalls, + MapBlockParameter(blockParameter)); + public Task> eth_getCode(Address address, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_getCode), address, MapBlockParameter(blockParameter)); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs index cd52b73b88a..4e7439db057 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs @@ -20,7 +20,7 @@ public interface IEthJsonRpcClientProxy Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null); //TODO:add tests - Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameterModel blockParameter = null); + Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameterModel blockParameter = null); Task> eth_getCode(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionByHash(Keccak transactionHash); Task> eth_pendingTransactions(); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs index 27f9c1b3d3d..bb74ba5db39 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs @@ -20,6 +20,7 @@ public AccountOverrideType Type /// AccountOverrideState and AccountOverrideStateDiff base public Address Address { get; set; } + public Address? MoveToAddress { get; set; } public UInt256 Nonce { get; set; } public UInt256 Balance { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs new file mode 100644 index 00000000000..fab080afac0 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core.Crypto; +using Nethermind.Core; +using Nethermind.Int256; + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public class MultiCallBlockResult +{ + public MultiCallCallResult[] Calls { get; set; } + public Keccak Hash { get; set; } + public ulong Number { get; set; } + public UInt256 Timestamp { get; set; } + public ulong GasLimit { get; set; } + public ulong GasUsed { get; set; } + public Address FeeRecipient { get; set; } + public UInt256 baseFeePerGas { get; set; } + + +} diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallResultModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs similarity index 94% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallResultModel.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs index 07b5d52367b..c98fe218257 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallResultModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs @@ -3,7 +3,7 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; -public class MultiCallResultModel +public class MultiCallCallResult { public ResultType Type { @@ -21,12 +21,9 @@ public ResultType Type return ResultType.Invalid; } } - + public Log[]? Logs { get; set; } public string Status { get; set; } public byte[]? Return { get; set; } - public ulong? GasUsed { get; set; } - public Error? Error { get; set; } - public Log[]? Logs { get; set; } - + public ulong? GasUsed { get; set; } } diff --git a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs index 9ee8920ae69..805e6a5f204 100644 --- a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs +++ b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs @@ -93,6 +93,7 @@ public virtual async Task Execute(CancellationToken cancellationToken) if (_api.GasPriceOracle is null) throw new StepDependencyException(nameof(_api.GasPriceOracle)); if (_api.EthSyncingInfo is null) throw new StepDependencyException(nameof(_api.EthSyncingInfo)); if (_api.ReadOnlyTrieStore is null) throw new StepDependencyException(nameof(_api.ReadOnlyTrieStore)); + if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider)); EthModuleFactory ethModuleFactory = new( _api.TxPool, @@ -106,11 +107,11 @@ public virtual async Task Execute(CancellationToken cancellationToken) _api.SpecProvider, _api.ReceiptStorage, _api.GasPriceOracle, - _api.EthSyncingInfo); + _api.EthSyncingInfo, + _api.DbProvider); rpcModuleProvider.RegisterBounded(ethModuleFactory, rpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, rpcConfig.Timeout); - if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider)); if (_api.BlockPreprocessor is null) throw new StepDependencyException(nameof(_api.BlockPreprocessor)); if (_api.BlockValidator is null) throw new StepDependencyException(nameof(_api.BlockValidator)); if (_api.RewardCalculatorSource is null) throw new StepDependencyException(nameof(_api.RewardCalculatorSource)); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs index 773e6d7b8d7..2c9718407a1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs @@ -59,7 +59,8 @@ public async Task Initialize() Substitute.For(), Substitute.For(), Substitute.For(), - Substitute.For()), + Substitute.For(), + dbProvider), 1, 1000); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs new file mode 100644 index 00000000000..a4a7c034ec1 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -0,0 +1,196 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Security.Policy; +using System.Threading.Tasks; +using FluentAssertions; +using Nethermind.Blockchain.Find; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; +using Nethermind.Core.Test.Builders; +using Nethermind.Crypto; +using Nethermind.Evm; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Evm.Precompiles; +using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.JsonRpc.Data; +using Nethermind.JsonRpc.Modules.Eth; +using Nethermind.JsonRpc.Modules.Eth.Multicall; +using NUnit.Framework; +using Moq; +using Nethermind.Core.Specs; +using Nethermind.Db; +using Nethermind.State; + +namespace Nethermind.JsonRpc.Test.Modules.Eth; + +public class EthMulticallTestsPrecompilesWithRedirection +{ + /* Compiled contract + pragma solidity ^0.8.7; + + // An interface wrapper for Ecrecover + interface IPrecompiledEcrecoverContract { + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) pure external returns (address) ; + } + + * contract that expects real ecrecover to be at 0x0000000000000000000000000000000000000666 and is to be used for ecrecover mocking + * Call example for TestItem.AddressA, "Hello, world!" message + * recover 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 28 0x7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c4403 0x7e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055 + * returns address mocked by hash ending 0xB6E16D check to: 0x0000000000000000000000000000000000011111 + * if hash does not end in 0xB6E16D returns narmal ecrecover values + * recover 0xA6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 28 0x7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c4403 0x7e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055 + * returns address: shall be as in ecrecover: 0x6F3566EDa7CF07302FDa3654Cc65e447Afd2871C + contract EcrecoverProxy + { + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure returns(address) + { + address redirectedToAddress = 0x0000000000000000000000000000000000000666; + address predefinedResultAddress = 0x0000000000000000000000000000000000011111; + + // "hash/(2**232)": This operation shifts the hash value 232 bits to the right. + // thus in 0xB6E16D27AC5AB427A7F68900AC5559CE272DC6C37C82B3E052246C82244C50E4 it would give 0xB6E16D + // In other words, it's dividing the hash by 2**232 which has the effect of + // discarding the lowest 232 bits and keeping the highest 24 bits (since 256 - 232 = 24). + // "uint24(...)": This casts the result of the division operation to a uint24. + // This is necessary because the result of the division is still a uint256, + // but the highest 24 bits are the ones we're interested in, and the rest are zeros. + uint24 end = uint24(uint256(hash) / (2 * *232)); + bool check = end == 0xB6E16D; + if (check) + { + return predefinedResultAddress; + } + else + { + IPrecompiledEcrecoverContract myInterface = IPrecompiledEcrecoverContract(redirectedToAddress); + return myInterface.ecrecover(hash, v, r, s); + } + + } + + } + */ + + //A way to call original ecrecover add an a redirecton argument + //Think in the future Allow to force a cost to code vs Dynamic code cost + //Peak Totall gas (before refunds substraction) + //Docker image + + //Taken from contract compiler output metadata + private const string EcRecoverProxyFunctionContractBytecode = + "608060405234801561001057600080fd5b506102b9806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806396d107f614610030575b600080fd5b61004a60048036038101906100459190610156565b610060565b60405161005791906101fe565b60405180910390f35b6000806106669050600062011111905060007d0100000000000000000000000000000000000000000000000000000000008860001c61009f9190610252565b9050600062b6e16d8262ffffff1614905080156100c257829450505050506100da565b3660008037600080366000875af43d6000803e3d6000f35b949350505050565b600080fd5b6000819050919050565b6100fa816100e7565b811461010557600080fd5b50565b600081359050610117816100f1565b92915050565b600060ff82169050919050565b6101338161011d565b811461013e57600080fd5b50565b6000813590506101508161012a565b92915050565b600080600080608085870312156101705761016f6100e2565b5b600061017e87828801610108565b945050602061018f87828801610141565b93505060406101a087828801610108565b92505060606101b187828801610108565b91505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101e8826101bd565b9050919050565b6101f8816101dd565b82525050565b600060208201905061021360008301846101ef565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061025d82610219565b915061026883610219565b92508261027857610277610223565b5b82820490509291505056fea2646970667358221220a26a78048ff9fffb3a331accd3da703877d83336f68578b26df710a5408e204364736f6c63430008120033"; + + + + /// + /// This test verifies that a temporary forked blockchain can updates precompiles + /// + [Test] + public async Task Test_eth_multicall_ecr_moved() + { + TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); + + //TODO: add IF-ELSE test clause. Sadly SC code was too hard to reimplement in opcodes and binary does not fit in asis + //So currently we use: + /* + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns(address) + { + + address redirectedToAddress = 0x0000000000000000000000000000000000000666; + assembly { + // Copy msg.data. We take full control of memory in this inline assembly + // block because it will not return to Solidity code. We overwrite the + // Solidity scratch pad at memory position 0. + calldatacopy(0, 0, calldatasize()) + + // Call the implementation. + // out and outsize are 0 because we don't know the size yet. + let result := delegatecall(gas(), redirectedToAddress, 0, calldatasize(), 0, 0) + + // Copy the returned data. + returndatacopy(0, 0, returndatasize()) + + return (0, returndatasize()) + } + } + */ + byte[] code = Prepare.EvmCode + .JUMPDEST() + .PushData(new byte[] { 0 }) + .Op(Instruction.DUP1) + .PushData(Bytes.FromHexString("0x0666"))// 666 + .Op(Instruction.SWAP1) + .Op(Instruction.POP) + .Op(Instruction.CALLDATASIZE) + .PushData(new byte[] { 0 }) + .Op(Instruction.DUP1) + .Op(Instruction.CALLDATACOPY) + .PushData(new byte[] { 0 }) + .Op(Instruction.DUP1) + .Op(Instruction.CALLDATASIZE) + .PushData(new byte[] { 0 }) + .Op(Instruction.DUP5) + .Op(Instruction.GAS) + .Op(Instruction.DELEGATECALL) + .Op(Instruction.RETURNDATASIZE) + .PushData(new byte[] { 0 }) + .Op(Instruction.DUP1) + .Op(Instruction.RETURNDATACOPY) + .Op(Instruction.RETURNDATASIZE) + .PushData(new byte[] { 0 }) + .Op(Instruction.RETURN) + .Done; + MultiCallBlockStateCallsModel requestMultiCall = new(); + requestMultiCall.StateOverrides = + new[] { new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code, MoveToAddress = new Address("0x0000000000000000000000000000000000000666") } }; + + var realSenderAccount = TestItem.AddressA; + var transactionData = EthRpcMulticallTests.GetTxData(chain, realSenderAccount); + + Address? contractAddress = await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EthMulticallTestsSimplePrecompiles.EcRecoverCallerContractBytecode); + + Address? mainChainRpcAddress = EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + + //Force persistancy of head block in main chain + chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + + //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not + using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider)) + { + + + bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => + { + EthRpcModule.MultiCallTxExecutor.ModifyAccounts(requestMultiCall, stateProvider, currentSpec, specProvider, virtualMachine); + }); + Assert.True(processed); + + //Generate and send transaction (shall be mocked) + SystemTransaction systemTransactionForModifiedVM = new() + { + Data = transactionData, + To = contractAddress, + SenderAddress = TestItem.PublicKeyB.Address + }; + systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); + TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); + ResultWrapper responseFromModifiedVM = + tmpChain.EthRpcModule.eth_call(transactionForRpcOfModifiedVM, BlockParameter.Pending); + responseFromModifiedVM.ErrorCode.Should().Be(ErrorCodes.None); + + + //Check results + byte[] addressBytes = Bytes.FromHexString(responseFromModifiedVM.Data) + .SliceWithZeroPaddingEmptyOnError(12, 20); + Address resultingAddress = new(addressBytes); + + //Address expectedMockResultAddress = new Address("0x0000000000000000000000000000000000011111"); + //We redirect to 666 so it will return correct data + Assert.AreEqual(realSenderAccount, resultingAddress); + } + + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs new file mode 100644 index 00000000000..98a64b7be57 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs @@ -0,0 +1,128 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Threading.Tasks; +using FluentAssertions; +using Nethermind.Blockchain.Find; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Core.Test.Builders; +using Nethermind.Crypto; +using Nethermind.Evm; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Evm.Precompiles; +using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.JsonRpc.Data; +using Nethermind.JsonRpc.Modules.Eth; +using Nethermind.JsonRpc.Modules.Eth.Multicall; +using NUnit.Framework; + +namespace Nethermind.JsonRpc.Test.Modules.Eth; + +public class EthMulticallTestsSimplePrecompiles +{ + /* Compiled contract +* Call example for TestItem.AddressA +* recover 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 28 0x7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c4403 0x7e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055 +* returns address: 0xb7705aE4c6F81B66cdB323C65f4E8133690fC099 + +pragma solidity ^0.8.7; + +contract EcrecoverProxy { + function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure returns (address) { + return ecrecover(hash, v, r, s); + } +} +*/ + //Taken from contract compiler output metadata + public const string EcRecoverCallerContractBytecode = + "608060405234801561001057600080fd5b5061028b806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c2bf17b014610030575b600080fd5b61004a6004803603810190610045919061012f565b610060565b60405161005791906101d7565b60405180910390f35b6000600185858585604051600081526020016040526040516100859493929190610210565b6020604051602081039080840390855afa1580156100a7573d6000803e3d6000fd5b505050602060405103519050949350505050565b600080fd5b6000819050919050565b6100d3816100c0565b81146100de57600080fd5b50565b6000813590506100f0816100ca565b92915050565b600060ff82169050919050565b61010c816100f6565b811461011757600080fd5b50565b60008135905061012981610103565b92915050565b60008060008060808587031215610149576101486100bb565b5b6000610157878288016100e1565b94505060206101688782880161011a565b9350506040610179878288016100e1565b925050606061018a878288016100e1565b91505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101c182610196565b9050919050565b6101d1816101b6565b82525050565b60006020820190506101ec60008301846101c8565b92915050565b6101fb816100c0565b82525050565b61020a816100f6565b82525050565b600060808201905061022560008301876101f2565b6102326020830186610201565b61023f60408301856101f2565b61024c60608301846101f2565b9594505050505056fea26469706673582212204855668ab62273dde1249722b61c57ad057ef3d17384f21233e1b7bb309db7e464736f6c63430008120033"; + + + /// + /// This test verifies that a temporary forked blockchain can updates precompiles + /// + [Test] + public async Task Test_eth_multicall_erc() + { + TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); + + //Empose Opcode instead of EcRecoverPrecompile, it returns const TestItem.AddressE address + byte[] code = Prepare.EvmCode + .StoreDataInMemory(0, TestItem.AddressE + .ToString(false, false) + .PadLeft(64, '0')) + .PushData(Bytes.FromHexString("0x20")) + .PushData(Bytes.FromHexString("0x0")) + .Op(Instruction.RETURN).Done; + MultiCallBlockStateCallsModel requestMultiCall = new(); + requestMultiCall.StateOverrides = + new[] { new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code } }; + + // Step 1: Take an account + Address account = TestItem.AddressA; + // Step 2: Hash the message + Keccak messageHash = Keccak.Compute("Hello, world!"); + // Step 3: Sign the hash + Signature signature = chain.EthereumEcdsa.Sign(TestItem.PrivateKeyA, messageHash); + + ulong v = signature.V; + byte[] r = signature.R; + byte[] s = signature.S; + + Address? contractAddress = await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EcRecoverCallerContractBytecode); + + //Check real address + Address recoveredAddress = chain.EthereumEcdsa.RecoverAddress(signature, messageHash); + Assert.AreEqual(TestItem.AddressA, recoveredAddress); + + byte[] transactionData = EthRpcMulticallTests.GenerateTransactionDataForEcRecover(messageHash, v, r, s); + + + Address? mainChainRpcAddress = EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + Assert.NotNull(mainChainRpcAddress); + Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); + + //Force persistancy of head block in main chain + chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider)) + { + bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => + { + EthRpcModule.MultiCallTxExecutor.ModifyAccounts(requestMultiCall, stateProvider, currentSpec, specProvider, virtualMachine); + }); + Assert.True(processed); + //Generate and send transaction + SystemTransaction systemTransactionForModifiedVM = new() + { + Data = transactionData, + To = contractAddress, + SenderAddress = TestItem.PublicKeyB.Address + }; + systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); + TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); + ResultWrapper responseFromModifiedVM = + tmpChain.EthRpcModule.eth_call(transactionForRpcOfModifiedVM, BlockParameter.Pending); + responseFromModifiedVM.ErrorCode.Should().Be(ErrorCodes.None); + + //Check results + byte[] addressBytes = Bytes.FromHexString(responseFromModifiedVM.Data) + .SliceWithZeroPaddingEmptyOnError(12, 20); + Address resultingAddress = new(addressBytes); + Assert.AreNotEqual(account, resultingAddress); + Assert.AreEqual(TestItem.AddressE, resultingAddress); + + //Note: real address can still be accessed + Address recoveredAddressOnMulticallChain = tmpChain.EthereumEcdsa.RecoverAddress(signature, messageHash); + Assert.AreEqual(TestItem.AddressA, recoveredAddressOnMulticallChain); + } + + //Check that initial VM is intact + mainChainRpcAddress = EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + Assert.NotNull(mainChainRpcAddress); + Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs index 79f576fe0b0..17c1e8cf15b 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using FluentAssertions; using Nethermind.Abi; @@ -15,12 +16,10 @@ using Nethermind.Core.Test.Builders; using Nethermind.Core.Test.IO; using Nethermind.Crypto; -using Nethermind.Evm; -using Nethermind.Evm.CodeAnalysis; -using Nethermind.Evm.Precompiles; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; +using Nethermind.JsonRpc.Modules.Eth; using Nethermind.JsonRpc.Modules.Eth.Multicall; using Nethermind.KeyStore; using Nethermind.KeyStore.Config; @@ -39,7 +38,7 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; public class EthRpcMulticallTests { - private static Task CreateChain(IReleaseSpec? releaseSpec = null, + public static Task CreateChain(IReleaseSpec? releaseSpec = null, UInt256? initialBaseFeePerGas = null) { TestRpcBlockchain testMevRpcBlockchain = new(); @@ -49,66 +48,9 @@ private static Task CreateChain(IReleaseSpec? releaseSpec = n return TestRpcBlockchain.ForTest(testMevRpcBlockchain).Build(testSpecProvider); } - private static void allocateAccounts(MultiCallBlockStateCallsModel requestBlockOne, IWorldState _stateProvider, - IReleaseSpec latestBlockSpec, ISpecProvider _specProvider, MultiCallVirtualMachine virtualMachine) - { - foreach (AccountOverride accountOverride in requestBlockOne.StateOverrides) - { - Address address = accountOverride.Address; - Account? acc = _stateProvider.GetAccount(address); - if (acc == null) - { - _stateProvider.CreateAccount(address, accountOverride.Balance, accountOverride.Nonce); - acc = _stateProvider.GetAccount(address); - } - - UInt256 t = acc.Balance; - _stateProvider.SubtractFromBalance(address, 666, latestBlockSpec); - - _stateProvider.Commit(latestBlockSpec); - // _storageProvider.Commit(); - - - if (acc != null) - if (accountOverride.Code is not null) - virtualMachine.SetOverwrite(address, new CodeInfo(accountOverride.Code)); - - - if (accountOverride.State is not null) - { - accountOverride.State = new Dictionary(); - foreach (KeyValuePair storage in accountOverride.State) - _stateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.WithoutLeadingZeros().ToArray()); - } - - if (accountOverride.StateDiff is not null) - { - foreach (KeyValuePair storage in accountOverride.StateDiff) - _stateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.WithoutLeadingZeros().ToArray()); - } - } - } - - /* Compiled contract - * Call example for TestItem.AddressA - * recover 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 28 0x7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c4403 0x7e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055 - * returns address: 0xb7705aE4c6F81B66cdB323C65f4E8133690fC099 - - pragma solidity ^0.8.7; - contract EcrecoverProxy { - function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure returns (address) { - return ecrecover(hash, v, r, s); - } - } - */ - private const string EcRecoverContractBytecode = - "608060405234801561001057600080fd5b5061028b806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c2bf17b014610030575b600080fd5b61004a6004803603810190610045919061012f565b610060565b60405161005791906101d7565b60405180910390f35b6000600185858585604051600081526020016040526040516100859493929190610210565b6020604051602081039080840390855afa1580156100a7573d6000803e3d6000fd5b505050602060405103519050949350505050565b600080fd5b6000819050919050565b6100d3816100c0565b81146100de57600080fd5b50565b6000813590506100f0816100ca565b92915050565b600060ff82169050919050565b61010c816100f6565b811461011757600080fd5b50565b60008135905061012981610103565b92915050565b60008060008060808587031215610149576101486100bb565b5b6000610157878288016100e1565b94505060206101688782880161011a565b9350506040610179878288016100e1565b925050606061018a878288016100e1565b91505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101c182610196565b9050919050565b6101d1816101b6565b82525050565b60006020820190506101ec60008301846101c8565b92915050565b6101fb816100c0565b82525050565b61020a816100f6565b82525050565b600060808201905061022560008301876101f2565b6102326020830186610201565b61023f60408301856101f2565b61024c60608301846101f2565b9594505050505056fea26469706673582212204855668ab62273dde1249722b61c57ad057ef3d17384f21233e1b7bb309db7e464736f6c63430008120033"; - //Taken from contract compiler output metadata - private const string EcRecoverContractJsonAbi = @"[ + public const string EcRecoverContractJsonAbi = @"[ { ""payable"": false, ""inputs"": [ @@ -146,17 +88,36 @@ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure return } ]"; + public static byte[] GetTxData(TestRpcBlockchain chain, Address account) + { + // Step 1: Take an account + // Step 2: Hash the message + Keccak messageHash = Keccak.Compute("Hello, world!"); + // Step 3: Sign the hash + Signature signature = chain.EthereumEcdsa.Sign(TestItem.PrivateKeyA, messageHash); + + ulong v = signature.V; + byte[] r = signature.R; + byte[] s = signature.S; - private async Task DeployEcRecoverContract(TestRpcBlockchain chain1) + //Check real address + Address recoveredAddress = chain.EthereumEcdsa.RecoverAddress(signature, messageHash); + Assert.AreEqual(account, recoveredAddress); + + byte[] transactionData = EthRpcMulticallTests.GenerateTransactionDataForEcRecover(messageHash, v, r, s); + return transactionData; + } + + public static async Task DeployEcRecoverContract(TestRpcBlockchain chain1, PrivateKey fromPrivateKey, string ContractBytecode) { - byte[] bytecode = Bytes.FromHexString(EcRecoverContractBytecode); + byte[] bytecode = Bytes.FromHexString(ContractBytecode); Transaction tx = new() { Value = UInt256.Zero, Nonce = 0, Data = bytecode, GasLimit = 3_000_000, - SenderAddress = TestItem.PublicKeyB.Address, + SenderAddress = fromPrivateKey.Address, To = null, GasPrice = 20.GWei() }; @@ -178,17 +139,18 @@ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure return TxPoolSender txSender = new(chain1.TxPool, txSealer, chain1.NonceManager, chain1.EthereumEcdsa); //Tested Alternative, often faster - //chain.EthereumEcdsa.Sign(TestItem.PrivateKeyB, tx, true); + //chain1.EthereumEcdsa.Sign(TestItem.PrivateKeyB, tx, true); //tx.Hash = tx.CalculateHash(); - //await chain.AddBlock(true, tx); - //TxReceipt? createContractTxReceipt = chain.Bridge.GetReceipt(tx.Hash); - //createContractTxReceipt.ContractAddress.Should().NotBeNull($"Contract transaction {tx.Hash} was not deployed."); + //await chain1.AddBlock(true, tx); + //TxReceipt? createContractTxReceipt2 = chain1.Bridge.GetReceipt(tx.Hash); + //createContractTxReceipt2.ContractAddress + // .Should().NotBeNull($"Contract transaction {tx.Hash} was not deployed."); Address contractAddress1 = null; using (SecureStringWrapper pass = new("testB")) { - wallet.Import(TestItem.PrivateKeyB.KeyBytes, pass.SecureData); - wallet.UnlockAccount(TestItem.PublicKeyB.Address, pass.SecureData, TimeSpan.MaxValue); + wallet.Import(fromPrivateKey.KeyBytes, pass.SecureData); + wallet.UnlockAccount(fromPrivateKey.Address, pass.SecureData, TimeSpan.MaxValue); (Keccak hash, AcceptTxResult? code) = await txSender.SendTransaction(tx, TxHandlingOptions.ManagedNonce | TxHandlingOptions.PersistentBroadcast); @@ -197,7 +159,6 @@ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure return await chain1.AddBlock(true, txs); - TxReceipt createContractTxReceipt = null; while (createContractTxReceipt == null) { @@ -213,112 +174,44 @@ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure return return contractAddress1; } - /// - /// This test verifies that a temporary forked blockchain can updates precompiles - /// - [Test] - public async Task Test_eth_multicall_erc() + public static byte[] GenerateTransactionDataForEcRecover(Keccak keccak, ulong @ulong, byte[] bytes1, byte[] bytes2) { - byte[] GenerateTransactionData(Keccak keccak, ulong @ulong, byte[] bytes1, byte[] bytes2) - { - AbiDefinitionParser parser = new(); - AbiDefinition call = parser.Parse(EcRecoverContractJsonAbi); - AbiEncodingInfo functionInfo = call.GetFunction("recover").GetCallInfo(); - byte[] transactionData1 = AbiEncoder.Instance.Encode(functionInfo.EncodingStyle, - functionInfo.Signature, - keccak, @ulong, bytes1, bytes2); - return transactionData1; - } - - void MainChainTransaction(byte[] bytes, Address? address, TestRpcBlockchain testRpcBlockchain) - { - SystemTransaction transaction = new() - { - Data = bytes, - To = address, - SenderAddress = TestItem.PublicKeyB.Address - }; - transaction.Hash = transaction.CalculateHash(); - TransactionForRpc transactionForRpc = new(transaction); - ResultWrapper mainChainResult = - testRpcBlockchain.EthRpcModule.eth_call(transactionForRpc, BlockParameter.Pending); - - byte[] mainChainResultBytes = - Bytes.FromHexString(mainChainResult.Data).SliceWithZeroPaddingEmptyOnError(12, 20); - Address mainChainRpcAddress = new(mainChainResultBytes); - Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); - } - - TestRpcBlockchain chain = await CreateChain(); - - //Empose Opcode instead of EcRecoverPrecompile, it returns const TestItem.AddressE address - byte[] code = Prepare.EvmCode - .StoreDataInMemory(0, TestItem.AddressE.ToString(false, false).PadLeft(64, '0')) - .PushData(Bytes.FromHexString("0x20")) - .PushData(Bytes.FromHexString("0x0")) - .Op(Instruction.RETURN).Done; - MultiCallBlockStateCallsModel requestMultiCall = new(); - requestMultiCall.StateOverrides = - new[] { new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code } }; - - // Step 1: Take an account - Address account = TestItem.AddressA; - // Step 2: Hash the message - Keccak messageHash = Keccak.Compute("Hello, world!"); - // Step 3: Sign the hash - Signature signature = chain.EthereumEcdsa.Sign(TestItem.PrivateKeyA, messageHash); - - ulong v = signature.V; - byte[] r = signature.R; - byte[] s = signature.S; - - Address? contractAddress = await DeployEcRecoverContract(chain); - - //Check real address - Address recoveredAddress = chain.EthereumEcdsa.RecoverAddress(signature, messageHash); - Assert.AreEqual(TestItem.AddressA, recoveredAddress); - - byte[] transactionData = GenerateTransactionData(messageHash, v, r, s); - + AbiDefinitionParser parser = new(); + AbiDefinition call = parser.Parse(EcRecoverContractJsonAbi); + AbiEncodingInfo functionInfo = call.GetFunction("recover").GetCallInfo(); + byte[] transactionData1 = AbiEncoder.Instance.Encode(functionInfo.EncodingStyle, + functionInfo.Signature, + keccak, @ulong, bytes1, bytes2); + return transactionData1; + } - MainChainTransaction(transactionData, contractAddress, chain); + public static Address? GetTransactionResultFromEcRecover(byte[] data) + { + AbiDefinitionParser parser = new(); + AbiDefinition call = parser.Parse(EcRecoverContractJsonAbi); + AbiEncodingInfo functionInfo = call.GetFunction("recover").GetReturnInfo(); + Address? transactionData1 = AbiEncoder.Instance.Decode(functionInfo.EncodingStyle, + functionInfo.Signature, data).FirstOrDefault() as Address; + return transactionData1; + } - //Force persistancy of head block in main chain - chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); - chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); - using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider)) + public static Address? MainChainTransaction(byte[] bytes, Address? toAddress, TestRpcBlockchain testRpcBlockchain, Address senderAddress) + { + SystemTransaction transaction = new() { - foreach (AccountOverride accountOverride in requestMultiCall.StateOverrides) - if (accountOverride.Code != null) - tmpChain.VirtualMachine.SetOverwrite(accountOverride.Address, new CodeInfo(accountOverride.Code)); - - //Generate and send transaction - SystemTransaction systemTransactionForModifiedVM = new() - { - Data = transactionData, - To = contractAddress, - SenderAddress = TestItem.PublicKeyB.Address - }; - systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); - TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); - ResultWrapper responseFromModifiedVM = - tmpChain.EthRpcModule.eth_call(transactionForRpcOfModifiedVM, BlockParameter.Pending); - responseFromModifiedVM.ErrorCode.Should().Be(ErrorCodes.None); - - //Check results - byte[] addressBytes = Bytes.FromHexString(responseFromModifiedVM.Data) - .SliceWithZeroPaddingEmptyOnError(12, 20); - Address resultingAddress = new(addressBytes); - Assert.AreNotEqual(account, resultingAddress); - Assert.AreEqual(TestItem.AddressE, resultingAddress); - - //Note: real address can still be accessed - Address recoveredAddressOnMulticallChain = tmpChain.EthereumEcdsa.RecoverAddress(signature, messageHash); - Assert.AreEqual(TestItem.AddressA, recoveredAddressOnMulticallChain); - } - - //Check that initial VM is intact - MainChainTransaction(transactionData, contractAddress, chain); + Data = bytes, + To = toAddress, + SenderAddress = senderAddress + }; + transaction.Hash = transaction.CalculateHash(); + TransactionForRpc transactionForRpc = new(transaction); + ResultWrapper mainChainResult = + testRpcBlockchain.EthRpcModule.eth_call(transactionForRpc, BlockParameter.Pending); + + //byte[] mainChainResultBytes = + // Bytes.FromHexString(mainChainResult.Data).SliceWithZeroPaddingEmptyOnError(12, 20); + Address? mainChainRpcAddress = GetTransactionResultFromEcRecover(Bytes.FromHexString(mainChainResult.Data)); //new(mainChainResultBytes); + return mainChainRpcAddress; } /// @@ -326,13 +219,15 @@ void MainChainTransaction(byte[] bytes, Address? address, TestRpcBlockchain test /// independently of the main chain, ensuring the main chain remains intact. /// [Test] - public async Task Test_eth_multicall() + public async Task Test_eth_multicall_account_data() { TestRpcBlockchain chain = await CreateChain(); - MultiCallBlockStateCallsModel requestBlockOne = new(); - requestBlockOne.StateOverrides = - new[] { new AccountOverride { Address = TestItem.AddressA, Balance = UInt256.One } }; + MultiCallBlockStateCallsModel requestBlockOne = new() + { + StateOverrides = new[] { new AccountOverride { Address = TestItem.AddressA, Balance = UInt256.One }} + }; + long blockNumberBefore = chain.BlockFinder.Head.Number; ResultWrapper userBalanceBefore = @@ -363,7 +258,7 @@ public async Task Test_eth_multicall() bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => { - allocateAccounts(requestBlockOne, stateProvider, currentSpec, specProvider, virtualMachine); + EthRpcModule.MultiCallTxExecutor.ModifyAccounts(requestBlockOne, stateProvider, currentSpec, specProvider, virtualMachine); }); //Check block has been added to chain as main diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs index a0ffde60192..c101c287c9a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs @@ -51,7 +51,8 @@ public async Task Initialize() Substitute.For(), Substitute.For(), Substitute.For(), - Substitute.For()); + Substitute.For(), + dbProvider); } [Test] diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index d49722ee754..946f81cb65a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -113,9 +113,9 @@ protected override async Task Build(ISpecProvider? specProvider await base.Build(specProvider, initialValues); IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = new FilterManager(filterStore, BlockProcessor, TxPool, LimboLogs.Instance); - + var dbProvider = new ReadOnlyDbProvider(DbProvider, false); ReadOnlyTxProcessingEnv processingEnv = new( - new ReadOnlyDbProvider(DbProvider, false), + dbProvider, new TrieStore(DbProvider.StateDb, LimboLogs.Instance).AsReadOnly(), new ReadOnlyBlockTree(BlockTree), SpecProvider, @@ -146,7 +146,8 @@ protected override async Task Build(ISpecProvider? specProvider SpecProvider, GasPriceOracle, new EthSyncingInfo(BlockTree, ReceiptStorage, syncConfig, new StaticSelector(SyncMode.All), LogManager), - FeeHistoryOracle); + FeeHistoryOracle, + dbProvider); return this; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index fc294f80ff1..6b8a532af21 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -2,18 +2,26 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; using System.Threading; using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Eip2930; using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Db; using Nethermind.Evm; +using Nethermind.Evm.CodeAnalysis; using Nethermind.Facade; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; +using Nethermind.JsonRpc.Modules.Eth.Multicall; using Nethermind.Specs; using Nethermind.Specs.Forks; +using Nethermind.State; namespace Nethermind.JsonRpc.Modules.Eth { @@ -84,19 +92,112 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, Transacti } } - private class MultiCallTxExecutor + internal class MultiCallTxExecutor { - public MultiCallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) + private readonly IDbProvider _dbProvider; + private readonly ISpecProvider _specProvider; + + internal static void ModifyAccounts(MultiCallBlockStateCallsModel requestBlockOne, IWorldState _stateProvider, + IReleaseSpec latestBlockSpec, ISpecProvider _specProvider, MultiCallVirtualMachine virtualMachine) { + Account? acc; + foreach (AccountOverride accountOverride in requestBlockOne.StateOverrides) + { + Address address = accountOverride.Address; + bool accExists = _stateProvider.AccountExists(address); + if (!accExists) + { + _stateProvider.CreateAccount(address, accountOverride.Balance, accountOverride.Nonce); + acc = _stateProvider.GetAccount(address); + } + else + { + acc = _stateProvider.GetAccount(address); + } + + UInt256 accBalance = acc.Balance; + if (accBalance > accountOverride.Balance) + { + _stateProvider.SubtractFromBalance(address, accBalance - accountOverride.Balance, latestBlockSpec); + } + else if (accBalance < accountOverride.Nonce) + { + _stateProvider.AddToBalance(address, accountOverride.Balance - accBalance, latestBlockSpec); + } + + UInt256 accNonce = acc.Nonce; + if (accNonce > accountOverride.Nonce) + { + _stateProvider.DecrementNonce(address); + } + else if (accNonce < accountOverride.Nonce) + { + _stateProvider.IncrementNonce(address); + } + + if (acc != null) + if (accountOverride.Code is not null) + virtualMachine.SetOverwrite(_stateProvider, latestBlockSpec, address, new CodeInfo(accountOverride.Code), accountOverride.MoveToAddress); + + + if (accountOverride.State is not null) + { + accountOverride.State = new Dictionary(); + foreach (KeyValuePair storage in accountOverride.State) + _stateProvider.Set(new StorageCell(address, storage.Key), + storage.Value.WithoutLeadingZeros().ToArray()); + } + + if (accountOverride.StateDiff is not null) + { + foreach (KeyValuePair storage in accountOverride.StateDiff) + _stateProvider.Set(new StorageCell(address, storage.Key), + storage.Value.WithoutLeadingZeros().ToArray()); + } + + _stateProvider.Commit(latestBlockSpec); + } + } + public MultiCallTxExecutor(IDbProvider DbProvider, ISpecProvider specProvider, IJsonRpcConfig rpcConfig) + { + _dbProvider = DbProvider; + _specProvider = specProvider; } - public ResultWrapper Execute(ulong version, MultiCallBlockStateCallsModel[] blockCalls, + //ToDO move to exctensions + private static IEnumerable Range(UInt256 start, UInt256 end) + { + for (var i = start; i <= end; i++) + { + yield return i; + } + } + + public ResultWrapper Execute(ulong version, MultiCallBlockStateCallsModel[] blockCallsToProcess, BlockParameter? blockParameter) { + List blockCalls = FillInMisingBlocks(blockCallsToProcess); + + using (MultiCallBlockchainFork tmpChain = new(_dbProvider, _specProvider)) + { + //TODO: remove assumption that we start from head and get back + foreach (MultiCallBlockStateCallsModel blockCall in blockCalls) + { + bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => + { + ModifyAccounts(blockCall, stateProvider, currentSpec, specProvider, virtualMachine); + }); + if (!processed) + { + break; + } + } + + } - throw new NotImplementedException(); + throw new NotImplementedException(); /* BlockchainBridge.CallOutput result = _blockchainBridge.Call(header, tx, token); @@ -112,7 +213,37 @@ public ResultWrapper Execute(ulong version, MultiCallBlock */ } + //Returns an ordered list of blockCallsToProcess without gaps + private static List FillInMisingBlocks(MultiCallBlockStateCallsModel[] blockCallsToProcess) + { + var blockCalls = blockCallsToProcess.OrderBy(model => model.BlockOverride.Number).ToList(); + + // Get the lowest and highest numbers + var minNumber = blockCalls.First().BlockOverride.Number; + var maxNumber = blockCalls.Last().BlockOverride.Number; + + // Generate a sequence of numbers in that range + var rangeNumbers = Range(minNumber, maxNumber - minNumber + 1); + + // Get the list of current numbers + var currentNumbers = new HashSet(blockCalls.Select(m => m.BlockOverride.Number)); + // Find which numbers are missing + var missingNumbers = rangeNumbers.Where(n => !currentNumbers.Contains(n)); + + // Fill in the gaps + foreach (var missingNumber in missingNumbers) + { + blockCalls.Add(new MultiCallBlockStateCallsModel() + { + BlockOverride = new BlockOverride() { Number = missingNumber } + }); + } + + // Sort again after filling the gaps + blockCalls = blockCalls.OrderBy(model => model.BlockOverride.Number).ToList(); + return blockCalls; + } } private class EstimateGasTxExecutor : TxExecutor diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs index 9ca52f2cc8a..562d5ee0566 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs @@ -7,6 +7,7 @@ using Nethermind.Blockchain.Receipts; using Nethermind.Consensus; using Nethermind.Core.Specs; +using Nethermind.Db; using Nethermind.Facade; using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; @@ -34,6 +35,7 @@ public class EthModuleFactory : ModuleFactoryBase private readonly IReceiptStorage _receiptStorage; private readonly IGasPriceOracle _gasPriceOracle; private readonly IEthSyncingInfo _ethSyncingInfo; + private readonly IDbProvider _dbProvider; public EthModuleFactory( ITxPool txPool, @@ -47,7 +49,8 @@ public EthModuleFactory( ISpecProvider specProvider, IReceiptStorage receiptStorage, IGasPriceOracle gasPriceOracle, - IEthSyncingInfo ethSyncingInfo) + IEthSyncingInfo ethSyncingInfo, + IDbProvider dbProvider) { _txPool = txPool ?? throw new ArgumentNullException(nameof(txPool)); _txSender = txSender ?? throw new ArgumentNullException(nameof(txSender)); @@ -58,6 +61,7 @@ public EthModuleFactory( _blockchainBridgeFactory = blockchainBridgeFactory ?? throw new ArgumentNullException(nameof(blockchainBridgeFactory)); _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _ethSyncingInfo = ethSyncingInfo ?? throw new ArgumentNullException(nameof(ethSyncingInfo)); + _dbProvider = dbProvider ?? throw new ArgumentNullException(nameof(dbProvider)); _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage)); _gasPriceOracle = gasPriceOracle ?? throw new ArgumentNullException(nameof(gasPriceOracle)); _blockTree = blockTree.AsReadOnly(); @@ -78,7 +82,8 @@ public override IEthRpcModule Create() _specProvider, _gasPriceOracle, _ethSyncingInfo, - new FeeHistoryOracle(_blockTree, _receiptStorage, _specProvider)); + new FeeHistoryOracle(_blockTree, _receiptStorage, _specProvider), + _dbProvider); } public static List Converters = new() diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index ef4b4da3d3c..55280389ddd 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -15,6 +15,7 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; +using Nethermind.Db; using Nethermind.Facade; using Nethermind.Facade.Eth; using Nethermind.Facade.Filters; @@ -55,6 +56,8 @@ public partial class EthRpcModule : IEthRpcModule private readonly IEthSyncingInfo _ethSyncingInfo; private readonly IFeeHistoryOracle _feeHistoryOracle; + private readonly IDbProvider _dbProvider; + private static bool HasStateForBlock(IBlockchainBridge blockchainBridge, BlockHeader header) { RootCheckVisitor rootCheckVisitor = new(); @@ -75,7 +78,8 @@ public EthRpcModule( ISpecProvider specProvider, IGasPriceOracle gasPriceOracle, IEthSyncingInfo ethSyncingInfo, - IFeeHistoryOracle feeHistoryOracle) + IFeeHistoryOracle feeHistoryOracle, + IDbProvider dbProvider) { _logger = logManager.GetClassLogger(); _rpcConfig = rpcConfig ?? throw new ArgumentNullException(nameof(rpcConfig)); @@ -90,6 +94,7 @@ public EthRpcModule( _gasPriceOracle = gasPriceOracle ?? throw new ArgumentNullException(nameof(gasPriceOracle)); _ethSyncingInfo = ethSyncingInfo ?? throw new ArgumentNullException(nameof(ethSyncingInfo)); _feeHistoryOracle = feeHistoryOracle ?? throw new ArgumentNullException(nameof(feeHistoryOracle)); + _dbProvider = dbProvider ?? throw new ArgumentNullException(nameof(dbProvider)); ; } public ResultWrapper eth_protocolVersion() @@ -367,10 +372,10 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); - public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, + public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null) { - return new MultiCallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) + return new MultiCallTxExecutor(_dbProvider, _specProvider, _rpcConfig) .Execute(version, blockCalls, blockParameter); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs index 7c43c7b6d55..a6967e1f0e7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs @@ -157,7 +157,7 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa throw new NotSupportedException(); } - public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, + public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null) { throw new NotImplementedException(); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index f155e6df0c8..391e2bac2cd 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -156,7 +156,7 @@ public interface IEthRpcModule : IRpcModule Description = "Executes a tx call (does not create a transaction)", IsSharable = false, ExampleResponse = "0x")] - ResultWrapper eth_multicall( + ResultWrapper eth_multicall( ulong version, [JsonRpcParameter(ExampleValue = "[{\"stateOverrides\":[{\"nonce\":\"0x1\", \"address\": \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\", \"balance\": \"0xde0b6b3a7640000\", \"state\": {\"0x2292f0db49e1af24fbcac7f32b7537f334244455ad0ed0b46a78202982e7b70d\": \"0xde0b6b3a7640000\", \"0x0x877bd4632ef8c8ddc43b67e5a4511d939eadb612553c8a060670e05ebb1bb83c\": \"0xde0b6b3a7640000\"}}],\"calls\":[{\"from\":\"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"to\":\"0x6b175474e89094c44da98b954eedeac495271d0f\",\"data\":\"0x18160ddd\"}]}]")] MultiCallBlockStateCallsModel[] blockCalls, diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index 7f8cf42d754..9d1aeb15977 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -247,7 +247,8 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv SpecProvider, gasPriceOracle, new EthSyncingInfo(BlockTree, receiptStorage, syncConfig, new StaticSelector(SyncMode.All), logManager), - feeHistoryOracle); + feeHistoryOracle, + dbProvider); } private BlockchainProcessor ChainProcessor { get; } @@ -263,7 +264,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv public EthereumEcdsa EthereumEcdsa { get; internal set; } public IReleaseSpec CurrentSpec => SpecProvider.GetSpec(LatestBlock!.Header); - public MultiCallVirtualMachine VirtualMachine { get; internal set; } + public virtual MultiCallVirtualMachine VirtualMachine { get; internal set; } public IDbProvider DbProvider { get; internal set; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs index 0011d05319f..42a6e289415 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs @@ -7,6 +7,7 @@ using Nethermind.Evm; using Nethermind.Evm.CodeAnalysis; using Nethermind.Logging; +using Nethermind.Network; using Nethermind.State; namespace Nethermind.JsonRpc.Modules.Eth.Multicall; @@ -16,11 +17,12 @@ public class MultiCallVirtualMachine : VirtualMachine private readonly IBlockhashProvider? _blockhashProvider; private readonly ISpecProvider? _specProvider; private readonly ILogManager? _logManager; + private readonly Dictionary _overloaded = new(); public MultiCallVirtualMachine(MultiCallVirtualMachine vm) : this(vm._blockhashProvider, vm._specProvider, vm._logManager) { - overloaded = vm.overloaded; + _overloaded = vm._overloaded; } public MultiCallVirtualMachine(IBlockhashProvider? blockhashProvider, @@ -32,16 +34,21 @@ public MultiCallVirtualMachine(IBlockhashProvider? blockhashProvider, _logManager = logManager; } - private Dictionary overloaded = new(); - public void SetOverwrite(Address key, CodeInfo value) + public void SetOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, Address? redirectAddress = null) { - overloaded[key] = value; + if (redirectAddress != null) + { + _overloaded[redirectAddress] = base.GetCachedCodeInfo(worldState, key, vmSpec); + } + _overloaded[key] = value; } public override CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) { - return overloaded.TryGetValue(codeSource, out CodeInfo result) ? - result : base.GetCachedCodeInfo(worldState, codeSource, vmSpec); + if (_overloaded.TryGetValue(codeSource, out CodeInfo result)) + return result; + else + return base.GetCachedCodeInfo(worldState, codeSource, vmSpec); } } From 332d48746b3df26904fc75c7f26ab2e9b1640166 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 1 Jun 2023 08:36:02 +0100 Subject: [PATCH 012/213] Cleanup --- .../Proxy/Models/MultiCall/AccountOverride.cs | 10 ++-- .../Proxy/Models/MultiCall/BlockOverride.cs | 3 +- .../Models/MultiCall/MultiCallBlockResult.cs | 4 +- .../Models/MultiCall/MultiCallCallResult.cs | 11 ++--- ...ulticallTestsPrecompilesWithRedirection.cs | 48 +++++++++---------- .../Eth/EthMulticallTestsSimplePrecompiles.cs | 19 ++++---- .../Eth/Multicall/MultiCallBlockValidator.cs | 16 +++---- .../MultiCallReadOnlyTxProcessingEnv.cs | 3 +- .../Eth/Multicall/MultiCallVirtualMachine.cs | 14 ++---- 9 files changed, 57 insertions(+), 71 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs index bb74ba5db39..d4c1a8e0002 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs @@ -4,22 +4,21 @@ using System.Collections.Generic; using Nethermind.Core; using Nethermind.Int256; -using Nethermind.State.Snap; namespace Nethermind.Facade.Proxy.Models.MultiCall; public class AccountOverride { - public AccountOverrideType Type - { - get => State != null ? AccountOverrideType.AccountOverrideState : AccountOverrideType.AccountOverrideStateDiff; - } + public AccountOverrideType Type => State != null + ? AccountOverrideType.AccountOverrideState + : AccountOverrideType.AccountOverrideStateDiff; public bool IsState => Type == AccountOverrideType.AccountOverrideState; public bool IsStateDiff => Type == AccountOverrideType.AccountOverrideStateDiff; /// AccountOverrideState and AccountOverrideStateDiff base public Address Address { get; set; } + public Address? MoveToAddress { get; set; } public UInt256 Nonce { get; set; } @@ -31,5 +30,4 @@ public AccountOverrideType Type //Storage difference for AccountOverrideStateDiff public Dictionary? StateDiff { get; set; } - } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index 56a18dd30b4..d7a70d48bb6 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Int256; @@ -13,7 +12,7 @@ public class BlockOverride public Keccak PrevRandao { get; set; } = Keccak.Zero; public UInt256 Number { get; set; } public UInt256 Time { get; set; } - public UInt64 GasLimit { get; set; } + public ulong GasLimit { get; set; } public Address FeeRecipient { get; set; } public UInt256 BaseFee { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs index fab080afac0..6a4b287f594 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs @@ -1,8 +1,8 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using Nethermind.Core.Crypto; using Nethermind.Core; +using Nethermind.Core.Crypto; using Nethermind.Int256; namespace Nethermind.Facade.Proxy.Models.MultiCall; @@ -17,6 +17,4 @@ public class MultiCallBlockResult public ulong GasUsed { get; set; } public Address FeeRecipient { get; set; } public UInt256 baseFeePerGas { get; set; } - - } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs index c98fe218257..e718760f4d4 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs @@ -9,18 +9,13 @@ public ResultType Type { get { - if (Logs != null) - { - return ResultType.Success; - } + if (Logs != null) return ResultType.Success; - if (Return != null && Error != null) - { - return ResultType.Failure; - } + if (Return != null && Error != null) return ResultType.Failure; return ResultType.Invalid; } } + public Log[]? Logs { get; set; } public string Status { get; set; } public byte[]? Return { get; set; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index a4a7c034ec1..735d0a4bf95 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -1,27 +1,20 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System.Security.Policy; using System.Threading.Tasks; using FluentAssertions; using Nethermind.Blockchain.Find; using Nethermind.Core; -using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; using Nethermind.Evm; -using Nethermind.Evm.CodeAnalysis; using Nethermind.Evm.Precompiles; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.JsonRpc.Modules.Eth.Multicall; using NUnit.Framework; -using Moq; -using Nethermind.Core.Specs; -using Nethermind.Db; -using Nethermind.State; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -83,7 +76,6 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure retu "608060405234801561001057600080fd5b506102b9806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806396d107f614610030575b600080fd5b61004a60048036038101906100459190610156565b610060565b60405161005791906101fe565b60405180910390f35b6000806106669050600062011111905060007d0100000000000000000000000000000000000000000000000000000000008860001c61009f9190610252565b9050600062b6e16d8262ffffff1614905080156100c257829450505050506100da565b3660008037600080366000875af43d6000803e3d6000f35b949350505050565b600080fd5b6000819050919050565b6100fa816100e7565b811461010557600080fd5b50565b600081359050610117816100f1565b92915050565b600060ff82169050919050565b6101338161011d565b811461013e57600080fd5b50565b6000813590506101508161012a565b92915050565b600080600080608085870312156101705761016f6100e2565b5b600061017e87828801610108565b945050602061018f87828801610141565b93505060406101a087828801610108565b92505060606101b187828801610108565b91505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101e8826101bd565b9050919050565b6101f8816101dd565b82525050565b600060208201905061021360008301846101ef565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061025d82610219565b915061026883610219565b92508261027857610277610223565b5b82820490509291505056fea2646970667358221220a26a78048ff9fffb3a331accd3da703877d83336f68578b26df710a5408e204364736f6c63430008120033"; - /// /// This test verifies that a temporary forked blockchain can updates precompiles /// @@ -120,7 +112,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( .JUMPDEST() .PushData(new byte[] { 0 }) .Op(Instruction.DUP1) - .PushData(Bytes.FromHexString("0x0666"))// 666 + .PushData(Bytes.FromHexString("0x0666")) // 666 .Op(Instruction.SWAP1) .Op(Instruction.POP) .Op(Instruction.CALLDATASIZE) @@ -142,38 +134,45 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( .PushData(new byte[] { 0 }) .Op(Instruction.RETURN) .Done; - MultiCallBlockStateCallsModel requestMultiCall = new(); + MultiCallBlockStateCallsModel requestMultiCall = new(); requestMultiCall.StateOverrides = - new[] { new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code, MoveToAddress = new Address("0x0000000000000000000000000000000000000666") } }; + new[] + { + new AccountOverride + { + Address = EcRecoverPrecompile.Instance.Address, + Code = code, + MoveToAddress = new Address("0x0000000000000000000000000000000000000666") + } + }; - var realSenderAccount = TestItem.AddressA; - var transactionData = EthRpcMulticallTests.GetTxData(chain, realSenderAccount); + Address realSenderAccount = TestItem.AddressA; + byte[] transactionData = EthRpcMulticallTests.GetTxData(chain, realSenderAccount); - Address? contractAddress = await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EthMulticallTestsSimplePrecompiles.EcRecoverCallerContractBytecode); + Address? contractAddress = await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, + EthMulticallTestsSimplePrecompiles.EcRecoverCallerContractBytecode); - Address? mainChainRpcAddress = EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + Address? mainChainRpcAddress = + EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); //Force persistancy of head block in main chain chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider)) + using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider)) { - - bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => - { - EthRpcModule.MultiCallTxExecutor.ModifyAccounts(requestMultiCall, stateProvider, currentSpec, specProvider, virtualMachine); - }); + { + EthRpcModule.MultiCallTxExecutor.ModifyAccounts(requestMultiCall, stateProvider, currentSpec, + specProvider, virtualMachine); + }); Assert.True(processed); //Generate and send transaction (shall be mocked) SystemTransaction systemTransactionForModifiedVM = new() { - Data = transactionData, - To = contractAddress, - SenderAddress = TestItem.PublicKeyB.Address + Data = transactionData, To = contractAddress, SenderAddress = TestItem.PublicKeyB.Address }; systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); @@ -191,6 +190,5 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( //We redirect to 666 so it will return correct data Assert.AreEqual(realSenderAccount, resultingAddress); } - } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs index 98a64b7be57..82a53101099 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs @@ -7,11 +7,9 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; using Nethermind.Evm; -using Nethermind.Evm.CodeAnalysis; using Nethermind.Evm.Precompiles; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; @@ -72,7 +70,9 @@ public async Task Test_eth_multicall_erc() byte[] r = signature.R; byte[] s = signature.S; - Address? contractAddress = await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EcRecoverCallerContractBytecode); + Address? contractAddress = + await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, + EcRecoverCallerContractBytecode); //Check real address Address recoveredAddress = chain.EthereumEcdsa.RecoverAddress(signature, messageHash); @@ -81,7 +81,8 @@ public async Task Test_eth_multicall_erc() byte[] transactionData = EthRpcMulticallTests.GenerateTransactionDataForEcRecover(messageHash, v, r, s); - Address? mainChainRpcAddress = EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + Address? mainChainRpcAddress = + EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); Assert.NotNull(mainChainRpcAddress); Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); @@ -92,15 +93,14 @@ public async Task Test_eth_multicall_erc() { bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => { - EthRpcModule.MultiCallTxExecutor.ModifyAccounts(requestMultiCall, stateProvider, currentSpec, specProvider, virtualMachine); + EthRpcModule.MultiCallTxExecutor.ModifyAccounts(requestMultiCall, stateProvider, currentSpec, + specProvider, virtualMachine); }); Assert.True(processed); //Generate and send transaction SystemTransaction systemTransactionForModifiedVM = new() { - Data = transactionData, - To = contractAddress, - SenderAddress = TestItem.PublicKeyB.Address + Data = transactionData, To = contractAddress, SenderAddress = TestItem.PublicKeyB.Address }; systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); @@ -121,7 +121,8 @@ public async Task Test_eth_multicall_erc() } //Check that initial VM is intact - mainChainRpcAddress = EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + mainChainRpcAddress = + EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); Assert.NotNull(mainChainRpcAddress); Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs index f926e6584cc..7dd5210890c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs @@ -12,6 +12,14 @@ namespace Nethermind.JsonRpc.Modules.Eth.Multicall; internal class MultiCallBlockValidator : BlockValidator { + public MultiCallBlockValidator(ITxValidator? txValidator, + IHeaderValidator? headerValidator, + IUnclesValidator? unclesValidator, + ISpecProvider? specProvider, + ILogManager? logManager) : base(txValidator, headerValidator, unclesValidator, specProvider, logManager) + { + } + public override bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) { if (processedBlock.Header.StateRoot != suggestedBlock.Header.StateRoot) @@ -24,12 +32,4 @@ public override bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] re return base.ValidateProcessedBlock(processedBlock, receipts, suggestedBlock); } - - public MultiCallBlockValidator(ITxValidator? txValidator, - IHeaderValidator? headerValidator, - IUnclesValidator? unclesValidator, - ISpecProvider? specProvider, - ILogManager? logManager) : base(txValidator, headerValidator, unclesValidator, specProvider, logManager) - { - } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs index ec9877c6e20..1ff37d0f840 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs @@ -19,7 +19,8 @@ public MultiCallReadOnlyTxProcessingEnv( IReadOnlyTrieStore? readOnlyTrieStore, IReadOnlyBlockTree? readOnlyBlockTree, ISpecProvider? specProvider, - ILogManager? logManager) : base(readOnlyDbProvider, readOnlyTrieStore, readOnlyBlockTree, specProvider, logManager) + ILogManager? logManager) : base(readOnlyDbProvider, readOnlyTrieStore, readOnlyBlockTree, specProvider, + logManager) { Machine = new MultiCallVirtualMachine(virtualMachine); TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, Machine, logManager); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs index 42a6e289415..28845391589 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs @@ -7,7 +7,6 @@ using Nethermind.Evm; using Nethermind.Evm.CodeAnalysis; using Nethermind.Logging; -using Nethermind.Network; using Nethermind.State; namespace Nethermind.JsonRpc.Modules.Eth.Multicall; @@ -15,9 +14,9 @@ namespace Nethermind.JsonRpc.Modules.Eth.Multicall; public class MultiCallVirtualMachine : VirtualMachine { private readonly IBlockhashProvider? _blockhashProvider; - private readonly ISpecProvider? _specProvider; private readonly ILogManager? _logManager; private readonly Dictionary _overloaded = new(); + private readonly ISpecProvider? _specProvider; public MultiCallVirtualMachine(MultiCallVirtualMachine vm) : this(vm._blockhashProvider, vm._specProvider, vm._logManager) @@ -35,12 +34,10 @@ public MultiCallVirtualMachine(IBlockhashProvider? blockhashProvider, } - public void SetOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, Address? redirectAddress = null) + public void SetOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, + Address? redirectAddress = null) { - if (redirectAddress != null) - { - _overloaded[redirectAddress] = base.GetCachedCodeInfo(worldState, key, vmSpec); - } + if (redirectAddress != null) _overloaded[redirectAddress] = base.GetCachedCodeInfo(worldState, key, vmSpec); _overloaded[key] = value; } @@ -48,7 +45,6 @@ public override CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeS { if (_overloaded.TryGetValue(codeSource, out CodeInfo result)) return result; - else - return base.GetCachedCodeInfo(worldState, codeSource, vmSpec); + return base.GetCachedCodeInfo(worldState, codeSource, vmSpec); } } From ca12d7f450e8f6341ae38374df5d41aa2a915729 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 1 Jun 2023 09:07:05 +0100 Subject: [PATCH 013/213] Fix whitespace --- .../Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs | 2 +- .../Eth/EthMulticallTestsPrecompilesWithRedirection.cs | 4 +++- .../Modules/Eth/EthMulticallTestsSimplePrecompiles.cs | 4 +++- .../Modules/Eth/EthRpcMulticallTests.cs | 2 +- .../Modules/Eth/EthModule.TransactionExecutor.cs | 4 ++-- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index 9bc2ddc9c41..dc3f1b67eb1 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -44,7 +44,7 @@ public Task> eth_multicall(ulong version, Mult nameof(eth_multicall), version, blockCalls, MapBlockParameter(blockParameter)); - + public Task> eth_getCode(Address address, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_getCode), address, MapBlockParameter(blockParameter)); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 735d0a4bf95..2e54dd50f5d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -172,7 +172,9 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( //Generate and send transaction (shall be mocked) SystemTransaction systemTransactionForModifiedVM = new() { - Data = transactionData, To = contractAddress, SenderAddress = TestItem.PublicKeyB.Address + Data = transactionData, + To = contractAddress, + SenderAddress = TestItem.PublicKeyB.Address }; systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs index 82a53101099..192c0cfa7e6 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs @@ -100,7 +100,9 @@ await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, //Generate and send transaction SystemTransaction systemTransactionForModifiedVM = new() { - Data = transactionData, To = contractAddress, SenderAddress = TestItem.PublicKeyB.Address + Data = transactionData, + To = contractAddress, + SenderAddress = TestItem.PublicKeyB.Address }; systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs index 17c1e8cf15b..73c4b186a51 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -225,7 +225,7 @@ public async Task Test_eth_multicall_account_data() MultiCallBlockStateCallsModel requestBlockOne = new() { - StateOverrides = new[] { new AccountOverride { Address = TestItem.AddressA, Balance = UInt256.One }} + StateOverrides = new[] { new AccountOverride { Address = TestItem.AddressA, Balance = UInt256.One } } }; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index 6b8a532af21..556350c57c6 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -193,11 +193,11 @@ public ResultWrapper Execute(ulong version, MultiCallBlo break; } } - + } - throw new NotImplementedException(); + throw new NotImplementedException(); /* BlockchainBridge.CallOutput result = _blockchainBridge.Call(header, tx, token); From 1f14658d4a7a8f38541911ddad9ce6d3490783d5 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 6 Jun 2023 09:04:59 +0100 Subject: [PATCH 014/213] Progress with blocks out of order Fixing issues related to multiple blocks transactions --- .../Executor/UserOperationTracer.cs | 8 +- .../Nethermind.Blockchain/BlockTree.cs | 3 +- .../BlockTreeMethodOptions.cs | 5 + .../Processing/BlockchainProcessor.cs | 2 +- .../TestAllTracerWithOutput.cs | 7 +- .../Nethermind.Evm/Tracing/AccessTxTracer.cs | 8 +- .../Tracing/AlwaysCancelTxTracer.cs | 5 +- .../Tracing/BlockReceiptsTracer.cs | 11 +- .../Tracing/CallOutputTracer.cs | 8 +- .../Tracing/CancellationTxTracer.cs | 18 +- .../Tracing/CompositeTxTracer.cs | 16 +- .../Tracing/Debugger/DebugTracer.cs | 8 +- .../Tracing/EstimateGasTracer.cs | 8 +- .../Nethermind.Evm/Tracing/FeesTracer.cs | 8 +- .../Nethermind.Evm/Tracing/GasEstimator.cs | 8 +- .../Tracing/GethStyle/GethLikeTxTracer.cs | 8 +- .../Nethermind.Evm/Tracing/ITxTracer.cs | 16 + .../Nethermind.Evm/Tracing/NullTxTracer.cs | 6 +- .../Tracing/ParityStyle/ParityLikeTxTracer.cs | 8 +- .../Tracing/Proofs/ProofTxTracer.cs | 8 +- .../Nethermind.Evm/VirtualMachine.cs | 4 + .../Proxy/Models/CallTransactionModel.cs | 57 ++- .../EthMulticallTestsBlocksAndTransactions.cs | 123 +++++ ...ulticallTestsPrecompilesWithRedirection.cs | 80 +--- .../Eth/EthMulticallTestsSimplePrecompiles.cs | 10 +- .../Modules/Eth/EthRpcMulticallTests.cs | 85 ++-- .../Nethermind.JsonRpc/IJsonRpcConfig.cs | 283 ++++++----- .../Nethermind.JsonRpc/JsonRpcConfig.cs | 90 ++-- .../Eth/EthModule.TransactionExecutor.cs | 450 +++++++++--------- .../Eth/Multicall/MultiCallBlockTracer.cs | 48 ++ .../Eth/Multicall/MultiCallBlockValidator.cs | 1 + .../Eth/Multicall/MultiCallBlockchainFork.cs | 200 ++++++-- .../Eth/Multicall/MultiCallTxTracer.cs | 208 ++++++++ .../Nethermind.Mev/BeneficiaryTracer.cs | 4 +- .../Execution/TxBundleSimulator.cs | 8 +- 35 files changed, 1222 insertions(+), 598 deletions(-) create mode 100644 src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs create mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs create mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs diff --git a/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs b/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs index fcc73300e1a..fc2ca5e8ce4 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs @@ -76,7 +76,8 @@ public UserOperationTxTracer( public bool IsTracingBlockHash => false; public bool IsTracingAccess => true; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) @@ -335,5 +336,10 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) { throw new NotImplementedException(); } + + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } } } diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index a768a50f2ce..5c51885a0b0 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -686,6 +686,7 @@ public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBloc private AddBlockResult Suggest(Block? block, BlockHeader header, BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) { bool shouldProcess = options.ContainsFlag(BlockTreeSuggestOptions.ShouldProcess); + bool noPatentCheck = options.ContainsFlag(BlockTreeSuggestOptions.ForceDontValidateParent); bool fillBeaconBlock = options.ContainsFlag(BlockTreeSuggestOptions.FillBeaconBlock); bool setAsMain = options.ContainsFlag(BlockTreeSuggestOptions.ForceSetAsMain) || !options.ContainsFlag(BlockTreeSuggestOptions.ForceDontSetAsMain) && !shouldProcess; @@ -724,7 +725,7 @@ private AddBlockResult Suggest(Block? block, BlockHeader header, BlockTreeSugges bool parentExists = IsKnownBlock(header.Number - 1, header.ParentHash!) || IsKnownBeaconBlock(header.Number - 1, header.ParentHash!); - if (!header.IsGenesis && !parentExists) + if (!header.IsGenesis && !noPatentCheck && !parentExists) { if (_logger.IsTrace) _logger.Trace($"Could not find parent ({header.ParentHash}) of block {header.Hash}"); return AddBlockResult.UnknownParent; diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTreeMethodOptions.cs b/src/Nethermind/Nethermind.Blockchain/BlockTreeMethodOptions.cs index 2eaab2ba9be..f5cdf862024 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTreeMethodOptions.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTreeMethodOptions.cs @@ -69,6 +69,11 @@ public enum BlockTreeSuggestOptions /// Force not to set as main block /// ForceDontSetAsMain = 8, + + /// + /// Force skip parent number is known checks + /// + ForceDontValidateParent = 8, } public static class BlockTreeSuggestOptionsExtensions diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs index 0e4ac8037d9..04316aba2e7 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs @@ -657,7 +657,7 @@ private ProcessingBranch PrepareProcessingBranch(Block suggestedBlock, Processin private bool RunSimpleChecksAheadOfProcessing(Block suggestedBlock, ProcessingOptions options) { /* a bit hacky way to get the invalid branch out of the processing loop */ - if (suggestedBlock.Number != 0 && + if (!options.ContainsFlag(ProcessingOptions.NoValidation) && suggestedBlock.Number != 0 && !_blockTree.IsKnownBlock(suggestedBlock.Number - 1, suggestedBlock.ParentHash)) { if (_logger.IsDebug) diff --git a/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs b/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs index afb14848dab..787e3a24c3f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs @@ -25,7 +25,8 @@ public class TestAllTracerWithOutput : ITxTracer public bool IsTracingBlockHash => true; public bool IsTracingAccess { get; set; } = true; public bool IsTracingFees => true; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => true; public byte[] ReturnValue { get; set; } @@ -171,5 +172,9 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet false; public bool IsTracingAccess => true; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public AccessTxTracer(params Address[] addressesToOptimize) { @@ -219,6 +220,11 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) throw new NotImplementedException(); } + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } + public long GasSpent { get; set; } public AccessList? AccessList { get; private set; } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs index 29b6c00dc34..e6f366946e3 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs @@ -41,7 +41,9 @@ public static AlwaysCancelTxTracer Instance public bool IsTracingBlockHash => true; public bool IsTracingAccess => true; public bool IsTracingFees => true; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracingEventLogs => true; + + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak stateRoot = null) => throw new OperationCanceledException(ErrorMessage); @@ -96,5 +98,6 @@ public static AlwaysCancelTxTracer Instance public void ReportExtraGasPressure(long extraGasPressure) => throw new OperationCanceledException(ErrorMessage); public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) => throw new OperationCanceledException(ErrorMessage); public void ReportFees(UInt256 fees, UInt256 burntFees) => throw new OperationCanceledException(ErrorMessage); + public void ReportEvent(LogEntry logEntry) => throw new OperationCanceledException(ErrorMessage); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index 83be8013b87..525a8aa3771 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -28,7 +28,8 @@ public class BlockReceiptsTracer : IBlockTracer, ITxTracer, IJournal, ITxTr public bool IsTracingBlockHash => _currentTxTracer.IsTracingBlockHash; public bool IsTracingAccess => _currentTxTracer.IsTracingAccess; public bool IsTracingFees => _currentTxTracer.IsTracingFees; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => _currentTxTracer.IsTracingEventLogs; private IBlockTracer _otherTracer = NullBlockTracer.Instance; @@ -192,6 +193,14 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) } } + public void ReportEvent(LogEntry logEntry) + { + if (_currentTxTracer.IsTracingEventLogs) + { + _currentTxTracer.ReportEvent(logEntry); + } + } + private ITxTracer _currentTxTracer = NullTxTracer.Instance; private int _currentIndex; private readonly List _txReceipts = new(); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs index 478911d573a..aa0d67c7800 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs @@ -25,7 +25,8 @@ public class CallOutputTracer : ITxTracer public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public byte[] ReturnValue { get; set; } @@ -194,5 +195,10 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) { throw new NotImplementedException(); } + + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs index 58047b538ec..c1c7944b18e 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs @@ -28,7 +28,14 @@ public class CancellationTxTracer : ITxTracer, ITxTracerWrapper private readonly bool _isTracingBlockHash; private readonly bool _isTracingBlockAccess; private readonly bool _isTracingFees; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + private readonly bool _isTracingEventLogs; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + + public bool IsTracingEventLogs + { + get => _isTracingEventLogs || _innerTracer.IsTracingEventLogs; + init => _isTracingEventLogs = value; + } public ITxTracer InnerTracer => _innerTracer; @@ -439,5 +446,14 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) _innerTracer.ReportFees(fees, burntFees); } } + + public void ReportEvent(LogEntry logEntry) + { + _token.ThrowIfCancellationRequested(); + if (_innerTracer.IsTracingEventLogs) + { + _innerTracer.ReportEvent(logEntry); + } + } } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs index 306863545ac..343846e92ee 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs @@ -36,6 +36,7 @@ public CompositeTxTracer(IList txTracers) IsTracingStorage |= t.IsTracingStorage; IsTracingAccess |= t.IsTracingAccess; IsTracingFees |= t.IsTracingFees; + IsTracingEventLogs |= t.IsTracingEventLogs; } } @@ -52,7 +53,8 @@ public CompositeTxTracer(IList txTracers) public bool IsTracingBlockHash { get; } public bool IsTracingAccess { get; } public bool IsTracingFees { get; } - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs { get; } public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) { @@ -485,5 +487,17 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) } } } + + public void ReportEvent(LogEntry logEntry) + { + for (int index = 0; index < _txTracers.Count; index++) + { + ITxTracer innerTracer = _txTracers[index]; + if (innerTracer.IsTracingEventLogs) + { + innerTracer.ReportEvent(logEntry); + } + } + } } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs index 6cf0aa5cd2f..92913ac4c59 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs @@ -64,7 +64,8 @@ public DebugTracer(ITxTracer tracer) public bool IsTracingState => ((IStateTracer)InnerTracer).IsTracingState; public bool IsTracingStorage => ((IStorageTracer)InnerTracer).IsTracingStorage; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => ((ITxTracer) InnerTracer).IsTracingEventLogs; internal Dictionary<(int depth, int pc), Func> _breakPoints = new(); public bool IsBreakpoitnSet(int depth, int programCounter) @@ -316,6 +317,11 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) ((ITxTracer)InnerTracer).ReportFees(fees, burntFees); } + public void ReportEvent(LogEntry logEntry) + { + ((ITxTracer)InnerTracer).ReportEvent(logEntry); + } + public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) { ((IStateTracer)InnerTracer).ReportBalanceChange(address, before, after); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/EstimateGasTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/EstimateGasTracer.cs index a2bc2186853..eb7e113b5b9 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/EstimateGasTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/EstimateGasTracer.cs @@ -32,7 +32,8 @@ public EstimateGasTracer() public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public byte[] ReturnValue { get; set; } @@ -299,5 +300,10 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) { throw new NotImplementedException(); } + + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/FeesTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/FeesTracer.cs index 3c66d810a0a..0af95473f2c 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/FeesTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/FeesTracer.cs @@ -25,7 +25,8 @@ public class FeesTracer : IBlockTracer, ITxTracer public bool IsTracingStorage => false; public bool IsTracingReceipt => false; public bool IsTracingFees => true; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public UInt256 Fees { get; private set; } = UInt256.Zero; public UInt256 BurntFees { get; private set; } = UInt256.Zero; @@ -36,6 +37,11 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) BurntFees += burntFees; } + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } + public void StartNewBlockTrace(Block block) { Fees = UInt256.Zero; diff --git a/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs b/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs index aeb16e89c4e..56786e40fb8 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs @@ -114,7 +114,8 @@ public OutOfGasTracer() public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public bool OutOfGas { get; set; } @@ -266,6 +267,11 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) { throw new NotImplementedException(); } + + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } } } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/GethLikeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/GethLikeTxTracer.cs index 497b35a72a7..076bac8fa54 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/GethLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/GethLikeTxTracer.cs @@ -37,7 +37,8 @@ public GethLikeTxTracer(GethTraceOptions options) public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) { @@ -241,6 +242,11 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) throw new NotImplementedException(); } + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } + public GethLikeTxTrace BuildResult() { return _trace; diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index 8a752a71ec2..11372e8e692 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -129,6 +129,15 @@ public interface ITxTracer : IWorldStateTracer bool IsTracing { get; } + /// + /// Traces transaction logs and events + /// + /// + /// Controls + /// - + /// + bool IsTracingEventLogs { get; } + /// /// Transaction completed successfully /// @@ -430,5 +439,12 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// EIP-1559 burnt fees /// Depends on void ReportFees(UInt256 fees, UInt256 burntFees); + + + /// + /// Reports event logs of a transaction + /// + /// log Entry created + void ReportEvent(LogEntry logEntry); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs index 87e2a69ce33..c816354279c 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs @@ -29,7 +29,8 @@ private NullTxTracer() { } public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) => throw new InvalidOperationException(ErrorMessage); @@ -116,5 +117,8 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet throw new InvalidOperationException(ErrorMessage); + + public void ReportEvent(LogEntry logEntry) + => throw new InvalidOperationException(ErrorMessage); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs index 14791c6a469..1c35aefb08f 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs @@ -78,7 +78,8 @@ public ParityLikeTxTracer(Block block, Transaction? tx, ParityTraceTypes parityT public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; private static string GetCallType(ExecutionType executionType) { @@ -531,5 +532,10 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) { throw new NotImplementedException(); } + + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/Proofs/ProofTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/Proofs/ProofTxTracer.cs index e027f8ffb7f..19fc3abccf3 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/Proofs/ProofTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/Proofs/ProofTxTracer.cs @@ -39,7 +39,8 @@ public ProofTxTracer(bool treatSystemAccountDifferently) public bool IsTracingState => true; public bool IsTracingStorage => true; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { @@ -224,5 +225,10 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) { throw new NotImplementedException(); } + + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } } } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index e75f61364e1..1fa693de850 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -1971,6 +1971,10 @@ static void UpdateCurrentState(EvmState state, int pc, long gas, int stackHead) data.ToArray(), topics); vmState.Logs.Add(logEntry); + if (_txTracer.IsTracingEventLogs) + { + _txTracer.ReportEvent(logEntry); + } break; } case Instruction.CREATE: diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs index 697b11eb3d7..d64ad26542a 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs @@ -1,30 +1,51 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Nethermind.Core; +using Nethermind.Crypto; using Nethermind.Int256; using static Nethermind.Core.Extensions.MemoryExtensions; -namespace Nethermind.Facade.Proxy.Models +namespace Nethermind.Facade.Proxy.Models; + +public class CallTransactionModel { - public class CallTransactionModel + public Address From { get; set; } + public Address To { get; set; } + public UInt256 Gas { get; set; } + public UInt256 GasPrice { get; set; } + public UInt256 Value { get; set; } + public byte[] Data { get; set; } + + public static CallTransactionModel FromTransaction(Transaction transaction) + { + return new() + { + From = transaction.SenderAddress, + To = transaction.To, + Data = transaction.Data.AsArray(), + Value = transaction.Value, + Gas = 50_000, + GasPrice = transaction.GasPrice + }; + } + + public Transaction GetTransaction() { - public Address From { get; set; } - public Address To { get; set; } - public UInt256 Gas { get; set; } - public UInt256 GasPrice { get; set; } - public UInt256 Value { get; set; } - public byte[] Data { get; set; } + if (Gas > long.MaxValue) throw new OverflowException("Gas value is too large to be converted to long we use."); + + Transaction? result = new Transaction + { + SenderAddress = From, + To = To, + Data = Data, + Value = Value, + GasLimit = (long)Gas, + GasPrice = GasPrice + }; - public static CallTransactionModel FromTransaction(Transaction transaction) - => new() - { - From = transaction.SenderAddress, - To = transaction.To, - Data = transaction.Data.AsArray(), - Value = transaction.Value, - Gas = (UInt256)transaction.GasLimit, - GasPrice = transaction.GasPrice - }; + result.Hash = result.CalculateHash(); + return result; } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs new file mode 100644 index 00000000000..8a59c008b29 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs @@ -0,0 +1,123 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Threading.Tasks; +using Nethermind.Blockchain.Find; +using Nethermind.Core; +using Nethermind.Core.Extensions; +using Nethermind.Core.Test.Builders; +using Nethermind.Crypto; +using Nethermind.Facade.Proxy.Models; +using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Int256; +using Nethermind.JsonRpc.Modules.Eth; +using NUnit.Framework; + +namespace Nethermind.JsonRpc.Test.Modules.Eth; + +public class EthMulticallTestsBlocksAndTransactions +{ + private Transaction GetTransferTxData(UInt256 Nonce, IEthereumEcdsa ethereumEcdsa, PrivateKey From, Address To, + UInt256 ammount) + { + Transaction tx = new() + { + Value = ammount, + Nonce = Nonce, + GasLimit = 3_000_000, + SenderAddress = From.Address, + To = To, + GasPrice = 20.GWei() + }; + + ethereumEcdsa.Sign(TestItem.PrivateKeyB, tx); + tx.Hash = tx.CalculateHash(); + return tx; + } + + /// + /// This test verifies that a temporary forked blockchain can make transactions, blocks and report on them + /// + [Test] + public async Task Test_eth_multicall_eth_moved() + { + TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); + + UInt256 nonceA = chain.State.GetNonce(TestItem.AddressA); + Transaction txMainnetAtoB = + GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); + Transaction txAtoB1 = + GetTransferTxData(nonceA + 1, chain.EthereumEcdsa, TestItem.PrivateKeyC, TestItem.AddressB, 1); + Transaction txAtoB2 = + GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); + Transaction txAtoB3 = + GetTransferTxData(nonceA + 3, chain.EthereumEcdsa, TestItem.PrivateKeyC, TestItem.AddressB, 1); + Transaction txAtoB4 = + GetTransferTxData(nonceA + 4, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); + + MultiCallBlockStateCallsModel[] requestMultiCall = + { + new() + { + BlockOverride = + new BlockOverride + { + Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10), + GasLimit = 5_000_000, + FeeRecipient = TestItem.AddressC, + BaseFee = 0 + }, + Calls = new[] + { + CallTransactionModel.FromTransaction(txAtoB1), CallTransactionModel.FromTransaction(txAtoB2) + } + }, + new() + { + BlockOverride = + new BlockOverride + { + Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10000), + GasLimit = 5_000_000, + FeeRecipient = TestItem.AddressC, + BaseFee = 0 + }, + Calls = new[] + { + CallTransactionModel.FromTransaction(txAtoB3), CallTransactionModel.FromTransaction(txAtoB4) + } + } + }; + + //Test that transfer tx works on mainchain + UInt256 before = chain.State.GetAccount(TestItem.AddressA).Balance; + await chain.AddBlock(true, txMainnetAtoB); + UInt256 after = chain.State.GetAccount(TestItem.AddressA).Balance; + Assert.Less(after, before); + + TxReceipt recept = chain.Bridge.GetReceipt(txMainnetAtoB.Hash); + LogEntry[]? ls = recept.Logs; + + //Force persistancy of head block in main chain + chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + + //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not + EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.SpecProvider, new JsonRpcConfig()); + ResultWrapper result = + executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); + MultiCallBlockResult[] data = result.Data; + + Assert.AreEqual(data.Length, 2); + + foreach (MultiCallBlockResult blockResult in data) + { + Assert.AreEqual(blockResult.Calls.Length, 2); + foreach (MultiCallCallResult callResult in blockResult.Calls) + { + //callResult.Logs + //Assert.Less(); + } + } + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 735d0a4bf95..5c499ab6511 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -12,85 +12,28 @@ using Nethermind.Evm.Precompiles; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; -using Nethermind.JsonRpc.Modules.Eth; using Nethermind.JsonRpc.Modules.Eth.Multicall; using NUnit.Framework; +using static Nethermind.JsonRpc.Modules.Eth.EthRpcModule; namespace Nethermind.JsonRpc.Test.Modules.Eth; public class EthMulticallTestsPrecompilesWithRedirection { - /* Compiled contract - pragma solidity ^0.8.7; - - // An interface wrapper for Ecrecover - interface IPrecompiledEcrecoverContract { - function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) pure external returns (address) ; - } - - * contract that expects real ecrecover to be at 0x0000000000000000000000000000000000000666 and is to be used for ecrecover mocking - * Call example for TestItem.AddressA, "Hello, world!" message - * recover 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 28 0x7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c4403 0x7e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055 - * returns address mocked by hash ending 0xB6E16D check to: 0x0000000000000000000000000000000000011111 - * if hash does not end in 0xB6E16D returns narmal ecrecover values - * recover 0xA6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 28 0x7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c4403 0x7e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055 - * returns address: shall be as in ecrecover: 0x6F3566EDa7CF07302FDa3654Cc65e447Afd2871C - contract EcrecoverProxy - { - function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure returns(address) - { - address redirectedToAddress = 0x0000000000000000000000000000000000000666; - address predefinedResultAddress = 0x0000000000000000000000000000000000011111; - - // "hash/(2**232)": This operation shifts the hash value 232 bits to the right. - // thus in 0xB6E16D27AC5AB427A7F68900AC5559CE272DC6C37C82B3E052246C82244C50E4 it would give 0xB6E16D - // In other words, it's dividing the hash by 2**232 which has the effect of - // discarding the lowest 232 bits and keeping the highest 24 bits (since 256 - 232 = 24). - // "uint24(...)": This casts the result of the division operation to a uint24. - // This is necessary because the result of the division is still a uint256, - // but the highest 24 bits are the ones we're interested in, and the rest are zeros. - uint24 end = uint24(uint256(hash) / (2 * *232)); - bool check = end == 0xB6E16D; - if (check) - { - return predefinedResultAddress; - } - else - { - IPrecompiledEcrecoverContract myInterface = IPrecompiledEcrecoverContract(redirectedToAddress); - return myInterface.ecrecover(hash, v, r, s); - } - - } - - } - */ - - //A way to call original ecrecover add an a redirecton argument - //Think in the future Allow to force a cost to code vs Dynamic code cost - //Peak Totall gas (before refunds substraction) - //Docker image - - //Taken from contract compiler output metadata - private const string EcRecoverProxyFunctionContractBytecode = - "608060405234801561001057600080fd5b506102b9806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806396d107f614610030575b600080fd5b61004a60048036038101906100459190610156565b610060565b60405161005791906101fe565b60405180910390f35b6000806106669050600062011111905060007d0100000000000000000000000000000000000000000000000000000000008860001c61009f9190610252565b9050600062b6e16d8262ffffff1614905080156100c257829450505050506100da565b3660008037600080366000875af43d6000803e3d6000f35b949350505050565b600080fd5b6000819050919050565b6100fa816100e7565b811461010557600080fd5b50565b600081359050610117816100f1565b92915050565b600060ff82169050919050565b6101338161011d565b811461013e57600080fd5b50565b6000813590506101508161012a565b92915050565b600080600080608085870312156101705761016f6100e2565b5b600061017e87828801610108565b945050602061018f87828801610141565b93505060406101a087828801610108565b92505060606101b187828801610108565b91505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101e8826101bd565b9050919050565b6101f8816101dd565b82525050565b600060208201905061021360008301846101ef565b92915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061025d82610219565b915061026883610219565b92508261027857610277610223565b5b82820490509291505056fea2646970667358221220a26a78048ff9fffb3a331accd3da703877d83336f68578b26df710a5408e204364736f6c63430008120033"; - - /// - /// This test verifies that a temporary forked blockchain can updates precompiles + /// This test verifies that a temporary forked blockchain can redirect precompiles /// [Test] public async Task Test_eth_multicall_ecr_moved() { TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); - - //TODO: add IF-ELSE test clause. Sadly SC code was too hard to reimplement in opcodes and binary does not fit in asis - //So currently we use: + //The following opcodes code is based on the following contract compiled: /* function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns(address) { address redirectedToAddress = 0x0000000000000000000000000000000000000666; + assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the @@ -134,6 +77,9 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( .PushData(new byte[] { 0 }) .Op(Instruction.RETURN) .Done; + //derive from receipt tracer + //emmit additional log with ffff eth movement logs + //gascap MultiCallBlockStateCallsModel requestMultiCall = new(); requestMultiCall.StateOverrides = new[] @@ -147,7 +93,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( }; Address realSenderAccount = TestItem.AddressA; - byte[] transactionData = EthRpcMulticallTests.GetTxData(chain, realSenderAccount); + byte[] transactionData = EthRpcMulticallTests.GetTxData(chain, TestItem.PrivateKeyA); Address? contractAddress = await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EthMulticallTestsSimplePrecompiles.EcRecoverCallerContractBytecode); @@ -160,13 +106,11 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider)) + using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider, + MultiCallTxExecutor.GetMaxGas(new JsonRpcConfig()))) { - bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => - { - EthRpcModule.MultiCallTxExecutor.ModifyAccounts(requestMultiCall, stateProvider, currentSpec, - specProvider, virtualMachine); - }); + (bool processed, Block? _) = tmpChain.ForgeChainBlock(requestMultiCall); + Assert.True(processed); //Generate and send transaction (shall be mocked) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs index 82a53101099..f594282a050 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs @@ -89,13 +89,11 @@ await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, //Force persistancy of head block in main chain chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); - using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider)) + using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider, + EthRpcModule.MultiCallTxExecutor.GetMaxGas(new JsonRpcConfig()))) { - bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => - { - EthRpcModule.MultiCallTxExecutor.ModifyAccounts(requestMultiCall, stateProvider, currentSpec, - specProvider, virtualMachine); - }); + (bool processed, Block? _) = tmpChain.ForgeChainBlock(requestMultiCall); + Assert.True(processed); //Generate and send transaction SystemTransaction systemTransactionForModifiedVM = new() diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs index 17c1e8cf15b..fc1135df987 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using FluentAssertions; @@ -19,7 +18,6 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; -using Nethermind.JsonRpc.Modules.Eth; using Nethermind.JsonRpc.Modules.Eth.Multicall; using Nethermind.KeyStore; using Nethermind.KeyStore.Config; @@ -27,11 +25,11 @@ using Nethermind.Serialization.Json; using Nethermind.Specs; using Nethermind.Specs.Forks; -using Nethermind.State; using Nethermind.Trie.Pruning; using Nethermind.TxPool; using Nethermind.Wallet; using NUnit.Framework; +using static Nethermind.JsonRpc.Modules.Eth.EthRpcModule; using ResultType = Nethermind.Core.ResultType; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -49,66 +47,68 @@ public static Task CreateChain(IReleaseSpec? releaseSpec = nu } - - public const string EcRecoverContractJsonAbi = @"[ - { + public static string getEcRecoverContractJsonAbi(string name = "recover") + { + return $@"[ + {{ ""payable"": false, ""inputs"": [ - { + {{ ""internalType"": ""bytes32"", ""name"": ""hash"", ""type"": ""bytes32"" - }, - { + }}, + {{ ""internalType"": ""uint8"", ""name"": ""v"", ""type"": ""uint8"" - }, - { + + }}, + {{ ""internalType"": ""bytes32"", ""name"": ""r"", ""type"": ""bytes32"" - }, - { + }}, + {{ ""internalType"": ""bytes32"", ""name"": ""s"", ""type"": ""bytes32"" - } + }} ], - ""name"": ""recover"", + ""name"": ""{name}"", ""outputs"": [ - { + {{ ""internalType"": ""address"", ""name"": """", ""type"": ""address"" - } + }} ], ""stateMutability"": ""pure"", ""type"": ""function"" - } + }} ]"; + } - public static byte[] GetTxData(TestRpcBlockchain chain, Address account) + public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, string name = "recover") { // Step 1: Take an account // Step 2: Hash the message Keccak messageHash = Keccak.Compute("Hello, world!"); // Step 3: Sign the hash - Signature signature = chain.EthereumEcdsa.Sign(TestItem.PrivateKeyA, messageHash); + Signature signature = chain.EthereumEcdsa.Sign(account, messageHash); ulong v = signature.V; byte[] r = signature.R; byte[] s = signature.S; //Check real address - Address recoveredAddress = chain.EthereumEcdsa.RecoverAddress(signature, messageHash); - Assert.AreEqual(account, recoveredAddress); - byte[] transactionData = EthRpcMulticallTests.GenerateTransactionDataForEcRecover(messageHash, v, r, s); + byte[] transactionData = GenerateTransactionDataForEcRecover(messageHash, v, r, s, name); return transactionData; } - public static async Task DeployEcRecoverContract(TestRpcBlockchain chain1, PrivateKey fromPrivateKey, string ContractBytecode) + public static async Task DeployEcRecoverContract(TestRpcBlockchain chain1, PrivateKey fromPrivateKey, + string ContractBytecode) { byte[] bytecode = Bytes.FromHexString(ContractBytecode); Transaction tx = new() @@ -141,7 +141,7 @@ public static byte[] GetTxData(TestRpcBlockchain chain, Address account) //Tested Alternative, often faster //chain1.EthereumEcdsa.Sign(TestItem.PrivateKeyB, tx, true); //tx.Hash = tx.CalculateHash(); - //await chain1.AddBlock(true, tx); + //wait chain1.AddBlock(true, tx); //TxReceipt? createContractTxReceipt2 = chain1.Bridge.GetReceipt(tx.Hash); //createContractTxReceipt2.ContractAddress // .Should().NotBeNull($"Contract transaction {tx.Hash} was not deployed."); @@ -174,35 +174,32 @@ public static byte[] GetTxData(TestRpcBlockchain chain, Address account) return contractAddress1; } - public static byte[] GenerateTransactionDataForEcRecover(Keccak keccak, ulong @ulong, byte[] bytes1, byte[] bytes2) + public static byte[] GenerateTransactionDataForEcRecover(Keccak keccak, ulong @ulong, byte[] bytes1, byte[] bytes2, + string name = "recover") { AbiDefinitionParser parser = new(); - AbiDefinition call = parser.Parse(EcRecoverContractJsonAbi); - AbiEncodingInfo functionInfo = call.GetFunction("recover").GetCallInfo(); + AbiDefinition call = parser.Parse(getEcRecoverContractJsonAbi(name)); + AbiEncodingInfo functionInfo = call.GetFunction(name).GetCallInfo(); byte[] transactionData1 = AbiEncoder.Instance.Encode(functionInfo.EncodingStyle, functionInfo.Signature, keccak, @ulong, bytes1, bytes2); return transactionData1; } - public static Address? GetTransactionResultFromEcRecover(byte[] data) + public static Address? GetTransactionResultFromEcRecover(byte[] data, string name = "recover") { AbiDefinitionParser parser = new(); - AbiDefinition call = parser.Parse(EcRecoverContractJsonAbi); + AbiDefinition call = parser.Parse(getEcRecoverContractJsonAbi(name)); AbiEncodingInfo functionInfo = call.GetFunction("recover").GetReturnInfo(); Address? transactionData1 = AbiEncoder.Instance.Decode(functionInfo.EncodingStyle, functionInfo.Signature, data).FirstOrDefault() as Address; return transactionData1; } - public static Address? MainChainTransaction(byte[] bytes, Address? toAddress, TestRpcBlockchain testRpcBlockchain, Address senderAddress) + public static Address? MainChainTransaction(byte[] bytes, Address? toAddress, TestRpcBlockchain testRpcBlockchain, + Address senderAddress) { - SystemTransaction transaction = new() - { - Data = bytes, - To = toAddress, - SenderAddress = senderAddress - }; + SystemTransaction transaction = new() { Data = bytes, To = toAddress, SenderAddress = senderAddress }; transaction.Hash = transaction.CalculateHash(); TransactionForRpc transactionForRpc = new(transaction); ResultWrapper mainChainResult = @@ -210,7 +207,8 @@ public static byte[] GenerateTransactionDataForEcRecover(Keccak keccak, ulong @u //byte[] mainChainResultBytes = // Bytes.FromHexString(mainChainResult.Data).SliceWithZeroPaddingEmptyOnError(12, 20); - Address? mainChainRpcAddress = GetTransactionResultFromEcRecover(Bytes.FromHexString(mainChainResult.Data)); //new(mainChainResultBytes); + Address? mainChainRpcAddress = + GetTransactionResultFromEcRecover(Bytes.FromHexString(mainChainResult.Data)); //new(mainChainResultBytes); return mainChainRpcAddress; } @@ -225,7 +223,7 @@ public async Task Test_eth_multicall_account_data() MultiCallBlockStateCallsModel requestBlockOne = new() { - StateOverrides = new[] { new AccountOverride { Address = TestItem.AddressA, Balance = UInt256.One }} + StateOverrides = new[] { new AccountOverride { Address = TestItem.AddressA, Balance = UInt256.One } } }; @@ -239,7 +237,8 @@ public async Task Test_eth_multicall_account_data() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); TrieStore tt = chain.TrieStore; - using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider)) + using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider, + MultiCallTxExecutor.GetMaxGas(new JsonRpcConfig()))) { //Check if tmpChain initialised Assert.AreEqual(chain.BlockTree.BestKnownNumber, tmpChain.BlockTree.BestKnownNumber); @@ -256,10 +255,8 @@ public async Task Test_eth_multicall_account_data() UInt256 num_tmp = userBalanceBefore_fromTmp.Data.Value; Assert.AreEqual(userBalanceBefore_fromTmp.Data, userBalanceBefore.Data); - bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => - { - EthRpcModule.MultiCallTxExecutor.ModifyAccounts(requestBlockOne, stateProvider, currentSpec, specProvider, virtualMachine); - }); + (bool processed, Block? _) = tmpChain.ForgeChainBlock(requestBlockOne); + //Check block has been added to chain as main Assert.True(processed); diff --git a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs index de57492245c..0dcf356f8cb 100644 --- a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs @@ -4,136 +4,157 @@ using Nethermind.Config; using Nethermind.JsonRpc.Modules.Eth; -namespace Nethermind.JsonRpc +namespace Nethermind.JsonRpc; + +public interface IJsonRpcConfig : IConfig { - public interface IJsonRpcConfig : IConfig - { - [ConfigItem( - Description = "Defines whether the JSON RPC service is enabled on node startup. Configure host and port if default values do not work for you.", - DefaultValue = "false")] - bool Enabled { get; set; } - - [ConfigItem( - Description = "Host for JSON RPC calls. Ensure the firewall is configured when enabling JSON RPC. If it does not work with 127.0.0.1 try something like 10.0.0.4 or 192.168.0.1", - DefaultValue = "\"127.0.0.1\"")] - string Host { get; set; } - - [ConfigItem( - Description = "JSON RPC' timeout value given in milliseconds.", - DefaultValue = "20000")] - int Timeout { get; set; } - - [ConfigItem( - Description = "Base file path for diagnostic JSON RPC recorder.", - DefaultValue = "\"logs/rpc.{counter}.txt\"")] - string RpcRecorderBaseFilePath { get; set; } - - [ConfigItem( - Description = "Defines whether the JSON RPC diagnostic recording is enabled on node startup. Do not enable unless you are a DEV diagnosing issues with JSON RPC. Possible values: None/Request/Response/All.", - DefaultValue = "None")] - RpcRecorderState RpcRecorderState { get; set; } - - [ConfigItem( - Description = "Port number for JSON RPC calls. Ensure the firewall is configured when enabling JSON RPC.", - DefaultValue = "8545")] - int Port { get; set; } - - [ConfigItem( - Description = "Port number for JSON RPC web sockets calls. By default same port is used as regular JSON RPC. Ensure the firewall is configured when enabling JSON RPC.", - DefaultValue = "8545")] - int WebSocketsPort { get; set; } - - [ConfigItem(Description = "The path to connect a unix domain socket over.")] - string IpcUnixDomainSocketPath { get; set; } - - [ConfigItem( - Description = "Defines which RPC modules should be enabled. Built in modules are: Admin, Clique, Consensus, Db, Debug, Deposit, Erc20, Eth, Evm, Health Mev, NdmConsumer, NdmProvider, Net, Nft, Parity, Personal, Proof, Subscribe, Trace, TxPool, Vault, Web3.", - DefaultValue = "[Eth, Subscribe, Trace, TxPool, Web3, Personal, Proof, Net, Parity, Health, Rpc]")] - string[] EnabledModules { get; set; } - - [ConfigItem( - Description = "Defines additional RPC urls to listen on. Example url format: http://localhost:8550|http;wss|engine;eth;net;subscribe", - DefaultValue = "[]")] - string[] AdditionalRpcUrls { get; set; } - - [ConfigItem( - Description = "Gas limit for eth_call and eth_estimateGas", - DefaultValue = "100000000")] - long? GasCap { get; set; } - - [ConfigItem( - Description = "Interval between the JSON RPC stats report log", - DefaultValue = "300")] - int ReportIntervalSeconds { get; set; } - - [ConfigItem( - Description = "Buffer responses before sending them to client. This allows to set Content-Length in response instead of using Transfer-Encoding: chunked. This may degrade performance on big responses. Max buffered response size is 2GB, chunked responses can be bigger.", - DefaultValue = "false")] - bool BufferResponses { get; set; } - - [ConfigItem( - Description = "A path to a file that contains a list of new-line separated approved JSON RPC calls", - DefaultValue = "Data/jsonrpc.filter")] - string CallsFilterFilePath { get; set; } - - [ConfigItem( - Description = "Max HTTP request body size", - DefaultValue = "30000000")] - long? MaxRequestBodySize { get; set; } - - [ConfigItem( - Description = "Number of concurrent instances for non-sharable calls (" + - nameof(IEthRpcModule.eth_call) + ", " + - nameof(IEthRpcModule.eth_estimateGas) + ", " + - nameof(IEthRpcModule.eth_getLogs) + ", " + - nameof(IEthRpcModule.eth_newFilter) + ", " + - nameof(IEthRpcModule.eth_newBlockFilter) + ", " + - nameof(IEthRpcModule.eth_newPendingTransactionFilter) + ", " + - nameof(IEthRpcModule.eth_uninstallFilter) + "). " + - "This will limit load on the node CPU and IO to reasonable levels. " + - "If this limit is exceeded on Http calls 503 Service Unavailable will be returned along with Json RPC error. " + - "Defaults to number of logical processes.")] - int? EthModuleConcurrentInstances { get; set; } - - [ConfigItem(Description = "Path to file with hex encoded secret for jwt authentication", DefaultValue = "keystore/jwt-secret")] - public string JwtSecretFile { get; set; } - - [ConfigItem(Description = "It shouldn't be set to true for production nodes. If set to true all modules can work without RPC authentication.", DefaultValue = "false", HiddenFromDocs = true)] - public bool UnsecureDevNoRpcAuthentication { get; set; } - - [ConfigItem( - Description = "Limits the Maximum characters printing to log for parameters of any Json RPC service request", - DefaultValue = "null")] - int? MaxLoggedRequestParametersCharacters { get; set; } - - [ConfigItem( - Description = "Defines method names of Json RPC service requests to NOT log. Example: {\"eth_blockNumber\"} will not log \"eth_blockNumber\" requests.", - DefaultValue = "[engine_newPayloadV1, engine_newPayloadV2, engine_newPayloadV3, engine_forkchoiceUpdatedV1, engine_forkchoiceUpdatedV2]")] - public string[]? MethodsLoggingFiltering { get; set; } - - [ConfigItem( - Description = "Host for Execution Engine calls. Ensure the firewall is configured when enabling JSON RPC. If it does not work with 127.0.0.1 try something like 10.0.0.4 or 192.168.0.1", - DefaultValue = "\"127.0.0.1\"")] - string EngineHost { get; set; } - - [ConfigItem( - Description = "Port for Execution Engine calls. Ensure the firewall is configured when enabling JSON RPC.", - DefaultValue = "null")] - int? EnginePort { get; set; } - - [ConfigItem( - Description = "Defines which RPC modules should be enabled Execution Engine port. Built in modules are: Admin, Clique, Consensus, Db, Debug, Deposit, Erc20, Eth, Evm, Health Mev, NdmConsumer, NdmProvider, Net, Nft, Parity, Personal, Proof, Subscribe, Trace, TxPool, Vault, Web3.", - DefaultValue = "[Net, Eth, Subscribe, Web3]")] - string[] EngineEnabledModules { get; set; } - - [ConfigItem( - Description = "Limit batch size for batched json rpc call", - DefaultValue = "1024")] - int MaxBatchSize { get; set; } - - [ConfigItem( - Description = "Max response body size when using batch requests, subsequent requests are trimmed", - DefaultValue = "30000000")] - long? MaxBatchResponseBodySize { get; set; } - } + [ConfigItem( + Description = + "Defines whether the JSON RPC service is enabled on node startup. Configure host and port if default values do not work for you.", + DefaultValue = "false")] + bool Enabled { get; set; } + + [ConfigItem( + Description = + "Host for JSON RPC calls. Ensure the firewall is configured when enabling JSON RPC. If it does not work with 127.0.0.1 try something like 10.0.0.4 or 192.168.0.1", + DefaultValue = "\"127.0.0.1\"")] + string Host { get; set; } + + [ConfigItem( + Description = "JSON RPC' timeout value given in milliseconds.", + DefaultValue = "20000")] + int Timeout { get; set; } + + [ConfigItem( + Description = "Base file path for diagnostic JSON RPC recorder.", + DefaultValue = "\"logs/rpc.{counter}.txt\"")] + string RpcRecorderBaseFilePath { get; set; } + + [ConfigItem( + Description = + "Defines whether the JSON RPC diagnostic recording is enabled on node startup. Do not enable unless you are a DEV diagnosing issues with JSON RPC. Possible values: None/Request/Response/All.", + DefaultValue = "None")] + RpcRecorderState RpcRecorderState { get; set; } + + [ConfigItem( + Description = "Port number for JSON RPC calls. Ensure the firewall is configured when enabling JSON RPC.", + DefaultValue = "8545")] + int Port { get; set; } + + [ConfigItem( + Description = + "Port number for JSON RPC web sockets calls. By default same port is used as regular JSON RPC. Ensure the firewall is configured when enabling JSON RPC.", + DefaultValue = "8545")] + int WebSocketsPort { get; set; } + + [ConfigItem(Description = "The path to connect a unix domain socket over.")] + string IpcUnixDomainSocketPath { get; set; } + + [ConfigItem( + Description = + "Defines which RPC modules should be enabled. Built in modules are: Admin, Clique, Consensus, Db, Debug, Deposit, Erc20, Eth, Evm, Health Mev, NdmConsumer, NdmProvider, Net, Nft, Parity, Personal, Proof, Subscribe, Trace, TxPool, Vault, Web3.", + DefaultValue = "[Eth, Subscribe, Trace, TxPool, Web3, Personal, Proof, Net, Parity, Health, Rpc]")] + string[] EnabledModules { get; set; } + + [ConfigItem( + Description = + "Defines additional RPC urls to listen on. Example url format: http://localhost:8550|http;wss|engine;eth;net;subscribe", + DefaultValue = "[]")] + string[] AdditionalRpcUrls { get; set; } + + [ConfigItem( + Description = "Gas limit for eth_call and eth_estimateGas", + DefaultValue = "100000000")] + long? GasCap { get; set; } + + [ConfigItem( + Description = "Gas limit multiplier for eth_multicall. uint256 = GasCap * value", + DefaultValue = "2")] + ulong? GasCapMultiplier { get; set; } + + + [ConfigItem( + Description = "Interval between the JSON RPC stats report log", + DefaultValue = "300")] + int ReportIntervalSeconds { get; set; } + + [ConfigItem( + Description = + "Buffer responses before sending them to client. This allows to set Content-Length in response instead of using Transfer-Encoding: chunked. This may degrade performance on big responses. Max buffered response size is 2GB, chunked responses can be bigger.", + DefaultValue = "false")] + bool BufferResponses { get; set; } + + [ConfigItem( + Description = "A path to a file that contains a list of new-line separated approved JSON RPC calls", + DefaultValue = "Data/jsonrpc.filter")] + string CallsFilterFilePath { get; set; } + + [ConfigItem( + Description = "Max HTTP request body size", + DefaultValue = "30000000")] + long? MaxRequestBodySize { get; set; } + + [ConfigItem( + Description = "Number of concurrent instances for non-sharable calls (" + + nameof(IEthRpcModule.eth_call) + ", " + + nameof(IEthRpcModule.eth_estimateGas) + ", " + + nameof(IEthRpcModule.eth_getLogs) + ", " + + nameof(IEthRpcModule.eth_newFilter) + ", " + + nameof(IEthRpcModule.eth_newBlockFilter) + ", " + + nameof(IEthRpcModule.eth_newPendingTransactionFilter) + ", " + + nameof(IEthRpcModule.eth_uninstallFilter) + ", " + + nameof(IEthRpcModule.eth_call) + "). " + + "This will limit load on the node CPU and IO to reasonable levels. " + + "If this limit is exceeded on Http calls 503 Service Unavailable will be returned along with Json RPC error. " + + "Defaults to number of logical processes.")] + int? EthModuleConcurrentInstances { get; set; } + + [ConfigItem(Description = "Path to file with hex encoded secret for jwt authentication", + DefaultValue = "keystore/jwt-secret")] + public string JwtSecretFile { get; set; } + + [ConfigItem( + Description = + "It shouldn't be set to true for production nodes. If set to true all modules can work without RPC authentication.", + DefaultValue = "false", HiddenFromDocs = true)] + public bool UnsecureDevNoRpcAuthentication { get; set; } + + [ConfigItem( + Description = "Limits the Maximum characters printing to log for parameters of any Json RPC service request", + DefaultValue = "null")] + int? MaxLoggedRequestParametersCharacters { get; set; } + + [ConfigItem( + Description = + "Defines method names of Json RPC service requests to NOT log. Example: {\"eth_blockNumber\"} will not log \"eth_blockNumber\" requests.", + DefaultValue = + "[engine_newPayloadV1, engine_newPayloadV2, engine_newPayloadV3, engine_forkchoiceUpdatedV1, engine_forkchoiceUpdatedV2]")] + public string[]? MethodsLoggingFiltering { get; set; } + + [ConfigItem( + Description = + "Host for Execution Engine calls. Ensure the firewall is configured when enabling JSON RPC. If it does not work with 127.0.0.1 try something like 10.0.0.4 or 192.168.0.1", + DefaultValue = "\"127.0.0.1\"")] + string EngineHost { get; set; } + + [ConfigItem( + Description = "Port for Execution Engine calls. Ensure the firewall is configured when enabling JSON RPC.", + DefaultValue = "null")] + int? EnginePort { get; set; } + + [ConfigItem( + Description = + "Defines which RPC modules should be enabled Execution Engine port. Built in modules are: Admin, Clique, Consensus, Db, Debug, Deposit, Erc20, Eth, Evm, Health Mev, NdmConsumer, NdmProvider, Net, Nft, Parity, Personal, Proof, Subscribe, Trace, TxPool, Vault, Web3.", + DefaultValue = "[Net, Eth, Subscribe, Web3]")] + string[] EngineEnabledModules { get; set; } + + [ConfigItem( + Description = "Limit batch size for batched json rpc call", + DefaultValue = "1024")] + int MaxBatchSize { get; set; } + + [ConfigItem( + Description = "Max response body size when using batch requests, subsequent requests are trimmed", + DefaultValue = "30000000")] + long? MaxBatchResponseBodySize { get; set; } } diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs index 96a7326b854..c19a2870df2 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs @@ -6,53 +6,51 @@ using Nethermind.Core.Extensions; using Nethermind.JsonRpc.Modules; -namespace Nethermind.JsonRpc +namespace Nethermind.JsonRpc; + +public class JsonRpcConfig : IJsonRpcConfig { - public class JsonRpcConfig : IJsonRpcConfig + public static readonly JsonRpcConfig Default = new(); + private int? _webSocketsPort; + public bool Enabled { get; set; } + public string Host { get; set; } = "127.0.0.1"; + public int Timeout { get; set; } = 20000; + public string RpcRecorderBaseFilePath { get; set; } = "logs/rpc.{counter}.txt"; + + public RpcRecorderState RpcRecorderState { get; set; } = RpcRecorderState.None; + + public int Port { get; set; } = 8545; + + public int WebSocketsPort + { + get => _webSocketsPort ?? Port; + set => _webSocketsPort = value; + } + + public string? IpcUnixDomainSocketPath { get; set; } = null; + + public string[] EnabledModules { get; set; } = ModuleType.DefaultModules.ToArray(); + public string[] AdditionalRpcUrls { get; set; } = Array.Empty(); + public long? GasCap { get; set; } = 100000000; + public ulong? GasCapMultiplier { get; set; } = 2; + public int ReportIntervalSeconds { get; set; } = 300; + public bool BufferResponses { get; set; } + public string CallsFilterFilePath { get; set; } = "Data/jsonrpc.filter"; + public long? MaxRequestBodySize { get; set; } = 30000000; + public int? EthModuleConcurrentInstances { get; set; } = null; + public string JwtSecretFile { get; set; } = "keystore/jwt-secret"; + public bool UnsecureDevNoRpcAuthentication { get; set; } + public int? MaxLoggedRequestParametersCharacters { get; set; } = null; + + public string[]? MethodsLoggingFiltering { get; set; } = { - public static readonly JsonRpcConfig Default = new(); - private int? _webSocketsPort; - public bool Enabled { get; set; } - public string Host { get; set; } = "127.0.0.1"; - public int Timeout { get; set; } = 20000; - public string RpcRecorderBaseFilePath { get; set; } = "logs/rpc.{counter}.txt"; - - public RpcRecorderState RpcRecorderState { get; set; } = RpcRecorderState.None; - - public int Port { get; set; } = 8545; - - public int WebSocketsPort - { - get => _webSocketsPort ?? Port; - set => _webSocketsPort = value; - } - - public string? IpcUnixDomainSocketPath { get; set; } = null; - - public string[] EnabledModules { get; set; } = ModuleType.DefaultModules.ToArray(); - public string[] AdditionalRpcUrls { get; set; } = Array.Empty(); - public long? GasCap { get; set; } = 100000000; - public int ReportIntervalSeconds { get; set; } = 300; - public bool BufferResponses { get; set; } - public string CallsFilterFilePath { get; set; } = "Data/jsonrpc.filter"; - public long? MaxRequestBodySize { get; set; } = 30000000; - public int? EthModuleConcurrentInstances { get; set; } = null; - public string JwtSecretFile { get; set; } = "keystore/jwt-secret"; - public bool UnsecureDevNoRpcAuthentication { get; set; } - public int? MaxLoggedRequestParametersCharacters { get; set; } = null; - public string[]? MethodsLoggingFiltering { get; set; } = - { - "engine_newPayloadV1", - "engine_newPayloadV2", - "engine_newPayloadV3", - "engine_forkchoiceUpdatedV1", - "engine_forkchoiceUpdatedV2" - }; - public string EngineHost { get; set; } = "127.0.0.1"; - public int? EnginePort { get; set; } = null; - public string[] EngineEnabledModules { get; set; } = ModuleType.DefaultEngineModules.ToArray(); - public int MaxBatchSize { get; set; } = 1024; - public long? MaxBatchResponseBodySize { get; set; } = 30.MB(); + "engine_newPayloadV1", "engine_newPayloadV2", "engine_newPayloadV3", "engine_forkchoiceUpdatedV1", + "engine_forkchoiceUpdatedV2" }; -}; + public string EngineHost { get; set; } = "127.0.0.1"; + public int? EnginePort { get; set; } = null; + public string[] EngineEnabledModules { get; set; } = ModuleType.DefaultEngineModules.ToArray(); + public int MaxBatchSize { get; set; } = 1024; + public long? MaxBatchResponseBodySize { get; set; } = 30.MB(); +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index 6b8a532af21..dbb2fb91629 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -4,313 +4,303 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Numerics; using System.Threading; +using Microsoft.IdentityModel.Tokens; using Nethermind.Blockchain.Find; +using Nethermind.Blockchain.Receipts; using Nethermind.Core; using Nethermind.Core.Eip2930; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Db; using Nethermind.Evm; -using Nethermind.Evm.CodeAnalysis; using Nethermind.Facade; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth.Multicall; -using Nethermind.Specs; using Nethermind.Specs.Forks; -using Nethermind.State; -namespace Nethermind.JsonRpc.Modules.Eth +namespace Nethermind.JsonRpc.Modules.Eth; + +public partial class EthRpcModule { - public partial class EthRpcModule + private abstract class TxExecutor { - private abstract class TxExecutor + protected readonly IBlockchainBridge _blockchainBridge; + private readonly IBlockFinder _blockFinder; + private readonly IJsonRpcConfig _rpcConfig; + + protected TxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) { - protected readonly IBlockchainBridge _blockchainBridge; - private readonly IBlockFinder _blockFinder; - private readonly IJsonRpcConfig _rpcConfig; + _blockchainBridge = blockchainBridge; + _blockFinder = blockFinder; + _rpcConfig = rpcConfig; + } - protected TxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) - { - _blockchainBridge = blockchainBridge; - _blockFinder = blockFinder; - _rpcConfig = rpcConfig; - } + public ResultWrapper ExecuteTx( + TransactionForRpc transactionCall, + BlockParameter? blockParameter) + { + SearchResult searchResult = _blockFinder.SearchForHeader(blockParameter); + if (searchResult.IsError) return ResultWrapper.Fail(searchResult); - public ResultWrapper ExecuteTx( - TransactionForRpc transactionCall, - BlockParameter? blockParameter) + BlockHeader header = searchResult.Object; + if (!HasStateForBlock(_blockchainBridge, header)) { - SearchResult searchResult = _blockFinder.SearchForHeader(blockParameter); - if (searchResult.IsError) - { - return ResultWrapper.Fail(searchResult); - } - - BlockHeader header = searchResult.Object; - if (!HasStateForBlock(_blockchainBridge, header)) - { - return ResultWrapper.Fail($"No state available for block {header.Hash}", - ErrorCodes.ResourceUnavailable); - } - - transactionCall.EnsureDefaults(_rpcConfig.GasCap); - - using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); - Transaction tx = transactionCall.ToTransaction(_blockchainBridge.GetChainId()); - return ExecuteTx(header.Clone(), tx, cancellationTokenSource.Token); + return ResultWrapper.Fail($"No state available for block {header.Hash}", + ErrorCodes.ResourceUnavailable); } - protected abstract ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token); + transactionCall.EnsureDefaults(_rpcConfig.GasCap); - protected ResultWrapper GetInputError(BlockchainBridge.CallOutput result) => - ResultWrapper.Fail(result.Error, ErrorCodes.InvalidInput); + using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); + Transaction tx = transactionCall.ToTransaction(_blockchainBridge.GetChainId()); + return ExecuteTx(header.Clone(), tx, cancellationTokenSource.Token); } - private class CallTxExecutor : TxExecutor - { - public CallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) - : base(blockchainBridge, blockFinder, rpcConfig) - { - } - - protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token) - { - BlockchainBridge.CallOutput result = _blockchainBridge.Call(header, tx, token); + protected abstract ResultWrapper + ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token); - if (result.Error is null) - { - return ResultWrapper.Success(result.OutputData.ToHexString(true)); - } + protected ResultWrapper GetInputError(BlockchainBridge.CallOutput result) + { + return ResultWrapper.Fail(result.Error, ErrorCodes.InvalidInput); + } + } - return result.InputError - ? GetInputError(result) - : ResultWrapper.Fail("VM execution error.", ErrorCodes.ExecutionError, result.Error); - } + private class CallTxExecutor : TxExecutor + { + public CallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) + : base(blockchainBridge, blockFinder, rpcConfig) + { } - internal class MultiCallTxExecutor + protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token) { - private readonly IDbProvider _dbProvider; - private readonly ISpecProvider _specProvider; + BlockchainBridge.CallOutput result = _blockchainBridge.Call(header, tx, token); - internal static void ModifyAccounts(MultiCallBlockStateCallsModel requestBlockOne, IWorldState _stateProvider, - IReleaseSpec latestBlockSpec, ISpecProvider _specProvider, MultiCallVirtualMachine virtualMachine) - { - Account? acc; - foreach (AccountOverride accountOverride in requestBlockOne.StateOverrides) - { - Address address = accountOverride.Address; - bool accExists = _stateProvider.AccountExists(address); - if (!accExists) - { - _stateProvider.CreateAccount(address, accountOverride.Balance, accountOverride.Nonce); - acc = _stateProvider.GetAccount(address); - } - else - { - acc = _stateProvider.GetAccount(address); - } + if (result.Error is null) return ResultWrapper.Success(result.OutputData.ToHexString(true)); - UInt256 accBalance = acc.Balance; - if (accBalance > accountOverride.Balance) - { - _stateProvider.SubtractFromBalance(address, accBalance - accountOverride.Balance, latestBlockSpec); - } - else if (accBalance < accountOverride.Nonce) - { - _stateProvider.AddToBalance(address, accountOverride.Balance - accBalance, latestBlockSpec); - } + return result.InputError + ? GetInputError(result) + : ResultWrapper.Fail("VM execution error.", ErrorCodes.ExecutionError, result.Error); + } + } - UInt256 accNonce = acc.Nonce; - if (accNonce > accountOverride.Nonce) - { - _stateProvider.DecrementNonce(address); - } - else if (accNonce < accountOverride.Nonce) - { - _stateProvider.IncrementNonce(address); - } + public class MultiCallTxExecutor + { + private readonly IDbProvider _dbProvider; + private readonly IJsonRpcConfig _rpcConfig; + private readonly ISpecProvider _specProvider; - if (acc != null) - if (accountOverride.Code is not null) - virtualMachine.SetOverwrite(_stateProvider, latestBlockSpec, address, new CodeInfo(accountOverride.Code), accountOverride.MoveToAddress); + public MultiCallTxExecutor(IDbProvider DbProvider, ISpecProvider specProvider, IJsonRpcConfig rpcConfig) + { + _dbProvider = DbProvider; + _specProvider = specProvider; + _rpcConfig = rpcConfig; + } + private UInt256 MaxGas => GetMaxGas(_rpcConfig); - if (accountOverride.State is not null) - { - accountOverride.State = new Dictionary(); - foreach (KeyValuePair storage in accountOverride.State) - _stateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.WithoutLeadingZeros().ToArray()); - } - if (accountOverride.StateDiff is not null) - { - foreach (KeyValuePair storage in accountOverride.StateDiff) - _stateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.WithoutLeadingZeros().ToArray()); - } + public static UInt256 GetMaxGas(IJsonRpcConfig config) + { + return (UInt256)config.GasCap * (UInt256)config.GasCapMultiplier; + } - _stateProvider.Commit(latestBlockSpec); - } - } + //ToDO move to exctensions + private static IEnumerable Range(UInt256 start, UInt256 end) + { + for (UInt256 i = start; i <= end; i++) yield return i; + } - public MultiCallTxExecutor(IDbProvider DbProvider, ISpecProvider specProvider, IJsonRpcConfig rpcConfig) - { - _dbProvider = DbProvider; - _specProvider = specProvider; - } + public ResultWrapper Execute(ulong version, + MultiCallBlockStateCallsModel[] blockCallsToProcess, + BlockParameter? blockParameter, bool traceTransfers) + { + IEnumerable? selsectResults = blockCallsToProcess.Select(model => model.BlockOverride.Number); + //Was not able to overcome all of the protections related to setting of new block as BlockTree head so will keep it fair for now - //ToDO move to exctensions - private static IEnumerable Range(UInt256 start, UInt256 end) + List results = new(); + using (MultiCallBlockchainFork tmpChain = new(_dbProvider, _specProvider, MaxGas)) { - for (var i = start; i <= end; i++) + List blockCalls = + FillInMisingBlocks(blockCallsToProcess, + (ulong)tmpChain.LatestBlock + .Number); // blockCallsToProcess.OrderBy(model => model.BlockOverride.Number).ToList(); + + tmpChain.BlockTracer.Trace = traceTransfers; + ulong logIndices = 0; + foreach (MultiCallBlockStateCallsModel blockCall in blockCalls) { - yield return i; - } - } + (bool processed, Block? block) = tmpChain.ForgeChainBlock(blockCall); - public ResultWrapper Execute(ulong version, MultiCallBlockStateCallsModel[] blockCallsToProcess, - BlockParameter? blockParameter) - { - List blockCalls = FillInMisingBlocks(blockCallsToProcess); + if (!processed) break; - using (MultiCallBlockchainFork tmpChain = new(_dbProvider, _specProvider)) - { - //TODO: remove assumption that we start from head and get back - foreach (MultiCallBlockStateCallsModel blockCall in blockCalls) + if (selsectResults.Contains(blockCall.BlockOverride.Number)) { - bool processed = tmpChain.ForgeChainBlock((stateProvider, currentSpec, specProvider, virtualMachine) => + List? txResults = new List(); + foreach (Transaction? tx in tmpChain.LatestBlock.Transactions) { - ModifyAccounts(blockCall, stateProvider, currentSpec, specProvider, virtualMachine); - }); - if (!processed) - { - break; + TxReceipt Receipt = null; + Receipt = tmpChain.receiptStorage.Get(tmpChain.LatestBlock.Hash) + .ForTransaction(tx.Hash); + + + IEnumerable txActions = null; + + if (traceTransfers) + txActions = tmpChain.BlockTracer.TxActions[tx.Hash]; + else + txActions = Receipt.Logs; + + Log[] logs = txActions.Select(entry => new Log + { + Data = entry.Data, + Address = entry.LoggersAddress, + Topics = entry.Topics, + BlockHash = tmpChain.LatestBlock.Hash, + BlockNumber = (ulong)tmpChain.LatestBlock.Number, + LogIndex = ++logIndices + }).ToArray(); + + txResults.Add(new MultiCallCallResult + { + GasUsed = (ulong)Receipt.GasUsed, + Error = new Facade.Proxy.Models.MultiCall.Error + { + Data = (Receipt.Error.IsNullOrEmpty() ? Receipt.Error : "") ?? + string.Empty + }, + Return = Receipt.ReturnValue, + Status = Receipt.StatusCode.ToString(), + Logs = logs.ToArray() + } + ); } - } - - } - - throw new NotImplementedException(); - - /* - BlockchainBridge.CallOutput result = _blockchainBridge.Call(header, tx, token); - - if (result.Error is null) - { - return ResultWrapper.Success(result.OutputData.ToHexString(true)); + MultiCallBlockResult? result = new MultiCallBlockResult + { + baseFeePerGas = tmpChain.LatestBlock.BaseFeePerGas, + FeeRecipient = tmpChain.LatestBlock.Beneficiary, + GasLimit = (ulong)tmpChain.LatestBlock.GasLimit, + GasUsed = (ulong)tmpChain.LatestBlock.GasUsed, + Number = (ulong)tmpChain.LatestBlock.Number, + Hash = tmpChain.LatestBlock.Hash, + Timestamp = tmpChain.LatestBlock.Timestamp, + Calls = txResults.ToArray() + }; + results.Add(result); + } } - - return result.InputError - ? GetInputError(result) - : ResultWrapper.Fail("VM execution error.", ErrorCodes.ExecutionError, result.Error); - */ } - //Returns an ordered list of blockCallsToProcess without gaps - private static List FillInMisingBlocks(MultiCallBlockStateCallsModel[] blockCallsToProcess) - { - var blockCalls = blockCallsToProcess.OrderBy(model => model.BlockOverride.Number).ToList(); + return ResultWrapper.Success(results.ToArray()); + } + + //Returns an ordered list of blockCallsToProcess without gaps + private static List FillInMisingBlocks( + MultiCallBlockStateCallsModel[] blockCallsToProcess, UInt256 from) + { + List? blockCalls = + blockCallsToProcess.OrderBy(model => model.BlockOverride.Number).ToList(); - // Get the lowest and highest numbers - var minNumber = blockCalls.First().BlockOverride.Number; - var maxNumber = blockCalls.Last().BlockOverride.Number; + // Get the lowest and highest numbers + UInt256 minNumber = from; + UInt256 maxNumber = blockCalls.Last().BlockOverride.Number; - // Generate a sequence of numbers in that range - var rangeNumbers = Range(minNumber, maxNumber - minNumber + 1); + // Generate a sequence of numbers in that range + IEnumerable? rangeNumbers = Range(minNumber, maxNumber - minNumber + 1); - // Get the list of current numbers - var currentNumbers = new HashSet(blockCalls.Select(m => m.BlockOverride.Number)); + // Get the list of current numbers + HashSet? currentNumbers = new HashSet(blockCalls.Select(m => m.BlockOverride.Number)); - // Find which numbers are missing - var missingNumbers = rangeNumbers.Where(n => !currentNumbers.Contains(n)); + // Find which numbers are missing + IEnumerable? missingNumbers = rangeNumbers.Where(n => !currentNumbers.Contains(n)); - // Fill in the gaps - foreach (var missingNumber in missingNumbers) + // Fill in the gaps + foreach (UInt256 missingNumber in missingNumbers) + blockCalls.Add(new MultiCallBlockStateCallsModel { - blockCalls.Add(new MultiCallBlockStateCallsModel() + BlockOverride = new BlockOverride { - BlockOverride = new BlockOverride() { Number = missingNumber } - }); - } + Number = missingNumber, GasLimit = 5_000_000, FeeRecipient = Address.Zero, BaseFee = 0 + } + }); - // Sort again after filling the gaps - blockCalls = blockCalls.OrderBy(model => model.BlockOverride.Number).ToList(); - return blockCalls; - } + // Sort again after filling the gaps + blockCalls = blockCalls.OrderBy(model => model.BlockOverride.Number).ToList(); + return blockCalls; } + } - private class EstimateGasTxExecutor : TxExecutor + private class EstimateGasTxExecutor : TxExecutor + { + public EstimateGasTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, + IJsonRpcConfig rpcConfig) + : base(blockchainBridge, blockFinder, rpcConfig) { - public EstimateGasTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) - : base(blockchainBridge, blockFinder, rpcConfig) - { - } + } - protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token) - { - BlockchainBridge.CallOutput result = _blockchainBridge.EstimateGas(header, tx, token); + protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, + CancellationToken token) + { + BlockchainBridge.CallOutput result = _blockchainBridge.EstimateGas(header, tx, token); - if (result.Error is null) - { - return ResultWrapper.Success((UInt256)result.GasSpent); - } + if (result.Error is null) return ResultWrapper.Success((UInt256)result.GasSpent); - return result.InputError - ? GetInputError(result) - : ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError); - } + return result.InputError + ? GetInputError(result) + : ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError); } + } + + private class CreateAccessListTxExecutor : TxExecutor + { + private readonly bool _optimize; - private class CreateAccessListTxExecutor : TxExecutor + public CreateAccessListTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, + IJsonRpcConfig rpcConfig, bool optimize) + : base(blockchainBridge, blockFinder, rpcConfig) { - private readonly bool _optimize; + _optimize = optimize; + } - public CreateAccessListTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig, bool optimize) - : base(blockchainBridge, blockFinder, rpcConfig) - { - _optimize = optimize; - } + protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, + CancellationToken token) + { + BlockchainBridge.CallOutput result = _blockchainBridge.CreateAccessList(header, tx, token, _optimize); - protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token) - { - BlockchainBridge.CallOutput result = _blockchainBridge.CreateAccessList(header, tx, token, _optimize); + if (result.Error is null) + return ResultWrapper.Success(new AccessListForRpc(GetResultAccessList(tx, result), + GetResultGas(tx, result))); - if (result.Error is null) - { - return ResultWrapper.Success(new(GetResultAccessList(tx, result), GetResultGas(tx, result))); - } + return result.InputError + ? GetInputError(result) + : ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError, + new AccessListForRpc(GetResultAccessList(tx, result), GetResultGas(tx, result))); + } - return result.InputError - ? GetInputError(result) - : ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError, new(GetResultAccessList(tx, result), GetResultGas(tx, result))); - } + private static AccessListItemForRpc[] GetResultAccessList(Transaction tx, BlockchainBridge.CallOutput result) + { + AccessList? accessList = result.AccessList ?? tx.AccessList; + return accessList is null + ? Array.Empty() + : AccessListItemForRpc.FromAccessList(accessList); + } - private static AccessListItemForRpc[] GetResultAccessList(Transaction tx, BlockchainBridge.CallOutput result) + private static UInt256 GetResultGas(Transaction transaction, BlockchainBridge.CallOutput result) + { + long gas = result.GasSpent; + if (result.AccessList is not null) { - AccessList? accessList = result.AccessList ?? tx.AccessList; - return accessList is null ? Array.Empty() : AccessListItemForRpc.FromAccessList(accessList); + // if we generated access list, we need to fix actual gas cost, as all storage was considered warm + gas -= IntrinsicGasCalculator.Calculate(transaction, Berlin.Instance); + transaction.AccessList = result.AccessList; + gas += IntrinsicGasCalculator.Calculate(transaction, Berlin.Instance); } - private static UInt256 GetResultGas(Transaction transaction, BlockchainBridge.CallOutput result) - { - long gas = result.GasSpent; - if (result.AccessList is not null) - { - // if we generated access list, we need to fix actual gas cost, as all storage was considered warm - gas -= IntrinsicGasCalculator.Calculate(transaction, Berlin.Instance); - transaction.AccessList = result.AccessList; - gas += IntrinsicGasCalculator.Calculate(transaction, Berlin.Instance); - } - - return (UInt256)gas; - } + return (UInt256)gas; } } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs new file mode 100644 index 00000000000..e83afc85b9c --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Evm.Tracing; +using Nethermind.Int256; + +namespace Nethermind.JsonRpc.Modules.Eth.Multicall; + +public class MultiCallBlockTracer : IBlockTracer +{ + public Dictionary> TxActions = new(); + public bool Trace { get; set; } + public bool IsTracingRewards => false; + + public void ReportReward(Address author, string rewardType, UInt256 rewardValue) + { + throw new NotImplementedException(); + } + + public void StartNewBlockTrace(Block block) + { + TxActions.Clear(); + } + + public ITxTracer StartNewTxTrace(Transaction? tx) + { + if (Trace && tx != null && tx.Hash != null) + { + List? actionsLog = new List(); + TxActions[tx.Hash] = actionsLog; + return new MultiCallTxTracer(tx, actionsLog); + } + + return NullTxTracer.Instance; + } + + public void EndTxTrace() + { + } + + public void EndBlockTrace() + { + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs index 7dd5210890c..cae77d98daa 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs @@ -27,6 +27,7 @@ public override bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] re //Note we mutate suggested block here to allow eth_multicall enforced State Root change //and still pass validation suggestedBlock.Header.StateRoot = processedBlock.Header.StateRoot; + suggestedBlock.Header.ReceiptsRoot = processedBlock.Header.ReceiptsRoot; suggestedBlock.Header.Hash = suggestedBlock.Header.CalculateHash(); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index 9d1aeb15977..26d69c97fa3 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using Nethermind.Blockchain; using Nethermind.Blockchain.Filters; @@ -17,14 +18,18 @@ using Nethermind.Consensus.Validators; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Db; using Nethermind.Db.Blooms; +using Nethermind.Evm.CodeAnalysis; using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; using Nethermind.Facade.Eth; +using Nethermind.Facade.Proxy.Models; +using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Modules.Eth.FeeHistory; using Nethermind.JsonRpc.Modules.Eth.GasPrice; @@ -47,6 +52,13 @@ namespace Nethermind.JsonRpc.Modules.Eth.Multicall; /// public class MultiCallBlockchainFork : IDisposable { + private UInt256 _maxGas; + + //todo remove public useless bridge + public BlockchainBridge bridge; + + public InMemoryReceiptStorage receiptStorage; + /// /// Creates a MultiCallBlockchainFork instance with the following steps: /// 1. Initialize MultiCallBlockchainFork object @@ -82,8 +94,10 @@ public class MultiCallBlockchainFork : IDisposable /// Current Code database /// Specification provider (optional) /// MultiCallBlockchainFork instance - public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProvider) + public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProvider, UInt256 MaxGas) { + _maxGas = MaxGas; + BlockTracer = new MultiCallBlockTracer(); //Init BlockChain //Writable inMemory DBs on with access to the data of existing ones (will not modify existing data) if (oldDbProvider == null) throw new ArgumentNullException(); @@ -145,7 +159,8 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv logManager, transactionComparerProvider.GetDefaultComparer()); - InMemoryReceiptStorage receiptStorage = new(); + + receiptStorage = new InMemoryReceiptStorage(); VirtualMachine = new MultiCallVirtualMachine( new BlockhashProvider(BlockTree, logManager), @@ -186,6 +201,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv BlockchainProcessor.Options.Default); ChainProcessor.Start(); + //Init RPC IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = @@ -209,7 +225,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv ITimestamper timestamper = Timestamper.Default; - BlockchainBridge bridge = new(processingEnv, + bridge = new BlockchainBridge(processingEnv, txPool, receiptFinder, filterStore, @@ -251,6 +267,8 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv dbProvider); } + public MultiCallBlockTracer BlockTracer { get; } + private BlockchainProcessor ChainProcessor { get; } private BlockProcessor BlockProcessor { get; } @@ -269,35 +287,81 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv public IDbProvider DbProvider { get; internal set; } //Create a new block next to current LatestBlock (BlockFinder.Head) - public Block CreateBlock() + public Block CreateBlock(BlockOverride? desiredBlock, CallTransactionModel[] desiredTransactions) { BlockHeader? parent = LatestBlock?.Header; if (parent == null) throw new Exception("Existing header expected"); - BlockHeader blockHeader = new( - parent.Hash, - Keccak.OfAnEmptySequenceRlp, - Address.Zero, - UInt256.Zero, - parent.Number + 1, - parent.GasLimit, - parent.Timestamp + 1, - Array.Empty()); + BlockHeader blockHeader = null; + if (desiredBlock != null) + { + ulong time = 0; + if (desiredBlock.Time <= ulong.MaxValue) + time = (ulong)desiredBlock.Time; + else + throw new OverflowException("Time value is too large to be converted to ulong we use."); + + long gasLimit = 0; + if (desiredBlock.GasLimit <= long.MaxValue) + gasLimit = (long)desiredBlock.GasLimit; + else + throw new OverflowException("GasLimit value is too large to be converted to long we use."); + + long blockNumber = 0; + if (desiredBlock.Number <= long.MaxValue) + blockNumber = (long)desiredBlock.Number; + else + throw new OverflowException("Block Number value is too large to be converted to long we use."); + + blockHeader = new BlockHeader( + parent.Hash, + Keccak.OfAnEmptySequenceRlp, + desiredBlock.FeeRecipient, + UInt256.Zero, + blockNumber, + gasLimit, + time, + Array.Empty()); + blockHeader.MixHash = desiredBlock.PrevRandao; + blockHeader.BaseFeePerGas = desiredBlock.BaseFee; + } + else + { + blockHeader = new BlockHeader( + parent.Hash, + Keccak.OfAnEmptySequenceRlp, + Address.Zero, + UInt256.Zero, + parent.Number + 1, + parent.GasLimit, + parent.Timestamp + 1, + Array.Empty()); + blockHeader.BaseFeePerGas = BaseFeeCalculator.Calculate(parent, SpecProvider.GetSpec(blockHeader)); + } + + if (_maxGas <= long.MaxValue) + blockHeader.GasLimit = + (long)Math.Min((ulong)blockHeader.GasLimit, _maxGas.ToUInt64(CultureInfo.InvariantCulture)); + else + _maxGas -= new UInt256((ulong)blockHeader.GasLimit); UInt256 difficulty = ConstantDifficulty.One.Calculate(blockHeader, parent); blockHeader.Difficulty = difficulty; blockHeader.TotalDifficulty = parent.TotalDifficulty + difficulty; - blockHeader.BaseFeePerGas = BaseFeeCalculator.Calculate(parent, SpecProvider.GetSpec(blockHeader)); - blockHeader.ReceiptsRoot = Keccak.EmptyTreeHash; - blockHeader.TxRoot = Keccak.EmptyTreeHash; - blockHeader.Bloom = Bloom.Empty; + //blockHeader.ReceiptsRoot = Keccak.EmptyTreeHash; + //blockHeader.TxRoot = Keccak.EmptyTreeHash; + //blockHeader.Bloom = Bloom.Empty; + + List transactions = new(); + if (desiredTransactions != null) + transactions = desiredTransactions.Select(model => model.GetTransaction()).ToList(); - Block? block = new(blockHeader, Array.Empty(), Array.Empty()); + Block? block = new(blockHeader, transactions, Array.Empty()); block = ChainProcessor.Process(block, - ProcessingOptions.ProducingBlock, + ProcessingOptions.ProducingBlock | ProcessingOptions.NoValidation, NullBlockTracer.Instance); return block; @@ -314,40 +378,106 @@ public bool FinalizeBlock(Block currentBlock) currentBlock.Header.IsPostMerge = true; //ToDo: Seal if necessary before merge 192 BPB currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); - AddBlockResult res = BlockTree.SuggestBlock(currentBlock, BlockTreeSuggestOptions.ForceSetAsMain); + AddBlockResult res = BlockTree.SuggestBlock(currentBlock, + BlockTreeSuggestOptions.ForceSetAsMain | BlockTreeSuggestOptions.ForceDontValidateParent); if (res != AddBlockResult.Added) return false; //ChainProcessor uses parent.StateRoot with the Process, it gets bad on InitBranch due to _state/storage resets + //Block[]? blocks = BlockProcessor.Process(currentBlock.StateRoot, + //new List { currentBlock! }, + //ProcessingOptions.StoreReceipts | ProcessingOptions.ForceProcessing | ProcessingOptions.DoNotVerifyNonce, + //BlockTracer); + Block[]? blocks = BlockProcessor.Process(currentBlock.StateRoot, new List { currentBlock! }, - ProcessingOptions.ForceProcessing, - new BlockReceiptsTracer()); - + ProcessingOptions.ForceProcessing | + ProcessingOptions.NoValidation | + ProcessingOptions.DoNotVerifyNonce | + ProcessingOptions.IgnoreParentNotOnMainChain | + ProcessingOptions.MarkAsProcessed | + ProcessingOptions.StoreReceipts + , + BlockTracer); + + //TODO: Here is a bug! + //TODO: It prevents block with 1+ transactions BlockTree.UpdateMainChain(blocks, true, true); - + BlockTree.UpdateHeadBlock(BlockFinder.Head.Hash); return true; } + + private void ModifyAccounts(AccountOverride[] StateOverrides) + { + Account? acc; + if (StateOverrides == null) return; + + foreach (AccountOverride accountOverride in StateOverrides) + { + Address address = accountOverride.Address; + bool accExists = StateProvider.AccountExists(address); + if (!accExists) + { + StateProvider.CreateAccount(address, accountOverride.Balance, accountOverride.Nonce); + acc = StateProvider.GetAccount(address); + } + else + acc = StateProvider.GetAccount(address); + + UInt256 accBalance = acc.Balance; + if (accBalance > accountOverride.Balance) + StateProvider.SubtractFromBalance(address, accBalance - accountOverride.Balance, CurrentSpec); + else if (accBalance < accountOverride.Nonce) + StateProvider.AddToBalance(address, accountOverride.Balance - accBalance, CurrentSpec); + + UInt256 accNonce = acc.Nonce; + if (accNonce > accountOverride.Nonce) + StateProvider.DecrementNonce(address); + else if (accNonce < accountOverride.Nonce) StateProvider.IncrementNonce(address); + + if (acc != null) + { + if (accountOverride.Code is not null) + { + VirtualMachine.SetOverwrite(StateProvider, CurrentSpec, address, + new CodeInfo(accountOverride.Code), accountOverride.MoveToAddress); + } + } + + + if (accountOverride.State is not null) + { + accountOverride.State = new Dictionary(); + foreach (KeyValuePair storage in accountOverride.State) + StateProvider.Set(new StorageCell(address, storage.Key), + storage.Value.WithoutLeadingZeros().ToArray()); + } + + if (accountOverride.StateDiff is not null) + { + foreach (KeyValuePair storage in accountOverride.StateDiff) + StateProvider.Set(new StorageCell(address, storage.Key), + storage.Value.WithoutLeadingZeros().ToArray()); + } + + StateProvider.Commit(CurrentSpec); + } + } + /// /// Forges a new block in the temp blockchain using the provided action to manipulate state, release spec, spec /// provider, and storage provider. /// - /// An action representing the modifications to the blockchain state and storage. - public bool ForgeChainBlock(Action action) + /// An action representing the modifications to the blockchain state and storage. + public (bool, Block? ) ForgeChainBlock(MultiCallBlockStateCallsModel blockMock) { //Prepare a block - Block? newBlock = CreateBlock(); - - action(StateProvider, - CurrentSpec, - SpecProvider, - VirtualMachine - ); + Block? newBlock = CreateBlock(blockMock.BlockOverride, blockMock.Calls); + ModifyAccounts(blockMock.StateOverrides); //Add block bool results = FinalizeBlock(newBlock); - return results; + return (results, newBlock); } //For using scope guard diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs new file mode 100644 index 00000000000..85dcb6e078c --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs @@ -0,0 +1,208 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using Nethermind.Abi; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Evm; +using Nethermind.Evm.Tracing; +using Nethermind.Int256; + +namespace Nethermind.JsonRpc.Modules.Eth.Multicall; + +//Why this is not visitor like DDD... +internal class MultiCallTxTracer : ITxTracer +{ + private readonly List _extendedLogs; + + public MultiCallTxTracer(Transaction t, List extendedLogs) + { + _extendedLogs = extendedLogs; + } + + public bool IsTracingState { get; } + + public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) + { + throw new NotImplementedException(); + } + + public void ReportCodeChange(Address address, byte[]? before, byte[]? after) + { + throw new NotImplementedException(); + } + + public void ReportNonceChange(Address address, UInt256? before, UInt256? after) + { + throw new NotImplementedException(); + } + + public void ReportAccountRead(Address address) + { + throw new NotImplementedException(); + } + + public bool IsTracingStorage { get; } + + public void ReportStorageChange(in ReadOnlySpan key, in ReadOnlySpan value) + { + throw new NotImplementedException(); + } + + public void ReportStorageChange(in StorageCell storageCell, byte[] before, byte[] after) + { + throw new NotImplementedException(); + } + + public void ReportStorageRead(in StorageCell storageCell) + { + throw new NotImplementedException(); + } + + public bool IsTracingReceipt { get; } + public bool IsTracingActions => true; + public bool IsTracingOpLevelStorage { get; } + public bool IsTracingMemory { get; } + public bool IsTracingInstructions { get; } + public bool IsTracingRefunds { get; } + public bool IsTracingCode { get; } + public bool IsTracingStack { get; } + public bool IsTracingBlockHash { get; } + public bool IsTracingAccess { get; } + public bool IsTracingFees { get; } + + + public bool IsTracing => IsTracingActions || IsTracingEventLogs; + public bool IsTracingEventLogs => true; + + public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, + Keccak? stateRoot = null) + { + throw new NotImplementedException(); + } + + public void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Keccak? stateRoot = null) + { + throw new NotImplementedException(); + } + + public void StartOperation(int depth, long gas, Instruction opcode, int pc, bool isPostMerge = false) + { + throw new NotImplementedException(); + } + + public void ReportOperationError(EvmExceptionType error) + { + throw new NotImplementedException(); + } + + public void ReportOperationRemainingGas(long gas) + { + throw new NotImplementedException(); + } + + public void SetOperationStack(List stackTrace) + { + throw new NotImplementedException(); + } + + public void ReportStackPush(in ReadOnlySpan stackItem) + { + throw new NotImplementedException(); + } + + public void SetOperationMemory(List memoryTrace) + { + throw new NotImplementedException(); + } + + public void SetOperationMemorySize(ulong newSize) + { + throw new NotImplementedException(); + } + + public void ReportMemoryChange(long offset, in ReadOnlySpan data) + { + throw new NotImplementedException(); + } + + public void SetOperationStorage(Address address, UInt256 storageIndex, ReadOnlySpan newValue, + ReadOnlySpan currentValue) + { + throw new NotImplementedException(); + } + + public void LoadOperationStorage(Address address, UInt256 storageIndex, ReadOnlySpan value) + { + throw new NotImplementedException(); + } + + public void ReportSelfDestruct(Address address, UInt256 balance, Address refundAddress) + { + } + + public void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, + ExecutionType callType, + bool isPrecompileCall = false) + { + byte[]? data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, + new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256), from, to, value); + LogEntry? result = new LogEntry(Address.Zero, data, new[] { Keccak.Zero }); + _extendedLogs.Add(result); + } + + public void ReportActionEnd(long gas, ReadOnlyMemory output) + { + } + + public void ReportActionError(EvmExceptionType evmExceptionType) + { + } + + public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + { + throw new NotImplementedException(); + } + + public void ReportBlockHash(Keccak blockHash) + { + throw new NotImplementedException(); + } + + public void ReportByteCode(byte[] byteCode) + { + throw new NotImplementedException(); + } + + public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) + { + throw new NotImplementedException(); + } + + public void ReportRefund(long refund) + { + throw new NotImplementedException(); + } + + public void ReportExtraGasPressure(long extraGasPressure) + { + throw new NotImplementedException(); + } + + public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) + { + throw new NotImplementedException(); + } + + public void ReportFees(UInt256 fees, UInt256 burntFees) + { + throw new NotImplementedException(); + } + + public void ReportEvent(LogEntry logEntry) + { + _extendedLogs.Add(logEntry); + } +} diff --git a/src/Nethermind/Nethermind.Mev/BeneficiaryTracer.cs b/src/Nethermind/Nethermind.Mev/BeneficiaryTracer.cs index e40914d60ab..d614b82ae54 100644 --- a/src/Nethermind/Nethermind.Mev/BeneficiaryTracer.cs +++ b/src/Nethermind/Nethermind.Mev/BeneficiaryTracer.cs @@ -46,7 +46,8 @@ public void EndBlockTrace() { } public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public void ReportReward(Address author, string rewardType, UInt256 rewardValue) { } public void ReportCodeChange(Address address, byte[]? before, byte[]? after) { } public void ReportNonceChange(Address address, UInt256? before, UInt256? after) { } @@ -78,5 +79,6 @@ public void ReportRefund(long refund) { } public void ReportExtraGasPressure(long extraGasPressure) { } public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) { } public void ReportFees(UInt256 fees, UInt256 burntFees) { } + public void ReportEvent(LogEntry logEntry) { } } } diff --git a/src/Nethermind/Nethermind.Mev/Execution/TxBundleSimulator.cs b/src/Nethermind/Nethermind.Mev/Execution/TxBundleSimulator.cs index 6ade1a7da89..4d37acb2b38 100644 --- a/src/Nethermind/Nethermind.Mev/Execution/TxBundleSimulator.cs +++ b/src/Nethermind/Nethermind.Mev/Execution/TxBundleSimulator.cs @@ -209,7 +209,8 @@ public BundleTxTracer(Address beneficiary, Transaction? transaction, int index) public bool IsTracingStorage => false; public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public long GasSpent { get; set; } public UInt256? BeneficiaryBalanceBefore { get; private set; } public UInt256? BeneficiaryBalanceAfter { get; private set; } @@ -377,6 +378,11 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) { throw new NotImplementedException(); } + + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } } } } From 016ad54119f31d16a1e3385ea3a9df2859f680b0 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 6 Jun 2023 09:06:52 +0100 Subject: [PATCH 015/213] fixing whitespace --- .../Executor/UserOperationTracer.cs | 2 +- .../Tracing/BlockReceiptsTracer.cs | 2 +- .../Nethermind.Evm/Tracing/ITxTracer.cs | 2 +- .../Tracing/Proofs/ProofTxTracer.cs | 2 +- .../Proxy/EthJsonRpcClientProxy.cs | 2 +- ...ulticallTestsPrecompilesWithRedirection.cs | 4 +++- .../Eth/EthMulticallTestsSimplePrecompiles.cs | 4 +++- .../Eth/EthModule.TransactionExecutor.cs | 23 +++++++++++-------- .../Eth/Multicall/MultiCallBlockchainFork.cs | 2 +- 9 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs b/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs index fc2ca5e8ce4..dab966190bf 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs @@ -77,7 +77,7 @@ public UserOperationTxTracer( public bool IsTracingAccess => true; public bool IsTracingFees => false; public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; - public bool IsTracingEventLogs => false; + public bool IsTracingEventLogs => false; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index 525a8aa3771..6b26400175f 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -29,7 +29,7 @@ public class BlockReceiptsTracer : IBlockTracer, ITxTracer, IJournal, ITxTr public bool IsTracingAccess => _currentTxTracer.IsTracingAccess; public bool IsTracingFees => _currentTxTracer.IsTracingFees; public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; - public bool IsTracingEventLogs => _currentTxTracer.IsTracingEventLogs; + public bool IsTracingEventLogs => _currentTxTracer.IsTracingEventLogs; private IBlockTracer _otherTracer = NullBlockTracer.Instance; diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index 11372e8e692..a652d58a0d1 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -136,7 +136,7 @@ public interface ITxTracer : IWorldStateTracer /// Controls /// - /// - bool IsTracingEventLogs { get; } + bool IsTracingEventLogs { get; } /// /// Transaction completed successfully diff --git a/src/Nethermind/Nethermind.Evm/Tracing/Proofs/ProofTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/Proofs/ProofTxTracer.cs index 19fc3abccf3..362499caef3 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/Proofs/ProofTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/Proofs/ProofTxTracer.cs @@ -39,7 +39,7 @@ public ProofTxTracer(bool treatSystemAccountDifferently) public bool IsTracingState => true; public bool IsTracingStorage => true; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; public bool IsTracingEventLogs => false; public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index 9bc2ddc9c41..dc3f1b67eb1 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -44,7 +44,7 @@ public Task> eth_multicall(ulong version, Mult nameof(eth_multicall), version, blockCalls, MapBlockParameter(blockParameter)); - + public Task> eth_getCode(Address address, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_getCode), address, MapBlockParameter(blockParameter)); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 5c499ab6511..df2ae08af0f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -116,7 +116,9 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( //Generate and send transaction (shall be mocked) SystemTransaction systemTransactionForModifiedVM = new() { - Data = transactionData, To = contractAddress, SenderAddress = TestItem.PublicKeyB.Address + Data = transactionData, + To = contractAddress, + SenderAddress = TestItem.PublicKeyB.Address }; systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs index f594282a050..3fd507b3d13 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs @@ -98,7 +98,9 @@ await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, //Generate and send transaction SystemTransaction systemTransactionForModifiedVM = new() { - Data = transactionData, To = contractAddress, SenderAddress = TestItem.PublicKeyB.Address + Data = transactionData, + To = contractAddress, + SenderAddress = TestItem.PublicKeyB.Address }; systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index dbb2fb91629..d4e897a68a9 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -165,17 +165,17 @@ public ResultWrapper Execute(ulong version, }).ToArray(); txResults.Add(new MultiCallCallResult + { + GasUsed = (ulong)Receipt.GasUsed, + Error = new Facade.Proxy.Models.MultiCall.Error { - GasUsed = (ulong)Receipt.GasUsed, - Error = new Facade.Proxy.Models.MultiCall.Error - { - Data = (Receipt.Error.IsNullOrEmpty() ? Receipt.Error : "") ?? + Data = (Receipt.Error.IsNullOrEmpty() ? Receipt.Error : "") ?? string.Empty - }, - Return = Receipt.ReturnValue, - Status = Receipt.StatusCode.ToString(), - Logs = logs.ToArray() - } + }, + Return = Receipt.ReturnValue, + Status = Receipt.StatusCode.ToString(), + Logs = logs.ToArray() + } ); } @@ -224,7 +224,10 @@ private static List FillInMisingBlocks( { BlockOverride = new BlockOverride { - Number = missingNumber, GasLimit = 5_000_000, FeeRecipient = Address.Zero, BaseFee = 0 + Number = missingNumber, + GasLimit = 5_000_000, + FeeRecipient = Address.Zero, + BaseFee = 0 } }); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index 26d69c97fa3..a7196cce731 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -469,7 +469,7 @@ private void ModifyAccounts(AccountOverride[] StateOverrides) /// provider, and storage provider. /// /// An action representing the modifications to the blockchain state and storage. - public (bool, Block? ) ForgeChainBlock(MultiCallBlockStateCallsModel blockMock) + public (bool, Block?) ForgeChainBlock(MultiCallBlockStateCallsModel blockMock) { //Prepare a block Block? newBlock = CreateBlock(blockMock.BlockOverride, blockMock.Calls); From a3be1b2c6daa5855c81ac49e6d0ea401839b83d4 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 7 Jun 2023 10:52:50 +0100 Subject: [PATCH 016/213] All tests passing Added execution of blocks with any given block numbers without linear blocks creation --- .../EthMulticallTestsBlocksAndTransactions.cs | 82 +++++++++++++- ...ulticallTestsPrecompilesWithRedirection.cs | 4 +- .../Eth/EthMulticallTestsSimplePrecompiles.cs | 3 +- .../Modules/Eth/EthRpcMulticallTests.cs | 6 +- .../Eth/EthModule.TransactionExecutor.cs | 61 +++-------- .../Modules/Eth/EthRpcModule.cs | 2 +- .../Eth/Multicall/MultiCallBlockValidator.cs | 36 ------- .../Eth/Multicall/MultiCallBlockchainFork.cs | 101 ++++++++---------- 8 files changed, 142 insertions(+), 153 deletions(-) delete mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs index 8a59c008b29..035abb782c2 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs @@ -37,6 +37,8 @@ private Transaction GetTransferTxData(UInt256 Nonce, IEthereumEcdsa ethereumEcds /// /// This test verifies that a temporary forked blockchain can make transactions, blocks and report on them + /// We test on blocks before current head and after it, + /// Note that if we get blocks before head we set simulation start state to one of that first block /// [Test] public async Task Test_eth_multicall_eth_moved() @@ -62,7 +64,7 @@ public async Task Test_eth_multicall_eth_moved() BlockOverride = new BlockOverride { - Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10), + Number = (UInt256)new decimal(2), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFee = 0 @@ -113,11 +115,81 @@ public async Task Test_eth_multicall_eth_moved() foreach (MultiCallBlockResult blockResult in data) { Assert.AreEqual(blockResult.Calls.Length, 2); - foreach (MultiCallCallResult callResult in blockResult.Calls) + } + } + + /// + /// This test verifies that a temporary forked blockchain can make transactions, blocks and report on them + /// + [Test] + public async Task Test_eth_multicall_transactions_forced_fail() + { + TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); + + UInt256 nonceA = chain.State.GetNonce(TestItem.AddressA); + + Transaction txMainnetAtoB = + GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); + //shall be Ok + Transaction txAtoB1 = + GetTransferTxData(nonceA + 1, chain.EthereumEcdsa, TestItem.PrivateKeyC, TestItem.AddressB, 1); + + //shall fail + Transaction txAtoB2 = + GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, UInt256.MaxValue); + + MultiCallBlockStateCallsModel[] requestMultiCall = + { + new() { - //callResult.Logs - //Assert.Less(); + BlockOverride = + new BlockOverride + { + Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10), + GasLimit = 5_000_000, + FeeRecipient = TestItem.AddressC, + BaseFee = 0 + }, + Calls = new[] + { + CallTransactionModel.FromTransaction(txAtoB1) + } + }, + new() + { + BlockOverride = + new BlockOverride + { + Number = (UInt256)new decimal(123), + GasLimit = 5_000_000, + FeeRecipient = TestItem.AddressC, + BaseFee = 0 + }, + Calls = new[] + { + CallTransactionModel.FromTransaction(txAtoB2) + } } - } + }; + + //Test that transfer tx works on mainchain + UInt256 before = chain.State.GetAccount(TestItem.AddressA).Balance; + await chain.AddBlock(true, txMainnetAtoB); + UInt256 after = chain.State.GetAccount(TestItem.AddressA).Balance; + Assert.Less(after, before); + + TxReceipt recept = chain.Bridge.GetReceipt(txMainnetAtoB.Hash); + LogEntry[]? ls = recept.Logs; + + //Force persistancy of head block in main chain + chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + + //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not + EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.SpecProvider, new JsonRpcConfig()); + ResultWrapper result = + executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); + Assert.AreEqual(ErrorCodes.InternalError, result.ErrorCode); + Assert.IsTrue(result.Result.Error.StartsWith("At block 123 got exception:")); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index df2ae08af0f..3508dfd4ef1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -109,9 +109,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider, MultiCallTxExecutor.GetMaxGas(new JsonRpcConfig()))) { - (bool processed, Block? _) = tmpChain.ForgeChainBlock(requestMultiCall); - - Assert.True(processed); + Block _ = tmpChain.ForgeChainBlock(requestMultiCall); //Generate and send transaction (shall be mocked) SystemTransaction systemTransactionForModifiedVM = new() diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs index 3fd507b3d13..1e3a0f8dd9c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs @@ -92,9 +92,8 @@ await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider, EthRpcModule.MultiCallTxExecutor.GetMaxGas(new JsonRpcConfig()))) { - (bool processed, Block? _) = tmpChain.ForgeChainBlock(requestMultiCall); + Block? _ = tmpChain.ForgeChainBlock(requestMultiCall); - Assert.True(processed); //Generate and send transaction SystemTransaction systemTransactionForModifiedVM = new() { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs index fc1135df987..0fb85d72e28 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -255,11 +255,7 @@ public async Task Test_eth_multicall_account_data() UInt256 num_tmp = userBalanceBefore_fromTmp.Data.Value; Assert.AreEqual(userBalanceBefore_fromTmp.Data, userBalanceBefore.Data); - (bool processed, Block? _) = tmpChain.ForgeChainBlock(requestBlockOne); - - - //Check block has been added to chain as main - Assert.True(processed); + Block? _= tmpChain.ForgeChainBlock(requestBlockOne); //Check block has updated values in tmp chain ResultWrapper userBalanceResult_fromTm = diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index d4e897a68a9..08b65d750fa 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -124,18 +124,22 @@ public ResultWrapper Execute(ulong version, List results = new(); using (MultiCallBlockchainFork tmpChain = new(_dbProvider, _specProvider, MaxGas)) { - List blockCalls = - FillInMisingBlocks(blockCallsToProcess, - (ulong)tmpChain.LatestBlock - .Number); // blockCallsToProcess.OrderBy(model => model.BlockOverride.Number).ToList(); - + List blockCalls = blockCallsToProcess.OrderBy(model => model.BlockOverride.Number).ToList(); + tmpChain.BlockTracer.Trace = traceTransfers; ulong logIndices = 0; foreach (MultiCallBlockStateCallsModel blockCall in blockCalls) { - (bool processed, Block? block) = tmpChain.ForgeChainBlock(blockCall); - - if (!processed) break; + Block ? block = null; + try + { + block = tmpChain.ForgeChainBlock(blockCall); + } + catch (Exception ex) + { + return ResultWrapper.Fail( + $"At block {blockCall.BlockOverride.Number} got exception: {ex.Message}"); + } if (selsectResults.Contains(blockCall.BlockOverride.Number)) { @@ -179,7 +183,7 @@ public ResultWrapper Execute(ulong version, ); } - MultiCallBlockResult? result = new MultiCallBlockResult + MultiCallBlockResult? result = new() { baseFeePerGas = tmpChain.LatestBlock.BaseFeePerGas, FeeRecipient = tmpChain.LatestBlock.Beneficiary, @@ -197,44 +201,7 @@ public ResultWrapper Execute(ulong version, return ResultWrapper.Success(results.ToArray()); } - - //Returns an ordered list of blockCallsToProcess without gaps - private static List FillInMisingBlocks( - MultiCallBlockStateCallsModel[] blockCallsToProcess, UInt256 from) - { - List? blockCalls = - blockCallsToProcess.OrderBy(model => model.BlockOverride.Number).ToList(); - - // Get the lowest and highest numbers - UInt256 minNumber = from; - UInt256 maxNumber = blockCalls.Last().BlockOverride.Number; - - // Generate a sequence of numbers in that range - IEnumerable? rangeNumbers = Range(minNumber, maxNumber - minNumber + 1); - - // Get the list of current numbers - HashSet? currentNumbers = new HashSet(blockCalls.Select(m => m.BlockOverride.Number)); - - // Find which numbers are missing - IEnumerable? missingNumbers = rangeNumbers.Where(n => !currentNumbers.Contains(n)); - - // Fill in the gaps - foreach (UInt256 missingNumber in missingNumbers) - blockCalls.Add(new MultiCallBlockStateCallsModel - { - BlockOverride = new BlockOverride - { - Number = missingNumber, - GasLimit = 5_000_000, - FeeRecipient = Address.Zero, - BaseFee = 0 - } - }); - - // Sort again after filling the gaps - blockCalls = blockCalls.OrderBy(model => model.BlockOverride.Number).ToList(); - return blockCalls; - } + } private class EstimateGasTxExecutor : TxExecutor diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index e53c1fb0e7b..1124ebf73d9 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -377,7 +377,7 @@ public ResultWrapper eth_multicall(ulong version, MultiC BlockParameter? blockParameter = null) { return new MultiCallTxExecutor(_dbProvider, _specProvider, _rpcConfig) - .Execute(version, blockCalls, blockParameter); + .Execute(version, blockCalls, blockParameter, true); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs deleted file mode 100644 index cae77d98daa..00000000000 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockValidator.cs +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Consensus.Validators; -using Nethermind.Core; -using Nethermind.Core.Specs; -using Nethermind.Crypto; -using Nethermind.Logging; -using Nethermind.TxPool; - -namespace Nethermind.JsonRpc.Modules.Eth.Multicall; - -internal class MultiCallBlockValidator : BlockValidator -{ - public MultiCallBlockValidator(ITxValidator? txValidator, - IHeaderValidator? headerValidator, - IUnclesValidator? unclesValidator, - ISpecProvider? specProvider, - ILogManager? logManager) : base(txValidator, headerValidator, unclesValidator, specProvider, logManager) - { - } - - public override bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) - { - if (processedBlock.Header.StateRoot != suggestedBlock.Header.StateRoot) - { - //Note we mutate suggested block here to allow eth_multicall enforced State Root change - //and still pass validation - suggestedBlock.Header.StateRoot = processedBlock.Header.StateRoot; - suggestedBlock.Header.ReceiptsRoot = processedBlock.Header.ReceiptsRoot; - suggestedBlock.Header.Hash = suggestedBlock.Header.CalculateHash(); - } - - return base.ValidateProcessedBlock(processedBlock, receipts, suggestedBlock); - } -} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index a7196cce731..77fdac63e75 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Transactions; using Nethermind.Blockchain; using Nethermind.Blockchain.Filters; using Nethermind.Blockchain.Find; @@ -35,11 +36,13 @@ using Nethermind.JsonRpc.Modules.Eth.GasPrice; using Nethermind.Logging; using Nethermind.State; +using Nethermind.State.Proofs; using Nethermind.State.Repositories; using Nethermind.Synchronization.ParallelSync; using Nethermind.Trie.Pruning; using Nethermind.TxPool; using Nethermind.Wallet; +using Transaction = Nethermind.Core.Transaction; namespace Nethermind.JsonRpc.Modules.Eth.Multicall; @@ -59,6 +62,8 @@ public class MultiCallBlockchainFork : IDisposable public InMemoryReceiptStorage receiptStorage; + + //TODO: throw away and replace with ...Env related stuff based implementations (decompose, remove unused functions) /// /// Creates a MultiCallBlockchainFork instance with the following steps: /// 1. Initialize MultiCallBlockchainFork object @@ -177,7 +182,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv SpecProvider, logManager); - MultiCallBlockValidator blockValidator = new(new TxValidator(SpecProvider.ChainId), + BlockValidator blockValidator = new(new TxValidator(SpecProvider.ChainId), headerValidator, Always.Valid, SpecProvider, @@ -287,15 +292,31 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv public IDbProvider DbProvider { get; internal set; } //Create a new block next to current LatestBlock (BlockFinder.Head) - public Block CreateBlock(BlockOverride? desiredBlock, CallTransactionModel[] desiredTransactions) + public Block CreateBlock(BlockOverride desiredBlock, CallTransactionModel[] desiredTransactions) { - BlockHeader? parent = LatestBlock?.Header; - if (parent == null) - throw new Exception("Existing header expected"); + BlockHeader? parent = null; + if (desiredBlock.Number < LatestBlock.Number) + { + var parentBlock = BlockFinder.FindBlock((long)(desiredBlock.Number - 1)); + if (parentBlock != null) + { + BlockTree.UpdateMainChain(new List(){ parentBlock }, true, true); + BlockTree.UpdateHeadBlock(parentBlock.Hash); + parent = parentBlock.Header; + StateProvider.StateRoot = parent.StateRoot; + } + else + { + throw new ArgumentException("could not find parent block and load the state"); + } + } + else + { + parent = LatestBlock?.Header; + } + BlockHeader blockHeader = null; - if (desiredBlock != null) - { ulong time = 0; if (desiredBlock.Time <= ulong.MaxValue) time = (ulong)desiredBlock.Time; @@ -325,20 +346,6 @@ public Block CreateBlock(BlockOverride? desiredBlock, CallTransactionModel[] des Array.Empty()); blockHeader.MixHash = desiredBlock.PrevRandao; blockHeader.BaseFeePerGas = desiredBlock.BaseFee; - } - else - { - blockHeader = new BlockHeader( - parent.Hash, - Keccak.OfAnEmptySequenceRlp, - Address.Zero, - UInt256.Zero, - parent.Number + 1, - parent.GasLimit, - parent.Timestamp + 1, - Array.Empty()); - blockHeader.BaseFeePerGas = BaseFeeCalculator.Calculate(parent, SpecProvider.GetSpec(blockHeader)); - } if (_maxGas <= long.MaxValue) blockHeader.GasLimit = @@ -350,25 +357,17 @@ public Block CreateBlock(BlockOverride? desiredBlock, CallTransactionModel[] des blockHeader.Difficulty = difficulty; blockHeader.TotalDifficulty = parent.TotalDifficulty + difficulty; - //blockHeader.ReceiptsRoot = Keccak.EmptyTreeHash; - //blockHeader.TxRoot = Keccak.EmptyTreeHash; - //blockHeader.Bloom = Bloom.Empty; - List transactions = new(); if (desiredTransactions != null) transactions = desiredTransactions.Select(model => model.GetTransaction()).ToList(); - Block? block = new(blockHeader, transactions, Array.Empty()); - - block = ChainProcessor.Process(block, - ProcessingOptions.ProducingBlock | ProcessingOptions.NoValidation, - NullBlockTracer.Instance); + Block? block = new(blockHeader, transactions , Array.Empty()); return block; } //Process Block and UpdateMainChain with it - public bool FinalizeBlock(Block currentBlock) + public Block FinalizeBlock(Block currentBlock) { StateProvider.Commit(SpecProvider.GetSpec(currentBlock.Header)); StateProvider.CommitTree(currentBlock.Number); @@ -378,35 +377,29 @@ public bool FinalizeBlock(Block currentBlock) currentBlock.Header.IsPostMerge = true; //ToDo: Seal if necessary before merge 192 BPB currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); - AddBlockResult res = BlockTree.SuggestBlock(currentBlock, - BlockTreeSuggestOptions.ForceSetAsMain | BlockTreeSuggestOptions.ForceDontValidateParent); - if (res != AddBlockResult.Added) return false; - - //ChainProcessor uses parent.StateRoot with the Process, it gets bad on InitBranch due to _state/storage resets - //Block[]? blocks = BlockProcessor.Process(currentBlock.StateRoot, - //new List { currentBlock! }, - //ProcessingOptions.StoreReceipts | ProcessingOptions.ForceProcessing | ProcessingOptions.DoNotVerifyNonce, - //BlockTracer); - Block[]? blocks = BlockProcessor.Process(currentBlock.StateRoot, - new List { currentBlock! }, + var block = ChainProcessor.Process( + currentBlock, ProcessingOptions.ForceProcessing | ProcessingOptions.NoValidation | ProcessingOptions.DoNotVerifyNonce | ProcessingOptions.IgnoreParentNotOnMainChain | ProcessingOptions.MarkAsProcessed | - ProcessingOptions.StoreReceipts + ProcessingOptions.StoreReceipts , BlockTracer); - //TODO: Here is a bug! - //TODO: It prevents block with 1+ transactions + var blocks = new List(){ block }; + var res = BlockTree.SuggestBlock(blocks.First(), + BlockTreeSuggestOptions.ForceSetAsMain | BlockTreeSuggestOptions.ForceDontValidateParent); + BlockTree.UpdateMainChain(blocks, true, true); - BlockTree.UpdateHeadBlock(BlockFinder.Head.Hash); - return true; + BlockTree.UpdateHeadBlock(block.Hash); + return block; } + //Apply changes to accounts and contracts states including precompiles private void ModifyAccounts(AccountOverride[] StateOverrides) { Account? acc; @@ -469,19 +462,19 @@ private void ModifyAccounts(AccountOverride[] StateOverrides) /// provider, and storage provider. /// /// An action representing the modifications to the blockchain state and storage. - public (bool, Block?) ForgeChainBlock(MultiCallBlockStateCallsModel blockMock) + public Block ForgeChainBlock(MultiCallBlockStateCallsModel blockMock) { - //Prepare a block + //Create a block Block? newBlock = CreateBlock(blockMock.BlockOverride, blockMock.Calls); + + //Update the state ModifyAccounts(blockMock.StateOverrides); - //Add block - bool results = FinalizeBlock(newBlock); - return (results, newBlock); + //Process transactions + newBlock = FinalizeBlock(newBlock); + return newBlock; } - //For using scope guard - #region IDisposable private bool _disposed; From 56eb06c31b5f7432e2d4257abf6ab3035dbe1ae7 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 7 Jun 2023 10:54:09 +0100 Subject: [PATCH 017/213] fix spacing --- .../EthMulticallTestsBlocksAndTransactions.cs | 2 +- .../Modules/Eth/EthRpcMulticallTests.cs | 2 +- .../Eth/EthModule.TransactionExecutor.cs | 6 +- .../Eth/Multicall/MultiCallBlockchainFork.cs | 62 +++++++++---------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs index 035abb782c2..15120e7294d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs @@ -64,7 +64,7 @@ public async Task Test_eth_multicall_eth_moved() BlockOverride = new BlockOverride { - Number = (UInt256)new decimal(2), + Number = (UInt256)new decimal(2), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFee = 0 diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs index 0fb85d72e28..bfeac6000be 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -255,7 +255,7 @@ public async Task Test_eth_multicall_account_data() UInt256 num_tmp = userBalanceBefore_fromTmp.Data.Value; Assert.AreEqual(userBalanceBefore_fromTmp.Data, userBalanceBefore.Data); - Block? _= tmpChain.ForgeChainBlock(requestBlockOne); + Block? _ = tmpChain.ForgeChainBlock(requestBlockOne); //Check block has updated values in tmp chain ResultWrapper userBalanceResult_fromTm = diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index 08b65d750fa..ae61b40b3fe 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -125,12 +125,12 @@ public ResultWrapper Execute(ulong version, using (MultiCallBlockchainFork tmpChain = new(_dbProvider, _specProvider, MaxGas)) { List blockCalls = blockCallsToProcess.OrderBy(model => model.BlockOverride.Number).ToList(); - + tmpChain.BlockTracer.Trace = traceTransfers; ulong logIndices = 0; foreach (MultiCallBlockStateCallsModel blockCall in blockCalls) { - Block ? block = null; + Block? block = null; try { block = tmpChain.ForgeChainBlock(blockCall); @@ -201,7 +201,7 @@ public ResultWrapper Execute(ulong version, return ResultWrapper.Success(results.ToArray()); } - + } private class EstimateGasTxExecutor : TxExecutor diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index 77fdac63e75..c5b83a65811 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -300,7 +300,7 @@ public Block CreateBlock(BlockOverride desiredBlock, CallTransactionModel[] desi var parentBlock = BlockFinder.FindBlock((long)(desiredBlock.Number - 1)); if (parentBlock != null) { - BlockTree.UpdateMainChain(new List(){ parentBlock }, true, true); + BlockTree.UpdateMainChain(new List() { parentBlock }, true, true); BlockTree.UpdateHeadBlock(parentBlock.Hash); parent = parentBlock.Header; StateProvider.StateRoot = parent.StateRoot; @@ -317,35 +317,35 @@ public Block CreateBlock(BlockOverride desiredBlock, CallTransactionModel[] desi BlockHeader blockHeader = null; - ulong time = 0; - if (desiredBlock.Time <= ulong.MaxValue) - time = (ulong)desiredBlock.Time; - else - throw new OverflowException("Time value is too large to be converted to ulong we use."); + ulong time = 0; + if (desiredBlock.Time <= ulong.MaxValue) + time = (ulong)desiredBlock.Time; + else + throw new OverflowException("Time value is too large to be converted to ulong we use."); - long gasLimit = 0; - if (desiredBlock.GasLimit <= long.MaxValue) - gasLimit = (long)desiredBlock.GasLimit; - else - throw new OverflowException("GasLimit value is too large to be converted to long we use."); + long gasLimit = 0; + if (desiredBlock.GasLimit <= long.MaxValue) + gasLimit = (long)desiredBlock.GasLimit; + else + throw new OverflowException("GasLimit value is too large to be converted to long we use."); - long blockNumber = 0; - if (desiredBlock.Number <= long.MaxValue) - blockNumber = (long)desiredBlock.Number; - else - throw new OverflowException("Block Number value is too large to be converted to long we use."); - - blockHeader = new BlockHeader( - parent.Hash, - Keccak.OfAnEmptySequenceRlp, - desiredBlock.FeeRecipient, - UInt256.Zero, - blockNumber, - gasLimit, - time, - Array.Empty()); - blockHeader.MixHash = desiredBlock.PrevRandao; - blockHeader.BaseFeePerGas = desiredBlock.BaseFee; + long blockNumber = 0; + if (desiredBlock.Number <= long.MaxValue) + blockNumber = (long)desiredBlock.Number; + else + throw new OverflowException("Block Number value is too large to be converted to long we use."); + + blockHeader = new BlockHeader( + parent.Hash, + Keccak.OfAnEmptySequenceRlp, + desiredBlock.FeeRecipient, + UInt256.Zero, + blockNumber, + gasLimit, + time, + Array.Empty()); + blockHeader.MixHash = desiredBlock.PrevRandao; + blockHeader.BaseFeePerGas = desiredBlock.BaseFee; if (_maxGas <= long.MaxValue) blockHeader.GasLimit = @@ -361,7 +361,7 @@ public Block CreateBlock(BlockOverride desiredBlock, CallTransactionModel[] desi if (desiredTransactions != null) transactions = desiredTransactions.Select(model => model.GetTransaction()).ToList(); - Block? block = new(blockHeader, transactions , Array.Empty()); + Block? block = new(blockHeader, transactions, Array.Empty()); return block; } @@ -385,11 +385,11 @@ public Block FinalizeBlock(Block currentBlock) ProcessingOptions.DoNotVerifyNonce | ProcessingOptions.IgnoreParentNotOnMainChain | ProcessingOptions.MarkAsProcessed | - ProcessingOptions.StoreReceipts + ProcessingOptions.StoreReceipts , BlockTracer); - var blocks = new List(){ block }; + var blocks = new List() { block }; var res = BlockTree.SuggestBlock(blocks.First(), BlockTreeSuggestOptions.ForceSetAsMain | BlockTreeSuggestOptions.ForceDontValidateParent); From 6a76c011bc76d5f5efc8801ce0ea460598b34e63 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 7 Jun 2023 11:30:12 +0100 Subject: [PATCH 018/213] fixing RPC tests --- .../Nethermind.Cli/Modules/EthCliModule.cs | 4 +- .../Proxy/EthJsonRpcClientProxyTests.cs | 17 +++ .../Proxy/EthJsonRpcClientProxy.cs | 5 +- .../Proxy/IEthJsonRpcClientProxy.cs | 2 +- .../Modules/Eth/EthRpcModule.cs | 4 +- .../Modules/Eth/EthRpcModuleProxy.cs | 5 +- .../Modules/Eth/IEthRpcModule.cs | 8 +- .../Eth/Multicall/MultiCallBlockchainFork.cs | 113 ++++++++++-------- 8 files changed, 98 insertions(+), 60 deletions(-) diff --git a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs index 2612275ae24..9726178761c 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs @@ -51,9 +51,9 @@ public JsValue GetProof(string address, string[] storageKeys, string? blockParam //TODO: add tests [CliFunction("eth", "multicall")] - public JsValue MultiCall(ulong version, object[] blockCalls, string? blockParameter = null) + public JsValue MultiCall(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) { - return NodeManager.PostJint("eth_multicall", version, blockCalls, blockParameter ?? "latest").Result; + return NodeManager.PostJint("eth_multicall", version, blockCalls, blockParameter ?? "latest", traceTransfers).Result; } diff --git a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs index d3bfb49245c..441a4e22227 100644 --- a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs @@ -2,6 +2,8 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Linq; +using System.Threading; using System.Threading.Tasks; using FluentAssertions; using Nethermind.Core.Crypto; @@ -9,6 +11,7 @@ using Nethermind.Int256; using Nethermind.Facade.Proxy; using Nethermind.Facade.Proxy.Models; +using Nethermind.Facade.Proxy.Models.MultiCall; using NSubstitute; using NUnit.Framework; @@ -84,6 +87,20 @@ await _client.Received().SendAsync(nameof(_proxy.eth_call), callTransaction, blockParameter.Type); } + + [Test] + public async Task eth_multicall_should_invoke_client_method() + { + var multyCallTransaction = new MultiCallBlockStateCallsModel[] { }; + var blockParameter = BlockParameterModel.Latest; + var traceTransactions = true; + await _proxy.eth_multicall(1, multyCallTransaction, blockParameter, traceTransactions); + + var calls = _client.ReceivedCalls().ToList(); + await _client.Received().SendAsync(nameof(_proxy.eth_multicall), + (ulong)1, multyCallTransaction, blockParameter.Type, traceTransactions); + } + [Test] public async Task eth_getCode_should_invoke_client_method() { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index dc3f1b67eb1..49119e0fa7a 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -40,10 +40,11 @@ public Task> eth_call(CallTransactionModel transaction, => _proxy.SendAsync(nameof(eth_call), transaction, MapBlockParameter(blockParameter)); public Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, - BlockParameterModel blockParameter = null) => _proxy.SendAsync( + BlockParameterModel blockParameter = null, bool traceTransfers = true) => _proxy.SendAsync( nameof(eth_multicall), version, blockCalls, - MapBlockParameter(blockParameter)); + MapBlockParameter(blockParameter), + traceTransfers); public Task> eth_getCode(Address address, BlockParameterModel blockParameter = null) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs index 4e7439db057..be46e9cda11 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs @@ -20,7 +20,7 @@ public interface IEthJsonRpcClientProxy Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null); //TODO:add tests - Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameterModel blockParameter = null); + Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameterModel blockParameter = null, bool traceTransfers = true); Task> eth_getCode(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionByHash(Keccak transactionHash); Task> eth_pendingTransactions(); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 1124ebf73d9..afa16671cf6 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -374,10 +374,10 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa .ExecuteTx(transactionCall, blockParameter); public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, - BlockParameter? blockParameter = null) + BlockParameter? blockParameter = null, bool traceTransfers = true) { return new MultiCallTxExecutor(_dbProvider, _specProvider, _rpcConfig) - .Execute(version, blockCalls, blockParameter, true); + .Execute(version, blockCalls, blockParameter, traceTransfers); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs index a6967e1f0e7..396d8968fe9 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs @@ -157,8 +157,9 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa throw new NotSupportedException(); } - public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, - BlockParameter? blockParameter = null) + public ResultWrapper eth_multicall(ulong version, + MultiCallBlockStateCallsModel[] blockCalls, + BlockParameter? blockParameter = null, bool traceTransfers = true) { throw new NotImplementedException(); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 391e2bac2cd..c1a4eaf90b7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -156,11 +156,11 @@ public interface IEthRpcModule : IRpcModule Description = "Executes a tx call (does not create a transaction)", IsSharable = false, ExampleResponse = "0x")] - ResultWrapper eth_multicall( - ulong version, - [JsonRpcParameter(ExampleValue = "[{\"stateOverrides\":[{\"nonce\":\"0x1\", \"address\": \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\", \"balance\": \"0xde0b6b3a7640000\", \"state\": {\"0x2292f0db49e1af24fbcac7f32b7537f334244455ad0ed0b46a78202982e7b70d\": \"0xde0b6b3a7640000\", \"0x0x877bd4632ef8c8ddc43b67e5a4511d939eadb612553c8a060670e05ebb1bb83c\": \"0xde0b6b3a7640000\"}}],\"calls\":[{\"from\":\"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"to\":\"0x6b175474e89094c44da98b954eedeac495271d0f\",\"data\":\"0x18160ddd\"}]}]")] + ResultWrapper eth_multicall(ulong version, + [JsonRpcParameter(ExampleValue = + "[{\"stateOverrides\":[{\"nonce\":\"0x1\", \"address\": \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\", \"balance\": \"0xde0b6b3a7640000\", \"state\": {\"0x2292f0db49e1af24fbcac7f32b7537f334244455ad0ed0b46a78202982e7b70d\": \"0xde0b6b3a7640000\", \"0x0x877bd4632ef8c8ddc43b67e5a4511d939eadb612553c8a060670e05ebb1bb83c\": \"0xde0b6b3a7640000\"}}],\"calls\":[{\"from\":\"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"to\":\"0x6b175474e89094c44da98b954eedeac495271d0f\",\"data\":\"0x18160ddd\"}]}]")] MultiCallBlockStateCallsModel[] blockCalls, - BlockParameter? blockParameter = null); + BlockParameter? blockParameter = null, bool traceTransfers = true); [JsonRpcMethod(IsImplemented = true, diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index c5b83a65811..368cff9145d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -292,60 +292,80 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv public IDbProvider DbProvider { get; internal set; } //Create a new block next to current LatestBlock (BlockFinder.Head) - public Block CreateBlock(BlockOverride desiredBlock, CallTransactionModel[] desiredTransactions) + public Block CreateBlock(BlockOverride? desiredBlock, CallTransactionModel[] desiredTransactions) { BlockHeader? parent = null; - if (desiredBlock.Number < LatestBlock.Number) + BlockHeader blockHeader = null; + + if (desiredBlock == null) + { + parent = LatestBlock?.Header; + + blockHeader = new BlockHeader( + parent.Hash, + Keccak.OfAnEmptySequenceRlp, + Address.Zero, + UInt256.Zero, + parent.Number + 1, + parent.GasLimit, + parent.Timestamp + 1, + Array.Empty()); + blockHeader.BaseFeePerGas = BaseFeeCalculator.Calculate(parent, SpecProvider.GetSpec(blockHeader)); + } + else { - var parentBlock = BlockFinder.FindBlock((long)(desiredBlock.Number - 1)); - if (parentBlock != null) + + if (desiredBlock.Number < LatestBlock.Number) { - BlockTree.UpdateMainChain(new List() { parentBlock }, true, true); - BlockTree.UpdateHeadBlock(parentBlock.Hash); - parent = parentBlock.Header; - StateProvider.StateRoot = parent.StateRoot; + var parentBlock = BlockFinder.FindBlock((long)(desiredBlock.Number - 1)); + if (parentBlock != null) + { + BlockTree.UpdateMainChain(new List() { parentBlock }, true, true); + BlockTree.UpdateHeadBlock(parentBlock.Hash); + parent = parentBlock.Header; + StateProvider.StateRoot = parent.StateRoot; + } + else + { + throw new ArgumentException("could not find parent block and load the state"); + } } else { - throw new ArgumentException("could not find parent block and load the state"); + parent = LatestBlock?.Header; } - } - else - { - parent = LatestBlock?.Header; - } - BlockHeader blockHeader = null; - ulong time = 0; - if (desiredBlock.Time <= ulong.MaxValue) - time = (ulong)desiredBlock.Time; - else - throw new OverflowException("Time value is too large to be converted to ulong we use."); + ulong time = 0; + if (desiredBlock.Time <= ulong.MaxValue) + time = (ulong)desiredBlock.Time; + else + throw new OverflowException("Time value is too large to be converted to ulong we use."); - long gasLimit = 0; - if (desiredBlock.GasLimit <= long.MaxValue) - gasLimit = (long)desiredBlock.GasLimit; - else - throw new OverflowException("GasLimit value is too large to be converted to long we use."); + long gasLimit = 0; + if (desiredBlock.GasLimit <= long.MaxValue) + gasLimit = (long)desiredBlock.GasLimit; + else + throw new OverflowException("GasLimit value is too large to be converted to long we use."); - long blockNumber = 0; - if (desiredBlock.Number <= long.MaxValue) - blockNumber = (long)desiredBlock.Number; - else - throw new OverflowException("Block Number value is too large to be converted to long we use."); - - blockHeader = new BlockHeader( - parent.Hash, - Keccak.OfAnEmptySequenceRlp, - desiredBlock.FeeRecipient, - UInt256.Zero, - blockNumber, - gasLimit, - time, - Array.Empty()); - blockHeader.MixHash = desiredBlock.PrevRandao; - blockHeader.BaseFeePerGas = desiredBlock.BaseFee; + long blockNumber = 0; + if (desiredBlock.Number <= long.MaxValue) + blockNumber = (long)desiredBlock.Number; + else + throw new OverflowException("Block Number value is too large to be converted to long we use."); + + blockHeader = new BlockHeader( + parent.Hash, + Keccak.OfAnEmptySequenceRlp, + desiredBlock.FeeRecipient, + UInt256.Zero, + blockNumber, + gasLimit, + time, + Array.Empty()); + blockHeader.MixHash = desiredBlock.PrevRandao; + blockHeader.BaseFeePerGas = desiredBlock.BaseFee; + } if (_maxGas <= long.MaxValue) blockHeader.GasLimit = @@ -378,8 +398,8 @@ public Block FinalizeBlock(Block currentBlock) currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); - var block = ChainProcessor.Process( - currentBlock, + var blocks = BlockProcessor.Process(StateProvider.StateRoot, + new List() { currentBlock }, ProcessingOptions.ForceProcessing | ProcessingOptions.NoValidation | ProcessingOptions.DoNotVerifyNonce | @@ -388,9 +408,8 @@ public Block FinalizeBlock(Block currentBlock) ProcessingOptions.StoreReceipts , BlockTracer); - - var blocks = new List() { block }; - var res = BlockTree.SuggestBlock(blocks.First(), + var block = blocks.First(); + var res = BlockTree.SuggestBlock(block, BlockTreeSuggestOptions.ForceSetAsMain | BlockTreeSuggestOptions.ForceDontValidateParent); BlockTree.UpdateMainChain(blocks, true, true); From 1040919a2c01d533b7443bc9aac3ccbcc9d93dd4 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 7 Jun 2023 11:45:08 +0100 Subject: [PATCH 019/213] fixing related project tests --- .../Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs | 3 ++- .../Nethermind.State.Test.Runner/StateTestTxTracer.cs | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index 922541c2d0c..cab597956a1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -146,7 +146,8 @@ TransactionProcessor transactionProcessor specProvider, gasPriceOracle, ethSyncingInfo, - feeHistoryOracle); + feeHistoryOracle, + dbProvider); } [Benchmark] diff --git a/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs b/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs index 92cdb19e917..5523dcaf9be 100644 --- a/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs +++ b/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs @@ -34,7 +34,8 @@ public class StateTestTxTracer : ITxTracer public bool IsTracingBlockHash { get; } = false; public bool IsTracingAccess { get; } = false; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; + public bool IsTracingEventLogs => false; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak stateRoot = null) @@ -247,5 +248,10 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) { throw new NotImplementedException(); } + + public void ReportEvent(LogEntry logEntry) + { + throw new NotImplementedException(); + } } } From 606e25b0583bce2753adf54006852f4d8cb0e3b9 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 8 Jun 2023 10:19:41 +0100 Subject: [PATCH 020/213] fixing JSON RPC bug --- .../JsonRpcServiceTests.cs | 387 ++++++------ .../Nethermind.JsonRpc/IJsonRpcConfig.cs | 2 +- .../Nethermind.JsonRpc/JsonRpcService.cs | 185 +++--- .../Eth/EthModule.TransactionExecutor.cs | 20 +- .../Modules/Eth/EthRpcModuleProxy.cs | 591 +++++++++--------- .../Eth/Multicall/MultiCallBlockTracer.cs | 2 +- .../Eth/Multicall/MultiCallBlockchainFork.cs | 23 +- .../Eth/Multicall/MultiCallTxTracer.cs | 2 +- 8 files changed, 623 insertions(+), 589 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 96f44044049..9105e2268aa 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -14,6 +14,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; +using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules; @@ -26,198 +27,236 @@ using NSubstitute; using NUnit.Framework; -namespace Nethermind.JsonRpc.Test +namespace Nethermind.JsonRpc.Test; + +[Parallelizable(ParallelScope.Self)] +[TestFixture] +public class JsonRpcServiceTests { - [Parallelizable(ParallelScope.Self)] - [TestFixture] - public class JsonRpcServiceTests + [SetUp] + public void Initialize() { - [SetUp] - public void Initialize() - { - Assembly jConfig = typeof(JsonRpcConfig).Assembly; - _configurationProvider = new ConfigProvider(); - _logManager = LimboLogs.Instance; - _context = new JsonRpcContext(RpcEndpoint.Http); - } - - private IJsonRpcService _jsonRpcService = null!; - private IConfigProvider _configurationProvider = null!; - private ILogManager _logManager = null!; - private JsonRpcContext _context = null!; - - private JsonRpcResponse TestRequest(T module, string method, params string[] parameters) where T : IRpcModule - { - RpcModuleProvider moduleProvider = new(new FileSystem(), _configurationProvider.GetConfig(), LimboLogs.Instance); - moduleProvider.Register(new SingletonModulePool(new SingletonFactory(module), true)); - _jsonRpcService = new JsonRpcService(moduleProvider, _logManager, _configurationProvider.GetConfig()); - JsonRpcRequest request = RpcTest.GetJsonRequest(method, parameters); - JsonRpcResponse response = _jsonRpcService.SendRequestAsync(request, _context).Result; - Assert.That(response.Id, Is.EqualTo(request.Id)); - return response; - } - - [Test] - public void GetBlockByNumberTest() - { - IEthRpcModule ethRpcModule = Substitute.For(); - ISpecProvider specProvider = Substitute.For(); - ethRpcModule.eth_getBlockByNumber(Arg.Any(), true).ReturnsForAnyArgs(x => ResultWrapper.Success(new BlockForRpc(Build.A.Block.WithNumber(2).TestObject, true, specProvider))); - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_getBlockByNumber", "0x1b4", "true") as JsonRpcSuccessResponse; - Assert.That((response?.Result as BlockForRpc)?.Number, Is.EqualTo(2L)); - } - - [Test] - public void Eth_module_populates_size_when_returning_block_data() - { - IEthRpcModule ethRpcModule = Substitute.For(); - ISpecProvider specProvider = Substitute.For(); - ethRpcModule.eth_getBlockByNumber(Arg.Any(), true).ReturnsForAnyArgs(x => ResultWrapper.Success(new BlockForRpc(Build.A.Block.WithNumber(2).TestObject, true, specProvider))); - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_getBlockByNumber", "0x1b4", "true") as JsonRpcSuccessResponse; - Assert.That((response?.Result as BlockForRpc)?.Size, Is.EqualTo(513L)); - } - - [Test] - public void CanHandleOptionalArguments() - { - EthereumJsonSerializer serializer = new(); - string serialized = serializer.Serialize(new TransactionForRpc()); - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_call(Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success("0x1")); - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized) as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo("0x1")); - } - - [Test] - public void Case_sensitivity_test() - { - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_chainId().ReturnsForAnyArgs(ResultWrapper.Success(1ul)); - TestRequest(ethRpcModule, "eth_chainID").Should().BeOfType(); - TestRequest(ethRpcModule, "eth_chainId").Should().BeOfType(); - } - - [Test] - public void GetNewFilterTest() - { - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_newFilter(Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success(1)); + Assembly jConfig = typeof(JsonRpcConfig).Assembly; + _configurationProvider = new ConfigProvider(); + _logManager = LimboLogs.Instance; + _context = new JsonRpcContext(RpcEndpoint.Http); + } + + private IJsonRpcService _jsonRpcService = null!; + private IConfigProvider _configurationProvider = null!; + private ILogManager _logManager = null!; + private JsonRpcContext _context = null!; + + private JsonRpcResponse TestRequest(T module, string method, params string[] parameters) where T : IRpcModule + { + RpcModuleProvider moduleProvider = new(new FileSystem(), _configurationProvider.GetConfig(), + LimboLogs.Instance); + moduleProvider.Register(new SingletonModulePool(new SingletonFactory(module))); + _jsonRpcService = + new JsonRpcService(moduleProvider, _logManager, _configurationProvider.GetConfig()); + JsonRpcRequest request = RpcTest.GetJsonRequest(method, parameters); + JsonRpcResponse response = _jsonRpcService.SendRequestAsync(request, _context).Result; + Assert.That(response.Id, Is.EqualTo(request.Id)); + return response; + } + + [Test] + public void GetBlockByNumberTest() + { + IEthRpcModule ethRpcModule = Substitute.For(); + ISpecProvider specProvider = Substitute.For(); + ethRpcModule.eth_getBlockByNumber(Arg.Any(), true).ReturnsForAnyArgs(x => + ResultWrapper.Success(new BlockForRpc(Build.A.Block.WithNumber(2).TestObject, true, + specProvider))); + JsonRpcSuccessResponse? response = + TestRequest(ethRpcModule, "eth_getBlockByNumber", "0x1b4", "true") as JsonRpcSuccessResponse; + Assert.That((response?.Result as BlockForRpc)?.Number, Is.EqualTo(2L)); + } + + [Test] + public void Eth_module_populates_size_when_returning_block_data() + { + IEthRpcModule ethRpcModule = Substitute.For(); + ISpecProvider specProvider = Substitute.For(); + ethRpcModule.eth_getBlockByNumber(Arg.Any(), true).ReturnsForAnyArgs(x => + ResultWrapper.Success(new BlockForRpc(Build.A.Block.WithNumber(2).TestObject, true, + specProvider))); + JsonRpcSuccessResponse? response = + TestRequest(ethRpcModule, "eth_getBlockByNumber", "0x1b4", "true") as JsonRpcSuccessResponse; + Assert.That((response?.Result as BlockForRpc)?.Size, Is.EqualTo(513L)); + } + + + [Test] + public void CanRunEthMulticallEmpty() + { + ulong version = 0; + MultiCallBlockStateCallsModel[] blockCalls = Array.Empty(); + + EthereumJsonSerializer serializer = new(); + + string serializedVersion = serializer.Serialize(version); + string serializedCall = serializer.Serialize(blockCalls); + + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_multicall(version, blockCalls).ReturnsForAnyArgs(x => + ResultWrapper.Success(Array.Empty())); + JsonRpcSuccessResponse? response = + TestRequest(ethRpcModule, "eth_multicall", serializedVersion, serializedCall) as JsonRpcSuccessResponse; + Assert.IsTrue(response != null); + Assert.That(response?.Result, Is.EqualTo(Array.Empty())); + } + + + [Test] + public void CanHandleOptionalArguments() + { + EthereumJsonSerializer serializer = new(); + string serialized = serializer.Serialize(new TransactionForRpc()); + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_call(Arg.Any()) + .ReturnsForAnyArgs(x => ResultWrapper.Success("0x1")); + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized) as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo("0x1")); + } + + [Test] + public void Case_sensitivity_test() + { + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_chainId().ReturnsForAnyArgs(ResultWrapper.Success(1ul)); + TestRequest(ethRpcModule, "eth_chainID").Should().BeOfType(); + TestRequest(ethRpcModule, "eth_chainId").Should().BeOfType(); + } + + [Test] + public void GetNewFilterTest() + { + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_newFilter(Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success(1)); - var parameters = new + var parameters = new + { + fromBlock = "0x1", + toBlock = "latest", + address = "0x1f88f1f195afa192cfee860698584c030f4c9db2", + topics = new List { - fromBlock = "0x1", - toBlock = "latest", - address = "0x1f88f1f195afa192cfee860698584c030f4c9db2", - topics = new List + "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + null!, + new[] { - "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", null!, - new[] - { - "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0x0000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc" - } + "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x0000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc" } - }; + } + }; - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_newFilter", JsonConvert.SerializeObject(parameters)) as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo(UInt256.One)); - } + JsonRpcSuccessResponse? response = + TestRequest(ethRpcModule, "eth_newFilter", JsonConvert.SerializeObject(parameters)) as + JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo(UInt256.One)); + } - [Test] - public void Eth_call_is_working_with_implicit_null_as_the_last_argument() - { - EthereumJsonSerializer serializer = new(); - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_call(Arg.Any(), Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success("0x")); + [Test] + public void Eth_call_is_working_with_implicit_null_as_the_last_argument() + { + EthereumJsonSerializer serializer = new(); + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_call(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(x => ResultWrapper.Success("0x")); - string serialized = serializer.Serialize(new TransactionForRpc()); + string serialized = serializer.Serialize(new TransactionForRpc()); - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized) as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo("0x")); - } + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized) as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo("0x")); + } - [TestCase("")] - [TestCase(null)] - public void Eth_call_is_working_with_explicit_null_as_the_last_argument(string nullValue) - { - EthereumJsonSerializer serializer = new(); - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_call(Arg.Any(), Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success("0x")); + [TestCase("")] + [TestCase(null)] + public void Eth_call_is_working_with_explicit_null_as_the_last_argument(string nullValue) + { + EthereumJsonSerializer serializer = new(); + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_call(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(x => ResultWrapper.Success("0x")); - string serialized = serializer.Serialize(new TransactionForRpc()); + string serialized = serializer.Serialize(new TransactionForRpc()); - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized, nullValue) as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo("0x")); - } + JsonRpcSuccessResponse? response = + TestRequest(ethRpcModule, "eth_call", serialized, nullValue) as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo("0x")); + } - [Test] - public void GetWorkTest() - { - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_getWork().ReturnsForAnyArgs(x => ResultWrapper>.Success(new[] { Bytes.FromHexString("aa"), Bytes.FromHexString("01") })); - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_getWork") as JsonRpcSuccessResponse; - byte[][]? dataList = response?.Result as byte[][]; - Assert.NotNull(dataList?.SingleOrDefault(d => d.ToHexString(true) == "0xaa")); - Assert.NotNull(dataList?.SingleOrDefault(d => d.ToHexString(true) == "0x01")); - } - - [Test] - public void IncorrectMethodNameTest() - { - JsonRpcErrorResponse? response = TestRequest(Substitute.For(), "incorrect_method") as JsonRpcErrorResponse; - Assert.That(response?.Error?.Code, Is.EqualTo(ErrorCodes.MethodNotFound)); - } + [Test] + public void GetWorkTest() + { + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_getWork().ReturnsForAnyArgs(x => + ResultWrapper>.Success(new[] { Bytes.FromHexString("aa"), Bytes.FromHexString("01") })); + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_getWork") as JsonRpcSuccessResponse; + byte[][]? dataList = response?.Result as byte[][]; + Assert.NotNull(dataList?.SingleOrDefault(d => d.ToHexString(true) == "0xaa")); + Assert.NotNull(dataList?.SingleOrDefault(d => d.ToHexString(true) == "0x01")); + } - [Test] - public void NetVersionTest() - { - INetRpcModule netRpcModule = Substitute.For(); - netRpcModule.net_version().ReturnsForAnyArgs(x => ResultWrapper.Success("1")); - JsonRpcSuccessResponse? response = TestRequest(netRpcModule, "net_version") as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo("1")); - Assert.IsNotInstanceOf(response); - } - - [Test] - public void Web3ShaTest() - { - IWeb3RpcModule web3RpcModule = Substitute.For(); - web3RpcModule.web3_sha3(Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success(TestItem.KeccakA)); - JsonRpcSuccessResponse? response = TestRequest(web3RpcModule, "web3_sha3", "0x68656c6c6f20776f726c64") as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo(TestItem.KeccakA)); - } - - [TestCaseSource(nameof(BlockForRpcTestSource))] - public void BlockForRpc_should_expose_withdrawals_if_any((bool Expected, Block Block) item) - { - var specProvider = Substitute.For(); - var rpcBlock = new BlockForRpc(item.Block, false, specProvider); + [Test] + public void IncorrectMethodNameTest() + { + JsonRpcErrorResponse? response = + TestRequest(Substitute.For(), "incorrect_method") as JsonRpcErrorResponse; + Assert.That(response?.Error?.Code, Is.EqualTo(ErrorCodes.MethodNotFound)); + } + + [Test] + public void NetVersionTest() + { + INetRpcModule netRpcModule = Substitute.For(); + netRpcModule.net_version().ReturnsForAnyArgs(x => ResultWrapper.Success("1")); + JsonRpcSuccessResponse? response = TestRequest(netRpcModule, "net_version") as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo("1")); + Assert.IsNotInstanceOf(response); + } + + [Test] + public void Web3ShaTest() + { + IWeb3RpcModule web3RpcModule = Substitute.For(); + web3RpcModule.web3_sha3(Arg.Any()) + .ReturnsForAnyArgs(x => ResultWrapper.Success(TestItem.KeccakA)); + JsonRpcSuccessResponse? response = + TestRequest(web3RpcModule, "web3_sha3", "0x68656c6c6f20776f726c64") as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo(TestItem.KeccakA)); + } - rpcBlock.WithdrawalsRoot.Should().BeEquivalentTo(item.Block.WithdrawalsRoot); - rpcBlock.Withdrawals.Should().BeEquivalentTo(item.Block.Withdrawals); + [TestCaseSource(nameof(BlockForRpcTestSource))] + public void BlockForRpc_should_expose_withdrawals_if_any((bool Expected, Core.Block Block) item) + { + ISpecProvider? specProvider = Substitute.For(); + BlockForRpc rpcBlock = new BlockForRpc(item.Block, false, specProvider); - var json = new EthereumJsonSerializer().Serialize(rpcBlock); + rpcBlock.WithdrawalsRoot.Should().BeEquivalentTo(item.Block.WithdrawalsRoot); + rpcBlock.Withdrawals.Should().BeEquivalentTo(item.Block.Withdrawals); - json.Contains("withdrawals\"", StringComparison.Ordinal).Should().Be(item.Expected); - json.Contains("withdrawalsRoot", StringComparison.Ordinal).Should().Be(item.Expected); - } + string? json = new EthereumJsonSerializer().Serialize(rpcBlock); - // With (Block, bool), tests don't run for some reason. Flipped to (bool, Block). - private static IEnumerable<(bool, Block)> BlockForRpcTestSource() => - new[] - { - (true, Build.A.Block - .WithWithdrawals(new[] - { - Build.A.Withdrawal - .WithAmount(1) - .WithRecipient(TestItem.AddressA) - .TestObject - }) - .TestObject - ), - - (false, Build.A.Block.WithWithdrawals(null).TestObject) - }; + json.Contains("withdrawals\"", StringComparison.Ordinal).Should().Be(item.Expected); + json.Contains("withdrawalsRoot", StringComparison.Ordinal).Should().Be(item.Expected); + } + + // With (Block, bool), tests don't run for some reason. Flipped to (bool, Block). + private static IEnumerable<(bool, Block)> BlockForRpcTestSource() + { + return new[] + { + (true, Build.A.Block + .WithWithdrawals(Build.A.Withdrawal + .WithAmount(1) + .WithRecipient(TestItem.AddressA) + .TestObject) + .TestObject + ), + (false, Build.A.Block.WithWithdrawals(null).TestObject) + }; } } diff --git a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs index 0dcf356f8cb..e7758a78fc4 100644 --- a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs @@ -103,7 +103,7 @@ public interface IJsonRpcConfig : IConfig nameof(IEthRpcModule.eth_newBlockFilter) + ", " + nameof(IEthRpcModule.eth_newPendingTransactionFilter) + ", " + nameof(IEthRpcModule.eth_uninstallFilter) + ", " + - nameof(IEthRpcModule.eth_call) + "). " + + nameof(IEthRpcModule.eth_multicall) + "). " + "This will limit load on the node CPU and IO to reasonable levels. " + "If this limit is exceeded on Http calls 503 Service Unavailable will be returned along with Json RPC error. " + "Defaults to number of logical processes.")] diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs index ccb4db48ed1..62c99fc90df 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs @@ -16,7 +16,6 @@ using Nethermind.Serialization.Json; using Nethermind.State; using Newtonsoft.Json; -using JsonSerializer = Newtonsoft.Json.JsonSerializer; namespace Nethermind.JsonRpc; @@ -24,10 +23,10 @@ namespace Nethermind.JsonRpc; public class JsonRpcService : IJsonRpcService { private readonly ILogger _logger; + private readonly int _maxLoggedRequestParametersCharacters; + private readonly HashSet _methodsLoggingFiltering; private readonly IRpcModuleProvider _rpcModuleProvider; private readonly JsonSerializer _serializer; - private readonly HashSet _methodsLoggingFiltering; - private readonly int _maxLoggedRequestParametersCharacters; public JsonRpcService(IRpcModuleProvider rpcModuleProvider, ILogManager logManager, IJsonRpcConfig jsonRpcConfig) { @@ -40,7 +39,8 @@ public JsonRpcService(IRpcModuleProvider rpcModuleProvider, ILogManager logManag List converterList = new(); foreach (JsonConverter converter in rpcModuleProvider.Converters) { - if (_logger.IsDebug) _logger.Debug($"Registering {converter.GetType().Name} inside {nameof(JsonRpcService)}"); + if (_logger.IsDebug) + _logger.Debug($"Registering {converter.GetType().Name} inside {nameof(JsonRpcService)}"); _serializer.Converters.Add(converter); converterList.Add(converter); } @@ -65,9 +65,7 @@ public async Task SendRequestAsync(JsonRpcRequest rpcRequest, J { (int? errorCode, string errorMessage) = Validate(rpcRequest, context); if (errorCode.HasValue) - { return GetErrorResponse(rpcRequest.Method, errorCode.Value, errorMessage, null, rpcRequest.Id); - } try { @@ -75,18 +73,22 @@ public async Task SendRequestAsync(JsonRpcRequest rpcRequest, J } catch (TargetInvocationException ex) { - if (_logger.IsError) _logger.Error($"Error during method execution, request: {rpcRequest}", ex.InnerException); - return GetErrorResponse(rpcRequest.Method, ErrorCodes.InternalError, "Internal error", ex.InnerException?.ToString(), rpcRequest.Id); + if (_logger.IsError) + _logger.Error($"Error during method execution, request: {rpcRequest}", ex.InnerException); + return GetErrorResponse(rpcRequest.Method, ErrorCodes.InternalError, "Internal error", + ex.InnerException?.ToString(), rpcRequest.Id); } catch (ModuleRentalTimeoutException ex) { if (_logger.IsError) _logger.Error($"Error during method execution, request: {rpcRequest}", ex); - return GetErrorResponse(rpcRequest.Method, ErrorCodes.ModuleTimeout, "Timeout", ex.ToString(), rpcRequest.Id); + return GetErrorResponse(rpcRequest.Method, ErrorCodes.ModuleTimeout, "Timeout", ex.ToString(), + rpcRequest.Id); } catch (Exception ex) { if (_logger.IsError) _logger.Error($"Error during method execution, request: {rpcRequest}", ex); - return GetErrorResponse(rpcRequest.Method, ErrorCodes.InternalError, "Internal error", ex.ToString(), rpcRequest.Id); + return GetErrorResponse(rpcRequest.Method, ErrorCodes.InternalError, "Internal error", ex.ToString(), + rpcRequest.Id); } } catch (Exception ex) @@ -96,6 +98,18 @@ public async Task SendRequestAsync(JsonRpcRequest rpcRequest, J } } + public JsonRpcErrorResponse GetErrorResponse(int errorCode, string errorMessage) + { + return GetErrorResponse(null, errorCode, errorMessage, null, null); + } + + public JsonRpcErrorResponse GetErrorResponse(string methodName, int errorCode, string errorMessage, object id) + { + return GetErrorResponse(methodName, errorCode, errorMessage, null, id); + } + + public JsonConverter[] Converters { get; } + private async Task ExecuteRequestAsync(JsonRpcRequest rpcRequest, JsonRpcContext context) { string methodName = rpcRequest.Method.Trim(); @@ -103,7 +117,8 @@ private async Task ExecuteRequestAsync(JsonRpcRequest rpcReques (MethodInfo MethodInfo, bool ReadOnly) result = _rpcModuleProvider.Resolve(methodName); return result.MethodInfo is not null ? await ExecuteAsync(rpcRequest, methodName, result, context) - : GetErrorResponse(methodName, ErrorCodes.MethodNotFound, "Method not found", $"{rpcRequest.Method}", rpcRequest.Id); + : GetErrorResponse(methodName, ErrorCodes.MethodNotFound, "Method not found", $"{rpcRequest.Method}", + rpcRequest.Id); } private async Task ExecuteAsync(JsonRpcRequest request, string methodName, @@ -114,7 +129,8 @@ private async Task ExecuteAsync(JsonRpcRequest request, string LogRequest(methodName, providedParameters, expectedParameters); - int missingParamsCount = expectedParameters.Length - providedParameters.Length + (providedParameters.Count(string.IsNullOrWhiteSpace)); + int missingParamsCount = expectedParameters.Length - providedParameters.Length + + providedParameters.Count(string.IsNullOrWhiteSpace); int explicitNullableParamsCount = 0; if (missingParamsCount != 0) @@ -132,10 +148,7 @@ private async Task ExecuteAsync(JsonRpcRequest request, string // or we can treat null as a missing parameter. Two tests for this cases: // Eth_call_is_working_with_implicit_null_as_the_last_argument and Eth_call_is_working_with_explicit_null_as_the_last_argument bool isExplicit = providedParameters.Length >= parameterIndex + 1; - if (nullable && isExplicit) - { - explicitNullableParamsCount += 1; - } + if (nullable && isExplicit) explicitNullableParamsCount += 1; if (!expectedParameters[expectedParameters.Length - missingParamsCount + i].IsOptional && !nullable) { hasIncorrectParameters = true; @@ -145,9 +158,9 @@ private async Task ExecuteAsync(JsonRpcRequest request, string } if (hasIncorrectParameters) - { - return GetErrorResponse(methodName, ErrorCodes.InvalidParams, "Invalid params", $"Incorrect parameters count, expected: {expectedParameters.Length}, actual: {expectedParameters.Length - missingParamsCount}", request.Id); - } + return GetErrorResponse(methodName, ErrorCodes.InvalidParams, "Invalid params", + $"Incorrect parameters count, expected: {expectedParameters.Length}, actual: {expectedParameters.Length - missingParamsCount}", + request.Id); } missingParamsCount -= explicitNullableParamsCount; @@ -159,7 +172,9 @@ private async Task ExecuteAsync(JsonRpcRequest request, string parameters = DeserializeParameters(expectedParameters, providedParameters, missingParamsCount); if (parameters is null) { - if (_logger.IsWarn) _logger.Warn($"Incorrect JSON RPC parameters when calling {methodName} with params [{string.Join(", ", providedParameters)}]"); + if (_logger.IsWarn) + _logger.Warn( + $"Incorrect JSON RPC parameters when calling {methodName} with params [{string.Join(", ", providedParameters)}]"); return GetErrorResponse(methodName, ErrorCodes.InvalidParams, "Invalid params", null, request.Id); } } @@ -167,12 +182,9 @@ private async Task ExecuteAsync(JsonRpcRequest request, string //execute method IResultWrapper resultWrapper = null; IRpcModule rpcModule = await _rpcModuleProvider.Rent(methodName, method.ReadOnly); - if (rpcModule is IContextAwareRpcModule contextAwareModule) - { - contextAwareModule.Context = context; - } + if (rpcModule is IContextAwareRpcModule contextAwareModule) contextAwareModule.Context = context; bool returnImmediately = methodName != "eth_getLogs"; - Action? returnAction = returnImmediately ? (Action)null : () => _rpcModuleProvider.Return(methodName, rpcModule); + Action? returnAction = returnImmediately ? null : () => _rpcModuleProvider.Return(methodName, rpcModule); try { object invocationResult = method.Info.Invoke(rpcModule, parameters); @@ -189,11 +201,13 @@ private async Task ExecuteAsync(JsonRpcRequest request, string } catch (TargetParameterCountException e) { - return GetErrorResponse(methodName, ErrorCodes.InvalidParams, e.Message, e.ToString(), request.Id, returnAction); + return GetErrorResponse(methodName, ErrorCodes.InvalidParams, e.Message, e.ToString(), request.Id, + returnAction); } catch (TargetInvocationException e) when (e.InnerException is JsonException) { - return GetErrorResponse(methodName, ErrorCodes.InvalidParams, "Invalid params", e.InnerException?.ToString(), request.Id, returnAction); + return GetErrorResponse(methodName, ErrorCodes.InvalidParams, "Invalid params", + e.InnerException?.ToString(), request.Id, returnAction); } catch (Exception e) when (e.InnerException is OperationCanceledException) { @@ -202,14 +216,12 @@ private async Task ExecuteAsync(JsonRpcRequest request, string } catch (Exception e) when (e.InnerException is InsufficientBalanceException) { - return GetErrorResponse(methodName, ErrorCodes.InvalidInput, e.InnerException.Message, e.ToString(), request.Id, returnAction); + return GetErrorResponse(methodName, ErrorCodes.InvalidInput, e.InnerException.Message, e.ToString(), + request.Id, returnAction); } finally { - if (returnImmediately) - { - _rpcModuleProvider.Return(methodName, rpcModule); - } + if (returnImmediately) _rpcModuleProvider.Return(methodName, rpcModule); } if (resultWrapper is null) @@ -223,13 +235,13 @@ private async Task ExecuteAsync(JsonRpcRequest request, string if (result is null) { if (_logger.IsError) _logger.Error($"Error during method: {methodName} execution: no result"); - return GetErrorResponse(methodName, resultWrapper.GetErrorCode(), "Internal error", resultWrapper.GetData(), request.Id, returnAction); + return GetErrorResponse(methodName, resultWrapper.GetErrorCode(), "Internal error", resultWrapper.GetData(), + request.Id, returnAction); } if (result.ResultType == ResultType.Failure) - { - return GetErrorResponse(methodName, resultWrapper.GetErrorCode(), result.Error, resultWrapper.GetData(), request.Id, returnAction); - } + return GetErrorResponse(methodName, resultWrapper.GetErrorCode(), result.Error, resultWrapper.GetData(), + request.Id, returnAction); return GetSuccessResponse(methodName, resultWrapper.GetData(), request.Id, returnAction); } @@ -238,7 +250,7 @@ private void LogRequest(string methodName, string?[] providedParameters, Paramet { if (_logger.IsInfo && !_methodsLoggingFiltering.Contains(methodName)) { - StringBuilder builder = new StringBuilder(); + StringBuilder builder = new(); builder.Append("Executing JSON RPC call "); builder.Append(methodName); builder.Append(" with params ["); @@ -268,40 +280,35 @@ private void LogRequest(string methodName, string?[] providedParameters, Paramet } builder.Append(parameter); - paramsLength += (parameter?.Length ?? 0); + paramsLength += parameter?.Length ?? 0; paramsCount++; } + builder.Append(']'); string log = builder.ToString(); _logger.Info(log); } } - private object[]? DeserializeParameters(ParameterInfo[] expectedParameters, string?[] providedParameters, int missingParamsCount) + private object[]? DeserializeParameters(ParameterInfo[] expectedParameters, string?[] providedParameters, + int missingParamsCount) { try { - List executionParameters = new List(); + List executionParameters = new(); for (int i = 0; i < providedParameters.Length; i++) { string providedParameter = providedParameters[i]; ParameterInfo expectedParameter = expectedParameters[i]; Type paramType = expectedParameter.ParameterType; - if (paramType.IsByRef) - { - paramType = paramType.GetElementType(); - } + if (paramType.IsByRef) paramType = paramType.GetElementType(); if (string.IsNullOrWhiteSpace(providedParameter)) { if (providedParameter is null && IsNullableParameter(expectedParameter)) - { executionParameters.Add(null); - } else - { executionParameters.Add(Type.Missing); - } continue; } @@ -313,32 +320,36 @@ private void LogRequest(string methodName, string?[] providedParameters, Paramet executionParam = jsonRpcParam; } else if (paramType == typeof(string)) - { executionParam = providedParameter; - } else if (paramType == typeof(string[])) - { - executionParam = _serializer.Deserialize(new JsonTextReader(new StringReader(providedParameter))); - } + executionParam = + _serializer.Deserialize(new JsonTextReader(new StringReader(providedParameter))); else { if (providedParameter.StartsWith('[') || providedParameter.StartsWith('{')) - { - executionParam = _serializer.Deserialize(new JsonTextReader(new StringReader(providedParameter)), paramType); - } + executionParam = + _serializer.Deserialize(new JsonTextReader(new StringReader(providedParameter)), paramType); else { - executionParam = _serializer.Deserialize(new JsonTextReader(new StringReader($"\"{providedParameter}\"")), paramType); + if (providedParameter.StartsWith("\"") && providedParameter.EndsWith("\"")) + { + executionParam = + _serializer.Deserialize( + new JsonTextReader(new StringReader(providedParameter)), paramType); + } + else + { + executionParam = + _serializer.Deserialize( + new JsonTextReader(new StringReader($"\"{providedParameter}\"")), paramType); + } } } executionParameters.Add(executionParam); } - for (int i = 0; i < missingParamsCount; i++) - { - executionParameters.Add(Type.Missing); - } + for (int i = 0; i < missingParamsCount; i++) executionParameters.Add(Type.Missing); return executionParameters.ToArray(); } @@ -352,21 +363,16 @@ private void LogRequest(string methodName, string?[] providedParameters, Paramet private bool IsNullableParameter(ParameterInfo parameterInfo) { Type parameterType = parameterInfo.ParameterType; - if (parameterType.IsValueType) - { - return Nullable.GetUnderlyingType(parameterType) is not null; - } + if (parameterType.IsValueType) return Nullable.GetUnderlyingType(parameterType) is not null; CustomAttributeData nullableAttribute = parameterInfo.CustomAttributes .FirstOrDefault(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableAttribute"); if (nullableAttribute is not null) { CustomAttributeTypedArgument attributeArgument = nullableAttribute.ConstructorArguments.FirstOrDefault(); - if (attributeArgument.ArgumentType == typeof(byte)) - { - return (byte)attributeArgument.Value! == 2; - } + if (attributeArgument.ArgumentType == typeof(byte)) return (byte)attributeArgument.Value! == 2; } + return false; } @@ -382,25 +388,15 @@ private JsonRpcResponse GetSuccessResponse(string methodName, object result, obj return response; } - public JsonRpcErrorResponse GetErrorResponse(int errorCode, string errorMessage) => - GetErrorResponse(null, errorCode, errorMessage, null, null); - - public JsonRpcErrorResponse GetErrorResponse(string methodName, int errorCode, string errorMessage, object id) => - GetErrorResponse(methodName, errorCode, errorMessage, null, id); - - public JsonConverter[] Converters { get; } - - private JsonRpcErrorResponse GetErrorResponse(string? methodName, int errorCode, string? errorMessage, object? errorData, object? id, Action? disposableAction = null) + private JsonRpcErrorResponse GetErrorResponse(string? methodName, int errorCode, string? errorMessage, + object? errorData, object? id, Action? disposableAction = null) { - if (_logger.IsDebug) _logger.Debug($"Sending error response, method: {methodName ?? "none"}, id: {id}, errorType: {errorCode}, message: {errorMessage}, errorData: {errorData}"); + if (_logger.IsDebug) + _logger.Debug( + $"Sending error response, method: {methodName ?? "none"}, id: {id}, errorType: {errorCode}, message: {errorMessage}, errorData: {errorData}"); JsonRpcErrorResponse response = new(disposableAction) { - Error = new Error - { - Code = errorCode, - Message = errorMessage, - Data = errorData, - }, + Error = new Error { Code = errorCode, Message = errorMessage, Data = errorData }, Id = id, MethodName = methodName }; @@ -410,16 +406,10 @@ private JsonRpcErrorResponse GetErrorResponse(string? methodName, int errorCode, private (int? ErrorType, string ErrorMessage) Validate(JsonRpcRequest? rpcRequest, JsonRpcContext context) { - if (rpcRequest is null) - { - return (ErrorCodes.InvalidRequest, "Invalid request"); - } + if (rpcRequest is null) return (ErrorCodes.InvalidRequest, "Invalid request"); string methodName = rpcRequest.Method; - if (string.IsNullOrWhiteSpace(methodName)) - { - return (ErrorCodes.InvalidRequest, "Method is required"); - } + if (string.IsNullOrWhiteSpace(methodName)) return (ErrorCodes.InvalidRequest, "Method is required"); methodName = methodName.Trim(); @@ -427,9 +417,12 @@ private JsonRpcErrorResponse GetErrorResponse(string? methodName, int errorCode, return result switch { ModuleResolution.Unknown => ((int?)ErrorCodes.MethodNotFound, $"Method {methodName} is not supported"), - ModuleResolution.Disabled => (ErrorCodes.InvalidRequest, $"{methodName} found but the containing module is disabled for the url '{context.Url?.ToString() ?? string.Empty}', consider adding module in JsonRpcConfig.AdditionalRpcUrls for additional url, or to JsonRpcConfig.EnabledModules for default url"), - ModuleResolution.EndpointDisabled => (ErrorCodes.InvalidRequest, $"{methodName} found for the url '{context.Url?.ToString() ?? string.Empty}' but is disabled for {context.RpcEndpoint}"), - ModuleResolution.NotAuthenticated => (ErrorCodes.InvalidRequest, $"Method {methodName} should be authenticated"), + ModuleResolution.Disabled => (ErrorCodes.InvalidRequest, + $"{methodName} found but the containing module is disabled for the url '{context.Url?.ToString() ?? string.Empty}', consider adding module in JsonRpcConfig.AdditionalRpcUrls for additional url, or to JsonRpcConfig.EnabledModules for default url"), + ModuleResolution.EndpointDisabled => (ErrorCodes.InvalidRequest, + $"{methodName} found for the url '{context.Url?.ToString() ?? string.Empty}' but is disabled for {context.RpcEndpoint}"), + ModuleResolution.NotAuthenticated => (ErrorCodes.InvalidRequest, + $"Method {methodName} should be authenticated"), _ => (null, null) }; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index ae61b40b3fe..13211562b0b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -118,13 +118,22 @@ public ResultWrapper Execute(ulong version, MultiCallBlockStateCallsModel[] blockCallsToProcess, BlockParameter? blockParameter, bool traceTransfers) { - IEnumerable? selsectResults = blockCallsToProcess.Select(model => model.BlockOverride.Number); //Was not able to overcome all of the protections related to setting of new block as BlockTree head so will keep it fair for now List results = new(); using (MultiCallBlockchainFork tmpChain = new(_dbProvider, _specProvider, MaxGas)) { - List blockCalls = blockCallsToProcess.OrderBy(model => model.BlockOverride.Number).ToList(); + IEnumerable? selsectResults = blockCallsToProcess.Select(model => + model.BlockOverride != null + ? model.BlockOverride.Number + : (ulong)tmpChain.LatestBlock.Header.Number + 1); + + List blockCalls = blockCallsToProcess + .OrderBy(model => + model.BlockOverride != null + ? model.BlockOverride.Number + : (ulong)tmpChain.LatestBlock.Header.Number + 1) + .ToList(); tmpChain.BlockTracer.Trace = traceTransfers; ulong logIndices = 0; @@ -138,12 +147,12 @@ public ResultWrapper Execute(ulong version, catch (Exception ex) { return ResultWrapper.Fail( - $"At block {blockCall.BlockOverride.Number} got exception: {ex.Message}"); + $"At block {(blockCall.BlockOverride != null ? blockCall.BlockOverride.Number : (ulong)tmpChain.LatestBlock.Header.Number + 1)} got exception: {ex.Message}\n{ex.StackTrace}"); } if (selsectResults.Contains(blockCall.BlockOverride.Number)) { - List? txResults = new List(); + List? txResults = new(); foreach (Transaction? tx in tmpChain.LatestBlock.Transactions) { TxReceipt Receipt = null; @@ -201,7 +210,6 @@ public ResultWrapper Execute(ulong version, return ResultWrapper.Success(results.ToArray()); } - } private class EstimateGasTxExecutor : TxExecutor @@ -242,8 +250,10 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, BlockchainBridge.CallOutput result = _blockchainBridge.CreateAccessList(header, tx, token, _optimize); if (result.Error is null) + { return ResultWrapper.Success(new AccessListForRpc(GetResultAccessList(tx, result), GetResultGas(tx, result))); + } return result.InputError ? GetInputError(result) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs index 396d8968fe9..6fe6174b8bc 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs @@ -19,359 +19,358 @@ using Nethermind.State.Proofs; using Nethermind.Wallet; -namespace Nethermind.JsonRpc.Modules.Eth +namespace Nethermind.JsonRpc.Modules.Eth; + +public class EthRpcModuleProxy : IEthRpcModule { - public class EthRpcModuleProxy : IEthRpcModule + private readonly IEthJsonRpcClientProxy _proxy; + private readonly IWallet _wallet; + + public EthRpcModuleProxy(IEthJsonRpcClientProxy proxy, IWallet wallet) { - private readonly IEthJsonRpcClientProxy _proxy; - private readonly IWallet _wallet; + _proxy = proxy; + _wallet = wallet; + } - public EthRpcModuleProxy(IEthJsonRpcClientProxy proxy, IWallet wallet) - { - _proxy = proxy; - _wallet = wallet; - } + public ResultWrapper eth_chainId() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_chainId() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_protocolVersion() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_protocolVersion() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_syncing() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_syncing() - { - throw new NotSupportedException(); - } + public ResultWrapper
eth_coinbase() + { + throw new NotSupportedException(); + } - public ResultWrapper
eth_coinbase() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_mining() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_mining() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_feeHistory(long blockCount, BlockParameter newestBlock, + double[]? rewardPercentiles = null) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_feeHistory(long blockCount, BlockParameter newestBlock, double[]? rewardPercentiles = null) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_snapshot() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_snapshot() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_hashrate() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_hashrate() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_maxPriorityFeePerGas() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_maxPriorityFeePerGas() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_gasPrice() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_gasPrice() - { - throw new NotSupportedException(); - } + public ResultWrapper> eth_accounts() + { + throw new NotSupportedException(); + } - public ResultWrapper> eth_accounts() - { - throw new NotSupportedException(); - } + public async Task> eth_blockNumber() + { + return ResultWrapper.From(await _proxy.eth_blockNumber()); + } - public async Task> eth_blockNumber() - => ResultWrapper.From(await _proxy.eth_blockNumber()); + public async Task> eth_getBalance(Address address, BlockParameter blockParameter) + { + return ResultWrapper.From(await _proxy.eth_getBalance(address, + MapBlockParameter(blockParameter))); + } - public async Task> eth_getBalance(Address address, BlockParameter blockParameter) - => ResultWrapper.From(await _proxy.eth_getBalance(address, MapBlockParameter(blockParameter))); + public ResultWrapper eth_getStorageAt(Address address, UInt256 positionIndex, + BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getStorageAt(Address address, UInt256 positionIndex, - BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public async Task> eth_getTransactionCount(Address address, BlockParameter blockParameter) + { + return ResultWrapper.From( + await _proxy.eth_getTransactionCount(address, MapBlockParameter(blockParameter))); + } - public async Task> eth_getTransactionCount(Address address, BlockParameter blockParameter) - => ResultWrapper.From(await _proxy.eth_getTransactionCount(address, MapBlockParameter(blockParameter))); + public ResultWrapper eth_getBlockTransactionCountByHash(Keccak blockHash) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getBlockTransactionCountByHash(Keccak blockHash) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getBlockTransactionCountByNumber(BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getBlockTransactionCountByNumber(BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getUncleCountByBlockHash(Keccak blockHash) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getUncleCountByBlockHash(Keccak blockHash) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getUncleCountByBlockNumber(BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getUncleCountByBlockNumber(BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getCode(Address address, BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getCode(Address address, BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_sign(Address addressData, byte[] message) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_sign(Address addressData, byte[] message) + public async Task> eth_sendTransaction(TransactionForRpc rpcTx) + { + Transaction transaction = rpcTx.ToTransactionWithDefaults(); + if (transaction.Signature is null) { - throw new NotSupportedException(); + RpcResult chainIdResult = await _proxy.eth_chainId(); + ulong chainId = chainIdResult?.IsValid == true ? (ulong)chainIdResult.Result : 0; + RpcResult nonceResult = + await _proxy.eth_getTransactionCount(transaction.SenderAddress, BlockParameterModel.Pending); + transaction.Nonce = nonceResult?.IsValid == true ? nonceResult.Result : UInt256.Zero; + _wallet.Sign(transaction, chainId); } - public async Task> eth_sendTransaction(TransactionForRpc rpcTx) - { - Transaction transaction = rpcTx.ToTransactionWithDefaults(); - if (transaction.Signature is null) - { - RpcResult chainIdResult = await _proxy.eth_chainId(); - ulong chainId = chainIdResult?.IsValid == true ? (ulong)chainIdResult.Result : 0; - RpcResult nonceResult = - await _proxy.eth_getTransactionCount(transaction.SenderAddress, BlockParameterModel.Pending); - transaction.Nonce = nonceResult?.IsValid == true ? nonceResult.Result : UInt256.Zero; - _wallet.Sign(transaction, chainId); - } - - return ResultWrapper.From(await _proxy.eth_sendRawTransaction(Rlp.Encode(transaction).Bytes)); - } + return ResultWrapper.From(await _proxy.eth_sendRawTransaction(Rlp.Encode(transaction).Bytes)); + } - public async Task> eth_sendRawTransaction(byte[] transaction) - => ResultWrapper.From(await _proxy.eth_sendRawTransaction(Rlp.Encode(transaction).Bytes)); + public async Task> eth_sendRawTransaction(byte[] transaction) + { + return ResultWrapper.From(await _proxy.eth_sendRawTransaction(Rlp.Encode(transaction).Bytes)); + } - public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockParameter? blockParameter = null) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockParameter? blockParameter = null) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_multicall(ulong version, - MultiCallBlockStateCallsModel[] blockCalls, - BlockParameter? blockParameter = null, bool traceTransfers = true) - { - throw new NotImplementedException(); - } + public ResultWrapper eth_multicall(ulong version, + MultiCallBlockStateCallsModel[] blockCalls, + BlockParameter? blockParameter = null, bool traceTransfers = true) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_estimateGas( - TransactionForRpc transactionCall, - BlockParameter? blockParameter = null) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_estimateGas( + TransactionForRpc transactionCall, + BlockParameter? blockParameter = null) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_createAccessList(TransactionForRpc transactionCall, BlockParameter? blockParameter = null, bool optimize = true) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_createAccessList(TransactionForRpc transactionCall, + BlockParameter? blockParameter = null, bool optimize = true) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getBlockByHash(Keccak blockHash, bool returnFullTransactionObjects) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getBlockByHash(Keccak blockHash, bool returnFullTransactionObjects) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getBlockByNumber(BlockParameter blockParameter, - bool returnFullTransactionObjects) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getBlockByNumber(BlockParameter blockParameter, + bool returnFullTransactionObjects) + { + throw new NotSupportedException(); + } - public async Task> eth_getTransactionByHash(Keccak transactionHash) - { - RpcResult result = await _proxy.eth_getTransactionByHash(transactionHash); - TransactionForRpc? transaction = MapTransaction(result.Result); - return transaction is null - ? ResultWrapper.Fail("Transaction was not found.") - : ResultWrapper.Success(transaction); - } + public async Task> eth_getTransactionByHash(Keccak transactionHash) + { + RpcResult result = await _proxy.eth_getTransactionByHash(transactionHash); + TransactionForRpc? transaction = MapTransaction(result.Result); + return transaction is null + ? ResultWrapper.Fail("Transaction was not found.") + : ResultWrapper.Success(transaction); + } - public ResultWrapper eth_pendingTransactions() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_pendingTransactions() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getTransactionByBlockHashAndIndex(Keccak blockHash, - UInt256 positionIndex) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getTransactionByBlockHashAndIndex(Keccak blockHash, + UInt256 positionIndex) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getTransactionByBlockNumberAndIndex(BlockParameter blockParameter, - UInt256 positionIndex) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getTransactionByBlockNumberAndIndex(BlockParameter blockParameter, + UInt256 positionIndex) + { + throw new NotSupportedException(); + } - public async Task> eth_getTransactionReceipt(Keccak txHashData) - { - RpcResult result = await _proxy.eth_getTransactionReceipt(txHashData); - ReceiptForRpc? receipt = MapReceipt(result.Result); + public async Task> eth_getTransactionReceipt(Keccak txHashData) + { + RpcResult result = await _proxy.eth_getTransactionReceipt(txHashData); + ReceiptForRpc? receipt = MapReceipt(result.Result); - return receipt is null - ? ResultWrapper.Fail("Receipt was not found.") - : ResultWrapper.Success(receipt); - } + return receipt is null + ? ResultWrapper.Fail("Receipt was not found.") + : ResultWrapper.Success(receipt); + } - public ResultWrapper eth_getUncleByBlockHashAndIndex(Keccak blockHashData, UInt256 positionIndex) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getUncleByBlockHashAndIndex(Keccak blockHashData, UInt256 positionIndex) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getUncleByBlockNumberAndIndex(BlockParameter blockParameter, - UInt256 positionIndex) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getUncleByBlockNumberAndIndex(BlockParameter blockParameter, + UInt256 positionIndex) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_newFilter(Filter filter) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_newFilter(Filter filter) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_newBlockFilter() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_newBlockFilter() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_newPendingTransactionFilter() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_newPendingTransactionFilter() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_uninstallFilter(UInt256 filterId) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_uninstallFilter(UInt256 filterId) + { + throw new NotSupportedException(); + } - public ResultWrapper> eth_getFilterChanges(UInt256 filterId) - { - throw new NotSupportedException(); - } + public ResultWrapper> eth_getFilterChanges(UInt256 filterId) + { + throw new NotSupportedException(); + } - public ResultWrapper> eth_getFilterLogs(UInt256 filterId) - { - throw new NotSupportedException(); - } + public ResultWrapper> eth_getFilterLogs(UInt256 filterId) + { + throw new NotSupportedException(); + } - public ResultWrapper> eth_getLogs(Filter filter) - { - throw new NotSupportedException(); - } + public ResultWrapper> eth_getLogs(Filter filter) + { + throw new NotSupportedException(); + } - public ResultWrapper> eth_getWork() - { - throw new NotSupportedException(); - } + public ResultWrapper> eth_getWork() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_submitWork(byte[] nonce, Keccak headerPowHash, byte[] mixDigest) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_submitWork(byte[] nonce, Keccak headerPowHash, byte[] mixDigest) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_submitHashrate(string hashRate, string id) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_submitHashrate(string hashRate, string id) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getProof(Address accountAddress, UInt256[] hashRate, - BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getProof(Address accountAddress, UInt256[] hashRate, + BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getAccount(Address accountAddress, BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getAccount(Address accountAddress, BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - private static TransactionForRpc? MapTransaction(TransactionModel? transaction) - { - if (transaction is null) - { - return null; - } - - return new TransactionForRpc - { - BlockHash = transaction.BlockHash, - BlockNumber = (long)transaction.BlockNumber, - From = transaction.From, - To = transaction.To, - Gas = (long)transaction.Gas, - GasPrice = transaction.GasPrice, - Hash = transaction.Hash, - Input = transaction.Input, - Nonce = transaction.Nonce, - Value = transaction.Value - }; - } + private static TransactionForRpc? MapTransaction(TransactionModel? transaction) + { + if (transaction is null) return null; + + return new TransactionForRpc + { + BlockHash = transaction.BlockHash, + BlockNumber = (long)transaction.BlockNumber, + From = transaction.From, + To = transaction.To, + Gas = (long)transaction.Gas, + GasPrice = transaction.GasPrice, + Hash = transaction.Hash, + Input = transaction.Input, + Nonce = transaction.Nonce, + Value = transaction.Value + }; + } - private static ReceiptForRpc? MapReceipt(ReceiptModel? receipt) - { - if (receipt is null) - { - return null; - } - - return new ReceiptForRpc - { - BlockHash = receipt.BlockHash, - BlockNumber = (long)receipt.BlockNumber, - ContractAddress = receipt.ContractAddress, - CumulativeGasUsed = (long)receipt.CumulativeGasUsed, - From = receipt.From, - GasUsed = (long)receipt.GasUsed, - Logs = receipt.Logs?.Select(MapLogEntry).ToArray() ?? Array.Empty(), - Status = (long)receipt.Status, - To = receipt.To, - TransactionHash = receipt.TransactionHash, - TransactionIndex = (long)receipt.TransactionIndex, - LogsBloom = receipt.LogsBloom is null ? null : new Bloom(receipt.LogsBloom), - EffectiveGasPrice = receipt.EffectiveGasPrice - }; - } + private static ReceiptForRpc? MapReceipt(ReceiptModel? receipt) + { + if (receipt is null) return null; + + return new ReceiptForRpc + { + BlockHash = receipt.BlockHash, + BlockNumber = (long)receipt.BlockNumber, + ContractAddress = receipt.ContractAddress, + CumulativeGasUsed = (long)receipt.CumulativeGasUsed, + From = receipt.From, + GasUsed = (long)receipt.GasUsed, + Logs = receipt.Logs?.Select(MapLogEntry).ToArray() ?? Array.Empty(), + Status = (long)receipt.Status, + To = receipt.To, + TransactionHash = receipt.TransactionHash, + TransactionIndex = (long)receipt.TransactionIndex, + LogsBloom = receipt.LogsBloom is null ? null : new Bloom(receipt.LogsBloom), + EffectiveGasPrice = receipt.EffectiveGasPrice + }; + } - private static LogEntryForRpc MapLogEntry(LogModel log) - => new() - { - Address = log.Address, - Data = log.Data, - Removed = log.Removed, - Topics = log.Topics, - BlockHash = log.BlockHash, - BlockNumber = (long)log.BlockNumber, - LogIndex = (long)log.LogIndex, - TransactionHash = log.TransactionHash, - TransactionIndex = (long)log.TransactionIndex - }; - - private static BlockParameterModel? MapBlockParameter(BlockParameter? blockParameter) - { - if (blockParameter is null) - { - return null; - } - - if (blockParameter.Type == BlockParameterType.BlockNumber && blockParameter.BlockNumber.HasValue) - { - return BlockParameterModel.FromNumber(blockParameter.BlockNumber.Value); - } - - return new BlockParameterModel - { - Type = blockParameter.Type.ToString() - }; - } + private static LogEntryForRpc MapLogEntry(LogModel log) + { + return new() + { + Address = log.Address, + Data = log.Data, + Removed = log.Removed, + Topics = log.Topics, + BlockHash = log.BlockHash, + BlockNumber = (long)log.BlockNumber, + LogIndex = (long)log.LogIndex, + TransactionHash = log.TransactionHash, + TransactionIndex = (long)log.TransactionIndex + }; + } + + private static BlockParameterModel? MapBlockParameter(BlockParameter? blockParameter) + { + if (blockParameter is null) return null; + + if (blockParameter.Type == BlockParameterType.BlockNumber && blockParameter.BlockNumber.HasValue) + return BlockParameterModel.FromNumber(blockParameter.BlockNumber.Value); + + return new BlockParameterModel { Type = blockParameter.Type.ToString() }; } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs index e83afc85b9c..cafaba94264 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs @@ -30,7 +30,7 @@ public ITxTracer StartNewTxTrace(Transaction? tx) { if (Trace && tx != null && tx.Hash != null) { - List? actionsLog = new List(); + List? actionsLog = new(); TxActions[tx.Hash] = actionsLog; return new MultiCallTxTracer(tx, actionsLog); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index 368cff9145d..50513bf4990 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Transactions; using Nethermind.Blockchain; using Nethermind.Blockchain.Filters; using Nethermind.Blockchain.Find; @@ -25,7 +24,6 @@ using Nethermind.Db; using Nethermind.Db.Blooms; using Nethermind.Evm.CodeAnalysis; -using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; using Nethermind.Facade.Eth; @@ -36,13 +34,11 @@ using Nethermind.JsonRpc.Modules.Eth.GasPrice; using Nethermind.Logging; using Nethermind.State; -using Nethermind.State.Proofs; using Nethermind.State.Repositories; using Nethermind.Synchronization.ParallelSync; using Nethermind.Trie.Pruning; using Nethermind.TxPool; using Nethermind.Wallet; -using Transaction = Nethermind.Core.Transaction; namespace Nethermind.JsonRpc.Modules.Eth.Multicall; @@ -314,26 +310,21 @@ public Block CreateBlock(BlockOverride? desiredBlock, CallTransactionModel[] des } else { - if (desiredBlock.Number < LatestBlock.Number) { - var parentBlock = BlockFinder.FindBlock((long)(desiredBlock.Number - 1)); + Block? parentBlock = BlockFinder.FindBlock((long)(desiredBlock.Number - 1)); if (parentBlock != null) { - BlockTree.UpdateMainChain(new List() { parentBlock }, true, true); + BlockTree.UpdateMainChain(new List { parentBlock }, true, true); BlockTree.UpdateHeadBlock(parentBlock.Hash); parent = parentBlock.Header; StateProvider.StateRoot = parent.StateRoot; } else - { throw new ArgumentException("could not find parent block and load the state"); - } } else - { parent = LatestBlock?.Header; - } ulong time = 0; @@ -368,8 +359,10 @@ public Block CreateBlock(BlockOverride? desiredBlock, CallTransactionModel[] des } if (_maxGas <= long.MaxValue) + { blockHeader.GasLimit = (long)Math.Min((ulong)blockHeader.GasLimit, _maxGas.ToUInt64(CultureInfo.InvariantCulture)); + } else _maxGas -= new UInt256((ulong)blockHeader.GasLimit); @@ -398,8 +391,8 @@ public Block FinalizeBlock(Block currentBlock) currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); - var blocks = BlockProcessor.Process(StateProvider.StateRoot, - new List() { currentBlock }, + Block[]? blocks = BlockProcessor.Process(StateProvider.StateRoot, + new List { currentBlock }, ProcessingOptions.ForceProcessing | ProcessingOptions.NoValidation | ProcessingOptions.DoNotVerifyNonce | @@ -408,8 +401,8 @@ public Block FinalizeBlock(Block currentBlock) ProcessingOptions.StoreReceipts , BlockTracer); - var block = blocks.First(); - var res = BlockTree.SuggestBlock(block, + Block? block = blocks.First(); + AddBlockResult res = BlockTree.SuggestBlock(block, BlockTreeSuggestOptions.ForceSetAsMain | BlockTreeSuggestOptions.ForceDontValidateParent); BlockTree.UpdateMainChain(blocks, true, true); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs index 85dcb6e078c..26041d0dc84 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs @@ -149,7 +149,7 @@ public void ReportAction(long gas, UInt256 value, Address from, Address to, Read { byte[]? data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256), from, to, value); - LogEntry? result = new LogEntry(Address.Zero, data, new[] { Keccak.Zero }); + LogEntry? result = new(Address.Zero, data, new[] { Keccak.Zero }); _extendedLogs.Add(result); } From 2f8831bcbfb25fdd58af7d080015da5a0f219669 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 12 Jun 2023 11:08:04 +0100 Subject: [PATCH 021/213] mainnet related bugfix oom detected --- .../Modules/Eth/Multicall/MultiCallBlockchainFork.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index 50513bf4990..84f94cc5a28 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -103,7 +103,6 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv //Writable inMemory DBs on with access to the data of existing ones (will not modify existing data) if (oldDbProvider == null) throw new ArgumentNullException(); - List? oldStack = oldDbProvider.StateDb.GetAllValues().ToList(); IDb inMemStateDb = new ReadOnlyDb(oldDbProvider.StateDb, true); IDb inMemBlockDb = new ReadOnlyDb(oldDbProvider.BlocksDb, true); IDb inMemHeaderDb = new ReadOnlyDb(oldDbProvider.HeadersDb, true); From cd7a89e0849823065fc86e7a9a0fea5d14681bc6 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 28 Jun 2023 06:38:04 +0100 Subject: [PATCH 022/213] Implemented processing in Envs Integration with Bridge and ProcessingEnvs --- .../Nethermind.Api/NethermindApi.cs | 8 + .../IMultiCallBlocksProcessingEnv.cs | 24 +++ .../Processing/IReadOnlyTxProcessingEnv.cs | 11 + .../IReadOnlyTxProcessingEnvBase.cs | 14 ++ .../Processing/MultiCallChainProcessor.cs | 31 +++ .../MultiCallReadOnlyBlocksProcessingEnv.cs | 113 +++++++++++ .../Processing/OneTimeProcessor.cs | 10 +- .../Processing/ReadOnlyChainProcessingEnv.cs | 49 ++--- .../ReadOnlyChainProcessingEnvBase.cs | 62 ++++++ .../Processing/ReadOnlyTxProcessingEnv.cs | 34 +--- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 39 ++++ .../Validators/MultiCallBlockValidator.cs | 21 ++ src/Nethermind/Nethermind.Db/ReadOnlyDb.cs | 2 +- .../MultiCallVirtualMachine.cs | 3 +- .../TransactionProcessor.cs | 27 ++- .../BlockchainBridgeTests.cs | 12 ++ .../Nethermind.Facade/BlockchainBridge.cs | 190 +++++++++++++++++- .../Nethermind.Facade/IBlockchainBridge.cs | 5 + .../Nethermind.Facade/MultiCallBlockTracer.cs | 85 ++++++++ .../MultiCallTxTracer.cs | 50 ++++- .../Proxy/Models/MultiCall/BlockOverride.cs | 55 ++++- .../MultiCallBlockStateCallsModel.cs | 2 +- .../Models/MultiCall/MultiCallCallResult.cs | 3 +- .../EthMulticallTestsBlocksAndTransactions.cs | 81 +++++++- .../EthMulticallTestsSimplePrecompiles.cs | 68 ++++--- .../Modules/TestRpcBlockchain.cs | 8 +- .../Eth/EthModule.TransactionExecutor.cs | 115 ++--------- .../Modules/Eth/EthRpcModule.cs | 2 +- .../Eth/Multicall/MultiCallBlockTracer.cs | 48 ----- .../Eth/Multicall/MultiCallBlockchainFork.cs | 10 +- .../MultiCallReadOnlyTxProcessingEnv.cs | 28 --- 31 files changed, 923 insertions(+), 287 deletions(-) create mode 100644 src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs create mode 100644 src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs create mode 100644 src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnvBase.cs create mode 100644 src/Nethermind/Nethermind.Consensus/Processing/MultiCallChainProcessor.cs create mode 100644 src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs create mode 100644 src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs create mode 100644 src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs create mode 100644 src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidator.cs rename src/Nethermind/{Nethermind.JsonRpc/Modules/Eth/Multicall => Nethermind.Evm}/MultiCallVirtualMachine.cs (95%) create mode 100644 src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs rename src/Nethermind/{Nethermind.JsonRpc/Modules/Eth/Multicall => Nethermind.Facade}/MultiCallTxTracer.cs (79%) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/{ => Multicall}/EthMulticallTestsBlocksAndTransactions.cs (70%) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/{ => Multicall}/EthMulticallTestsSimplePrecompiles.cs (74%) delete mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs delete mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index fe323844e39..b88831b32b4 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -71,11 +71,13 @@ public NethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSeriali } private IReadOnlyDbProvider? _readOnlyDbProvider; + private IReadOnlyDbProvider? _multiCallReadOnlyDbProvider; public IBlockchainBridge CreateBlockchainBridge() { ReadOnlyBlockTree readOnlyTree = BlockTree!.AsReadOnly(); LazyInitializer.EnsureInitialized(ref _readOnlyDbProvider, () => new ReadOnlyDbProvider(DbProvider, false)); + LazyInitializer.EnsureInitialized(ref _multiCallReadOnlyDbProvider, () => new ReadOnlyDbProvider(DbProvider, true)); // TODO: reuse the same trie cache here ReadOnlyTxProcessingEnv readOnlyTxProcessingEnv = new( @@ -84,12 +86,18 @@ public IBlockchainBridge CreateBlockchainBridge() readOnlyTree, SpecProvider, LogManager); + IMultiCallBlocksProcessingEnv multiCallReadOnlyBlocksProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + _multiCallReadOnlyDbProvider, + SpecProvider, + LogManager); + IMiningConfig miningConfig = ConfigProvider.GetConfig(); IBlocksConfig blocksConfig = ConfigProvider.GetConfig(); return new BlockchainBridge( readOnlyTxProcessingEnv, + multiCallReadOnlyBlocksProcessingEnv, TxPool, ReceiptFinder, FilterStore, diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs new file mode 100644 index 00000000000..38a3b682ae3 --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; +using Nethermind.Db; +using Nethermind.Evm; +using Nethermind.Logging; + +namespace Nethermind.Consensus.Processing; + +public interface IMultiCallBlocksProcessingEnv : IReadOnlyTxProcessingEnvBase, IDisposable +{ + //Instance VM can be edited during processing + ISpecProvider SpecProvider { get; } + MultiCallVirtualMachine Machine { get; } + + //We need abilety to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning + IMultiCallBlocksProcessingEnv Clone(); + + //We keep original ProcessingEnv spirit with Build() that can start from any stateRoot + IBlockProcessor GetProcessor(Keccak stateRoot); +} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs new file mode 100644 index 00000000000..9fd6c853900 --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Evm.TransactionProcessing; + +namespace Nethermind.Consensus.Processing; + +public interface IReadOnlyTxProcessingEnv: IReadOnlyTxProcessorSource, IReadOnlyTxProcessingEnvBase +{ + ITransactionProcessor TransactionProcessor { get; set; } +} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnvBase.cs new file mode 100644 index 00000000000..49f16df8dbf --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnvBase.cs @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Blockchain; +using Nethermind.State; + +namespace Nethermind.Consensus.Processing; + +public interface IReadOnlyTxProcessingEnvBase +{ + IStateReader StateReader { get; } + IWorldState StateProvider { get; } + IBlockTree BlockTree { get; } +} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallChainProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallChainProcessor.cs new file mode 100644 index 00000000000..a94e7490226 --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallChainProcessor.cs @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; +using Nethermind.Db; +using Nethermind.Evm.Tracing; + +namespace Nethermind.Consensus.Processing; + +public class MultiCallChainProcessor : OneTimeChainProcessor +{ + public MultiCallChainProcessor(IReadOnlyDbProvider readOnlyDbProvider, IBlockchainProcessor processor) : base(readOnlyDbProvider, processor) + { + } + + public override Block? Process(Block block, ProcessingOptions options, IBlockTracer tracer) + { + lock (_lock) + { + Block result; + result = _processor.Process(block, options, tracer); + return result; + } + } + + public override void Dispose() + { + _readOnlyDbProvider.ClearTempChanges(); + base.Dispose(); + } +} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs new file mode 100644 index 00000000000..d2dd653d0e1 --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -0,0 +1,113 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Blockchain; +using Nethermind.Blockchain.Receipts; +using Nethermind.Blockchain.Synchronization; +using Nethermind.Consensus.Comparers; +using Nethermind.Consensus.Rewards; +using Nethermind.Consensus.Validators; +using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; +using Nethermind.Db; +using Nethermind.Db.Blooms; +using Nethermind.Evm; +using Nethermind.Evm.TransactionProcessing; +using Nethermind.Logging; +using Nethermind.State; +using Nethermind.State.Repositories; +using Nethermind.Trie.Pruning; + +namespace Nethermind.Consensus.Processing; + +public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IMultiCallBlocksProcessingEnv +{ + private readonly ITrieStore? _trieStore; + private readonly ILogManager? _logManager; + private readonly IBlockValidator _blockValidator; + private readonly InMemoryReceiptStorage _receiptStorage; + public ITransactionProcessor TransactionProcessor { get; } + public ISpecProvider SpecProvider { get; } + public MultiCallVirtualMachine Machine { get; } + + //We need abilety to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning + public static IMultiCallBlocksProcessingEnv Create(IReadOnlyDbProvider? readOnlyDbProvider, + ISpecProvider? specProvider, + ILogManager? logManager + ) + { + ReadOnlyDbProvider? DbProvider = new(readOnlyDbProvider, true); + TrieStore trieStore = new(readOnlyDbProvider.StateDb, logManager); + BlockTree BlockTree = new(readOnlyDbProvider, + new ChainLevelInfoRepository(readOnlyDbProvider.BlockInfosDb), + specProvider, + NullBloomStorage.Instance, + new SyncConfig(), + logManager); + + return new MultiCallReadOnlyBlocksProcessingEnv( + DbProvider, + trieStore, + BlockTree, + specProvider, + logManager); + } + + public IMultiCallBlocksProcessingEnv Clone() + { + return Create(DbProvider, SpecProvider, _logManager); + } + + private MultiCallReadOnlyBlocksProcessingEnv( + IReadOnlyDbProvider? readOnlyDbProvider, + ITrieStore? trieStore, + IBlockTree? blockTree, + ISpecProvider? specProvider, + ILogManager? logManager) : base(readOnlyDbProvider, trieStore, blockTree, + logManager) + { + + _trieStore = trieStore; + _logManager = logManager; + SpecProvider = specProvider; + + + _receiptStorage = new InMemoryReceiptStorage(); + + Machine = new MultiCallVirtualMachine(BlockhashProvider, specProvider, logManager); + + HeaderValidator headerValidator = new( + BlockTree, + Always.Valid, + SpecProvider, + _logManager); + + _blockValidator = new MultiCallBlockValidator(new TxValidator(SpecProvider.ChainId), + headerValidator, + Always.Valid, + SpecProvider, + _logManager); + + } + + public IBlockProcessor GetProcessor(Keccak stateRoot) + { + var yransactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, Machine, _logManager); + + return new BlockProcessor(SpecProvider, + _blockValidator, + NoBlockRewards.Instance, + new BlockProcessor.BlockValidationTransactionsExecutor(yransactionProcessor, StateProvider), + StateProvider, + _receiptStorage, + NullWitnessCollector.Instance, + _logManager); + } + + public void Dispose() + { + _trieStore?.Dispose(); + DbProvider.Dispose(); + } +} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/OneTimeProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/OneTimeProcessor.cs index 668319e3b0a..781c13fbb8d 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/OneTimeProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/OneTimeProcessor.cs @@ -14,10 +14,10 @@ public class OneTimeChainProcessor : IBlockchainProcessor { public ITracerBag Tracers => _processor.Tracers; - private readonly IBlockchainProcessor _processor; - private readonly IReadOnlyDbProvider _readOnlyDbProvider; + protected readonly IBlockchainProcessor _processor; + protected readonly IReadOnlyDbProvider _readOnlyDbProvider; - private object _lock = new(); + protected object _lock = new(); public OneTimeChainProcessor(IReadOnlyDbProvider readOnlyDbProvider, IBlockchainProcessor processor) { @@ -35,7 +35,7 @@ public Task StopAsync(bool processRemainingBlocks = false) return _processor.StopAsync(processRemainingBlocks); } - public Block? Process(Block block, ProcessingOptions options, IBlockTracer tracer) + public virtual Block? Process(Block block, ProcessingOptions options, IBlockTracer tracer) { lock (_lock) { @@ -64,7 +64,7 @@ public bool IsProcessingBlocks(ulong? maxProcessingInterval) public event EventHandler? InvalidBlock; #pragma warning restore 67 - public void Dispose() + public virtual void Dispose() { _processor?.Dispose(); _readOnlyDbProvider?.Dispose(); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs index da38938699c..92a9fb68ae7 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using Nethermind.Blockchain.Receipts; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; @@ -9,25 +8,18 @@ using Nethermind.Core.Specs; using Nethermind.Db; using Nethermind.Logging; -using Nethermind.State; namespace Nethermind.Consensus.Processing { /// /// Not thread safe. /// - public class ReadOnlyChainProcessingEnv : IDisposable + public class ReadOnlyChainProcessingEnv : ReadOnlyChainProcessingEnvBase { - private readonly ReadOnlyTxProcessingEnv _txEnv; - - private readonly BlockchainProcessor _blockProcessingQueue; - public IBlockProcessor BlockProcessor { get; } public IBlockchainProcessor ChainProcessor { get; } - public IBlockProcessingQueue BlockProcessingQueue { get; } - public IWorldState StateProvider => _txEnv.StateProvider; public ReadOnlyChainProcessingEnv( - ReadOnlyTxProcessingEnv txEnv, + IReadOnlyTxProcessingEnv txEnv, IBlockValidator blockValidator, IBlockPreprocessorStep recoveryStep, IRewardCalculator rewardCalculator, @@ -35,31 +27,28 @@ public ReadOnlyChainProcessingEnv( IReadOnlyDbProvider dbProvider, ISpecProvider specProvider, ILogManager logManager, - IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) + IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) : base(txEnv, blockValidator, recoveryStep, rewardCalculator, receiptStorage, dbProvider, specProvider, logManager, blockTransactionsExecutor) { - _txEnv = txEnv; - - IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor = - blockTransactionsExecutor ?? new BlockProcessor.BlockValidationTransactionsExecutor(_txEnv.TransactionProcessor, StateProvider); - - BlockProcessor = new BlockProcessor( - specProvider, - blockValidator, - rewardCalculator, - transactionsExecutor, - StateProvider, - receiptStorage, - NullWitnessCollector.Instance, - logManager); - - _blockProcessingQueue = new BlockchainProcessor(_txEnv.BlockTree, BlockProcessor, recoveryStep, _txEnv.StateReader, logManager, BlockchainProcessor.Options.NoReceipts); - BlockProcessingQueue = _blockProcessingQueue; ChainProcessor = new OneTimeChainProcessor(dbProvider, _blockProcessingQueue); } + } + + public class MultiCallReadOnlyChainProcessingEnv : ReadOnlyChainProcessingEnvBase + { + public IBlockchainProcessor ChainProcessor { get; } - public void Dispose() + public MultiCallReadOnlyChainProcessingEnv( + IReadOnlyTxProcessingEnv txEnv, + IBlockValidator blockValidator, + IBlockPreprocessorStep recoveryStep, + IRewardCalculator rewardCalculator, + IReceiptStorage receiptStorage, + IReadOnlyDbProvider dbProvider, + ISpecProvider specProvider, + ILogManager logManager, + IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) : base(txEnv, blockValidator, recoveryStep, rewardCalculator, receiptStorage, dbProvider, specProvider, logManager, blockTransactionsExecutor) { - _blockProcessingQueue?.Dispose(); + ChainProcessor = new MultiCallChainProcessor(dbProvider, _blockProcessingQueue); } } } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs new file mode 100644 index 00000000000..66249042070 --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Blockchain.Receipts; +using Nethermind.Consensus.Rewards; +using Nethermind.Consensus.Validators; +using Nethermind.Core.Specs; +using Nethermind.Db; +using Nethermind.Logging; +using Nethermind.State; + +namespace Nethermind.Consensus.Processing; + +/// +/// Not thread safe. +/// +public class ReadOnlyChainProcessingEnvBase : IDisposable +{ + protected readonly IReadOnlyTxProcessingEnv _txEnv; + + protected readonly BlockchainProcessor _blockProcessingQueue; + public IBlockProcessor BlockProcessor { get; } + public IBlockProcessingQueue BlockProcessingQueue { get; } + public IWorldState StateProvider => _txEnv.StateProvider; + + public ReadOnlyChainProcessingEnvBase( + IReadOnlyTxProcessingEnv txEnv, + IBlockValidator blockValidator, + IBlockPreprocessorStep recoveryStep, + IRewardCalculator rewardCalculator, + IReceiptStorage receiptStorage, + IReadOnlyDbProvider dbProvider, + ISpecProvider specProvider, + ILogManager logManager, + IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) + { + _txEnv = txEnv; + + IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor = + blockTransactionsExecutor ?? new BlockProcessor.BlockValidationTransactionsExecutor(_txEnv.TransactionProcessor, StateProvider); + + BlockProcessor = new BlockProcessor( + specProvider, + blockValidator, + rewardCalculator, + transactionsExecutor, + StateProvider, + receiptStorage, + NullWitnessCollector.Instance, + logManager); + + _blockProcessingQueue = new BlockchainProcessor(_txEnv.BlockTree, BlockProcessor, recoveryStep, _txEnv.StateReader, logManager, BlockchainProcessor.Options.NoReceipts); + BlockProcessingQueue = _blockProcessingQueue; + + } + + public void Dispose() + { + _blockProcessingQueue?.Dispose(); + } +} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index fe44cce7305..2e316034a4d 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using Nethermind.Blockchain; using Nethermind.Consensus.Withdrawals; using Nethermind.Core.Crypto; @@ -10,22 +9,17 @@ using Nethermind.Evm; using Nethermind.Evm.TransactionProcessing; using Nethermind.Logging; -using Nethermind.State; using Nethermind.Trie.Pruning; + // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedAutoPropertyAccessor.Global namespace Nethermind.Consensus.Processing { - public class ReadOnlyTxProcessingEnv : IReadOnlyTxProcessorSource + public class ReadOnlyTxProcessingEnv : ReadOnlyTxProcessingEnvBase, IReadOnlyTxProcessingEnv + { - public IStateReader StateReader { get; } - public IWorldState StateProvider { get; } public ITransactionProcessor TransactionProcessor { get; set; } - public IBlockTree BlockTree { get; } - public IReadOnlyDbProvider DbProvider { get; } - public IBlockhashProvider BlockhashProvider { get; } - public IVirtualMachine Machine { get; protected set; } public ReadOnlyTxProcessingEnv( IDbProvider? dbProvider, @@ -39,24 +33,14 @@ public ReadOnlyTxProcessingEnv( public ReadOnlyTxProcessingEnv( IReadOnlyDbProvider? readOnlyDbProvider, - IReadOnlyTrieStore? readOnlyTrieStore, - IReadOnlyBlockTree? readOnlyBlockTree, + IReadOnlyTrieStore? trieStore, + IReadOnlyBlockTree? blockTree, ISpecProvider? specProvider, - ILogManager? logManager) + ILogManager? logManager + ): base(readOnlyDbProvider, trieStore, blockTree, logManager) { - if (specProvider is null) throw new ArgumentNullException(nameof(specProvider)); - - DbProvider = readOnlyDbProvider ?? throw new ArgumentNullException(nameof(readOnlyDbProvider)); - ReadOnlyDb codeDb = readOnlyDbProvider.CodeDb.AsReadOnly(true); - - StateReader = new StateReader(readOnlyTrieStore, codeDb, logManager); - StateProvider = new WorldState(readOnlyTrieStore, codeDb, logManager); - - BlockTree = readOnlyBlockTree ?? throw new ArgumentNullException(nameof(readOnlyBlockTree)); - BlockhashProvider = new BlockhashProvider(BlockTree, logManager); - - Machine = new VirtualMachine(BlockhashProvider, specProvider, logManager); - TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, Machine, logManager); + IVirtualMachine machine = new VirtualMachine(BlockhashProvider, specProvider, logManager); + TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, machine, logManager); } public IReadOnlyTransactionProcessor Build(Keccak stateRoot) => new ReadOnlyTransactionProcessor(TransactionProcessor, StateProvider, stateRoot); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs new file mode 100644 index 00000000000..b4ef058c2e9 --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Blockchain; +using Nethermind.Db; +using Nethermind.Evm; +using Nethermind.Logging; +using Nethermind.State; +using Nethermind.Trie.Pruning; + +namespace Nethermind.Consensus.Processing; + +public class ReadOnlyTxProcessingEnvBase : IReadOnlyTxProcessingEnvBase +{ + public IStateReader StateReader { get; } + public IWorldState StateProvider { get; } + public IBlockTree BlockTree { get; } + public IReadOnlyDbProvider DbProvider { get; } + public IBlockhashProvider BlockhashProvider { get; } + + public ReadOnlyTxProcessingEnvBase( + IReadOnlyDbProvider? readOnlyDbProvider, + ITrieStore? trieStore, + IBlockTree? blockTree, + ILogManager? logManager + ) + { + DbProvider = readOnlyDbProvider ?? throw new ArgumentNullException(nameof(readOnlyDbProvider)); + ReadOnlyDb codeDb = readOnlyDbProvider.CodeDb.AsReadOnly(true); + + StateReader = new StateReader(trieStore, codeDb, logManager); + StateProvider = new WorldState(trieStore, codeDb, logManager); + + BlockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); + BlockhashProvider = new BlockhashProvider(BlockTree, logManager); + + } +} diff --git a/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidator.cs new file mode 100644 index 00000000000..92801666519 --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidator.cs @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Logging; +using Nethermind.TxPool; + +namespace Nethermind.Consensus.Validators; + +public class MultiCallBlockValidator : BlockValidator +{ + public MultiCallBlockValidator(ITxValidator? txValidator, IHeaderValidator? headerValidator, IUnclesValidator? unclesValidator, ISpecProvider? specProvider, ILogManager? logManager) : base(txValidator, headerValidator, unclesValidator, specProvider, logManager) + { + } + + public override bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) + { + return true; + } +} diff --git a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs index dc218d30165..5682e62c131 100644 --- a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs +++ b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs @@ -26,7 +26,7 @@ public void Dispose() _memDb.Dispose(); } - public string Name { get; } = "ReadOnlyDb"; + public string Name { get => _wrappedDb.Name; } public byte[]? Get(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs b/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs similarity index 95% rename from src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs rename to src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs index 28845391589..c6af4f3f8d0 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs @@ -4,12 +4,11 @@ using System.Collections.Generic; using Nethermind.Core; using Nethermind.Core.Specs; -using Nethermind.Evm; using Nethermind.Evm.CodeAnalysis; using Nethermind.Logging; using Nethermind.State; -namespace Nethermind.JsonRpc.Modules.Eth.Multicall; +namespace Nethermind.Evm; public class MultiCallVirtualMachine : VirtualMachine { diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 590e5adb8d5..728bf879dde 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -246,12 +246,32 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra if (notSystemTransaction) { UInt256 senderBalance = _worldState.GetBalance(caller); - if (!noValidation && ((ulong)intrinsicGas * effectiveGasPrice + value > senderBalance || - senderReservedGasPayment + value > senderBalance)) + UInt256 gasWithValue; + UInt256 rederveWithValue; + + if (UInt256.AddOverflow((ulong)intrinsicGas * effectiveGasPrice, value, out gasWithValue)) + { + TraceLogInvalidTx(transaction, + $"VALUE_TOO_BIG"); + QuickFail(transaction, block, txTracer, eip658NotEnabled, "numeric overflow detected!"); + return; + } + + if (UInt256.AddOverflow((ulong)intrinsicGas * effectiveGasPrice, value, out rederveWithValue)) + { + TraceLogInvalidTx(transaction, + $"VALUE_TOO_BIG"); + QuickFail(transaction, block, txTracer, eip658NotEnabled, "numeric overflow detected!"); + return; + } + + if (!noValidation && (gasWithValue > senderBalance || rederveWithValue > senderBalance)) { + TraceLogInvalidTx(transaction, $"INSUFFICIENT_SENDER_BALANCE: ({caller})_BALANCE = {senderBalance}"); - QuickFail(transaction, block, txTracer, eip658NotEnabled, "insufficient sender balance"); + QuickFail(transaction, block, txTracer, eip658NotEnabled, + $"insufficient sender balance {senderBalance} while {(ulong)intrinsicGas * effectiveGasPrice + value} expected"); return; } @@ -273,6 +293,7 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra return; } + _worldState.IncrementNonce(caller); } diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index 6ace9a200d0..be55a0ab635 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -66,10 +66,16 @@ public async Task SetUp() _specProvider, LimboLogs.Instance); + IMultiCallBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + new ReadOnlyDbProvider(_dbProvider, true), + _specProvider, + LimboLogs.Instance); + processingEnv.TransactionProcessor = _transactionProcessor; _blockchainBridge = new BlockchainBridge( processingEnv, + multiCallProcessingEnv, _txPool, _receiptStorage, _filterStore, @@ -209,6 +215,11 @@ public void Bridge_head_is_correct(long headNumber) _specProvider, LimboLogs.Instance); + IMultiCallBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + new ReadOnlyDbProvider(_dbProvider, true), + _specProvider, + LimboLogs.Instance); + Block head = Build.A.Block.WithNumber(headNumber).TestObject; Block bestSuggested = Build.A.Block.WithNumber(8).TestObject; @@ -217,6 +228,7 @@ public void Bridge_head_is_correct(long headNumber) _blockchainBridge = new BlockchainBridge( processingEnv, + multiCallProcessingEnv, _txPool, _receiptStorage, _filterStore, diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 7bc9ddb5399..ed9aa6820b8 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Nethermind.Blockchain; using Nethermind.Blockchain.Filters; using Nethermind.Blockchain.Find; @@ -26,6 +27,12 @@ using Nethermind.State; using Nethermind.Core.Extensions; using Nethermind.Config; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Facade.Proxy.Models.MultiCall; +using System.Transactions; +using Microsoft.CSharp.RuntimeBinder; +using Transaction = Nethermind.Core.Transaction; +using Nethermind.Specs; namespace Nethermind.Facade { @@ -37,7 +44,8 @@ public interface IBlockchainBridgeFactory [Todo(Improve.Refactor, "I want to remove BlockchainBridge, split it into something with logging, state and tx processing. Then we can start using independent modules.")] public class BlockchainBridge : IBlockchainBridge { - private readonly ReadOnlyTxProcessingEnv _processingEnv; + private readonly IReadOnlyTxProcessingEnv _processingEnv; + private readonly IMultiCallBlocksProcessingEnv _multiCallProcessingEnv; private readonly ITxPool _txPool; private readonly IFilterStore _filterStore; private readonly IEthereumEcdsa _ecdsa; @@ -48,7 +56,8 @@ public class BlockchainBridge : IBlockchainBridge private readonly ISpecProvider _specProvider; private readonly IBlocksConfig _blocksConfig; - public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, + public BlockchainBridge(IReadOnlyTxProcessingEnv processingEnv, + IMultiCallBlocksProcessingEnv multiCallProcessingEnv, ITxPool? txPool, IReceiptFinder? receiptStorage, IFilterStore? filterStore, @@ -61,6 +70,7 @@ public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, bool isMining) { _processingEnv = processingEnv ?? throw new ArgumentNullException(nameof(processingEnv)); + _multiCallProcessingEnv = multiCallProcessingEnv ?? throw new ArgumentNullException(nameof(multiCallProcessingEnv)); _txPool = txPool ?? throw new ArgumentNullException(nameof(_txPool)); _receiptFinder = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage)); _filterStore = filterStore ?? throw new ArgumentNullException(nameof(filterStore)); @@ -167,6 +177,16 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can }; } + + public List MultiCall(BlockHeader header, MultiCallBlockStateCallsModel[] blocks, CancellationToken cancellationToken) + { + MultiCallBlockTracer multiCallOutputTracer = new(); + + MultiCallTrace(header, blocks, multiCallOutputTracer.WithCancellation(cancellationToken)); + + return multiCallOutputTracer._results; + } + public CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken) { using IReadOnlyTransactionProcessor? readOnlyTransactionProcessor = _processingEnv.Build(header.StateRoot!); @@ -284,6 +304,116 @@ private void CallAndRestore( transactionProcessor.CallAndRestore(transaction, callHeader, tracer); } + public void MultiCallTrace(BlockHeader parent, MultiCallBlockStateCallsModel[] blocks, + IBlockTracer tracer) + { + using (IMultiCallBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone()) + { + var processor = env.GetProcessor(env.StateProvider.StateRoot); + var firstBlock = blocks.FirstOrDefault(); + var startStateRoot = parent.StateRoot; + if (firstBlock?.BlockOverride?.Number != null + && firstBlock?.BlockOverride?.Number > UInt256.Zero + && firstBlock?.BlockOverride?.Number < (ulong)long.MaxValue) + { + BlockHeader? searchResult = + _multiCallProcessingEnv.BlockTree.FindHeader((long)firstBlock?.BlockOverride.Number); + if (searchResult != null) + { + startStateRoot = searchResult.StateRoot; + } + } + + foreach (MultiCallBlockStateCallsModel? callInputBlock in blocks) + { + BlockHeader callHeader = null; + if (callInputBlock.BlockOverride == null) + { + callHeader = new BlockHeader( + parent.Hash, + Keccak.OfAnEmptySequenceRlp, + Address.Zero, + UInt256.Zero, + parent.Number + 1, + parent.GasLimit, + parent.Timestamp + 1, + Array.Empty()); + callHeader.BaseFeePerGas = BaseFeeCalculator.Calculate(parent, _specProvider.GetSpec(parent)); + } + else + { + callHeader = callInputBlock.BlockOverride.GetBlockHeader(parent); + } + + env.StateProvider.StateRoot = parent.StateRoot; + + IReleaseSpec releaseSpec = _specProvider.GetSpec(parent); + + if (releaseSpec.IsEip4844Enabled) + { + // TODO: Calculate ExcessDataGas depending on parent ExcessDataGas and number of blobs in txs + callHeader.ExcessDataGas = 0; + } + + callHeader.MixHash = parent.MixHash; + callHeader.IsPostMerge = parent.Difficulty == 0; + + var transactions = callInputBlock.Calls.Select(model => model.GetTransaction()).ToList(); + foreach (Transaction transaction in transactions) + { + transaction.SenderAddress ??= Address.SystemUser; + + Keccak stateRoot = callHeader.StateRoot!; + + if (transaction.Nonce == 0) + { + transaction.Nonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; + } + + transaction.Hash = transaction.CalculateHash(); + } + + Block? currentBlock = new(callHeader, transactions, Array.Empty()); + + var currentSpec = env.SpecProvider.GetSpec(currentBlock.Header); + if (callInputBlock.StateOverrides != null) + { + ModifyAccounts(callInputBlock.StateOverrides, env.StateProvider, currentSpec); + } + + env.StateProvider.Commit(currentSpec); + env.StateProvider.CommitTree(currentBlock.Number); + env.StateProvider.RecalculateStateRoot(); + + currentBlock.Header.StateRoot = env.StateProvider.StateRoot; + currentBlock.Header.IsPostMerge = true; //ToDo: Seal if necessary before merge 192 BPB + currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); + + + Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, + new List { currentBlock }, + ProcessingOptions.ForceProcessing | + // ProcessingOptions.NoValidation | + ProcessingOptions.DoNotVerifyNonce | + ProcessingOptions.IgnoreParentNotOnMainChain | + ProcessingOptions.MarkAsProcessed | + ProcessingOptions.StoreReceipts + , tracer); + + var processedBlock = currentBlocks.FirstOrDefault(); + if (processedBlock != null) + { + parent = processedBlock.Header; + //env.StateProvider.CommitTree(parent.Number); + } + else + { + throw new RuntimeBinderException("Processing failed"); //Todo fix + } + } + } + } + public ulong GetChainId() { return _processingEnv.BlockTree.ChainId; @@ -294,6 +424,62 @@ private UInt256 GetNonce(Keccak stateRoot, Address address) return _processingEnv.StateReader.GetNonce(stateRoot, address); } + //Apply changes to accounts and contracts states including precompiles + private void ModifyAccounts(AccountOverride[] StateOverrides, IWorldState? StateProvider, IReleaseSpec? CurrentSpec) + { + Account? acc; + + foreach (AccountOverride accountOverride in StateOverrides) + { + Address address = accountOverride.Address; + bool accExists = StateProvider.AccountExists(address); + if (!accExists) + { + StateProvider.CreateAccount(address, accountOverride.Balance, accountOverride.Nonce); + acc = StateProvider.GetAccount(address); + } + else + acc = StateProvider.GetAccount(address); + + UInt256 accBalance = acc.Balance; + if (accBalance > accountOverride.Balance) + StateProvider.SubtractFromBalance(address, accBalance - accountOverride.Balance, CurrentSpec); + else if (accBalance < accountOverride.Nonce) + StateProvider.AddToBalance(address, accountOverride.Balance - accBalance, CurrentSpec); + + UInt256 accNonce = acc.Nonce; + if (accNonce > accountOverride.Nonce) + StateProvider.DecrementNonce(address); + else if (accNonce < accountOverride.Nonce) StateProvider.IncrementNonce(address); + + if (acc != null) + { + if (accountOverride.Code is not null) + { + _multiCallProcessingEnv.Machine.SetOverwrite(StateProvider, CurrentSpec, address, + new CodeInfo(accountOverride.Code), accountOverride.MoveToAddress); + } + } + + + if (accountOverride.State is not null) + { + accountOverride.State = new Dictionary(); + foreach (KeyValuePair storage in accountOverride.State) + StateProvider.Set(new StorageCell(address, storage.Key), + storage.Value.WithoutLeadingZeros().ToArray()); + } + + if (accountOverride.StateDiff is not null) + { + foreach (KeyValuePair storage in accountOverride.StateDiff) + StateProvider.Set(new StorageCell(address, storage.Key), + storage.Value.WithoutLeadingZeros().ToArray()); + } + StateProvider.Commit(CurrentSpec); + } + } + public bool FilterExists(int filterId) => _filterStore.FilterExists(filterId); public FilterType GetFilterType(int filterId) => _filterStore.GetFilterType(filterId); public FilterLog[] GetFilterLogs(int filterId) => _filterManager.GetLogs(filterId); diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index 0b39fac85b9..26c1a275a5e 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -8,6 +8,7 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Facade.Filters; +using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.Trie; using Block = Nethermind.Core.Block; @@ -23,6 +24,10 @@ public interface IBlockchainBridge : ILogFinder TxReceipt GetReceipt(Keccak txHash); (TxReceipt Receipt, UInt256? EffectiveGasPrice, int LogIndexStart) GetReceiptAndEffectiveGasPrice(Keccak txHash); (TxReceipt Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Keccak txHash); + + List MultiCall(BlockHeader header, MultiCallBlockStateCallsModel[] blocks, + CancellationToken cancellationToken); + BlockchainBridge.CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken); BlockchainBridge.CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken); BlockchainBridge.CallOutput CreateAccessList(BlockHeader header, Transaction tx, CancellationToken cancellationToken, bool optimize); diff --git a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs new file mode 100644 index 00000000000..2b9b9217239 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Nethermind.Core; +using Nethermind.Core.Collections; +using Nethermind.Evm.Tracing; +using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Int256; + +namespace Nethermind.Facade; + +public class MultiCallBlockTracer : IBlockTracer +{ + public List _results = new(); + + private List _txTracers = new(); + + private Block currentBlock; + public bool TraceDetails { get; set; } + public bool IsTracingRewards => false; + + public MultiCallBlockTracer(bool traceDetails= true) + { + TraceDetails = traceDetails; + } + + + public void ReportReward(Address author, string rewardType, UInt256 rewardValue) + { + throw new NotImplementedException(); + } + + public void StartNewBlockTrace(Block block) + { + _txTracers.Clear(); + currentBlock = block; + } + + public ITxTracer StartNewTxTrace(Transaction? tx) + { + if (tx != null && tx.Hash != null) + { + MultiCallTxTracer result = new(tx, TraceDetails); + _txTracers.Add(result); + return result; + } + + return NullTxTracer.Instance; + } + + public void EndTxTrace() + { + } + + public void EndBlockTrace() + { + MultiCallBlockResult? result = new() + { + Calls = _txTracers.Select(t => t.TraceResult).ToArray(), + Number = (ulong)currentBlock.Number, + Hash = currentBlock.Hash, + GasLimit = (ulong)currentBlock.GasLimit, + GasUsed = (ulong)currentBlock.GasUsed, + Timestamp = currentBlock.Timestamp, + FeeRecipient = currentBlock.Beneficiary, + baseFeePerGas = currentBlock.BaseFeePerGas, + + }; + result.Calls.ForEach(callResult => + { + callResult.Logs.ForEach(log => + { + log.BlockHash = currentBlock.Hash; + log.BlockNumber = (ulong)currentBlock.Number; + }); + }); + + _results.Add(result); + + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs similarity index 79% rename from src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs rename to src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs index 26041d0dc84..b33bf3133eb 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs @@ -3,23 +3,27 @@ using System; using System.Collections.Generic; +using System.Linq; using Nethermind.Abi; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Evm; using Nethermind.Evm.Tracing; +using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; -namespace Nethermind.JsonRpc.Modules.Eth.Multicall; +namespace Nethermind.Facade; -//Why this is not visitor like DDD... internal class MultiCallTxTracer : ITxTracer { private readonly List _extendedLogs; - public MultiCallTxTracer(Transaction t, List extendedLogs) + public MultiCallCallResult TraceResult { get; set; } + + public MultiCallTxTracer(Transaction t, bool logEvents = true) { - _extendedLogs = extendedLogs; + _extendedLogs = new(); + IsTracingEventLogs = logEvents; } public bool IsTracingState { get; } @@ -61,7 +65,7 @@ public void ReportStorageRead(in StorageCell storageCell) throw new NotImplementedException(); } - public bool IsTracingReceipt { get; } + public bool IsTracingReceipt => true; public bool IsTracingActions => true; public bool IsTracingOpLevelStorage { get; } public bool IsTracingMemory { get; } @@ -75,17 +79,47 @@ public void ReportStorageRead(in StorageCell storageCell) public bool IsTracing => IsTracingActions || IsTracingEventLogs; - public bool IsTracingEventLogs => true; + public bool IsTracingEventLogs { get; } public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) { - throw new NotImplementedException(); + TraceResult = new MultiCallCallResult() + { + GasUsed = (ulong)gasSpent, + Return = output, + Status = StatusCode.Success.ToString(), + Logs = _extendedLogs.Select((entry, i) => new Log + { + Data = entry.Data, + Address = entry.LoggersAddress, + Topics = entry.Topics, + LogIndex = (ulong)i + }).ToArray() + }; } public void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Keccak? stateRoot = null) { - throw new NotImplementedException(); + TraceResult = new MultiCallCallResult() + { + + GasUsed = (ulong)gasSpent, + Error = new Facade.Proxy.Models.MultiCall.Error + { + Code = StatusCode.Failure, + Message = error + }, + Return = output, + Status = StatusCode.Failure.ToString(), + Logs = _extendedLogs.Select((entry, i) => new Log + { + Data = entry.Data, + Address = entry.LoggersAddress, + Topics = entry.Topics, + LogIndex = (ulong)i + }).ToArray() + }; } public void StartOperation(int depth, long gas, Instruction opcode, int pc, bool isPostMerge = false) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index d7a70d48bb6..ab5564cb86f 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -1,8 +1,11 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; +using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; using Nethermind.Int256; namespace Nethermind.Facade.Proxy.Models.MultiCall; @@ -13,6 +16,56 @@ public class BlockOverride public UInt256 Number { get; set; } public UInt256 Time { get; set; } public ulong GasLimit { get; set; } - public Address FeeRecipient { get; set; } + public Address FeeRecipient { get; set; } = Address.Zero; public UInt256 BaseFee { get; set; } + + public BlockHeader GetBlockHeader(BlockHeader parent ) + { + ulong newTime = parent.Timestamp + 1; + if(0 == Time) {} + else if (Time <= ulong.MaxValue) + newTime = (ulong)Time; + else + throw new OverflowException("Time value is too large to be converted to ulong we use."); + + long newGasLimit = parent.GasLimit; + if (0 == GasLimit) { } + else if (GasLimit <= long.MaxValue) + newGasLimit = (long)GasLimit; + else + throw new OverflowException("GasLimit value is too large to be converted to long we use."); + + long newBlockNumber = parent.Number + 1; + if (0 == Number) { } + else if (Number <= long.MaxValue) + newBlockNumber = (long)Number; + else + throw new OverflowException("Block Number value is too large to be converted to long we use."); + + Address newFeeRecipientAddress = parent.Beneficiary; + if (FeeRecipient != Address.Zero) + { + newFeeRecipientAddress = FeeRecipient; + } + + var result = new BlockHeader( + parent.Hash, + Keccak.OfAnEmptySequenceRlp, + newFeeRecipientAddress, + UInt256.Zero, + newBlockNumber, + newGasLimit, + newTime, + Array.Empty()); + + result.MixHash = PrevRandao; + + //Note we treet parent block as such + result.BaseFeePerGas = BaseFee != 0 ? BaseFee : parent.BaseFeePerGas; + + UInt256 difficulty = ConstantDifficulty.One.Calculate(result, parent); + result.Difficulty = difficulty; + result.TotalDifficulty = parent.TotalDifficulty + difficulty; + return result; + } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs index 5cda1bad8b9..6c1f7b16a15 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs @@ -5,7 +5,7 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class MultiCallBlockStateCallsModel { - public BlockOverride BlockOverride { get; set; } + public BlockOverride? BlockOverride { get; set; } public AccountOverride[] StateOverrides { get; set; } public CallTransactionModel[] Calls { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs index e718760f4d4..2085dee77b2 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs @@ -9,9 +9,10 @@ public ResultType Type { get { + if (Error != null) return ResultType.Failure; + if (Logs != null) return ResultType.Success; - if (Return != null && Error != null) return ResultType.Failure; return ResultType.Invalid; } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs similarity index 70% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 15120e7294d..5543162f12a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Threading.Tasks; using Nethermind.Blockchain.Find; using Nethermind.Core; @@ -11,7 +12,9 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Modules.Eth; +using Nethermind.Serialization.Json; using NUnit.Framework; +using ResultType = Nethermind.Facade.Proxy.Models.MultiCall.ResultType; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -35,6 +38,74 @@ private Transaction GetTransferTxData(UInt256 Nonce, IEthereumEcdsa ethereumEcds return tx; } + [Test] + public async Task Test_eth_multicall_serialisation() + { + TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); + + + var pk = new PrivateKey("0xc7ba1a2892ec0ea1940eebeae739b1effe0543b3104469d5b66625f49ca86e94"); + + UInt256 nonceA = chain.State.GetNonce(pk.Address); + Transaction txMainnetAtoBtoFail = + GetTransferTxData(nonceA, + chain.EthereumEcdsa, pk, new Address("0xA143c0eA6f8059f7B3651417ccD2bAA80FC2d4Ab"), 10_000_000); + + UInt256 nextNonceA = nonceA++; + Transaction txMainnetAtoBToComplete = + GetTransferTxData(nextNonceA, + chain.EthereumEcdsa, pk, new Address("0xA143c0eA6f8059f7B3651417ccD2bAA80FC2d4Ab"), 4_000_000); + + + MultiCallBlockStateCallsModel[] requestMultiCall = + { + new() + { + BlockOverride = new BlockOverride() + { + Number = 18000000 + }, + Calls = new[] + { + CallTransactionModel.FromTransaction(txMainnetAtoBtoFail), + CallTransactionModel.FromTransaction(txMainnetAtoBToComplete), + }, + StateOverrides = new[] + { + new AccountOverride() + { + Address = pk.Address, + Balance = Math.Max(420_000_004_000_001UL, 1_000_000_004_000_001UL) + } + } + } + }; + EthereumJsonSerializer serializer = new(); + + string serializedCall = serializer.Serialize(requestMultiCall); + Console.WriteLine(serializedCall); + + + //Force persistancy of head block in main chain + chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not + EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + ResultWrapper result = + executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); + MultiCallBlockResult[] data = result.Data; + + Assert.AreEqual(1, data.Length); + + foreach (MultiCallBlockResult blockResult in data) + { + Assert.AreEqual(2, blockResult.Calls.Length); + Assert.AreEqual(blockResult.Calls[0].Type, ResultType.Failure); + Assert.AreEqual(blockResult.Calls[1].Type, ResultType.Success); + } + } + + /// /// This test verifies that a temporary forked blockchain can make transactions, blocks and report on them /// We test on blocks before current head and after it, @@ -105,7 +176,7 @@ public async Task Test_eth_multicall_eth_moved() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.SpecProvider, new JsonRpcConfig()); + EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); ResultWrapper result = executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); MultiCallBlockResult[] data = result.Data; @@ -177,7 +248,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() await chain.AddBlock(true, txMainnetAtoB); UInt256 after = chain.State.GetAccount(TestItem.AddressA).Balance; Assert.Less(after, before); - + TxReceipt recept = chain.Bridge.GetReceipt(txMainnetAtoB.Hash); LogEntry[]? ls = recept.Logs; @@ -186,10 +257,10 @@ public async Task Test_eth_multicall_transactions_forced_fail() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.SpecProvider, new JsonRpcConfig()); + EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + ResultWrapper result = executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); - Assert.AreEqual(ErrorCodes.InternalError, result.ErrorCode); - Assert.IsTrue(result.Result.Error.StartsWith("At block 123 got exception:")); + Assert.IsTrue(result.Data[1].Calls[0].Error.Message.StartsWith("numeric overflow")); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs similarity index 74% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 1e3a0f8dd9c..1a55b6c47be 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.Linq; +using System.Threading; using System.Threading.Tasks; using FluentAssertions; using Nethermind.Blockchain.Find; @@ -11,6 +13,7 @@ using Nethermind.Crypto; using Nethermind.Evm; using Nethermind.Evm.Precompiles; +using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; @@ -55,9 +58,7 @@ public async Task Test_eth_multicall_erc() .PushData(Bytes.FromHexString("0x20")) .PushData(Bytes.FromHexString("0x0")) .Op(Instruction.RETURN).Done; - MultiCallBlockStateCallsModel requestMultiCall = new(); - requestMultiCall.StateOverrides = - new[] { new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code } }; + // Step 1: Take an account Address account = TestItem.AddressA; @@ -80,6 +81,24 @@ await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, byte[] transactionData = EthRpcMulticallTests.GenerateTransactionDataForEcRecover(messageHash, v, r, s); + SystemTransaction systemTransactionForModifiedVM = new() + { + Data = transactionData, + To = contractAddress, + SenderAddress = TestItem.PublicKeyB.Address + }; + + systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); + MultiCallBlockStateCallsModel requestMultiCall = new() + { + StateOverrides = new[] + { + new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code } + + }, + Calls = new [] { CallTransactionModel.FromTransaction(systemTransactionForModifiedVM) } + }; + Address? mainChainRpcAddress = EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); @@ -89,35 +108,22 @@ await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, //Force persistancy of head block in main chain chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); - using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider, - EthRpcModule.MultiCallTxExecutor.GetMaxGas(new JsonRpcConfig()))) - { - Block? _ = tmpChain.ForgeChainBlock(requestMultiCall); - //Generate and send transaction - SystemTransaction systemTransactionForModifiedVM = new() - { - Data = transactionData, - To = contractAddress, - SenderAddress = TestItem.PublicKeyB.Address - }; - systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); - TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); - ResultWrapper responseFromModifiedVM = - tmpChain.EthRpcModule.eth_call(transactionForRpcOfModifiedVM, BlockParameter.Pending); - responseFromModifiedVM.ErrorCode.Should().Be(ErrorCodes.None); - - //Check results - byte[] addressBytes = Bytes.FromHexString(responseFromModifiedVM.Data) - .SliceWithZeroPaddingEmptyOnError(12, 20); - Address resultingAddress = new(addressBytes); - Assert.AreNotEqual(account, resultingAddress); - Assert.AreEqual(TestItem.AddressE, resultingAddress); - - //Note: real address can still be accessed - Address recoveredAddressOnMulticallChain = tmpChain.EthereumEcdsa.RecoverAddress(signature, messageHash); - Assert.AreEqual(TestItem.AddressA, recoveredAddressOnMulticallChain); - } + var result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, new[] { requestMultiCall }, CancellationToken.None); + var logs = result.First().Calls.First().Logs; + + //Check results + /* + byte[] addressBytes = Bytes.FromHexString(responseFromModifiedVM.Data) + .SliceWithZeroPaddingEmptyOnError(12, 20); + Address resultingAddress = new(addressBytes); + Assert.AreNotEqual(account, resultingAddress); + Assert.AreEqual(TestItem.AddressE, resultingAddress); + + //Note: real address can still be accessed + Address recoveredAddressOnMulticallChain = tmpChain.EthereumEcdsa.RecoverAddress(signature, messageHash); + Assert.AreEqual(TestItem.AddressA, recoveredAddressOnMulticallChain); + */ //Check that initial VM is intact mainChainRpcAddress = diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 946f81cb65a..e4403b484e9 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -114,6 +114,7 @@ protected override async Task Build(ISpecProvider? specProvider IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = new FilterManager(filterStore, BlockProcessor, TxPool, LimboLogs.Instance); var dbProvider = new ReadOnlyDbProvider(DbProvider, false); + ReadOnlyTxProcessingEnv processingEnv = new( dbProvider, new TrieStore(DbProvider.StateDb, LimboLogs.Instance).AsReadOnly(), @@ -121,8 +122,13 @@ protected override async Task Build(ISpecProvider? specProvider SpecProvider, LimboLogs.Instance); + IMultiCallBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + new ReadOnlyDbProvider(dbProvider, true), + SpecProvider, + LimboLogs.Instance); + ReceiptFinder ??= ReceiptStorage; - Bridge ??= new BlockchainBridge(processingEnv, TxPool, ReceiptFinder, filterStore, filterManager, EthereumEcdsa, Timestamper, LogFinder, SpecProvider, new BlocksConfig(), false); + Bridge ??= new BlockchainBridge(processingEnv, multiCallProcessingEnv, TxPool, ReceiptFinder, filterStore, filterManager, EthereumEcdsa, Timestamper, LogFinder, SpecProvider, new BlocksConfig(), false); BlockFinder ??= BlockTree; GasPriceOracle ??= new GasPriceOracle(BlockFinder, SpecProvider, LogManager); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index 13211562b0b..3b5f42ba76d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -90,14 +90,23 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, Transacti public class MultiCallTxExecutor { private readonly IDbProvider _dbProvider; + private readonly IBlockchainBridge _blockchainBridge; + private readonly IBlockFinder _blockFinder; private readonly IJsonRpcConfig _rpcConfig; private readonly ISpecProvider _specProvider; - public MultiCallTxExecutor(IDbProvider DbProvider, ISpecProvider specProvider, IJsonRpcConfig rpcConfig) + public MultiCallTxExecutor(IDbProvider DbProvider, + IBlockchainBridge blockchainBridge, + IBlockFinder blockFinder, + ISpecProvider specProvider, + IJsonRpcConfig rpcConfig) { _dbProvider = DbProvider; + _blockchainBridge = blockchainBridge; + _blockFinder = blockFinder; _specProvider = specProvider; _rpcConfig = rpcConfig; + } private UInt256 MaxGas => GetMaxGas(_rpcConfig); @@ -108,106 +117,26 @@ public static UInt256 GetMaxGas(IJsonRpcConfig config) return (UInt256)config.GasCap * (UInt256)config.GasCapMultiplier; } - //ToDO move to exctensions - private static IEnumerable Range(UInt256 start, UInt256 end) - { - for (UInt256 i = start; i <= end; i++) yield return i; - } - public ResultWrapper Execute(ulong version, MultiCallBlockStateCallsModel[] blockCallsToProcess, BlockParameter? blockParameter, bool traceTransfers) { - //Was not able to overcome all of the protections related to setting of new block as BlockTree head so will keep it fair for now + SearchResult searchResult = _blockFinder.SearchForHeader(blockParameter); + if (searchResult.IsError) return ResultWrapper.Fail(searchResult); - List results = new(); - using (MultiCallBlockchainFork tmpChain = new(_dbProvider, _specProvider, MaxGas)) + BlockHeader header = searchResult.Object; + if (!HasStateForBlock(_blockchainBridge, header)) { - IEnumerable? selsectResults = blockCallsToProcess.Select(model => - model.BlockOverride != null - ? model.BlockOverride.Number - : (ulong)tmpChain.LatestBlock.Header.Number + 1); - - List blockCalls = blockCallsToProcess - .OrderBy(model => - model.BlockOverride != null - ? model.BlockOverride.Number - : (ulong)tmpChain.LatestBlock.Header.Number + 1) - .ToList(); - - tmpChain.BlockTracer.Trace = traceTransfers; - ulong logIndices = 0; - foreach (MultiCallBlockStateCallsModel blockCall in blockCalls) - { - Block? block = null; - try - { - block = tmpChain.ForgeChainBlock(blockCall); - } - catch (Exception ex) - { - return ResultWrapper.Fail( - $"At block {(blockCall.BlockOverride != null ? blockCall.BlockOverride.Number : (ulong)tmpChain.LatestBlock.Header.Number + 1)} got exception: {ex.Message}\n{ex.StackTrace}"); - } - - if (selsectResults.Contains(blockCall.BlockOverride.Number)) - { - List? txResults = new(); - foreach (Transaction? tx in tmpChain.LatestBlock.Transactions) - { - TxReceipt Receipt = null; - Receipt = tmpChain.receiptStorage.Get(tmpChain.LatestBlock.Hash) - .ForTransaction(tx.Hash); - - - IEnumerable txActions = null; - - if (traceTransfers) - txActions = tmpChain.BlockTracer.TxActions[tx.Hash]; - else - txActions = Receipt.Logs; - - Log[] logs = txActions.Select(entry => new Log - { - Data = entry.Data, - Address = entry.LoggersAddress, - Topics = entry.Topics, - BlockHash = tmpChain.LatestBlock.Hash, - BlockNumber = (ulong)tmpChain.LatestBlock.Number, - LogIndex = ++logIndices - }).ToArray(); - - txResults.Add(new MultiCallCallResult - { - GasUsed = (ulong)Receipt.GasUsed, - Error = new Facade.Proxy.Models.MultiCall.Error - { - Data = (Receipt.Error.IsNullOrEmpty() ? Receipt.Error : "") ?? - string.Empty - }, - Return = Receipt.ReturnValue, - Status = Receipt.StatusCode.ToString(), - Logs = logs.ToArray() - } - ); - } - - MultiCallBlockResult? result = new() - { - baseFeePerGas = tmpChain.LatestBlock.BaseFeePerGas, - FeeRecipient = tmpChain.LatestBlock.Beneficiary, - GasLimit = (ulong)tmpChain.LatestBlock.GasLimit, - GasUsed = (ulong)tmpChain.LatestBlock.GasUsed, - Number = (ulong)tmpChain.LatestBlock.Number, - Hash = tmpChain.LatestBlock.Hash, - Timestamp = tmpChain.LatestBlock.Timestamp, - Calls = txResults.ToArray() - }; - results.Add(result); - } - } + return ResultWrapper.Fail($"No state available for block {header.Hash}", + ErrorCodes.ResourceUnavailable); } + using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); + + List results = _blockchainBridge.MultiCall(header.Clone(), + blockCallsToProcess, + cancellationTokenSource.Token); + return ResultWrapper.Success(results.ToArray()); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index afa16671cf6..ca25e30221b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -376,7 +376,7 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null, bool traceTransfers = true) { - return new MultiCallTxExecutor(_dbProvider, _specProvider, _rpcConfig) + return new MultiCallTxExecutor(_dbProvider, _blockchainBridge, _blockFinder, _specProvider, _rpcConfig) .Execute(version, blockCalls, blockParameter, traceTransfers); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs deleted file mode 100644 index cafaba94264..00000000000 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockTracer.cs +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Collections.Generic; -using Nethermind.Core; -using Nethermind.Core.Crypto; -using Nethermind.Evm.Tracing; -using Nethermind.Int256; - -namespace Nethermind.JsonRpc.Modules.Eth.Multicall; - -public class MultiCallBlockTracer : IBlockTracer -{ - public Dictionary> TxActions = new(); - public bool Trace { get; set; } - public bool IsTracingRewards => false; - - public void ReportReward(Address author, string rewardType, UInt256 rewardValue) - { - throw new NotImplementedException(); - } - - public void StartNewBlockTrace(Block block) - { - TxActions.Clear(); - } - - public ITxTracer StartNewTxTrace(Transaction? tx) - { - if (Trace && tx != null && tx.Hash != null) - { - List? actionsLog = new(); - TxActions[tx.Hash] = actionsLog; - return new MultiCallTxTracer(tx, actionsLog); - } - - return NullTxTracer.Instance; - } - - public void EndTxTrace() - { - } - - public void EndBlockTrace() - { - } -} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index 84f94cc5a28..d5644a5e8ed 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -23,6 +23,7 @@ using Nethermind.Crypto; using Nethermind.Db; using Nethermind.Db.Blooms; +using Nethermind.Evm; using Nethermind.Evm.CodeAnalysis; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; @@ -208,13 +209,19 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv new FilterManager(filterStore, BlockProcessor, txPool, logManager); //ToDO make use of our VM!!! - MultiCallReadOnlyTxProcessingEnv processingEnv = new(VirtualMachine, + ReadOnlyTxProcessingEnv processingEnv = new( new ReadOnlyDbProvider(DbProvider, false), new TrieStore(DbProvider.StateDb, logManager).AsReadOnly(), new ReadOnlyBlockTree(BlockTree), SpecProvider, logManager); + IMultiCallBlocksProcessingEnv mcProcessingEnv = + MultiCallReadOnlyBlocksProcessingEnv.Create( + new ReadOnlyDbProvider(DbProvider, true), + SpecProvider, + logManager); + BloomStorage bloomStorage = new(new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory()); ReceiptsRecovery receiptsRecovery = @@ -226,6 +233,7 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv bridge = new BlockchainBridge(processingEnv, + mcProcessingEnv, txPool, receiptFinder, filterStore, diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs deleted file mode 100644 index 1ff37d0f840..00000000000 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallReadOnlyTxProcessingEnv.cs +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Blockchain; -using Nethermind.Consensus.Processing; -using Nethermind.Core.Specs; -using Nethermind.Db; -using Nethermind.Evm.TransactionProcessing; -using Nethermind.Logging; -using Nethermind.Trie.Pruning; - -namespace Nethermind.JsonRpc.Modules.Eth.Multicall; - -internal class MultiCallReadOnlyTxProcessingEnv : ReadOnlyTxProcessingEnv -{ - public MultiCallReadOnlyTxProcessingEnv( - MultiCallVirtualMachine virtualMachine, - IReadOnlyDbProvider? readOnlyDbProvider, - IReadOnlyTrieStore? readOnlyTrieStore, - IReadOnlyBlockTree? readOnlyBlockTree, - ISpecProvider? specProvider, - ILogManager? logManager) : base(readOnlyDbProvider, readOnlyTrieStore, readOnlyBlockTree, specProvider, - logManager) - { - Machine = new MultiCallVirtualMachine(virtualMachine); - TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, Machine, logManager); - } -} From c816867e51b19b5c20eb975ced8b9897f1ac8f72 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 28 Jun 2023 06:39:20 +0100 Subject: [PATCH 023/213] fixing spaces --- .../Processing/IReadOnlyTxProcessingEnv.cs | 2 +- .../Processing/MultiCallReadOnlyBlocksProcessingEnv.cs | 2 +- .../Processing/ReadOnlyTxProcessingEnv.cs | 2 +- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 2 +- src/Nethermind/Nethermind.Facade/BlockchainBridge.cs | 8 ++++---- src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs | 6 +++--- src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs | 2 +- .../Proxy/Models/MultiCall/BlockOverride.cs | 6 +++--- .../Multicall/EthMulticallTestsBlocksAndTransactions.cs | 4 ++-- .../Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs | 6 +++--- .../Modules/Eth/EthModule.TransactionExecutor.cs | 2 +- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs index 9fd6c853900..a3b84331ed0 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs @@ -5,7 +5,7 @@ namespace Nethermind.Consensus.Processing; -public interface IReadOnlyTxProcessingEnv: IReadOnlyTxProcessorSource, IReadOnlyTxProcessingEnvBase +public interface IReadOnlyTxProcessingEnv : IReadOnlyTxProcessorSource, IReadOnlyTxProcessingEnvBase { ITransactionProcessor TransactionProcessor { get; set; } } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs index d2dd653d0e1..90327022a23 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -67,7 +67,7 @@ private MultiCallReadOnlyBlocksProcessingEnv( ILogManager? logManager) : base(readOnlyDbProvider, trieStore, blockTree, logManager) { - + _trieStore = trieStore; _logManager = logManager; SpecProvider = specProvider; diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index 2e316034a4d..2f2d49abd67 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -37,7 +37,7 @@ public ReadOnlyTxProcessingEnv( IReadOnlyBlockTree? blockTree, ISpecProvider? specProvider, ILogManager? logManager - ): base(readOnlyDbProvider, trieStore, blockTree, logManager) + ) : base(readOnlyDbProvider, trieStore, blockTree, logManager) { IVirtualMachine machine = new VirtualMachine(BlockhashProvider, specProvider, logManager); TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, machine, logManager); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index b4ef058c2e9..1a307217c82 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -34,6 +34,6 @@ public ReadOnlyTxProcessingEnvBase( BlockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); BlockhashProvider = new BlockhashProvider(BlockTree, logManager); - + } } diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index ed9aa6820b8..4105b019b97 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -183,7 +183,7 @@ public List MultiCall(BlockHeader header, MultiCallBlockSt MultiCallBlockTracer multiCallOutputTracer = new(); MultiCallTrace(header, blocks, multiCallOutputTracer.WithCancellation(cancellationToken)); - + return multiCallOutputTracer._results; } @@ -323,7 +323,7 @@ public void MultiCallTrace(BlockHeader parent, MultiCallBlockStateCallsModel[] b startStateRoot = searchResult.StateRoot; } } - + foreach (MultiCallBlockStateCallsModel? callInputBlock in blocks) { BlockHeader callHeader = null; @@ -346,7 +346,7 @@ public void MultiCallTrace(BlockHeader parent, MultiCallBlockStateCallsModel[] b } env.StateProvider.StateRoot = parent.StateRoot; - + IReleaseSpec releaseSpec = _specProvider.GetSpec(parent); if (releaseSpec.IsEip4844Enabled) @@ -357,7 +357,7 @@ public void MultiCallTrace(BlockHeader parent, MultiCallBlockStateCallsModel[] b callHeader.MixHash = parent.MixHash; callHeader.IsPostMerge = parent.Difficulty == 0; - + var transactions = callInputBlock.Calls.Select(model => model.GetTransaction()).ToList(); foreach (Transaction transaction in transactions) { diff --git a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs index 2b9b9217239..7e5b4735a3c 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs @@ -20,10 +20,10 @@ public class MultiCallBlockTracer : IBlockTracer private List _txTracers = new(); private Block currentBlock; - public bool TraceDetails { get; set; } + public bool TraceDetails { get; set; } public bool IsTracingRewards => false; - public MultiCallBlockTracer(bool traceDetails= true) + public MultiCallBlockTracer(bool traceDetails = true) { TraceDetails = traceDetails; } @@ -68,7 +68,7 @@ public void EndBlockTrace() Timestamp = currentBlock.Timestamp, FeeRecipient = currentBlock.Beneficiary, baseFeePerGas = currentBlock.BaseFeePerGas, - + }; result.Calls.ForEach(callResult => { diff --git a/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs index b33bf3133eb..b1ac894a507 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs @@ -103,7 +103,7 @@ public void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string { TraceResult = new MultiCallCallResult() { - + GasUsed = (ulong)gasSpent, Error = new Facade.Proxy.Models.MultiCall.Error { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index ab5564cb86f..45d5587a457 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -19,10 +19,10 @@ public class BlockOverride public Address FeeRecipient { get; set; } = Address.Zero; public UInt256 BaseFee { get; set; } - public BlockHeader GetBlockHeader(BlockHeader parent ) + public BlockHeader GetBlockHeader(BlockHeader parent) { ulong newTime = parent.Timestamp + 1; - if(0 == Time) {} + if (0 == Time) { } else if (Time <= ulong.MaxValue) newTime = (ulong)Time; else @@ -62,7 +62,7 @@ public BlockHeader GetBlockHeader(BlockHeader parent ) //Note we treet parent block as such result.BaseFeePerGas = BaseFee != 0 ? BaseFee : parent.BaseFeePerGas; - + UInt256 difficulty = ConstantDifficulty.One.Calculate(result, parent); result.Difficulty = difficulty; result.TotalDifficulty = parent.TotalDifficulty + difficulty; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 5543162f12a..97c1005a01c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -176,7 +176,7 @@ public async Task Test_eth_multicall_eth_moved() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); ResultWrapper result = executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); MultiCallBlockResult[] data = result.Data; @@ -248,7 +248,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() await chain.AddBlock(true, txMainnetAtoB); UInt256 after = chain.State.GetAccount(TestItem.AddressA).Balance; Assert.Less(after, before); - + TxReceipt recept = chain.Bridge.GetReceipt(txMainnetAtoB.Hash); LogEntry[]? ls = recept.Logs; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 1a55b6c47be..03178528db6 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -93,10 +93,10 @@ await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, { StateOverrides = new[] { - new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code } + new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code } }, - Calls = new [] { CallTransactionModel.FromTransaction(systemTransactionForModifiedVM) } + Calls = new[] { CallTransactionModel.FromTransaction(systemTransactionForModifiedVM) } }; @@ -111,7 +111,7 @@ await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, var result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, new[] { requestMultiCall }, CancellationToken.None); var logs = result.First().Calls.First().Logs; - + //Check results /* byte[] addressBytes = Bytes.FromHexString(responseFromModifiedVM.Data) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs index 3b5f42ba76d..9c45e4b98db 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModule.TransactionExecutor.cs @@ -136,7 +136,7 @@ public ResultWrapper Execute(ulong version, List results = _blockchainBridge.MultiCall(header.Clone(), blockCallsToProcess, cancellationTokenSource.Token); - + return ResultWrapper.Success(results.ToArray()); } } From c094898c1aec834621dff89a0435b798944e1ec5 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 28 Jun 2023 07:36:56 +0100 Subject: [PATCH 024/213] Post merge fixes --- .../Nethermind.Evm/VirtualMachine.cs | 4 +- .../Eth/EthRpcModule.TransactionExecutor.cs | 58 +++++++++++++++++++ .../Modules/Eth/EthRpcModule.cs | 2 + .../Eth/Multicall/MultiCallBlockchainFork.cs | 1 - 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 5f3e62faf34..920f9271a20 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -57,7 +57,7 @@ public VirtualMachine( } } - public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec spec) + public virtual CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec spec) => _evm.GetCachedCodeInfo(worldState, codeSource, spec); public TransactionSubstate Run(EvmState state, IWorldState worldState, ITxTracer txTracer) @@ -479,7 +479,7 @@ private void RevertParityTouchBugAccount(IReleaseSpec spec) } } - public virtual CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) + public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) { if (codeSource.IsPrecompile(vmSpec)) { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 8ff24d73ed1..4f7cc991ea8 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -2,13 +2,17 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Generic; using System.Threading; using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Eip2930; using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Db; using Nethermind.Evm; using Nethermind.Facade; +using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.Specs.Forks; @@ -59,6 +63,60 @@ public ResultWrapper ExecuteTx( protected ResultWrapper GetInputError(BlockchainBridge.CallOutput result) => ResultWrapper.Fail(result.Error, ErrorCodes.InvalidInput); } + public class MultiCallTxExecutor + { + private readonly IDbProvider _dbProvider; + private readonly IBlockchainBridge _blockchainBridge; + private readonly IBlockFinder _blockFinder; + private readonly IJsonRpcConfig _rpcConfig; + private readonly ISpecProvider _specProvider; + + public MultiCallTxExecutor(IDbProvider DbProvider, + IBlockchainBridge blockchainBridge, + IBlockFinder blockFinder, + ISpecProvider specProvider, + IJsonRpcConfig rpcConfig) + { + _dbProvider = DbProvider; + _blockchainBridge = blockchainBridge; + _blockFinder = blockFinder; + _specProvider = specProvider; + _rpcConfig = rpcConfig; + + } + + private UInt256 MaxGas => GetMaxGas(_rpcConfig); + + + public static UInt256 GetMaxGas(IJsonRpcConfig config) + { + return (UInt256)config.GasCap * (UInt256)config.GasCapMultiplier; + } + + public ResultWrapper Execute(ulong version, + MultiCallBlockStateCallsModel[] blockCallsToProcess, + BlockParameter? blockParameter, bool traceTransfers) + { + SearchResult searchResult = _blockFinder.SearchForHeader(blockParameter); + if (searchResult.IsError) return ResultWrapper.Fail(searchResult); + + BlockHeader header = searchResult.Object; + if (!HasStateForBlock(_blockchainBridge, header)) + { + return ResultWrapper.Fail($"No state available for block {header.Hash}", + ErrorCodes.ResourceUnavailable); + } + + using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); + + List results = _blockchainBridge.MultiCall(header.Clone(), + blockCallsToProcess, + cancellationTokenSource.Token); + + return ResultWrapper.Success(results.ToArray()); + } + } + private class CallTxExecutor : TxExecutor { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 2e212182266..4b3f6a035ad 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -39,6 +39,8 @@ namespace Nethermind.JsonRpc.Modules.Eth; + + public partial class EthRpcModule : IEthRpcModule { private readonly Encoding _messageEncoding = Encoding.UTF8; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs index d5644a5e8ed..cdeff44708c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs @@ -266,7 +266,6 @@ public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProv txPool, txSender, wallet, - receiptFinder, logManager, SpecProvider, gasPriceOracle, From f0b56463e97484f8b054a1ec3953560abd011783 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 29 Jun 2023 13:13:05 +0100 Subject: [PATCH 025/213] Fixing tests --- ...ulticallTestsPrecompilesWithRedirection.cs | 1 + .../Modules/Eth/EthRpcMulticallTests.cs | 1 + .../EthMulticallTestsBlocksAndTransactions.cs | 8 +-- .../Nethermind.JsonRpc/JsonRpcService.cs | 13 +++- .../Eth/EthRpcModule.TransactionExecutor.cs | 54 --------------- .../Modules/Eth/EthRpcModule.cs | 4 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 65 +++++++++++++++++++ 7 files changed, 84 insertions(+), 62 deletions(-) create mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 3508dfd4ef1..f73a0d214ca 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -12,6 +12,7 @@ using Nethermind.Evm.Precompiles; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; +using Nethermind.JsonRpc.Modules.Eth; using Nethermind.JsonRpc.Modules.Eth.Multicall; using NUnit.Framework; using static Nethermind.JsonRpc.Modules.Eth.EthRpcModule; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs index bfeac6000be..d42559f22bd 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs @@ -18,6 +18,7 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; +using Nethermind.JsonRpc.Modules.Eth; using Nethermind.JsonRpc.Modules.Eth.Multicall; using Nethermind.KeyStore; using Nethermind.KeyStore.Config; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 97c1005a01c..23c0ad667c3 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -90,7 +90,7 @@ public async Task Test_eth_multicall_serialisation() chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); ResultWrapper result = executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); MultiCallBlockResult[] data = result.Data; @@ -176,7 +176,7 @@ public async Task Test_eth_multicall_eth_moved() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); ResultWrapper result = executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); MultiCallBlockResult[] data = result.Data; @@ -257,10 +257,10 @@ public async Task Test_eth_multicall_transactions_forced_fail() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - EthRpcModule.MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); ResultWrapper result = executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); - Assert.IsTrue(result.Data[1].Calls[0].Error.Message.StartsWith("numeric overflow")); + Assert.IsTrue(result.Data[1].Calls[0].Error.Message.StartsWith("insufficient")); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs index 3bed9ae8e00..6a976e4de44 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs @@ -320,7 +320,18 @@ private void LogRequest(string methodName, string?[] providedParameters, Paramet } else { - executionParam = _serializer.Deserialize(new JsonTextReader(new StringReader($"\"{providedParameter}\"")), paramType); + if (providedParameter.StartsWith("\"") && providedParameter.EndsWith("\"")) + { + executionParam = + _serializer.Deserialize( + new JsonTextReader(new StringReader(providedParameter)), paramType); + } + else + { + executionParam = + _serializer.Deserialize( + new JsonTextReader(new StringReader($"\"{providedParameter}\"")), paramType); + } } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 4f7cc991ea8..c1daa28255d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -63,60 +63,6 @@ public ResultWrapper ExecuteTx( protected ResultWrapper GetInputError(BlockchainBridge.CallOutput result) => ResultWrapper.Fail(result.Error, ErrorCodes.InvalidInput); } - public class MultiCallTxExecutor - { - private readonly IDbProvider _dbProvider; - private readonly IBlockchainBridge _blockchainBridge; - private readonly IBlockFinder _blockFinder; - private readonly IJsonRpcConfig _rpcConfig; - private readonly ISpecProvider _specProvider; - - public MultiCallTxExecutor(IDbProvider DbProvider, - IBlockchainBridge blockchainBridge, - IBlockFinder blockFinder, - ISpecProvider specProvider, - IJsonRpcConfig rpcConfig) - { - _dbProvider = DbProvider; - _blockchainBridge = blockchainBridge; - _blockFinder = blockFinder; - _specProvider = specProvider; - _rpcConfig = rpcConfig; - - } - - private UInt256 MaxGas => GetMaxGas(_rpcConfig); - - - public static UInt256 GetMaxGas(IJsonRpcConfig config) - { - return (UInt256)config.GasCap * (UInt256)config.GasCapMultiplier; - } - - public ResultWrapper Execute(ulong version, - MultiCallBlockStateCallsModel[] blockCallsToProcess, - BlockParameter? blockParameter, bool traceTransfers) - { - SearchResult searchResult = _blockFinder.SearchForHeader(blockParameter); - if (searchResult.IsError) return ResultWrapper.Fail(searchResult); - - BlockHeader header = searchResult.Object; - if (!HasStateForBlock(_blockchainBridge, header)) - { - return ResultWrapper.Fail($"No state available for block {header.Hash}", - ErrorCodes.ResourceUnavailable); - } - - using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); - - List results = _blockchainBridge.MultiCall(header.Clone(), - blockCallsToProcess, - cancellationTokenSource.Token); - - return ResultWrapper.Success(results.ToArray()); - } - } - private class CallTxExecutor : TxExecutor { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 4b3f6a035ad..aaa45c7bb34 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -39,8 +39,6 @@ namespace Nethermind.JsonRpc.Modules.Eth; - - public partial class EthRpcModule : IEthRpcModule { private readonly Encoding _messageEncoding = Encoding.UTF8; @@ -59,7 +57,7 @@ public partial class EthRpcModule : IEthRpcModule private readonly IFeeHistoryOracle _feeHistoryOracle; private readonly IDbProvider _dbProvider; - private static bool HasStateForBlock(IBlockchainBridge blockchainBridge, BlockHeader header) + public static bool HasStateForBlock(IBlockchainBridge blockchainBridge, BlockHeader header) { RootCheckVisitor rootCheckVisitor = new(); blockchainBridge.RunTreeVisitor(rootCheckVisitor, header.StateRoot!); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs new file mode 100644 index 00000000000..2ced7cec601 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -0,0 +1,65 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using System.Threading; +using Nethermind.Blockchain.Find; +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Db; +using Nethermind.Facade; +using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Int256; + +namespace Nethermind.JsonRpc.Modules.Eth; +public class MultiCallTxExecutor +{ + private readonly IDbProvider _dbProvider; + private readonly IBlockchainBridge _blockchainBridge; + private readonly IBlockFinder _blockFinder; + private readonly IJsonRpcConfig _rpcConfig; + private readonly ISpecProvider _specProvider; + + public MultiCallTxExecutor(IDbProvider DbProvider, + IBlockchainBridge blockchainBridge, + IBlockFinder blockFinder, + ISpecProvider specProvider, + IJsonRpcConfig rpcConfig) + { + _dbProvider = DbProvider; + _blockchainBridge = blockchainBridge; + _blockFinder = blockFinder; + _specProvider = specProvider; + _rpcConfig = rpcConfig; + } + + private UInt256 MaxGas => GetMaxGas(_rpcConfig); + + public static UInt256 GetMaxGas(IJsonRpcConfig config) + { + return (UInt256)config.GasCap * (UInt256)config.GasCapMultiplier; + } + + public ResultWrapper Execute(ulong version, + MultiCallBlockStateCallsModel[] blockCallsToProcess, + BlockParameter? blockParameter, bool traceTransfers) + { + SearchResult searchResult = _blockFinder.SearchForHeader(blockParameter); + if (searchResult.IsError) return ResultWrapper.Fail(searchResult); + + BlockHeader header = searchResult.Object; + if (!EthRpcModule.HasStateForBlock(_blockchainBridge, header)) + { + return ResultWrapper.Fail($"No state available for block {header.Hash}", + ErrorCodes.ResourceUnavailable); + } + + using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); + + List results = _blockchainBridge.MultiCall(header.Clone(), + blockCallsToProcess, + cancellationTokenSource.Token); + + return ResultWrapper.Success(results.ToArray()); + } +} From abc59c3da39773e6e5e685df27d037b989e18144 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 29 Jun 2023 13:35:59 +0100 Subject: [PATCH 026/213] finalising transfer to Env based approach Removed Chain Fork related code --- ...ulticallTestsPrecompilesWithRedirection.cs | 87 ++- ...llTests.cs => EthRpcMulticallTestsBase.cs} | 78 +-- .../EthMulticallTestsBlocksAndTransactions.cs | 6 +- .../EthMulticallTestsSimplePrecompiles.cs | 15 +- .../Eth/Multicall/MultiCallBlockchainFork.cs | 520 ------------------ 5 files changed, 48 insertions(+), 658 deletions(-) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/{EthRpcMulticallTests.cs => EthRpcMulticallTestsBase.cs} (65%) delete mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index f73a0d214ca..c8b7efcab77 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -2,20 +2,16 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Threading.Tasks; -using FluentAssertions; using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; -using Nethermind.Crypto; using Nethermind.Evm; using Nethermind.Evm.Precompiles; +using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; -using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; -using Nethermind.JsonRpc.Modules.Eth.Multicall; using NUnit.Framework; -using static Nethermind.JsonRpc.Modules.Eth.EthRpcModule; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -27,7 +23,7 @@ public class EthMulticallTestsPrecompilesWithRedirection [Test] public async Task Test_eth_multicall_ecr_moved() { - TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); //The following opcodes code is based on the following contract compiled: /* function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns(address) @@ -78,12 +74,26 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( .PushData(new byte[] { 0 }) .Op(Instruction.RETURN) .Done; - //derive from receipt tracer - //emmit additional log with ffff eth movement logs - //gascap - MultiCallBlockStateCallsModel requestMultiCall = new(); - requestMultiCall.StateOverrides = - new[] + + Address realSenderAccount = TestItem.AddressA; + byte[] transactionData = EthRpcMulticallTestsBase.GetTxData(chain, TestItem.PrivateKeyA); + + Address? contractAddress = await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, + EthMulticallTestsSimplePrecompiles.EcRecoverCallerContractBytecode); + + Address? mainChainRpcAddress = + EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + + Transaction systemTransactionForModifiedVM = new() + { + Data = transactionData, + To = contractAddress, + SenderAddress = TestItem.PublicKeyB.Address + }; + + MultiCallBlockStateCallsModel requestMultiCall = new() + { + StateOverrides = new[] { new AccountOverride { @@ -91,49 +101,30 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( Code = code, MoveToAddress = new Address("0x0000000000000000000000000000000000000666") } - }; - - Address realSenderAccount = TestItem.AddressA; - byte[] transactionData = EthRpcMulticallTests.GetTxData(chain, TestItem.PrivateKeyA); - - Address? contractAddress = await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, - EthMulticallTestsSimplePrecompiles.EcRecoverCallerContractBytecode); + }, + Calls = new[] + { + CallTransactionModel.FromTransaction(systemTransactionForModifiedVM) + } + }; - Address? mainChainRpcAddress = - EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); //Force persistancy of head block in main chain chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider, - MultiCallTxExecutor.GetMaxGas(new JsonRpcConfig()))) - { - Block _ = tmpChain.ForgeChainBlock(requestMultiCall); + MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + + ResultWrapper result = + executor.Execute(1, new[] { requestMultiCall }, BlockParameter.Latest, true); + + + //Check results + byte[] addressBytes = result.Data[0].Calls[0].Return + .SliceWithZeroPaddingEmptyOnError(12, 20); + Address resultingAddress = new(addressBytes); + Assert.AreEqual(realSenderAccount, resultingAddress); - //Generate and send transaction (shall be mocked) - SystemTransaction systemTransactionForModifiedVM = new() - { - Data = transactionData, - To = contractAddress, - SenderAddress = TestItem.PublicKeyB.Address - }; - systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); - TransactionForRpc transactionForRpcOfModifiedVM = new(systemTransactionForModifiedVM); - ResultWrapper responseFromModifiedVM = - tmpChain.EthRpcModule.eth_call(transactionForRpcOfModifiedVM, BlockParameter.Pending); - responseFromModifiedVM.ErrorCode.Should().Be(ErrorCodes.None); - - - //Check results - byte[] addressBytes = Bytes.FromHexString(responseFromModifiedVM.Data) - .SliceWithZeroPaddingEmptyOnError(12, 20); - Address resultingAddress = new(addressBytes); - - //Address expectedMockResultAddress = new Address("0x0000000000000000000000000000000000011111"); - //We redirect to 666 so it will return correct data - Assert.AreEqual(realSenderAccount, resultingAddress); - } } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs similarity index 65% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs index d42559f22bd..a386cfc2144 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs @@ -12,30 +12,22 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; -using Nethermind.Core.Test.Builders; using Nethermind.Core.Test.IO; using Nethermind.Crypto; -using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; -using Nethermind.JsonRpc.Modules.Eth; -using Nethermind.JsonRpc.Modules.Eth.Multicall; using Nethermind.KeyStore; using Nethermind.KeyStore.Config; using Nethermind.Logging; using Nethermind.Serialization.Json; using Nethermind.Specs; using Nethermind.Specs.Forks; -using Nethermind.Trie.Pruning; using Nethermind.TxPool; using Nethermind.Wallet; -using NUnit.Framework; -using static Nethermind.JsonRpc.Modules.Eth.EthRpcModule; -using ResultType = Nethermind.Core.ResultType; namespace Nethermind.JsonRpc.Test.Modules.Eth; -public class EthRpcMulticallTests +public class EthRpcMulticallTestsBase { public static Task CreateChain(IReleaseSpec? releaseSpec = null, UInt256? initialBaseFeePerGas = null) @@ -213,72 +205,4 @@ public static byte[] GenerateTransactionDataForEcRecover(Keccak keccak, ulong @u return mainChainRpcAddress; } - /// - /// This test verifies that a temporary forked blockchain updates the user balance and block number - /// independently of the main chain, ensuring the main chain remains intact. - /// - [Test] - public async Task Test_eth_multicall_account_data() - { - TestRpcBlockchain chain = await CreateChain(); - - MultiCallBlockStateCallsModel requestBlockOne = new() - { - StateOverrides = new[] { new AccountOverride { Address = TestItem.AddressA, Balance = UInt256.One } } - }; - - - long blockNumberBefore = chain.BlockFinder.Head.Number; - ResultWrapper userBalanceBefore = - await chain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); - userBalanceBefore.Result.ResultType.Should().Be(ResultType.Success); - - //Force persistancy of head block in main chain - chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); - chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); - - TrieStore tt = chain.TrieStore; - using (MultiCallBlockchainFork tmpChain = new(chain.DbProvider, chain.SpecProvider, - MultiCallTxExecutor.GetMaxGas(new JsonRpcConfig()))) - { - //Check if tmpChain initialised - Assert.AreEqual(chain.BlockTree.BestKnownNumber, tmpChain.BlockTree.BestKnownNumber); - Assert.AreEqual(chain.BlockFinder.BestPersistedState, tmpChain.BlockFinder.BestPersistedState); - Assert.AreEqual(chain.BlockFinder.Head.Number, tmpChain.BlockFinder.Head.Number); - - //Check if tmpChain RPC initialised - ResultWrapper userBalanceBefore_fromTmp = - await tmpChain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); - userBalanceBefore_fromTmp.Result.ResultType.Should().Be(ResultType.Success); - - //Check if tmpChain shows same values as main one - UInt256 num_real = userBalanceBefore.Data.Value; - UInt256 num_tmp = userBalanceBefore_fromTmp.Data.Value; - Assert.AreEqual(userBalanceBefore_fromTmp.Data, userBalanceBefore.Data); - - Block? _ = tmpChain.ForgeChainBlock(requestBlockOne); - - //Check block has updated values in tmp chain - ResultWrapper userBalanceResult_fromTm = - await tmpChain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); - userBalanceResult_fromTm.Result.ResultType.Should().Be(ResultType.Success); - UInt256 tval = tmpChain.StateProvider.GetBalance(TestItem.AddressA); - - Assert.AreNotEqual(userBalanceResult_fromTm.Data, userBalanceBefore.Data); - - //Check block has not updated values in the main chain - ResultWrapper userBalanceResult = - await chain.EthRpcModule.eth_getBalance(TestItem.AddressA, BlockParameter.Latest); - userBalanceResult.Result.ResultType.Should().Be(ResultType.Success); - Assert.AreEqual(userBalanceResult.Data, userBalanceBefore.Data); //Main chain is intact - Assert.AreNotEqual(userBalanceResult.Data, userBalanceResult_fromTm.Data); // Balance was changed - Assert.AreNotEqual(chain.BlockFinder.Head.Number, tmpChain.LatestBlock.Number); // Block number changed - } - - GC.Collect(); - GC.WaitForFullGCComplete(); - - Assert.AreEqual(chain.BlockFinder.Head.Number, - blockNumberBefore); // tmp chain is disposed, main chain block number is still the same - } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 23c0ad667c3..c20e6668398 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -41,7 +41,7 @@ private Transaction GetTransferTxData(UInt256 Nonce, IEthereumEcdsa ethereumEcds [Test] public async Task Test_eth_multicall_serialisation() { - TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); var pk = new PrivateKey("0xc7ba1a2892ec0ea1940eebeae739b1effe0543b3104469d5b66625f49ca86e94"); @@ -114,7 +114,7 @@ public async Task Test_eth_multicall_serialisation() [Test] public async Task Test_eth_multicall_eth_moved() { - TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); UInt256 nonceA = chain.State.GetNonce(TestItem.AddressA); Transaction txMainnetAtoB = @@ -195,7 +195,7 @@ public async Task Test_eth_multicall_eth_moved() [Test] public async Task Test_eth_multicall_transactions_forced_fail() { - TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); UInt256 nonceA = chain.State.GetNonce(TestItem.AddressA); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 03178528db6..f246b38aa50 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -4,8 +4,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using FluentAssertions; -using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; @@ -15,9 +13,6 @@ using Nethermind.Evm.Precompiles; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; -using Nethermind.JsonRpc.Data; -using Nethermind.JsonRpc.Modules.Eth; -using Nethermind.JsonRpc.Modules.Eth.Multicall; using NUnit.Framework; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -48,7 +43,7 @@ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure return [Test] public async Task Test_eth_multicall_erc() { - TestRpcBlockchain chain = await EthRpcMulticallTests.CreateChain(); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); //Empose Opcode instead of EcRecoverPrecompile, it returns const TestItem.AddressE address byte[] code = Prepare.EvmCode @@ -72,14 +67,14 @@ public async Task Test_eth_multicall_erc() byte[] s = signature.S; Address? contractAddress = - await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, + await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EcRecoverCallerContractBytecode); //Check real address Address recoveredAddress = chain.EthereumEcdsa.RecoverAddress(signature, messageHash); Assert.AreEqual(TestItem.AddressA, recoveredAddress); - byte[] transactionData = EthRpcMulticallTests.GenerateTransactionDataForEcRecover(messageHash, v, r, s); + byte[] transactionData = EthRpcMulticallTestsBase.GenerateTransactionDataForEcRecover(messageHash, v, r, s); SystemTransaction systemTransactionForModifiedVM = new() { @@ -101,7 +96,7 @@ await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, Address? mainChainRpcAddress = - EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); Assert.NotNull(mainChainRpcAddress); Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); @@ -127,7 +122,7 @@ await EthRpcMulticallTests.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, //Check that initial VM is intact mainChainRpcAddress = - EthRpcMulticallTests.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); Assert.NotNull(mainChainRpcAddress); Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs deleted file mode 100644 index cdeff44708c..00000000000 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/Multicall/MultiCallBlockchainFork.cs +++ /dev/null @@ -1,520 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using Nethermind.Blockchain; -using Nethermind.Blockchain.Filters; -using Nethermind.Blockchain.Find; -using Nethermind.Blockchain.Receipts; -using Nethermind.Blockchain.Synchronization; -using Nethermind.Config; -using Nethermind.Consensus; -using Nethermind.Consensus.Comparers; -using Nethermind.Consensus.Processing; -using Nethermind.Consensus.Rewards; -using Nethermind.Consensus.Validators; -using Nethermind.Core; -using Nethermind.Core.Crypto; -using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; -using Nethermind.Crypto; -using Nethermind.Db; -using Nethermind.Db.Blooms; -using Nethermind.Evm; -using Nethermind.Evm.CodeAnalysis; -using Nethermind.Evm.TransactionProcessing; -using Nethermind.Facade; -using Nethermind.Facade.Eth; -using Nethermind.Facade.Proxy.Models; -using Nethermind.Facade.Proxy.Models.MultiCall; -using Nethermind.Int256; -using Nethermind.JsonRpc.Modules.Eth.FeeHistory; -using Nethermind.JsonRpc.Modules.Eth.GasPrice; -using Nethermind.Logging; -using Nethermind.State; -using Nethermind.State.Repositories; -using Nethermind.Synchronization.ParallelSync; -using Nethermind.Trie.Pruning; -using Nethermind.TxPool; -using Nethermind.Wallet; - -namespace Nethermind.JsonRpc.Modules.Eth.Multicall; - -/// -/// The MultiCallBlockchainFork class enables the creation of temporary in-memory blockchain instances, -/// based on a base chain's state. It's useful for simulating transactions, testing, -/// and executing smart contracts without affecting the base chain. The class offers RPC, -/// StateProvider, and StorageProvider utilities for swift chain data manipulation -/// and supports multi-block chain simulations using CreateBlock/FinaliseBlock pair manually or ForgeChainBlock method. -/// -public class MultiCallBlockchainFork : IDisposable -{ - private UInt256 _maxGas; - - //todo remove public useless bridge - public BlockchainBridge bridge; - - public InMemoryReceiptStorage receiptStorage; - - - //TODO: throw away and replace with ...Env related stuff based implementations (decompose, remove unused functions) - /// - /// Creates a MultiCallBlockchainFork instance with the following steps: - /// 1. Initialize MultiCallBlockchainFork object - /// 2. Create read-only in-memory databases - /// 3. Set spec provider - /// 4. Set up log manager - /// 5. Establish EthereumEcdsa - /// 6. Configure TrieStore, StateProvider, and StorageProvider - /// 7. Prepare state reader - /// 8. Instantiate BlockTree - /// 9. Launch read-only state provider - /// 10. Create transaction comparer provider and transaction pool - /// 11. Start receipt storage - /// 12. Initialize virtual machine - /// 13. Initialize transaction processor and block preprocessor step - /// 14. Initialize header and block validators - /// 15. Initialize block processor - /// 16. Initialize and start chain processor - /// 17. Create and initialize temp database provider for RPC calls - /// 18. Initialize filter store and manager - /// 19. Set up read-only processing environment - /// 20. Initialize Bloom storage and log finder - /// 21. Set up timestamper, blockchain bridge, and gas price oracle - /// 22. Configure fee history oracle and sync config - /// 23. Initialize nonce manager, wallet, and transaction signer - /// 24. Create transaction sealer and sender - /// 25. Set up EthRpcModule - /// - /// Current state database - /// Current Block database - /// Current Header database - /// Current Block information database - /// Current Code database - /// Specification provider (optional) - /// MultiCallBlockchainFork instance - public MultiCallBlockchainFork(IDbProvider oldDbProvider, ISpecProvider specProvider, UInt256 MaxGas) - { - _maxGas = MaxGas; - BlockTracer = new MultiCallBlockTracer(); - //Init BlockChain - //Writable inMemory DBs on with access to the data of existing ones (will not modify existing data) - if (oldDbProvider == null) throw new ArgumentNullException(); - - IDb inMemStateDb = new ReadOnlyDb(oldDbProvider.StateDb, true); - IDb inMemBlockDb = new ReadOnlyDb(oldDbProvider.BlocksDb, true); - IDb inMemHeaderDb = new ReadOnlyDb(oldDbProvider.HeadersDb, true); - IDb inMemBlockInfoDb = new ReadOnlyDb(oldDbProvider.BlockInfosDb, true); - IDb inMemCodeDb = new ReadOnlyDb(oldDbProvider.CodeDb, true); - IDb inMemMetadataDb = new ReadOnlyDb(oldDbProvider.MetadataDb, true); - - DbProvider dbProvider = new(DbModeHint.Mem); - DbProvider = dbProvider; - - dbProvider.RegisterDb(DbNames.State, inMemStateDb); - dbProvider.RegisterDb(DbNames.Blocks, inMemBlockDb); - dbProvider.RegisterDb(DbNames.Headers, inMemHeaderDb); - dbProvider.RegisterDb(DbNames.BlockInfos, inMemBlockInfoDb); - dbProvider.RegisterDb(DbNames.Code, inMemCodeDb); - dbProvider.RegisterDb(DbNames.Metadata, inMemMetadataDb); - - SpecProvider = specProvider; - - ILogManager logManager = SimpleConsoleLogManager.Instance; - - TrieStore trieStore = new(inMemStateDb, logManager); - StateProvider = new WorldState(trieStore, inMemCodeDb, logManager); - - IReadOnlyTrieStore readOnlyTrieStore = trieStore.AsReadOnly(inMemStateDb); - StateReader stateReader = new(readOnlyTrieStore, inMemCodeDb, logManager); - SyncConfig syncConfig = new(); - BlockTree = new BlockTree(DbProvider.BlocksDb, - DbProvider.HeadersDb, - DbProvider.BlockInfosDb, - DbProvider.MetadataDb, - new ChainLevelInfoRepository(DbProvider.BlockInfosDb), - SpecProvider, - NullBloomStorage.Instance, - syncConfig, - logManager); - - StateProvider.StateRoot = BlockTree.Head.StateRoot; - - ChainHeadReadOnlyStateProvider readOnlyState = new(BlockTree, stateReader); - - TransactionComparerProvider transactionComparerProvider = new(SpecProvider, BlockTree); - - EthereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId, logManager); - - Nethermind.TxPool.TxPool txPool = new( - EthereumEcdsa, - new ChainHeadInfoProvider( - SpecProvider, - BlockTree, - readOnlyState), - new TxPoolConfig(), - new TxValidator(SpecProvider.ChainId), - logManager, - transactionComparerProvider.GetDefaultComparer()); - - - receiptStorage = new InMemoryReceiptStorage(); - - VirtualMachine = new MultiCallVirtualMachine( - new BlockhashProvider(BlockTree, logManager), - SpecProvider, - logManager); - - TransactionProcessor txProcessor = - new(SpecProvider, StateProvider, VirtualMachine, logManager); - RecoverSignatures blockPreprocessorStep = new(EthereumEcdsa, txPool, SpecProvider, logManager); - - HeaderValidator headerValidator = new( - BlockTree, - Always.Valid, - SpecProvider, - logManager); - - BlockValidator blockValidator = new(new TxValidator(SpecProvider.ChainId), - headerValidator, - Always.Valid, - SpecProvider, - logManager); - - BlockProcessor = new BlockProcessor(SpecProvider, - blockValidator, - NoBlockRewards.Instance, - new BlockProcessor.BlockValidationTransactionsExecutor(txProcessor, StateProvider), - StateProvider, - receiptStorage, - NullWitnessCollector.Instance, - logManager); - - ChainProcessor = new BlockchainProcessor( - BlockTree, - BlockProcessor, - blockPreprocessorStep, - stateReader, - logManager, - BlockchainProcessor.Options.Default); - ChainProcessor.Start(); - - - //Init RPC - IFilterStore filterStore = new FilterStore(); - IFilterManager filterManager = - new FilterManager(filterStore, BlockProcessor, txPool, logManager); - - //ToDO make use of our VM!!! - ReadOnlyTxProcessingEnv processingEnv = new( - new ReadOnlyDbProvider(DbProvider, false), - new TrieStore(DbProvider.StateDb, logManager).AsReadOnly(), - new ReadOnlyBlockTree(BlockTree), - SpecProvider, - logManager); - - IMultiCallBlocksProcessingEnv mcProcessingEnv = - MultiCallReadOnlyBlocksProcessingEnv.Create( - new ReadOnlyDbProvider(DbProvider, true), - SpecProvider, - logManager); - - BloomStorage bloomStorage = - new(new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory()); - ReceiptsRecovery receiptsRecovery = - new(new EthereumEcdsa(SpecProvider.ChainId, logManager), SpecProvider); - IReceiptFinder receiptFinder = receiptStorage; - LogFinder logFinder = new(BlockTree, receiptStorage, receiptStorage, bloomStorage, - logManager, receiptsRecovery); - ITimestamper timestamper = Timestamper.Default; - - - bridge = new BlockchainBridge(processingEnv, - mcProcessingEnv, - txPool, - receiptFinder, - filterStore, - filterManager, - EthereumEcdsa, - timestamper, - logFinder, - SpecProvider, - new BlocksConfig(), - false); - - GasPriceOracle gasPriceOracle = new(BlockFinder, SpecProvider, logManager); - FeeHistoryOracle feeHistoryOracle = - new(BlockFinder, receiptStorage, SpecProvider); - IChainHeadInfoProvider chainHeadInfoProvider = - new ChainHeadInfoProvider(SpecProvider, BlockTree, stateReader); - NonceManager nonceManager = new(chainHeadInfoProvider.AccountStateProvider); - NullWallet? wallet = NullWallet.Instance; // May be use one from API directly? - ITxSigner txSigner = new WalletTxSigner(wallet, SpecProvider.ChainId); - TxSealer txSealer = new(txSigner, timestamper); - TxPoolSender txSender = new(txPool, txSealer, nonceManager, EthereumEcdsa); - - JsonRpcConfig? jsonRpcConfig = new(); - - EthRpcModule = new EthRpcModule( - jsonRpcConfig, - bridge, - BlockFinder, - stateReader, - txPool, - txSender, - wallet, - logManager, - SpecProvider, - gasPriceOracle, - new EthSyncingInfo(BlockTree, receiptStorage, syncConfig, new StaticSelector(SyncMode.All), logManager), - feeHistoryOracle, - dbProvider); - } - - public MultiCallBlockTracer BlockTracer { get; } - - private BlockchainProcessor ChainProcessor { get; } - private BlockProcessor BlockProcessor { get; } - - public IWorldState StateProvider { get; internal set; } - public ISpecProvider SpecProvider { get; internal set; } - public IBlockTree BlockTree { get; internal set; } - public IBlockFinder BlockFinder => BlockTree; - public Block? LatestBlock => BlockFinder.Head; - - public EthRpcModule EthRpcModule { get; internal set; } - - public EthereumEcdsa EthereumEcdsa { get; internal set; } - public IReleaseSpec CurrentSpec => SpecProvider.GetSpec(LatestBlock!.Header); - public virtual MultiCallVirtualMachine VirtualMachine { get; internal set; } - - public IDbProvider DbProvider { get; internal set; } - - //Create a new block next to current LatestBlock (BlockFinder.Head) - public Block CreateBlock(BlockOverride? desiredBlock, CallTransactionModel[] desiredTransactions) - { - BlockHeader? parent = null; - BlockHeader blockHeader = null; - - if (desiredBlock == null) - { - parent = LatestBlock?.Header; - - blockHeader = new BlockHeader( - parent.Hash, - Keccak.OfAnEmptySequenceRlp, - Address.Zero, - UInt256.Zero, - parent.Number + 1, - parent.GasLimit, - parent.Timestamp + 1, - Array.Empty()); - blockHeader.BaseFeePerGas = BaseFeeCalculator.Calculate(parent, SpecProvider.GetSpec(blockHeader)); - } - else - { - if (desiredBlock.Number < LatestBlock.Number) - { - Block? parentBlock = BlockFinder.FindBlock((long)(desiredBlock.Number - 1)); - if (parentBlock != null) - { - BlockTree.UpdateMainChain(new List { parentBlock }, true, true); - BlockTree.UpdateHeadBlock(parentBlock.Hash); - parent = parentBlock.Header; - StateProvider.StateRoot = parent.StateRoot; - } - else - throw new ArgumentException("could not find parent block and load the state"); - } - else - parent = LatestBlock?.Header; - - - ulong time = 0; - if (desiredBlock.Time <= ulong.MaxValue) - time = (ulong)desiredBlock.Time; - else - throw new OverflowException("Time value is too large to be converted to ulong we use."); - - long gasLimit = 0; - if (desiredBlock.GasLimit <= long.MaxValue) - gasLimit = (long)desiredBlock.GasLimit; - else - throw new OverflowException("GasLimit value is too large to be converted to long we use."); - - long blockNumber = 0; - if (desiredBlock.Number <= long.MaxValue) - blockNumber = (long)desiredBlock.Number; - else - throw new OverflowException("Block Number value is too large to be converted to long we use."); - - blockHeader = new BlockHeader( - parent.Hash, - Keccak.OfAnEmptySequenceRlp, - desiredBlock.FeeRecipient, - UInt256.Zero, - blockNumber, - gasLimit, - time, - Array.Empty()); - blockHeader.MixHash = desiredBlock.PrevRandao; - blockHeader.BaseFeePerGas = desiredBlock.BaseFee; - } - - if (_maxGas <= long.MaxValue) - { - blockHeader.GasLimit = - (long)Math.Min((ulong)blockHeader.GasLimit, _maxGas.ToUInt64(CultureInfo.InvariantCulture)); - } - else - _maxGas -= new UInt256((ulong)blockHeader.GasLimit); - - UInt256 difficulty = ConstantDifficulty.One.Calculate(blockHeader, parent); - blockHeader.Difficulty = difficulty; - blockHeader.TotalDifficulty = parent.TotalDifficulty + difficulty; - - List transactions = new(); - if (desiredTransactions != null) - transactions = desiredTransactions.Select(model => model.GetTransaction()).ToList(); - - Block? block = new(blockHeader, transactions, Array.Empty()); - - return block; - } - - //Process Block and UpdateMainChain with it - public Block FinalizeBlock(Block currentBlock) - { - StateProvider.Commit(SpecProvider.GetSpec(currentBlock.Header)); - StateProvider.CommitTree(currentBlock.Number); - StateProvider.RecalculateStateRoot(); - - currentBlock.Header.StateRoot = StateProvider.StateRoot; - currentBlock.Header.IsPostMerge = true; //ToDo: Seal if necessary before merge 192 BPB - currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); - - - Block[]? blocks = BlockProcessor.Process(StateProvider.StateRoot, - new List { currentBlock }, - ProcessingOptions.ForceProcessing | - ProcessingOptions.NoValidation | - ProcessingOptions.DoNotVerifyNonce | - ProcessingOptions.IgnoreParentNotOnMainChain | - ProcessingOptions.MarkAsProcessed | - ProcessingOptions.StoreReceipts - , - BlockTracer); - Block? block = blocks.First(); - AddBlockResult res = BlockTree.SuggestBlock(block, - BlockTreeSuggestOptions.ForceSetAsMain | BlockTreeSuggestOptions.ForceDontValidateParent); - - BlockTree.UpdateMainChain(blocks, true, true); - BlockTree.UpdateHeadBlock(block.Hash); - return block; - } - - - //Apply changes to accounts and contracts states including precompiles - private void ModifyAccounts(AccountOverride[] StateOverrides) - { - Account? acc; - if (StateOverrides == null) return; - - foreach (AccountOverride accountOverride in StateOverrides) - { - Address address = accountOverride.Address; - bool accExists = StateProvider.AccountExists(address); - if (!accExists) - { - StateProvider.CreateAccount(address, accountOverride.Balance, accountOverride.Nonce); - acc = StateProvider.GetAccount(address); - } - else - acc = StateProvider.GetAccount(address); - - UInt256 accBalance = acc.Balance; - if (accBalance > accountOverride.Balance) - StateProvider.SubtractFromBalance(address, accBalance - accountOverride.Balance, CurrentSpec); - else if (accBalance < accountOverride.Nonce) - StateProvider.AddToBalance(address, accountOverride.Balance - accBalance, CurrentSpec); - - UInt256 accNonce = acc.Nonce; - if (accNonce > accountOverride.Nonce) - StateProvider.DecrementNonce(address); - else if (accNonce < accountOverride.Nonce) StateProvider.IncrementNonce(address); - - if (acc != null) - { - if (accountOverride.Code is not null) - { - VirtualMachine.SetOverwrite(StateProvider, CurrentSpec, address, - new CodeInfo(accountOverride.Code), accountOverride.MoveToAddress); - } - } - - - if (accountOverride.State is not null) - { - accountOverride.State = new Dictionary(); - foreach (KeyValuePair storage in accountOverride.State) - StateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.WithoutLeadingZeros().ToArray()); - } - - if (accountOverride.StateDiff is not null) - { - foreach (KeyValuePair storage in accountOverride.StateDiff) - StateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.WithoutLeadingZeros().ToArray()); - } - - StateProvider.Commit(CurrentSpec); - } - } - - /// - /// Forges a new block in the temp blockchain using the provided action to manipulate state, release spec, spec - /// provider, and storage provider. - /// - /// An action representing the modifications to the blockchain state and storage. - public Block ForgeChainBlock(MultiCallBlockStateCallsModel blockMock) - { - //Create a block - Block? newBlock = CreateBlock(blockMock.BlockOverride, blockMock.Calls); - - //Update the state - ModifyAccounts(blockMock.StateOverrides); - - //Process transactions - newBlock = FinalizeBlock(newBlock); - return newBlock; - } - - #region IDisposable - - private bool _disposed; - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool disposing) - { - if (!_disposed) - { - _disposed = true; - DbProvider?.Dispose(); - } - } - - ~MultiCallBlockchainFork() - { - Dispose(false); - } - - #endregion -} From f682a720adbff72a87ea9b967e3ce352e6e949e0 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 29 Jun 2023 13:46:34 +0100 Subject: [PATCH 027/213] fixing Benchmarks --- .../Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index d017c65063e..bfcd56feeaa 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -115,6 +115,10 @@ TransactionProcessor transactionProcessor new ReadOnlyBlockTree(blockTree), specProvider, LimboLogs.Instance), + MultiCallReadOnlyBlocksProcessingEnv.Create( + new ReadOnlyDbProvider(dbProvider, true), + specProvider, + LimboLogs.Instance), NullTxPool.Instance, NullReceiptStorage.Instance, NullFilterStore.Instance, From 1162cc34fe32efe348445cc11e0a093e6d435369 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Fri, 30 Jun 2023 04:51:37 +0100 Subject: [PATCH 028/213] Using eth_multicallV1 signature --- .../Nethermind.Cli/Modules/EthCliModule.cs | 6 ++- .../IMultiCallBlocksProcessingEnv.cs | 2 +- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 4 +- .../Proxy/EthJsonRpcClientProxyTests.cs | 13 +++++ .../Nethermind.Facade/BlockchainBridge.cs | 50 +++++++++++++------ .../Nethermind.Facade/IBlockchainBridge.cs | 2 +- .../Proxy/EthJsonRpcClientProxy.cs | 6 +++ .../Proxy/IEthJsonRpcClientProxy.cs | 1 + .../Proxy/Models/CallTransactionModel.cs | 4 +- .../EthMulticallTestsSimplePrecompiles.cs | 2 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 11 +++- 11 files changed, 76 insertions(+), 25 deletions(-) diff --git a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs index 9726178761c..d4e22ed132a 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs @@ -49,13 +49,17 @@ public JsValue GetProof(string address, string[] storageKeys, string? blockParam return NodeManager.Post("eth_call", tx, blockParameter ?? "latest").Result; } - //TODO: add tests [CliFunction("eth", "multicall")] public JsValue MultiCall(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) { return NodeManager.PostJint("eth_multicall", version, blockCalls, blockParameter ?? "latest", traceTransfers).Result; } + [CliFunction("eth", "multicallV1")] + public JsValue MultiCallV1(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) + { + return NodeManager.PostJint("eth_multicallV1", 1, blockCalls, blockParameter ?? "latest", traceTransfers).Result; + } [CliFunction("eth", "getBlockByHash")] diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs index 38a3b682ae3..05481061812 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs @@ -20,5 +20,5 @@ public interface IMultiCallBlocksProcessingEnv : IReadOnlyTxProcessingEnvBase, I IMultiCallBlocksProcessingEnv Clone(); //We keep original ProcessingEnv spirit with Build() that can start from any stateRoot - IBlockProcessor GetProcessor(Keccak stateRoot); + IBlockProcessor GetProcessor(); } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs index 90327022a23..968a4d35a1f 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -31,7 +31,7 @@ public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, public ISpecProvider SpecProvider { get; } public MultiCallVirtualMachine Machine { get; } - //We need abilety to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning + //We need ability to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning public static IMultiCallBlocksProcessingEnv Create(IReadOnlyDbProvider? readOnlyDbProvider, ISpecProvider? specProvider, ILogManager? logManager @@ -91,7 +91,7 @@ private MultiCallReadOnlyBlocksProcessingEnv( } - public IBlockProcessor GetProcessor(Keccak stateRoot) + public IBlockProcessor GetProcessor() { var yransactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, Machine, _logManager); diff --git a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs index 441a4e22227..80395cc825e 100644 --- a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs @@ -101,6 +101,19 @@ await _client.Received().SendAsync(nameof(_proxy.eth_mul (ulong)1, multyCallTransaction, blockParameter.Type, traceTransactions); } + [Test] + public async Task eth_multicallV1_should_invoke_client_method() + { + var multyCallTransaction = new MultiCallBlockStateCallsModel[] { }; + var blockParameter = BlockParameterModel.Latest; + var traceTransactions = true; + await _proxy.eth_multicallV1(multyCallTransaction, blockParameter, traceTransactions); + + var calls = _client.ReceivedCalls().ToList(); + await _client.Received().SendAsync(nameof(_proxy.eth_multicall), + 1, multyCallTransaction, blockParameter.Type, traceTransactions); + } + [Test] public async Task eth_getCode_should_invoke_client_method() { diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 89a4950bfe2..45592e498c6 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -138,6 +138,14 @@ public Block? HeadBlock return blockHash is not null ? _receiptFinder.Get(blockHash).ForTransaction(txHash) : null; } + + public class MultiCallOutput + { + public string? Error { get; set; } + + public List items; + } + public class CallOutput { public CallOutput() @@ -178,13 +186,28 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can } - public List MultiCall(BlockHeader header, MultiCallBlockStateCallsModel[] blocks, CancellationToken cancellationToken) + + public MultiCallOutput MultiCall(BlockHeader header, MultiCallBlockStateCallsModel[] blocks, CancellationToken cancellationToken) { MultiCallBlockTracer multiCallOutputTracer = new(); + MultiCallOutput result = new(); + try + { + (bool Success, string Error) tryMultiCallResult = TryMultiCallTrace(header, blocks, + multiCallOutputTracer.WithCancellation(cancellationToken)); - MultiCallTrace(header, blocks, multiCallOutputTracer.WithCancellation(cancellationToken)); + if (!tryMultiCallResult.Success) + { + result.Error = tryMultiCallResult.Error; + } + } + catch (Exception ex) + { + result.Error = ex.ToString(); + } - return multiCallOutputTracer._results; + result.items = multiCallOutputTracer._results; + return result; } public CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken) @@ -304,12 +327,12 @@ private void CallAndRestore( transactionProcessor.CallAndRestore(transaction, callHeader, tracer); } - public void MultiCallTrace(BlockHeader parent, MultiCallBlockStateCallsModel[] blocks, + private (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallBlockStateCallsModel[] blocks, IBlockTracer tracer) { using (IMultiCallBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone()) { - var processor = env.GetProcessor(env.StateProvider.StateRoot); + var processor = env.GetProcessor(); var firstBlock = blocks.FirstOrDefault(); var startStateRoot = parent.StateRoot; if (firstBlock?.BlockOverride?.Number != null @@ -393,7 +416,7 @@ public void MultiCallTrace(BlockHeader parent, MultiCallBlockStateCallsModel[] b Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, new List { currentBlock }, ProcessingOptions.ForceProcessing | - // ProcessingOptions.NoValidation | + // ProcessingOptions.NoValidation | ProcessingOptions.DoNotVerifyNonce | ProcessingOptions.IgnoreParentNotOnMainChain | ProcessingOptions.MarkAsProcessed | @@ -404,14 +427,15 @@ public void MultiCallTrace(BlockHeader parent, MultiCallBlockStateCallsModel[] b if (processedBlock != null) { parent = processedBlock.Header; - //env.StateProvider.CommitTree(parent.Number); } else { - throw new RuntimeBinderException("Processing failed"); //Todo fix + return (false, $"Processing failed at block {currentBlock.Number}"); } } } + + return (true, ""); } public ulong GetChainId() @@ -452,14 +476,8 @@ private void ModifyAccounts(AccountOverride[] StateOverrides, IWorldState? State StateProvider.DecrementNonce(address); else if (accNonce < accountOverride.Nonce) StateProvider.IncrementNonce(address); - if (acc != null) - { - if (accountOverride.Code is not null) - { - _multiCallProcessingEnv.Machine.SetOverwrite(StateProvider, CurrentSpec, address, - new CodeInfo(accountOverride.Code), accountOverride.MoveToAddress); - } - } + _multiCallProcessingEnv.Machine.SetOverwrite(StateProvider, CurrentSpec, address, + new CodeInfo(accountOverride.Code), accountOverride.MoveToAddress); if (accountOverride.State is not null) diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index 6e7b2bfe1c0..b282308ca1f 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -25,7 +25,7 @@ public interface IBlockchainBridge : ILogFinder (TxReceipt Receipt, UInt256? EffectiveGasPrice, int LogIndexStart) GetReceiptAndEffectiveGasPrice(Keccak txHash); (TxReceipt Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Keccak txHash); - List MultiCall(BlockHeader header, MultiCallBlockStateCallsModel[] blocks, + BlockchainBridge.MultiCallOutput MultiCall(BlockHeader header, MultiCallBlockStateCallsModel[] blocks, CancellationToken cancellationToken); BlockchainBridge.CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index 49119e0fa7a..7709db00019 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -46,6 +46,12 @@ public Task> eth_multicall(ulong version, Mult MapBlockParameter(blockParameter), traceTransfers); + public Task> eth_multicallV1(MultiCallBlockStateCallsModel[] blockCalls, + BlockParameterModel blockParameter = null, bool traceTransfers = true) => _proxy.SendAsync( + nameof(eth_multicall), + 1, blockCalls, + MapBlockParameter(blockParameter), + traceTransfers); public Task> eth_getCode(Address address, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_getCode), address, MapBlockParameter(blockParameter)); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs index be46e9cda11..c5ad13c7487 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs @@ -21,6 +21,7 @@ public interface IEthJsonRpcClientProxy //TODO:add tests Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameterModel blockParameter = null, bool traceTransfers = true); + Task> eth_multicallV1(MultiCallBlockStateCallsModel[] blockCalls, BlockParameterModel blockParameter = null, bool traceTransfers = true); Task> eth_getCode(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionByHash(Keccak transactionHash); Task> eth_pendingTransactions(); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs index d64ad26542a..f3fa33b78f1 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs @@ -11,7 +11,7 @@ namespace Nethermind.Facade.Proxy.Models; public class CallTransactionModel { - public Address From { get; set; } + public Address? From { get; set; } public Address To { get; set; } public UInt256 Gas { get; set; } public UInt256 GasPrice { get; set; } @@ -35,6 +35,8 @@ public Transaction GetTransaction() { if (Gas > long.MaxValue) throw new OverflowException("Gas value is too large to be converted to long we use."); + From ??= Address.SystemUser; + Transaction? result = new Transaction { SenderAddress = From, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index f246b38aa50..d50f7e3b66e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -105,7 +105,7 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); var result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, new[] { requestMultiCall }, CancellationToken.None); - var logs = result.First().Calls.First().Logs; + var logs = result.items.First().Calls.First().Logs; //Check results /* diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 2ced7cec601..55047e78be3 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -56,10 +56,17 @@ public ResultWrapper Execute(ulong version, using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); - List results = _blockchainBridge.MultiCall(header.Clone(), + BlockchainBridge.MultiCallOutput results = _blockchainBridge.MultiCall(header.Clone(), blockCallsToProcess, cancellationTokenSource.Token); - return ResultWrapper.Success(results.ToArray()); + if (results.Error == null) + { + return ResultWrapper.Success(results.items.ToArray()); + } + + return ResultWrapper.Fail(results.Error, results.items.ToArray()); + + } } From 72ac349451f1887553e0aad5ad38461842a6eb22 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Fri, 30 Jun 2023 05:04:38 +0100 Subject: [PATCH 029/213] RPC test added --- .../JsonRpcServiceTests.cs | 20 +++++++++++++++++++ .../Modules/Eth/EthRpcModule.cs | 5 +++++ .../Modules/Eth/EthRpcModuleProxy.cs | 6 ++++++ .../Modules/Eth/IEthRpcModule.cs | 11 ++++++++++ 4 files changed, 42 insertions(+) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 9105e2268aa..3b04ca6e842 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -108,6 +108,26 @@ public void CanRunEthMulticallEmpty() } + [Test] + public void CanRunEthMulticallV1Empty() + { + ulong version = 0; + MultiCallBlockStateCallsModel[] blockCalls = Array.Empty(); + + EthereumJsonSerializer serializer = new(); + + string serializedCall = serializer.Serialize(blockCalls); + + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_multicallV1(blockCalls).ReturnsForAnyArgs(x => + ResultWrapper.Success(Array.Empty())); + JsonRpcSuccessResponse? response = + TestRequest(ethRpcModule, "eth_multicallV1", serializedCall) as JsonRpcSuccessResponse; + Assert.IsTrue(response != null); + Assert.That(response?.Result, Is.EqualTo(Array.Empty())); + } + + [Test] public void CanHandleOptionalArguments() { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index aaa45c7bb34..de0f17bd8ba 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -360,6 +360,11 @@ public ResultWrapper eth_multicall(ulong version, MultiC .Execute(version, blockCalls, blockParameter, traceTransfers); } + public ResultWrapper eth_multicallV1(MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null, + bool traceTransfers = true) + { + return eth_multicall(1, blockCalls, blockParameter, traceTransfers); + } public ResultWrapper eth_estimateGas(TransactionForRpc transactionCall, BlockParameter blockParameter) => diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs index 6fe6174b8bc..34aac6281d6 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs @@ -175,6 +175,12 @@ public ResultWrapper eth_multicall(ulong version, throw new NotSupportedException(); } + public ResultWrapper eth_multicallV1(MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null, + bool traceTransfers = true) + { + throw new NotImplementedException(); + } + public ResultWrapper eth_estimateGas( TransactionForRpc transactionCall, BlockParameter? blockParameter = null) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index c1a4eaf90b7..18b891d765b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -162,6 +162,17 @@ ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null, bool traceTransfers = true); + [JsonRpcMethod(IsImplemented = true, + Description = "Executes a tx call (does not create a transaction)", + IsSharable = false, + ExampleResponse = "0x")] + ResultWrapper eth_multicallV1( + [JsonRpcParameter(ExampleValue = + "[{\"stateOverrides\":[{\"nonce\":\"0x1\", \"address\": \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\", \"balance\": \"0xde0b6b3a7640000\", \"state\": {\"0x2292f0db49e1af24fbcac7f32b7537f334244455ad0ed0b46a78202982e7b70d\": \"0xde0b6b3a7640000\", \"0x0x877bd4632ef8c8ddc43b67e5a4511d939eadb612553c8a060670e05ebb1bb83c\": \"0xde0b6b3a7640000\"}}],\"calls\":[{\"from\":\"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"to\":\"0x6b175474e89094c44da98b954eedeac495271d0f\",\"data\":\"0x18160ddd\"}]}]")] + MultiCallBlockStateCallsModel[] blockCalls, + BlockParameter? blockParameter = null, bool traceTransfers = true); + + [JsonRpcMethod(IsImplemented = true, Description = "Executes a tx call and returns gas used (does not create a transaction)", From bf4c9295c2062c6cc72cc3c6d9b3775d69409243 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Sat, 1 Jul 2023 14:40:59 +0100 Subject: [PATCH 030/213] post merge fix --- src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index fe80c672fa0..e9e42924bcb 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -23,8 +23,8 @@ public interface IBlockchainBridge : ILogFinder void RecoverTxSenders(Block block); Address? RecoverTxSender(Transaction tx); TxReceipt GetReceipt(Keccak txHash); - (TxReceipt Receipt, UInt256? EffectiveGasPrice, int LogIndexStart) GetReceiptAndEffectiveGasPrice(Keccak txHash); - (TxReceipt Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Keccak txHash); + (TxReceipt? Receipt, TxGasInfo? GasInfo, int LogIndexStart) GetReceiptAndGasInfo(Keccak txHash); + (TxReceipt? Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Keccak txHash); BlockchainBridge.MultiCallOutput MultiCall(BlockHeader header, MultiCallBlockStateCallsModel[] blocks, CancellationToken cancellationToken); BlockchainBridge.CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken); From 472054b31bcc8544538c811071cbd0d532e0dcce Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 4 Jul 2023 22:05:10 +0100 Subject: [PATCH 031/213] Update src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs Fixes for Success/Failure at MultiCallCallResult Co-authored-by: Ahmad Bitar <33181301+smartprogrammer93@users.noreply.github.com> --- .../Proxy/Models/MultiCall/MultiCallCallResult.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs index 2085dee77b2..a66f74f69c1 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs @@ -9,11 +9,11 @@ public ResultType Type { get { - if (Error != null) return ResultType.Failure; + if (Error is null) return ResultType.Success; - if (Logs != null) return ResultType.Success; + if (Return is not null) return ResultType.Failure; - return ResultType.Invalid; + return ResultType.invalid; } } From 63e361d9c0187a62b40a86717c43908b276afdb4 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 4 Jul 2023 22:10:29 +0100 Subject: [PATCH 032/213] fixes upon first review --- .../Nethermind.Blockchain/BlockTree.cs | 4 +- .../Nethermind.Facade/BlockchainBridge.cs | 2 +- .../Nethermind.Facade/MultiCallTxTracer.cs | 2 +- .../Proxy/Models/CallTransactionModel.cs | 14 +- .../Proxy/Models/MultiCall/BlockOverride.cs | 5 +- .../Models/MultiCall/MultiCallCallResult.cs | 2 +- .../ConsensusHelperTests.cs | 449 +++++++++--------- ...ulticallTestsPrecompilesWithRedirection.cs | 2 +- .../EthMulticallTestsBlocksAndTransactions.cs | 12 +- .../EthMulticallTestsSimplePrecompiles.cs | 2 +- .../Eth/EthRpcModule.TransactionExecutor.cs | 4 - 11 files changed, 251 insertions(+), 247 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index d6347ce9e1e..74b8db1fbe6 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -684,7 +684,7 @@ public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBloc private AddBlockResult Suggest(Block? block, BlockHeader header, BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) { bool shouldProcess = options.ContainsFlag(BlockTreeSuggestOptions.ShouldProcess); - bool noPatentCheck = options.ContainsFlag(BlockTreeSuggestOptions.ForceDontValidateParent); + bool noParentCheck = options.ContainsFlag(BlockTreeSuggestOptions.ForceDontValidateParent); bool fillBeaconBlock = options.ContainsFlag(BlockTreeSuggestOptions.FillBeaconBlock); bool setAsMain = options.ContainsFlag(BlockTreeSuggestOptions.ForceSetAsMain) || !options.ContainsFlag(BlockTreeSuggestOptions.ForceDontSetAsMain) && !shouldProcess; @@ -723,7 +723,7 @@ private AddBlockResult Suggest(Block? block, BlockHeader header, BlockTreeSugges bool parentExists = IsKnownBlock(header.Number - 1, header.ParentHash!) || IsKnownBeaconBlock(header.Number - 1, header.ParentHash!); - if (!header.IsGenesis && !noPatentCheck && !parentExists) + if (!header.IsGenesis && !noParentCheck && !parentExists) { if (_logger.IsTrace) _logger.Trace($"Could not find parent ({header.ParentHash}) of block {header.Hash}"); return AddBlockResult.UnknownParent; diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 6617cbdd5c4..dcf08416aca 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -362,7 +362,7 @@ private void CallAndRestore( } else { - callHeader = callInputBlock.BlockOverride.GetBlockHeader(parent); + callHeader = callInputBlock.BlockOverride.GetBlockHeader(parent, _blocksConfig); } env.StateProvider.StateRoot = parent.StateRoot; diff --git a/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs index b1ac894a507..fc7a7e3411f 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs @@ -77,9 +77,9 @@ public void ReportStorageRead(in StorageCell storageCell) public bool IsTracingAccess { get; } public bool IsTracingFees { get; } + public bool IsTracingEventLogs { get; } public bool IsTracing => IsTracingActions || IsTracingEventLogs; - public bool IsTracingEventLogs { get; } public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs index f3fa33b78f1..571e9e1f714 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs @@ -18,19 +18,6 @@ public class CallTransactionModel public UInt256 Value { get; set; } public byte[] Data { get; set; } - public static CallTransactionModel FromTransaction(Transaction transaction) - { - return new() - { - From = transaction.SenderAddress, - To = transaction.To, - Data = transaction.Data.AsArray(), - Value = transaction.Value, - Gas = 50_000, - GasPrice = transaction.GasPrice - }; - } - public Transaction GetTransaction() { if (Gas > long.MaxValue) throw new OverflowException("Gas value is too large to be converted to long we use."); @@ -45,6 +32,7 @@ public Transaction GetTransaction() Value = Value, GasLimit = (long)Gas, GasPrice = GasPrice + }; result.Hash = result.CalculateHash(); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index 45d5587a457..1b140418feb 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using Nethermind.Config; using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -19,9 +20,9 @@ public class BlockOverride public Address FeeRecipient { get; set; } = Address.Zero; public UInt256 BaseFee { get; set; } - public BlockHeader GetBlockHeader(BlockHeader parent) + public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) { - ulong newTime = parent.Timestamp + 1; + ulong newTime = parent.Timestamp + cfg.SecondsPerSlot; if (0 == Time) { } else if (Time <= ulong.MaxValue) newTime = (ulong)Time; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs index a66f74f69c1..776717d4500 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs @@ -13,7 +13,7 @@ public ResultType Type if (Return is not null) return ResultType.Failure; - return ResultType.invalid; + return ResultType.Invalid; } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs index 2be75896609..d01e7c7025f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs @@ -8,8 +8,11 @@ using FluentAssertions; using FluentAssertions.Equivalency; using FluentAssertions.Json; +using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Evm.Tracing.GethStyle; +using Nethermind.Facade.Proxy.Models; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.DebugModule; using Nethermind.JsonRpc.Modules.Trace; @@ -18,280 +21,296 @@ using Newtonsoft.Json.Linq; using NUnit.Framework; -namespace Nethermind.JsonRpc.Test +namespace Nethermind.JsonRpc.Test; + +public static class Extensions { - [Explicit] - public partial class ConsensusHelperTests + public static CallTransactionModel FromTransaction(this Transaction transaction) { - private static Func, EquivalencyAssertionOptions> ReceiptOptions = - options => options.WithStrictOrdering() - .IncludingNestedObjects() - .Including(r => r.TransactionHash) - .Including(r => r.TransactionIndex) - .Including(r => r.BlockHash) - .Including(r => r.BlockNumber) - .Including(r => r.From) - .Including(r => r.To) - .Including(r => r.CumulativeGasUsed) - .Including(r => r.GasUsed) - .Including(r => r.ContractAddress) - .Including(r => r.LogsBloom) - .Including(r => r.Logs) - .Including(r => r.Root) - .Including(r => r.Status); - - public static IEnumerable Tests + return new() { - get - { - // yield return new TestCaseData(new Uri("file:///c:/temp/data1"), new Uri("file:///c:/temp/data1")); - // yield return new TestCaseData(new Uri("http://localhost:8545"), new Uri("http://localhost:8545"), 10l); - // yield return new TestCaseData(new Uri("http://localhost:8545"), new Uri("http://localhost:8545"), new Keccak("0x0"), new GethTraceOptions()); - yield break; - } - } + From = transaction.SenderAddress, + To = transaction.To, + Data = transaction.Data.AsArray(), + Value = transaction.Value, + Gas = (ulong)transaction.GasLimit, + GasPrice = transaction.GasPrice + }; + } +} - [TestCaseSource(nameof(Tests))] - public async Task CompareReceipts(Uri uri1, Uri uri2, Keccak? blockHash = null) - { - using IConsensusDataSource> receipt1Source = GetSource>(uri1); - using IConsensusDataSource> receipt2Source = GetSource>(uri2); - TrySetData(blockHash, receipt1Source, receipt2Source); - await CompareCollection(receipt1Source, receipt2Source, false, ReceiptOptions); - } - [TestCaseSource(nameof(Tests))] - public async Task CompareReceipt(Uri uri1, Uri uri2, Keccak? blockHash = null) - { - using IConsensusDataSource receipt1Source = GetSource(uri1); - using IConsensusDataSource receipt2Source = GetSource(uri2); - TrySetData(blockHash, receipt1Source, receipt2Source); - await Compare(receipt1Source, receipt2Source, false, ReceiptOptions); - } +[Explicit] +public partial class ConsensusHelperTests +{ + private static Func, EquivalencyAssertionOptions> ReceiptOptions = + options => options.WithStrictOrdering() + .IncludingNestedObjects() + .Including(r => r.TransactionHash) + .Including(r => r.TransactionIndex) + .Including(r => r.BlockHash) + .Including(r => r.BlockNumber) + .Including(r => r.From) + .Including(r => r.To) + .Including(r => r.CumulativeGasUsed) + .Including(r => r.GasUsed) + .Including(r => r.ContractAddress) + .Including(r => r.LogsBloom) + .Including(r => r.Logs) + .Including(r => r.Root) + .Including(r => r.Status); - [TestCaseSource(nameof(Tests))] - public async Task CompareGethBlockTrace(Uri uri1, Uri uri2, Keccak? blockHash = null, GethTraceOptions? gethTraceOptions = null) + public static IEnumerable Tests + { + get { - gethTraceOptions ??= GethTraceOptions.Default; - using IConsensusDataSource> receipt1Source = GetSource>(uri1, DebugModuleFactory.Converters); - using IConsensusDataSource> receipt2Source = GetSource>(uri2, DebugModuleFactory.Converters); - TrySetData(blockHash, receipt1Source, receipt2Source); - TrySetData(gethTraceOptions, receipt1Source, receipt2Source); - await CompareCollection(receipt1Source, receipt2Source, true); + // yield return new TestCaseData(new Uri("file:///c:/temp/data1"), new Uri("file:///c:/temp/data1")); + // yield return new TestCaseData(new Uri("http://localhost:8545"), new Uri("http://localhost:8545"), 10l); + // yield return new TestCaseData(new Uri("http://localhost:8545"), new Uri("http://localhost:8545"), new Keccak("0x0"), new GethTraceOptions()); + yield break; } + } - [TestCaseSource(nameof(Tests))] - public async Task CompareGethTxTrace(Uri uri1, Uri uri2, Keccak? transactionHash = null, GethTraceOptions? gethTraceOptions = null) - { - gethTraceOptions ??= GethTraceOptions.Default; - using IConsensusDataSource receipt1Source = GetSource(uri1, DebugModuleFactory.Converters); - using IConsensusDataSource receipt2Source = GetSource(uri2, DebugModuleFactory.Converters); - TrySetData(transactionHash, receipt1Source, receipt2Source); - TrySetData(gethTraceOptions, receipt1Source, receipt2Source); - await Compare(receipt1Source, receipt2Source, true); - } + [TestCaseSource(nameof(Tests))] + public async Task CompareReceipts(Uri uri1, Uri uri2, Keccak? blockHash = null) + { + using IConsensusDataSource> receipt1Source = GetSource>(uri1); + using IConsensusDataSource> receipt2Source = GetSource>(uri2); + TrySetData(blockHash, receipt1Source, receipt2Source); + await CompareCollection(receipt1Source, receipt2Source, false, ReceiptOptions); + } - [TestCaseSource(nameof(Tests))] - public async Task CompareParityBlockTrace(Uri uri1, Uri uri2, long blockNumber) - { - using IConsensusDataSource> receipt1Source = GetSource>(uri1, TraceModuleFactory.Converters); - using IConsensusDataSource> receipt2Source = GetSource>(uri2, TraceModuleFactory.Converters); - TrySetData(blockNumber, receipt1Source, receipt2Source); - await CompareCollection(receipt1Source, receipt2Source, true); - } + [TestCaseSource(nameof(Tests))] + public async Task CompareReceipt(Uri uri1, Uri uri2, Keccak? blockHash = null) + { + using IConsensusDataSource receipt1Source = GetSource(uri1); + using IConsensusDataSource receipt2Source = GetSource(uri2); + TrySetData(blockHash, receipt1Source, receipt2Source); + await Compare(receipt1Source, receipt2Source, false, ReceiptOptions); + } + + [TestCaseSource(nameof(Tests))] + public async Task CompareGethBlockTrace(Uri uri1, Uri uri2, Keccak? blockHash = null, GethTraceOptions? gethTraceOptions = null) + { + gethTraceOptions ??= GethTraceOptions.Default; + using IConsensusDataSource> receipt1Source = GetSource>(uri1, DebugModuleFactory.Converters); + using IConsensusDataSource> receipt2Source = GetSource>(uri2, DebugModuleFactory.Converters); + TrySetData(blockHash, receipt1Source, receipt2Source); + TrySetData(gethTraceOptions, receipt1Source, receipt2Source); + await CompareCollection(receipt1Source, receipt2Source, true); + } + + [TestCaseSource(nameof(Tests))] + public async Task CompareGethTxTrace(Uri uri1, Uri uri2, Keccak? transactionHash = null, GethTraceOptions? gethTraceOptions = null) + { + gethTraceOptions ??= GethTraceOptions.Default; + using IConsensusDataSource receipt1Source = GetSource(uri1, DebugModuleFactory.Converters); + using IConsensusDataSource receipt2Source = GetSource(uri2, DebugModuleFactory.Converters); + TrySetData(transactionHash, receipt1Source, receipt2Source); + TrySetData(gethTraceOptions, receipt1Source, receipt2Source); + await Compare(receipt1Source, receipt2Source, true); + } - private void TrySetData(TData blockHash, params object[] sources) + [TestCaseSource(nameof(Tests))] + public async Task CompareParityBlockTrace(Uri uri1, Uri uri2, long blockNumber) + { + using IConsensusDataSource> receipt1Source = GetSource>(uri1, TraceModuleFactory.Converters); + using IConsensusDataSource> receipt2Source = GetSource>(uri2, TraceModuleFactory.Converters); + TrySetData(blockNumber, receipt1Source, receipt2Source); + await CompareCollection(receipt1Source, receipt2Source, true); + } + + private void TrySetData(TData blockHash, params object[] sources) + { + foreach (object source in sources) { - foreach (object source in sources) + if (source is IConsensusDataSourceWithParameter consensusDataSourceWithBlock) { - if (source is IConsensusDataSourceWithParameter consensusDataSourceWithBlock) - { - consensusDataSourceWithBlock.Parameter = blockHash; - } + consensusDataSourceWithBlock.Parameter = blockHash; } } + } - private IConsensusDataSource GetSource(Uri uri, IEnumerable? additionalConverters = null) + private IConsensusDataSource GetSource(Uri uri, IEnumerable? additionalConverters = null) + { + var serializer = GetSerializer(additionalConverters!); + if (uri.IsFile) + { + return new FileConsensusDataSource(uri, serializer); + } + else if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) { - var serializer = GetSerializer(additionalConverters!); - if (uri.IsFile) + Type type = typeof(T); + if (type == typeof(IEnumerable)) { - return new FileConsensusDataSource(uri, serializer); + return (IConsensusDataSource)new ReceiptsJsonRpcDataSource(uri, serializer); } - else if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) + if (type == typeof(ReceiptForRpc)) { - Type type = typeof(T); - if (type == typeof(IEnumerable)) - { - return (IConsensusDataSource)new ReceiptsJsonRpcDataSource(uri, serializer); - } - if (type == typeof(ReceiptForRpc)) - { - return (IConsensusDataSource)new ReceiptsJsonRpcDataSource(uri, serializer); - } - else if (type == typeof(IEnumerable)) - { - return (IConsensusDataSource)new GethLikeBlockTraceJsonRpcDataSource(uri, serializer); - } - else if (type == typeof(GethLikeTxTrace)) - { - return (IConsensusDataSource)new GethLikeTxTraceJsonRpcDataSource(uri, serializer); - } - else if (type == typeof(IEnumerable)) - { - return (IConsensusDataSource)new ParityLikeBlockTraceJsonRpcDataSource(uri, serializer); - } + return (IConsensusDataSource)new ReceiptsJsonRpcDataSource(uri, serializer); } - - throw new NotSupportedException($"Uri: {uri} is not supported"); - } - - private IJsonSerializer GetSerializer(IEnumerable? additionalConverters) - { - IJsonSerializer jsonSerializer = new EthereumJsonSerializer(); - if (additionalConverters is not null) + else if (type == typeof(IEnumerable)) { - jsonSerializer.RegisterConverters(additionalConverters); + return (IConsensusDataSource)new GethLikeBlockTraceJsonRpcDataSource(uri, serializer); } - - return jsonSerializer; - } - - private static async Task Compare(IConsensusDataSource source1, - IConsensusDataSource source2, - bool compareJson, - Func, EquivalencyAssertionOptions>? options = null) - { - - if (compareJson) + else if (type == typeof(GethLikeTxTrace)) { - JToken data = JsonHelper.ParseNormalize(await source1.GetJsonData()); - JToken expectation = JsonHelper.ParseNormalize(await source2.GetJsonData()); - data.Should().BeEquivalentTo(expectation); - data["error"].Should().BeNull(data["error"]?.ToString()); + return (IConsensusDataSource)new GethLikeTxTraceJsonRpcDataSource(uri, serializer); } - else + else if (type == typeof(IEnumerable)) { - string dataJson = string.Empty, expectationJson = string.Empty; - try - { - T data, expectation; - (data, dataJson) = await source1.GetData(); - (expectation, expectationJson) = await source2.GetData(); - data.Should().BeEquivalentTo(expectation, options ?? (o => o)); - } - finally - { - await WriteOutJson(dataJson, expectationJson); - } + return (IConsensusDataSource)new ParityLikeBlockTraceJsonRpcDataSource(uri, serializer); } } - private static async Task CompareCollection(IConsensusDataSource> source1, - IConsensusDataSource> source2, - bool compareJson, - Func, EquivalencyAssertionOptions>? options = null) + throw new NotSupportedException($"Uri: {uri} is not supported"); + } + + private IJsonSerializer GetSerializer(IEnumerable? additionalConverters) + { + IJsonSerializer jsonSerializer = new EthereumJsonSerializer(); + if (additionalConverters is not null) { + jsonSerializer.RegisterConverters(additionalConverters); + } + + return jsonSerializer; + } + + private static async Task Compare(IConsensusDataSource source1, + IConsensusDataSource source2, + bool compareJson, + Func, EquivalencyAssertionOptions>? options = null) + { - if (compareJson) + if (compareJson) + { + JToken data = JsonHelper.ParseNormalize(await source1.GetJsonData()); + JToken expectation = JsonHelper.ParseNormalize(await source2.GetJsonData()); + data.Should().BeEquivalentTo(expectation); + data["error"].Should().BeNull(data["error"]?.ToString()); + } + else + { + string dataJson = string.Empty, expectationJson = string.Empty; + try { - JToken data = JsonHelper.ParseNormalize(await source1.GetJsonData()); - JToken expectation = JsonHelper.ParseNormalize(await source2.GetJsonData()); - data.Should().BeEquivalentTo(expectation); - data["error"].Should().BeNull(data["error"]?.ToString()); + T data, expectation; + (data, dataJson) = await source1.GetData(); + (expectation, expectationJson) = await source2.GetData(); + data.Should().BeEquivalentTo(expectation, options ?? (o => o)); } - else + finally { - string dataJson = string.Empty, expectationJson = string.Empty; - try - { - IEnumerable data, expectation; - (data, dataJson) = await source1.GetData(); - (expectation, expectationJson) = await source2.GetData(); - data.Should().BeEquivalentTo(expectation, options ?? (o => o)); - } - finally - { - await WriteOutJson(dataJson, expectationJson); - } - + await WriteOutJson(dataJson, expectationJson); } } + } - private static async Task WriteOutJson(string dataJson, string expectationJson) + private static async Task CompareCollection(IConsensusDataSource> source1, + IConsensusDataSource> source2, + bool compareJson, + Func, EquivalencyAssertionOptions>? options = null) + { + + if (compareJson) + { + JToken data = JsonHelper.ParseNormalize(await source1.GetJsonData()); + JToken expectation = JsonHelper.ParseNormalize(await source2.GetJsonData()); + data.Should().BeEquivalentTo(expectation); + data["error"].Should().BeNull(data["error"]?.ToString()); + } + else { + string dataJson = string.Empty, expectationJson = string.Empty; try { - JToken data = JsonHelper.ParseNormalize(dataJson); - JToken expectation = JsonHelper.ParseNormalize(expectationJson); - await TestContext.Out.WriteLineAsync(); - await TestContext.Out.WriteLineAsync(data.ToString(Formatting.Indented)); - await TestContext.Out.WriteLineAsync(); - await TestContext.Out.WriteLineAsync("-------------------------------------------------------------"); - await TestContext.Out.WriteLineAsync(); - await TestContext.Out.WriteLineAsync(expectation.ToString(Formatting.Indented)); + IEnumerable data, expectation; + (data, dataJson) = await source1.GetData(); + (expectation, expectationJson) = await source2.GetData(); + data.Should().BeEquivalentTo(expectation, options ?? (o => o)); + } + finally + { + await WriteOutJson(dataJson, expectationJson); } - catch (JsonException) { } - } - private interface IConsensusDataSource : IDisposable - { - Task<(T, string)> GetData(); - Task GetJsonData(); } + } - private interface IConsensusDataSourceWithParameter + private static async Task WriteOutJson(string dataJson, string expectationJson) + { + try { - TData Parameter { get; set; } + JToken data = JsonHelper.ParseNormalize(dataJson); + JToken expectation = JsonHelper.ParseNormalize(expectationJson); + await TestContext.Out.WriteLineAsync(); + await TestContext.Out.WriteLineAsync(data.ToString(Formatting.Indented)); + await TestContext.Out.WriteLineAsync(); + await TestContext.Out.WriteLineAsync("-------------------------------------------------------------"); + await TestContext.Out.WriteLineAsync(); + await TestContext.Out.WriteLineAsync(expectation.ToString(Formatting.Indented)); } + catch (JsonException) { } + } - public static class JsonHelper - { - public static JToken ParseNormalize(string json) => Normalize(JToken.Parse(json)); + private interface IConsensusDataSource : IDisposable + { + Task<(T, string)> GetData(); + Task GetJsonData(); + } + + private interface IConsensusDataSourceWithParameter + { + TData Parameter { get; set; } + } - public static JToken Normalize(JToken token) + public static class JsonHelper + { + public static JToken ParseNormalize(string json) => Normalize(JToken.Parse(json)); + + public static JToken Normalize(JToken token) + { + if (token.Type == JTokenType.Object) { - if (token.Type == JTokenType.Object) + JObject copy = new(); + foreach (JProperty prop in token.Children()) { - JObject copy = new(); - foreach (JProperty prop in token.Children()) + JToken child = prop.Value; + if (child.HasValues) { - JToken child = prop.Value; - if (child.HasValues) - { - child = Normalize(child); - } - if (!IsEmpty(child)) - { - copy.Add(prop.Name, child); - } + child = Normalize(child); + } + if (!IsEmpty(child)) + { + copy.Add(prop.Name, child); } - return copy; } - else if (token.Type == JTokenType.Array) + return copy; + } + else if (token.Type == JTokenType.Array) + { + JArray copy = new(); + foreach (JToken item in token.Children()) { - JArray copy = new(); - foreach (JToken item in token.Children()) + JToken child = item; + if (child.HasValues) { - JToken child = item; - if (child.HasValues) - { - child = Normalize(child); - } - if (!IsEmpty(child)) - { - copy.Add(child); - } + child = Normalize(child); + } + if (!IsEmpty(child)) + { + copy.Add(child); } - return copy; } - return token; + return copy; } + return token; + } - public static bool IsEmpty(JToken token) - { - return (token.Type == JTokenType.Null); - } + public static bool IsEmpty(JToken token) + { + return (token.Type == JTokenType.Null); } } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index c8b7efcab77..5a4fff49003 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -104,7 +104,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( }, Calls = new[] { - CallTransactionModel.FromTransaction(systemTransactionForModifiedVM) + systemTransactionForModifiedVM.FromTransaction() } }; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index c20e6668398..070d1f9ed59 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -67,8 +67,8 @@ public async Task Test_eth_multicall_serialisation() }, Calls = new[] { - CallTransactionModel.FromTransaction(txMainnetAtoBtoFail), - CallTransactionModel.FromTransaction(txMainnetAtoBToComplete), + txMainnetAtoBtoFail.FromTransaction(), + txMainnetAtoBToComplete.FromTransaction(), }, StateOverrides = new[] { @@ -142,7 +142,7 @@ public async Task Test_eth_multicall_eth_moved() }, Calls = new[] { - CallTransactionModel.FromTransaction(txAtoB1), CallTransactionModel.FromTransaction(txAtoB2) + txAtoB1.FromTransaction(), txAtoB2.FromTransaction() } }, new() @@ -157,7 +157,7 @@ public async Task Test_eth_multicall_eth_moved() }, Calls = new[] { - CallTransactionModel.FromTransaction(txAtoB3), CallTransactionModel.FromTransaction(txAtoB4) + txAtoB3.FromTransaction(), txAtoB4.FromTransaction() } } }; @@ -223,7 +223,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() }, Calls = new[] { - CallTransactionModel.FromTransaction(txAtoB1) + txAtoB1.FromTransaction() } }, new() @@ -238,7 +238,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() }, Calls = new[] { - CallTransactionModel.FromTransaction(txAtoB2) + txAtoB2.FromTransaction() } } }; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index d50f7e3b66e..715f55cb626 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -91,7 +91,7 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code } }, - Calls = new[] { CallTransactionModel.FromTransaction(systemTransactionForModifiedVM) } + Calls = new[] { systemTransactionForModifiedVM.FromTransaction() } }; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index c1daa28255d..8ff24d73ed1 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -2,17 +2,13 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Collections.Generic; using System.Threading; using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Eip2930; using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; -using Nethermind.Db; using Nethermind.Evm; using Nethermind.Facade; -using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.Specs.Forks; From 717e58370183464b1428056241ed695050e9718a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 31 Jul 2023 10:43:11 +0100 Subject: [PATCH 033/213] test fixes --- .../EthMulticallTestsSimplePrecompiles.cs | 40 +++++-------------- .../TransactionExtensions.cs | 2 +- 2 files changed, 11 insertions(+), 31 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 715f55cb626..799e75a6c1c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -11,6 +11,7 @@ using Nethermind.Crypto; using Nethermind.Evm; using Nethermind.Evm.Precompiles; +using Nethermind.Facade; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; using NUnit.Framework; @@ -43,6 +44,8 @@ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure return [Test] public async Task Test_eth_multicall_erc() { + + // Arrange TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); //Empose Opcode instead of EcRecoverPrecompile, it returns const TestItem.AddressE address @@ -54,7 +57,6 @@ public async Task Test_eth_multicall_erc() .PushData(Bytes.FromHexString("0x0")) .Op(Instruction.RETURN).Done; - // Step 1: Take an account Address account = TestItem.AddressA; // Step 2: Hash the message @@ -70,10 +72,6 @@ public async Task Test_eth_multicall_erc() await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EcRecoverCallerContractBytecode); - //Check real address - Address recoveredAddress = chain.EthereumEcdsa.RecoverAddress(signature, messageHash); - Assert.AreEqual(TestItem.AddressA, recoveredAddress); - byte[] transactionData = EthRpcMulticallTestsBase.GenerateTransactionDataForEcRecover(messageHash, v, r, s); SystemTransaction systemTransactionForModifiedVM = new() @@ -95,35 +93,17 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe }; - Address? mainChainRpcAddress = - EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); - Assert.NotNull(mainChainRpcAddress); - Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); - - //Force persistancy of head block in main chain - chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); - chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); - - var result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, new[] { requestMultiCall }, CancellationToken.None); - var logs = result.items.First().Calls.First().Logs; - - //Check results - /* - byte[] addressBytes = Bytes.FromHexString(responseFromModifiedVM.Data) - .SliceWithZeroPaddingEmptyOnError(12, 20); - Address resultingAddress = new(addressBytes); - Assert.AreNotEqual(account, resultingAddress); - Assert.AreEqual(TestItem.AddressE, resultingAddress); - - //Note: real address can still be accessed - Address recoveredAddressOnMulticallChain = tmpChain.EthereumEcdsa.RecoverAddress(signature, messageHash); - Assert.AreEqual(TestItem.AddressA, recoveredAddressOnMulticallChain); - */ + // Act + BlockchainBridge.MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, new[] { requestMultiCall }, CancellationToken.None); + Log[]? logs = result.items.First().Calls.First().Logs; + //Check that initial VM is intact - mainChainRpcAddress = + Address? mainChainRpcAddress = EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + Assert.NotNull(mainChainRpcAddress); Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); + } } diff --git a/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs b/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs index 2c1ee5cfbcf..e1dc2d97fe7 100644 --- a/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs +++ b/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs @@ -23,7 +23,7 @@ public static int GetLength(this Transaction tx) public static bool CanBeBroadcast(this Transaction tx) => !tx.SupportsBlobs && tx.GetLength() <= MaxSizeOfTxForBroadcast; - internal static UInt256 CalculateGasPrice(this Transaction tx, bool eip1559Enabled, in UInt256 baseFee) + public static UInt256 CalculateGasPrice(this Transaction tx, bool eip1559Enabled, in UInt256 baseFee) { if (eip1559Enabled && tx.Supports1559) { From 85e228b0acf6402be7e0633af0bcf889e1648187 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 31 Jul 2023 10:58:10 +0100 Subject: [PATCH 034/213] Nonce and account checks --- .../Nethermind.Facade/BlockchainBridge.cs | 31 ++++++++++++------- ...ulticallTestsPrecompilesWithRedirection.cs | 10 ++++++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 54cd72471ce..5cd15122e00 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -377,6 +377,17 @@ private void CallAndRestore( callHeader.MixHash = parent.MixHash; callHeader.IsPostMerge = parent.Difficulty == 0; + Block? currentBlock = new(callHeader, Array.Empty(), Array.Empty()); + + var currentSpec = env.SpecProvider.GetSpec(currentBlock.Header); + if (callInputBlock.StateOverrides != null) + { + ModifyAccounts(callInputBlock.StateOverrides, env.StateProvider, currentSpec); + } + + env.StateProvider.Commit(currentSpec); + env.StateProvider.CommitTree(currentBlock.Number); + env.StateProvider.RecalculateStateRoot(); var transactions = callInputBlock.Calls.Select(model => model.GetTransaction()).ToList(); foreach (Transaction transaction in transactions) @@ -387,23 +398,21 @@ private void CallAndRestore( if (transaction.Nonce == 0) { - transaction.Nonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; + try + { + transaction.Nonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; + } + catch (TrieException) + { + // Transaction from unknown account + } } transaction.Hash = transaction.CalculateHash(); } - Block? currentBlock = new(callHeader, transactions, Array.Empty()); + currentBlock = currentBlock.WithReplacedBody(currentBlock.Body.WithChangedTransactions(transactions.ToArray())); - var currentSpec = env.SpecProvider.GetSpec(currentBlock.Header); - if (callInputBlock.StateOverrides != null) - { - ModifyAccounts(callInputBlock.StateOverrides, env.StateProvider, currentSpec); - } - - env.StateProvider.Commit(currentSpec); - env.StateProvider.CommitTree(currentBlock.Number); - env.StateProvider.RecalculateStateRoot(); currentBlock.Header.StateRoot = env.StateProvider.StateRoot; currentBlock.Header.IsPostMerge = true; //ToDo: Seal if necessary before merge 192 BPB diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 5a4fff49003..e624af33b7e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -12,6 +12,7 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Modules.Eth; using NUnit.Framework; +using static Nethermind.TxPool.TransactionExtensions; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -91,6 +92,15 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( SenderAddress = TestItem.PublicKeyB.Address }; + + chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + + var header = chain.BlockFinder.Head.Header; + var spec = chain.SpecProvider.GetSpec(header); + systemTransactionForModifiedVM.GasPrice = header.BaseFeePerGas >= 1 ? header.BaseFeePerGas : 1; + systemTransactionForModifiedVM.GasLimit = (long)systemTransactionForModifiedVM.CalculateTransactionPotentialCost(spec.IsEip1559Enabled, header.BaseFeePerGas); + MultiCallBlockStateCallsModel requestMultiCall = new() { StateOverrides = new[] From 8ab2090640e1f9845606dd410d7dcb2c4d60f59a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 31 Jul 2023 11:34:02 +0100 Subject: [PATCH 035/213] Cleaning up tracers --- .../Tracing/AlwaysCancelTxTracer.cs | 1 - .../Tracing/BlockReceiptsTracer.cs | 8 - .../Tracing/CancellationTxTracer.cs | 15 - .../Tracing/CompositeTxTracer.cs | 13 - .../Tracing/Debugger/DebugTracer.cs | 5 - .../Nethermind.Evm/Tracing/ITxTracer.cs | 16 - .../Proxy/Models/CallTransactionModel.cs | 63 +- .../ConsensusHelperTests.cs | 449 +++++++------ .../EthMulticallTestsSimplePrecompiles.cs | 4 +- .../Nethermind.JsonRpc/IJsonRpcConfig.cs | 267 ++++---- .../Nethermind.JsonRpc/JsonRpcConfig.cs | 76 +-- .../Modules/Eth/EthRpcModuleProxy.cs | 601 +++++++++--------- .../StateTestTxTracer.cs | 8 +- 13 files changed, 717 insertions(+), 809 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs index fd0ed81a509..837e9e1701d 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs @@ -95,6 +95,5 @@ public static AlwaysCancelTxTracer Instance public void ReportExtraGasPressure(long extraGasPressure) => throw new OperationCanceledException(ErrorMessage); public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) => throw new OperationCanceledException(ErrorMessage); public void ReportFees(UInt256 fees, UInt256 burntFees) => throw new OperationCanceledException(ErrorMessage); - public void ReportEvent(LogEntry logEntry) => throw new OperationCanceledException(ErrorMessage); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index eee31af1cfc..98d7bbca3a0 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -191,14 +191,6 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) } } - public void ReportEvent(LogEntry logEntry) - { - if (_currentTxTracer.IsTracingEventLogs) - { - _currentTxTracer.ReportEvent(logEntry); - } - } - private ITxTracer _currentTxTracer = NullTxTracer.Instance; private int _currentIndex; private readonly List _txReceipts = new(); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs index 97280f3c971..2358f0db77a 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs @@ -28,12 +28,6 @@ public class CancellationTxTracer : ITxTracer, ITxTracerWrapper private readonly bool _isTracingBlockAccess; private readonly bool _isTracingFees; - public bool IsTracingEventLogs - { - get => _isTracingEventLogs || _innerTracer.IsTracingEventLogs; - init => _isTracingEventLogs = value; - } - public ITxTracer InnerTracer => _innerTracer; public CancellationTxTracer(ITxTracer innerTracer, CancellationToken token = default) @@ -443,14 +437,5 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) _innerTracer.ReportFees(fees, burntFees); } } - - public void ReportEvent(LogEntry logEntry) - { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingEventLogs) - { - _innerTracer.ReportEvent(logEntry); - } - } } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs index d12ba068a96..46fce372255 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CompositeTxTracer.cs @@ -36,7 +36,6 @@ public CompositeTxTracer(IList txTracers) IsTracingStorage |= t.IsTracingStorage; IsTracingAccess |= t.IsTracingAccess; IsTracingFees |= t.IsTracingFees; - IsTracingEventLogs |= t.IsTracingEventLogs; } } @@ -485,17 +484,5 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) } } } - - public void ReportEvent(LogEntry logEntry) - { - for (int index = 0; index < _txTracers.Count; index++) - { - ITxTracer innerTracer = _txTracers[index]; - if (innerTracer.IsTracingEventLogs) - { - innerTracer.ReportEvent(logEntry); - } - } - } } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs index 398f3ac99ff..9dc26248fe1 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/Debugger/DebugTracer.cs @@ -256,11 +256,6 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet InnerTracer.ReportFees(fees, burntFees); - public void ReportEvent(LogEntry logEntry) - { - ((ITxTracer)InnerTracer).ReportEvent(logEntry); - } - public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) => InnerTracer.ReportBalanceChange(address, before, after); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index 2a347b18fa4..74bf60f8f6e 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -137,15 +137,6 @@ public interface ITxTracer : IWorldStateTracer || IsTracingAccess || IsTracingFees; - /// - /// Traces transaction logs and events - /// - /// - /// Controls - /// - - /// - bool IsTracingEventLogs { get; } - /// /// Transaction completed successfully /// @@ -428,12 +419,5 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// EIP-1559 burnt fees /// Depends on void ReportFees(UInt256 fees, UInt256 burntFees); - - - /// - /// Reports event logs of a transaction - /// - /// log Entry created - void ReportEvent(LogEntry logEntry); } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs index 571e9e1f714..ce407d04d5b 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs @@ -1,41 +1,52 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using Nethermind.Core; -using Nethermind.Crypto; using Nethermind.Int256; using static Nethermind.Core.Extensions.MemoryExtensions; -namespace Nethermind.Facade.Proxy.Models; - -public class CallTransactionModel +namespace Nethermind.Facade.Proxy.Models { - public Address? From { get; set; } - public Address To { get; set; } - public UInt256 Gas { get; set; } - public UInt256 GasPrice { get; set; } - public UInt256 Value { get; set; } - public byte[] Data { get; set; } - - public Transaction GetTransaction() + public class CallTransactionModel { - if (Gas > long.MaxValue) throw new OverflowException("Gas value is too large to be converted to long we use."); + public Address From { get; set; } + public Address To { get; set; } + public UInt256 Gas { get; set; } + public UInt256 GasPrice { get; set; } + public UInt256 Value { get; set; } + public byte[] Data { get; set; } + + public static CallTransactionModel FromTransaction(Transaction transaction) + => new() + { + From = transaction.SenderAddress, + To = transaction.To, + Data = transaction.Data.AsArray(), + Value = transaction.Value, + Gas = (UInt256)transaction.GasLimit, + GasPrice = transaction.GasPrice + }; + + public Transaction GetTransaction() + { + if (Gas > long.MaxValue) throw new OverflowException("Gas value is too large to be converted to long we use."); - From ??= Address.SystemUser; + From ??= Address.SystemUser; - Transaction? result = new Transaction - { - SenderAddress = From, - To = To, - Data = Data, - Value = Value, - GasLimit = (long)Gas, - GasPrice = GasPrice + Transaction? result = new Transaction + { + SenderAddress = From, + To = To, + Data = Data, + Value = Value, + GasLimit = (long)Gas, + GasPrice = GasPrice + + }; - }; + result.Hash = result.CalculateHash(); + return result; + } - result.Hash = result.CalculateHash(); - return result; } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs index d01e7c7025f..2be75896609 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.cs @@ -8,11 +8,8 @@ using FluentAssertions; using FluentAssertions.Equivalency; using FluentAssertions.Json; -using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Core.Extensions; using Nethermind.Evm.Tracing.GethStyle; -using Nethermind.Facade.Proxy.Models; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.DebugModule; using Nethermind.JsonRpc.Modules.Trace; @@ -21,296 +18,280 @@ using Newtonsoft.Json.Linq; using NUnit.Framework; -namespace Nethermind.JsonRpc.Test; - -public static class Extensions +namespace Nethermind.JsonRpc.Test { - public static CallTransactionModel FromTransaction(this Transaction transaction) + [Explicit] + public partial class ConsensusHelperTests { - return new() - { - From = transaction.SenderAddress, - To = transaction.To, - Data = transaction.Data.AsArray(), - Value = transaction.Value, - Gas = (ulong)transaction.GasLimit, - GasPrice = transaction.GasPrice - }; - } -} - - -[Explicit] -public partial class ConsensusHelperTests -{ - private static Func, EquivalencyAssertionOptions> ReceiptOptions = - options => options.WithStrictOrdering() - .IncludingNestedObjects() - .Including(r => r.TransactionHash) - .Including(r => r.TransactionIndex) - .Including(r => r.BlockHash) - .Including(r => r.BlockNumber) - .Including(r => r.From) - .Including(r => r.To) - .Including(r => r.CumulativeGasUsed) - .Including(r => r.GasUsed) - .Including(r => r.ContractAddress) - .Including(r => r.LogsBloom) - .Including(r => r.Logs) - .Including(r => r.Root) - .Including(r => r.Status); + private static Func, EquivalencyAssertionOptions> ReceiptOptions = + options => options.WithStrictOrdering() + .IncludingNestedObjects() + .Including(r => r.TransactionHash) + .Including(r => r.TransactionIndex) + .Including(r => r.BlockHash) + .Including(r => r.BlockNumber) + .Including(r => r.From) + .Including(r => r.To) + .Including(r => r.CumulativeGasUsed) + .Including(r => r.GasUsed) + .Including(r => r.ContractAddress) + .Including(r => r.LogsBloom) + .Including(r => r.Logs) + .Including(r => r.Root) + .Including(r => r.Status); - public static IEnumerable Tests - { - get + public static IEnumerable Tests { - // yield return new TestCaseData(new Uri("file:///c:/temp/data1"), new Uri("file:///c:/temp/data1")); - // yield return new TestCaseData(new Uri("http://localhost:8545"), new Uri("http://localhost:8545"), 10l); - // yield return new TestCaseData(new Uri("http://localhost:8545"), new Uri("http://localhost:8545"), new Keccak("0x0"), new GethTraceOptions()); - yield break; + get + { + // yield return new TestCaseData(new Uri("file:///c:/temp/data1"), new Uri("file:///c:/temp/data1")); + // yield return new TestCaseData(new Uri("http://localhost:8545"), new Uri("http://localhost:8545"), 10l); + // yield return new TestCaseData(new Uri("http://localhost:8545"), new Uri("http://localhost:8545"), new Keccak("0x0"), new GethTraceOptions()); + yield break; + } } - } - [TestCaseSource(nameof(Tests))] - public async Task CompareReceipts(Uri uri1, Uri uri2, Keccak? blockHash = null) - { - using IConsensusDataSource> receipt1Source = GetSource>(uri1); - using IConsensusDataSource> receipt2Source = GetSource>(uri2); - TrySetData(blockHash, receipt1Source, receipt2Source); - await CompareCollection(receipt1Source, receipt2Source, false, ReceiptOptions); - } + [TestCaseSource(nameof(Tests))] + public async Task CompareReceipts(Uri uri1, Uri uri2, Keccak? blockHash = null) + { + using IConsensusDataSource> receipt1Source = GetSource>(uri1); + using IConsensusDataSource> receipt2Source = GetSource>(uri2); + TrySetData(blockHash, receipt1Source, receipt2Source); + await CompareCollection(receipt1Source, receipt2Source, false, ReceiptOptions); + } - [TestCaseSource(nameof(Tests))] - public async Task CompareReceipt(Uri uri1, Uri uri2, Keccak? blockHash = null) - { - using IConsensusDataSource receipt1Source = GetSource(uri1); - using IConsensusDataSource receipt2Source = GetSource(uri2); - TrySetData(blockHash, receipt1Source, receipt2Source); - await Compare(receipt1Source, receipt2Source, false, ReceiptOptions); - } + [TestCaseSource(nameof(Tests))] + public async Task CompareReceipt(Uri uri1, Uri uri2, Keccak? blockHash = null) + { + using IConsensusDataSource receipt1Source = GetSource(uri1); + using IConsensusDataSource receipt2Source = GetSource(uri2); + TrySetData(blockHash, receipt1Source, receipt2Source); + await Compare(receipt1Source, receipt2Source, false, ReceiptOptions); + } - [TestCaseSource(nameof(Tests))] - public async Task CompareGethBlockTrace(Uri uri1, Uri uri2, Keccak? blockHash = null, GethTraceOptions? gethTraceOptions = null) - { - gethTraceOptions ??= GethTraceOptions.Default; - using IConsensusDataSource> receipt1Source = GetSource>(uri1, DebugModuleFactory.Converters); - using IConsensusDataSource> receipt2Source = GetSource>(uri2, DebugModuleFactory.Converters); - TrySetData(blockHash, receipt1Source, receipt2Source); - TrySetData(gethTraceOptions, receipt1Source, receipt2Source); - await CompareCollection(receipt1Source, receipt2Source, true); - } + [TestCaseSource(nameof(Tests))] + public async Task CompareGethBlockTrace(Uri uri1, Uri uri2, Keccak? blockHash = null, GethTraceOptions? gethTraceOptions = null) + { + gethTraceOptions ??= GethTraceOptions.Default; + using IConsensusDataSource> receipt1Source = GetSource>(uri1, DebugModuleFactory.Converters); + using IConsensusDataSource> receipt2Source = GetSource>(uri2, DebugModuleFactory.Converters); + TrySetData(blockHash, receipt1Source, receipt2Source); + TrySetData(gethTraceOptions, receipt1Source, receipt2Source); + await CompareCollection(receipt1Source, receipt2Source, true); + } - [TestCaseSource(nameof(Tests))] - public async Task CompareGethTxTrace(Uri uri1, Uri uri2, Keccak? transactionHash = null, GethTraceOptions? gethTraceOptions = null) - { - gethTraceOptions ??= GethTraceOptions.Default; - using IConsensusDataSource receipt1Source = GetSource(uri1, DebugModuleFactory.Converters); - using IConsensusDataSource receipt2Source = GetSource(uri2, DebugModuleFactory.Converters); - TrySetData(transactionHash, receipt1Source, receipt2Source); - TrySetData(gethTraceOptions, receipt1Source, receipt2Source); - await Compare(receipt1Source, receipt2Source, true); - } + [TestCaseSource(nameof(Tests))] + public async Task CompareGethTxTrace(Uri uri1, Uri uri2, Keccak? transactionHash = null, GethTraceOptions? gethTraceOptions = null) + { + gethTraceOptions ??= GethTraceOptions.Default; + using IConsensusDataSource receipt1Source = GetSource(uri1, DebugModuleFactory.Converters); + using IConsensusDataSource receipt2Source = GetSource(uri2, DebugModuleFactory.Converters); + TrySetData(transactionHash, receipt1Source, receipt2Source); + TrySetData(gethTraceOptions, receipt1Source, receipt2Source); + await Compare(receipt1Source, receipt2Source, true); + } - [TestCaseSource(nameof(Tests))] - public async Task CompareParityBlockTrace(Uri uri1, Uri uri2, long blockNumber) - { - using IConsensusDataSource> receipt1Source = GetSource>(uri1, TraceModuleFactory.Converters); - using IConsensusDataSource> receipt2Source = GetSource>(uri2, TraceModuleFactory.Converters); - TrySetData(blockNumber, receipt1Source, receipt2Source); - await CompareCollection(receipt1Source, receipt2Source, true); - } + [TestCaseSource(nameof(Tests))] + public async Task CompareParityBlockTrace(Uri uri1, Uri uri2, long blockNumber) + { + using IConsensusDataSource> receipt1Source = GetSource>(uri1, TraceModuleFactory.Converters); + using IConsensusDataSource> receipt2Source = GetSource>(uri2, TraceModuleFactory.Converters); + TrySetData(blockNumber, receipt1Source, receipt2Source); + await CompareCollection(receipt1Source, receipt2Source, true); + } - private void TrySetData(TData blockHash, params object[] sources) - { - foreach (object source in sources) + private void TrySetData(TData blockHash, params object[] sources) { - if (source is IConsensusDataSourceWithParameter consensusDataSourceWithBlock) + foreach (object source in sources) { - consensusDataSourceWithBlock.Parameter = blockHash; + if (source is IConsensusDataSourceWithParameter consensusDataSourceWithBlock) + { + consensusDataSourceWithBlock.Parameter = blockHash; + } } } - } - private IConsensusDataSource GetSource(Uri uri, IEnumerable? additionalConverters = null) - { - var serializer = GetSerializer(additionalConverters!); - if (uri.IsFile) - { - return new FileConsensusDataSource(uri, serializer); - } - else if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) + private IConsensusDataSource GetSource(Uri uri, IEnumerable? additionalConverters = null) { - Type type = typeof(T); - if (type == typeof(IEnumerable)) + var serializer = GetSerializer(additionalConverters!); + if (uri.IsFile) { - return (IConsensusDataSource)new ReceiptsJsonRpcDataSource(uri, serializer); + return new FileConsensusDataSource(uri, serializer); } - if (type == typeof(ReceiptForRpc)) + else if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) { - return (IConsensusDataSource)new ReceiptsJsonRpcDataSource(uri, serializer); + Type type = typeof(T); + if (type == typeof(IEnumerable)) + { + return (IConsensusDataSource)new ReceiptsJsonRpcDataSource(uri, serializer); + } + if (type == typeof(ReceiptForRpc)) + { + return (IConsensusDataSource)new ReceiptsJsonRpcDataSource(uri, serializer); + } + else if (type == typeof(IEnumerable)) + { + return (IConsensusDataSource)new GethLikeBlockTraceJsonRpcDataSource(uri, serializer); + } + else if (type == typeof(GethLikeTxTrace)) + { + return (IConsensusDataSource)new GethLikeTxTraceJsonRpcDataSource(uri, serializer); + } + else if (type == typeof(IEnumerable)) + { + return (IConsensusDataSource)new ParityLikeBlockTraceJsonRpcDataSource(uri, serializer); + } } - else if (type == typeof(IEnumerable)) + + throw new NotSupportedException($"Uri: {uri} is not supported"); + } + + private IJsonSerializer GetSerializer(IEnumerable? additionalConverters) + { + IJsonSerializer jsonSerializer = new EthereumJsonSerializer(); + if (additionalConverters is not null) { - return (IConsensusDataSource)new GethLikeBlockTraceJsonRpcDataSource(uri, serializer); + jsonSerializer.RegisterConverters(additionalConverters); } - else if (type == typeof(GethLikeTxTrace)) + + return jsonSerializer; + } + + private static async Task Compare(IConsensusDataSource source1, + IConsensusDataSource source2, + bool compareJson, + Func, EquivalencyAssertionOptions>? options = null) + { + + if (compareJson) { - return (IConsensusDataSource)new GethLikeTxTraceJsonRpcDataSource(uri, serializer); + JToken data = JsonHelper.ParseNormalize(await source1.GetJsonData()); + JToken expectation = JsonHelper.ParseNormalize(await source2.GetJsonData()); + data.Should().BeEquivalentTo(expectation); + data["error"].Should().BeNull(data["error"]?.ToString()); } - else if (type == typeof(IEnumerable)) + else { - return (IConsensusDataSource)new ParityLikeBlockTraceJsonRpcDataSource(uri, serializer); + string dataJson = string.Empty, expectationJson = string.Empty; + try + { + T data, expectation; + (data, dataJson) = await source1.GetData(); + (expectation, expectationJson) = await source2.GetData(); + data.Should().BeEquivalentTo(expectation, options ?? (o => o)); + } + finally + { + await WriteOutJson(dataJson, expectationJson); + } } } - throw new NotSupportedException($"Uri: {uri} is not supported"); - } - - private IJsonSerializer GetSerializer(IEnumerable? additionalConverters) - { - IJsonSerializer jsonSerializer = new EthereumJsonSerializer(); - if (additionalConverters is not null) + private static async Task CompareCollection(IConsensusDataSource> source1, + IConsensusDataSource> source2, + bool compareJson, + Func, EquivalencyAssertionOptions>? options = null) { - jsonSerializer.RegisterConverters(additionalConverters); - } - - return jsonSerializer; - } - - private static async Task Compare(IConsensusDataSource source1, - IConsensusDataSource source2, - bool compareJson, - Func, EquivalencyAssertionOptions>? options = null) - { - if (compareJson) - { - JToken data = JsonHelper.ParseNormalize(await source1.GetJsonData()); - JToken expectation = JsonHelper.ParseNormalize(await source2.GetJsonData()); - data.Should().BeEquivalentTo(expectation); - data["error"].Should().BeNull(data["error"]?.ToString()); - } - else - { - string dataJson = string.Empty, expectationJson = string.Empty; - try + if (compareJson) { - T data, expectation; - (data, dataJson) = await source1.GetData(); - (expectation, expectationJson) = await source2.GetData(); - data.Should().BeEquivalentTo(expectation, options ?? (o => o)); + JToken data = JsonHelper.ParseNormalize(await source1.GetJsonData()); + JToken expectation = JsonHelper.ParseNormalize(await source2.GetJsonData()); + data.Should().BeEquivalentTo(expectation); + data["error"].Should().BeNull(data["error"]?.ToString()); } - finally + else { - await WriteOutJson(dataJson, expectationJson); + string dataJson = string.Empty, expectationJson = string.Empty; + try + { + IEnumerable data, expectation; + (data, dataJson) = await source1.GetData(); + (expectation, expectationJson) = await source2.GetData(); + data.Should().BeEquivalentTo(expectation, options ?? (o => o)); + } + finally + { + await WriteOutJson(dataJson, expectationJson); + } + } } - } - private static async Task CompareCollection(IConsensusDataSource> source1, - IConsensusDataSource> source2, - bool compareJson, - Func, EquivalencyAssertionOptions>? options = null) - { - - if (compareJson) - { - JToken data = JsonHelper.ParseNormalize(await source1.GetJsonData()); - JToken expectation = JsonHelper.ParseNormalize(await source2.GetJsonData()); - data.Should().BeEquivalentTo(expectation); - data["error"].Should().BeNull(data["error"]?.ToString()); - } - else + private static async Task WriteOutJson(string dataJson, string expectationJson) { - string dataJson = string.Empty, expectationJson = string.Empty; try { - IEnumerable data, expectation; - (data, dataJson) = await source1.GetData(); - (expectation, expectationJson) = await source2.GetData(); - data.Should().BeEquivalentTo(expectation, options ?? (o => o)); - } - finally - { - await WriteOutJson(dataJson, expectationJson); + JToken data = JsonHelper.ParseNormalize(dataJson); + JToken expectation = JsonHelper.ParseNormalize(expectationJson); + await TestContext.Out.WriteLineAsync(); + await TestContext.Out.WriteLineAsync(data.ToString(Formatting.Indented)); + await TestContext.Out.WriteLineAsync(); + await TestContext.Out.WriteLineAsync("-------------------------------------------------------------"); + await TestContext.Out.WriteLineAsync(); + await TestContext.Out.WriteLineAsync(expectation.ToString(Formatting.Indented)); } - + catch (JsonException) { } } - } - private static async Task WriteOutJson(string dataJson, string expectationJson) - { - try + private interface IConsensusDataSource : IDisposable { - JToken data = JsonHelper.ParseNormalize(dataJson); - JToken expectation = JsonHelper.ParseNormalize(expectationJson); - await TestContext.Out.WriteLineAsync(); - await TestContext.Out.WriteLineAsync(data.ToString(Formatting.Indented)); - await TestContext.Out.WriteLineAsync(); - await TestContext.Out.WriteLineAsync("-------------------------------------------------------------"); - await TestContext.Out.WriteLineAsync(); - await TestContext.Out.WriteLineAsync(expectation.ToString(Formatting.Indented)); + Task<(T, string)> GetData(); + Task GetJsonData(); } - catch (JsonException) { } - } - private interface IConsensusDataSource : IDisposable - { - Task<(T, string)> GetData(); - Task GetJsonData(); - } - - private interface IConsensusDataSourceWithParameter - { - TData Parameter { get; set; } - } - - public static class JsonHelper - { - public static JToken ParseNormalize(string json) => Normalize(JToken.Parse(json)); + private interface IConsensusDataSourceWithParameter + { + TData Parameter { get; set; } + } - public static JToken Normalize(JToken token) + public static class JsonHelper { - if (token.Type == JTokenType.Object) + public static JToken ParseNormalize(string json) => Normalize(JToken.Parse(json)); + + public static JToken Normalize(JToken token) { - JObject copy = new(); - foreach (JProperty prop in token.Children()) + if (token.Type == JTokenType.Object) { - JToken child = prop.Value; - if (child.HasValues) + JObject copy = new(); + foreach (JProperty prop in token.Children()) { - child = Normalize(child); - } - if (!IsEmpty(child)) - { - copy.Add(prop.Name, child); + JToken child = prop.Value; + if (child.HasValues) + { + child = Normalize(child); + } + if (!IsEmpty(child)) + { + copy.Add(prop.Name, child); + } } + return copy; } - return copy; - } - else if (token.Type == JTokenType.Array) - { - JArray copy = new(); - foreach (JToken item in token.Children()) + else if (token.Type == JTokenType.Array) { - JToken child = item; - if (child.HasValues) + JArray copy = new(); + foreach (JToken item in token.Children()) { - child = Normalize(child); - } - if (!IsEmpty(child)) - { - copy.Add(child); + JToken child = item; + if (child.HasValues) + { + child = Normalize(child); + } + if (!IsEmpty(child)) + { + copy.Add(child); + } } + return copy; } - return copy; + return token; } - return token; - } - public static bool IsEmpty(JToken token) - { - return (token.Type == JTokenType.Null); + public static bool IsEmpty(JToken token) + { + return (token.Type == JTokenType.Null); + } } } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 799e75a6c1c..81cc4fe1e0e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -97,13 +97,13 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe BlockchainBridge.MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, new[] { requestMultiCall }, CancellationToken.None); Log[]? logs = result.items.First().Calls.First().Logs; - + //Check that initial VM is intact Address? mainChainRpcAddress = EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); Assert.NotNull(mainChainRpcAddress); Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); - + } } diff --git a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs index 98a2b7c870b..506f7b4749b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs @@ -4,26 +4,24 @@ using Nethermind.Config; using Nethermind.JsonRpc.Modules.Eth; -namespace Nethermind.JsonRpc; - -public interface IJsonRpcConfig : IConfig +namespace Nethermind.JsonRpc { - [ConfigItem( - Description = - "Defines whether the JSON RPC service is enabled on node startup. Configure host and port if default values do not work for you.", - DefaultValue = "false")] - bool Enabled { get; set; } + public interface IJsonRpcConfig : IConfig + { + [ConfigItem( + Description = "Defines whether the JSON RPC service is enabled on node startup. Configure host and port if default values do not work for you.", + DefaultValue = "false")] + bool Enabled { get; set; } - [ConfigItem( - Description = - "Host for JSON RPC calls. Ensure the firewall is configured when enabling JSON RPC. If it does not work with 127.0.0.1 try something like 10.0.0.4 or 192.168.0.1", - DefaultValue = "\"127.0.0.1\"")] - string Host { get; set; } + [ConfigItem( + Description = "Host for JSON RPC calls. Ensure the firewall is configured when enabling JSON RPC. If it does not work with 127.0.0.1 try something like 10.0.0.4 or 192.168.0.1", + DefaultValue = "\"127.0.0.1\"")] + string Host { get; set; } - [ConfigItem( - Description = "JSON RPC' timeout value given in milliseconds.", - DefaultValue = "20000")] - int Timeout { get; set; } + [ConfigItem( + Description = "JSON RPC' timeout value given in milliseconds.", + DefaultValue = "20000")] + int Timeout { get; set; } [ConfigItem( Description = "The queued request limit for calls above the max concurrency amount for (" + @@ -43,131 +41,112 @@ public interface IJsonRpcConfig : IConfig DefaultValue = "\"logs/rpc.{counter}.txt\"")] string RpcRecorderBaseFilePath { get; set; } - [ConfigItem( - Description = - "Defines whether the JSON RPC diagnostic recording is enabled on node startup. Do not enable unless you are a DEV diagnosing issues with JSON RPC. Possible values: None/Request/Response/All.", - DefaultValue = "None")] - RpcRecorderState RpcRecorderState { get; set; } - - [ConfigItem( - Description = "Port number for JSON RPC calls. Ensure the firewall is configured when enabling JSON RPC.", - DefaultValue = "8545")] - int Port { get; set; } - - [ConfigItem( - Description = - "Port number for JSON RPC web sockets calls. By default same port is used as regular JSON RPC. Ensure the firewall is configured when enabling JSON RPC.", - DefaultValue = "8545")] - int WebSocketsPort { get; set; } - - [ConfigItem(Description = "The path to connect a unix domain socket over.")] - string IpcUnixDomainSocketPath { get; set; } - - [ConfigItem( - Description = - "Defines which RPC modules should be enabled. Built in modules are: Admin, Clique, Consensus, Db, Debug, Deposit, Erc20, Eth, Evm, Health Mev, NdmConsumer, NdmProvider, Net, Nft, Parity, Personal, Proof, Subscribe, Trace, TxPool, Vault, Web3.", - DefaultValue = "[Eth, Subscribe, Trace, TxPool, Web3, Personal, Proof, Net, Parity, Health, Rpc]")] - string[] EnabledModules { get; set; } - - [ConfigItem( - Description = - "Defines additional RPC urls to listen on. Example url format: http://localhost:8550|http;wss|engine;eth;net;subscribe", - DefaultValue = "[]")] - string[] AdditionalRpcUrls { get; set; } - - [ConfigItem( - Description = "Gas limit for eth_call and eth_estimateGas", - DefaultValue = "100000000")] - long? GasCap { get; set; } - - [ConfigItem( - Description = "Gas limit multiplier for eth_multicall. uint256 = GasCap * value", - DefaultValue = "2")] - ulong? GasCapMultiplier { get; set; } - - - [ConfigItem( - Description = "Interval between the JSON RPC stats report log", - DefaultValue = "300")] - int ReportIntervalSeconds { get; set; } - - [ConfigItem( - Description = - "Buffer responses before sending them to client. This allows to set Content-Length in response instead of using Transfer-Encoding: chunked. This may degrade performance on big responses. Max buffered response size is 2GB, chunked responses can be bigger.", - DefaultValue = "false")] - bool BufferResponses { get; set; } - - [ConfigItem( - Description = "A path to a file that contains a list of new-line separated approved JSON RPC calls", - DefaultValue = "Data/jsonrpc.filter")] - string CallsFilterFilePath { get; set; } - - [ConfigItem( - Description = "Max HTTP request body size", - DefaultValue = "30000000")] - long? MaxRequestBodySize { get; set; } - - [ConfigItem( - Description = "Number of concurrent instances for non-sharable calls (" + - nameof(IEthRpcModule.eth_call) + ", " + - nameof(IEthRpcModule.eth_estimateGas) + ", " + - nameof(IEthRpcModule.eth_getLogs) + ", " + - nameof(IEthRpcModule.eth_newFilter) + ", " + - nameof(IEthRpcModule.eth_newBlockFilter) + ", " + - nameof(IEthRpcModule.eth_newPendingTransactionFilter) + ", " + - nameof(IEthRpcModule.eth_uninstallFilter) + ", " + - nameof(IEthRpcModule.eth_multicall) + "). " + - "This will limit load on the node CPU and IO to reasonable levels. " + - "If this limit is exceeded on Http calls 503 Service Unavailable will be returned along with Json RPC error. " + - "Defaults to number of logical processes.")] - int? EthModuleConcurrentInstances { get; set; } - - [ConfigItem(Description = "Path to file with hex encoded secret for jwt authentication", - DefaultValue = "keystore/jwt-secret")] - public string JwtSecretFile { get; set; } - - [ConfigItem( - Description = - "It shouldn't be set to true for production nodes. If set to true all modules can work without RPC authentication.", - DefaultValue = "false", HiddenFromDocs = true)] - public bool UnsecureDevNoRpcAuthentication { get; set; } - - [ConfigItem( - Description = "Limits the Maximum characters printing to log for parameters of any Json RPC service request", - DefaultValue = "null")] - int? MaxLoggedRequestParametersCharacters { get; set; } - - [ConfigItem( - Description = - "Defines method names of Json RPC service requests to NOT log. Example: {\"eth_blockNumber\"} will not log \"eth_blockNumber\" requests.", - DefaultValue = - "[engine_newPayloadV1, engine_newPayloadV2, engine_newPayloadV3, engine_forkchoiceUpdatedV1, engine_forkchoiceUpdatedV2]")] - public string[]? MethodsLoggingFiltering { get; set; } - - [ConfigItem( - Description = - "Host for Execution Engine calls. Ensure the firewall is configured when enabling JSON RPC. If it does not work with 127.0.0.1 try something like 10.0.0.4 or 192.168.0.1", - DefaultValue = "\"127.0.0.1\"")] - string EngineHost { get; set; } - - [ConfigItem( - Description = "Port for Execution Engine calls. Ensure the firewall is configured when enabling JSON RPC.", - DefaultValue = "null")] - int? EnginePort { get; set; } - - [ConfigItem( - Description = - "Defines which RPC modules should be enabled Execution Engine port. Built in modules are: Admin, Clique, Consensus, Db, Debug, Deposit, Erc20, Eth, Evm, Health Mev, NdmConsumer, NdmProvider, Net, Nft, Parity, Personal, Proof, Subscribe, Trace, TxPool, Vault, Web3.", - DefaultValue = "[Net, Eth, Subscribe, Web3]")] - string[] EngineEnabledModules { get; set; } - - [ConfigItem( - Description = "Limit batch size for batched json rpc call", - DefaultValue = "1024")] - int MaxBatchSize { get; set; } - - [ConfigItem( - Description = "Max response body size when using batch requests, subsequent requests are trimmed", - DefaultValue = "30000000")] - long? MaxBatchResponseBodySize { get; set; } + [ConfigItem( + Description = "Defines whether the JSON RPC diagnostic recording is enabled on node startup. Do not enable unless you are a DEV diagnosing issues with JSON RPC. Possible values: None/Request/Response/All.", + DefaultValue = "None")] + RpcRecorderState RpcRecorderState { get; set; } + + [ConfigItem( + Description = "Port number for JSON RPC calls. Ensure the firewall is configured when enabling JSON RPC.", + DefaultValue = "8545")] + int Port { get; set; } + + [ConfigItem( + Description = "Port number for JSON RPC web sockets calls. By default same port is used as regular JSON RPC. Ensure the firewall is configured when enabling JSON RPC.", + DefaultValue = "8545")] + int WebSocketsPort { get; set; } + + [ConfigItem(Description = "The path to connect a unix domain socket over.")] + string IpcUnixDomainSocketPath { get; set; } + + [ConfigItem( + Description = "Defines which RPC modules should be enabled. Built in modules are: Admin, Clique, Consensus, Db, Debug, Deposit, Erc20, Eth, Evm, Health Mev, NdmConsumer, NdmProvider, Net, Nft, Parity, Personal, Proof, Subscribe, Trace, TxPool, Vault, Web3.", + DefaultValue = "[Eth, Subscribe, Trace, TxPool, Web3, Personal, Proof, Net, Parity, Health, Rpc]")] + string[] EnabledModules { get; set; } + + [ConfigItem( + Description = "Defines additional RPC urls to listen on. Example url format: http://localhost:8550|http;wss|engine;eth;net;subscribe", + DefaultValue = "[]")] + string[] AdditionalRpcUrls { get; set; } + + [ConfigItem( + Description = "Gas limit for eth_call and eth_estimateGas", + DefaultValue = "100000000")] + long? GasCap { get; set; } + + [ConfigItem( + Description = "Interval between the JSON RPC stats report log", + DefaultValue = "300")] + int ReportIntervalSeconds { get; set; } + + [ConfigItem( + Description = "Buffer responses before sending them to client. This allows to set Content-Length in response instead of using Transfer-Encoding: chunked. This may degrade performance on big responses. Max buffered response size is 2GB, chunked responses can be bigger.", + DefaultValue = "false")] + bool BufferResponses { get; set; } + + [ConfigItem( + Description = "A path to a file that contains a list of new-line separated approved JSON RPC calls", + DefaultValue = "Data/jsonrpc.filter")] + string CallsFilterFilePath { get; set; } + + [ConfigItem( + Description = "Max HTTP request body size", + DefaultValue = "30000000")] + long? MaxRequestBodySize { get; set; } + + [ConfigItem( + Description = "Number of concurrent instances for non-sharable calls (" + + nameof(IEthRpcModule.eth_call) + ", " + + nameof(IEthRpcModule.eth_estimateGas) + ", " + + nameof(IEthRpcModule.eth_getLogs) + ", " + + nameof(IEthRpcModule.eth_newFilter) + ", " + + nameof(IEthRpcModule.eth_newBlockFilter) + ", " + + nameof(IEthRpcModule.eth_newPendingTransactionFilter) + ", " + + nameof(IEthRpcModule.eth_uninstallFilter) + "). " + + "This will limit load on the node CPU and IO to reasonable levels. " + + "If this limit is exceeded on Http calls 503 Service Unavailable will be returned along with Json RPC error. " + + "Defaults to number of logical processes.")] + int? EthModuleConcurrentInstances { get; set; } + + [ConfigItem(Description = "Path to file with hex encoded secret for jwt authentication", DefaultValue = "keystore/jwt-secret")] + public string JwtSecretFile { get; set; } + + [ConfigItem(Description = "It shouldn't be set to true for production nodes. If set to true all modules can work without RPC authentication.", DefaultValue = "false", HiddenFromDocs = true)] + public bool UnsecureDevNoRpcAuthentication { get; set; } + + [ConfigItem( + Description = "Limits the Maximum characters printing to log for parameters of any Json RPC service request", + DefaultValue = "null")] + int? MaxLoggedRequestParametersCharacters { get; set; } + + [ConfigItem( + Description = "Defines method names of Json RPC service requests to NOT log. Example: {\"eth_blockNumber\"} will not log \"eth_blockNumber\" requests.", + DefaultValue = "[engine_newPayloadV1, engine_newPayloadV2, engine_newPayloadV3, engine_forkchoiceUpdatedV1, engine_forkchoiceUpdatedV2]")] + public string[]? MethodsLoggingFiltering { get; set; } + + [ConfigItem( + Description = "Host for Execution Engine calls. Ensure the firewall is configured when enabling JSON RPC. If it does not work with 127.0.0.1 try something like 10.0.0.4 or 192.168.0.1", + DefaultValue = "\"127.0.0.1\"")] + string EngineHost { get; set; } + + [ConfigItem( + Description = "Port for Execution Engine calls. Ensure the firewall is configured when enabling JSON RPC.", + DefaultValue = "null")] + int? EnginePort { get; set; } + + [ConfigItem( + Description = "Defines which RPC modules should be enabled Execution Engine port. Built in modules are: Admin, Clique, Consensus, Db, Debug, Deposit, Erc20, Eth, Evm, Health Mev, NdmConsumer, NdmProvider, Net, Nft, Parity, Personal, Proof, Subscribe, Trace, TxPool, Vault, Web3.", + DefaultValue = "[Net, Eth, Subscribe, Web3]")] + string[] EngineEnabledModules { get; set; } + + [ConfigItem( + Description = "Limit batch size for batched json rpc call", + DefaultValue = "1024")] + int MaxBatchSize { get; set; } + + [ConfigItem( + Description = "Max response body size when using batch requests, subsequent requests are trimmed", + DefaultValue = "30000000")] + long? MaxBatchResponseBodySize { get; set; } + } } diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs index 12c13ad329d..79bdf2dd36c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs @@ -6,9 +6,7 @@ using Nethermind.Core.Extensions; using Nethermind.JsonRpc.Modules; -namespace Nethermind.JsonRpc; - -public class JsonRpcConfig : IJsonRpcConfig +namespace Nethermind.JsonRpc { public class JsonRpcConfig : IJsonRpcConfig { @@ -20,40 +18,42 @@ public class JsonRpcConfig : IJsonRpcConfig public int RequestQueueLimit { get; set; } = 500; public string RpcRecorderBaseFilePath { get; set; } = "logs/rpc.{counter}.txt"; - public RpcRecorderState RpcRecorderState { get; set; } = RpcRecorderState.None; - - public int Port { get; set; } = 8545; - - public int WebSocketsPort - { - get => _webSocketsPort ?? Port; - set => _webSocketsPort = value; - } - - public string? IpcUnixDomainSocketPath { get; set; } = null; - - public string[] EnabledModules { get; set; } = ModuleType.DefaultModules.ToArray(); - public string[] AdditionalRpcUrls { get; set; } = Array.Empty(); - public long? GasCap { get; set; } = 100000000; - public ulong? GasCapMultiplier { get; set; } = 2; - public int ReportIntervalSeconds { get; set; } = 300; - public bool BufferResponses { get; set; } - public string CallsFilterFilePath { get; set; } = "Data/jsonrpc.filter"; - public long? MaxRequestBodySize { get; set; } = 30000000; - public int? EthModuleConcurrentInstances { get; set; } = null; - public string JwtSecretFile { get; set; } = "keystore/jwt-secret"; - public bool UnsecureDevNoRpcAuthentication { get; set; } - public int? MaxLoggedRequestParametersCharacters { get; set; } = null; - - public string[]? MethodsLoggingFiltering { get; set; } = - { - "engine_newPayloadV1", "engine_newPayloadV2", "engine_newPayloadV3", "engine_forkchoiceUpdatedV1", - "engine_forkchoiceUpdatedV2" + public RpcRecorderState RpcRecorderState { get; set; } = RpcRecorderState.None; + + public int Port { get; set; } = 8545; + + public int WebSocketsPort + { + get => _webSocketsPort ?? Port; + set => _webSocketsPort = value; + } + + public string? IpcUnixDomainSocketPath { get; set; } = null; + + public string[] EnabledModules { get; set; } = ModuleType.DefaultModules.ToArray(); + public string[] AdditionalRpcUrls { get; set; } = Array.Empty(); + public long? GasCap { get; set; } = 100000000; + public int ReportIntervalSeconds { get; set; } = 300; + public bool BufferResponses { get; set; } + public string CallsFilterFilePath { get; set; } = "Data/jsonrpc.filter"; + public long? MaxRequestBodySize { get; set; } = 30000000; + public int? EthModuleConcurrentInstances { get; set; } = null; + public string JwtSecretFile { get; set; } = "keystore/jwt-secret"; + public bool UnsecureDevNoRpcAuthentication { get; set; } + public int? MaxLoggedRequestParametersCharacters { get; set; } = null; + public string[]? MethodsLoggingFiltering { get; set; } = + { + "engine_newPayloadV1", + "engine_newPayloadV2", + "engine_newPayloadV3", + "engine_forkchoiceUpdatedV1", + "engine_forkchoiceUpdatedV2" + }; + public string EngineHost { get; set; } = "127.0.0.1"; + public int? EnginePort { get; set; } = null; + public string[] EngineEnabledModules { get; set; } = ModuleType.DefaultEngineModules.ToArray(); + public int MaxBatchSize { get; set; } = 1024; + public long? MaxBatchResponseBodySize { get; set; } = 30.MB(); }; +}; - public string EngineHost { get; set; } = "127.0.0.1"; - public int? EnginePort { get; set; } = null; - public string[] EngineEnabledModules { get; set; } = ModuleType.DefaultEngineModules.ToArray(); - public int MaxBatchSize { get; set; } = 1024; - public long? MaxBatchResponseBodySize { get; set; } = 30.MB(); -} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs index 34aac6281d6..e85fbfb9044 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs @@ -19,364 +19,365 @@ using Nethermind.State.Proofs; using Nethermind.Wallet; -namespace Nethermind.JsonRpc.Modules.Eth; - -public class EthRpcModuleProxy : IEthRpcModule +namespace Nethermind.JsonRpc.Modules.Eth { - private readonly IEthJsonRpcClientProxy _proxy; - private readonly IWallet _wallet; - - public EthRpcModuleProxy(IEthJsonRpcClientProxy proxy, IWallet wallet) + public class EthRpcModuleProxy : IEthRpcModule { - _proxy = proxy; - _wallet = wallet; - } + private readonly IEthJsonRpcClientProxy _proxy; + private readonly IWallet _wallet; - public ResultWrapper eth_chainId() - { - throw new NotSupportedException(); - } - - public ResultWrapper eth_protocolVersion() - { - throw new NotSupportedException(); - } - - public ResultWrapper eth_syncing() - { - throw new NotSupportedException(); - } - - public ResultWrapper
eth_coinbase() - { - throw new NotSupportedException(); - } + public EthRpcModuleProxy(IEthJsonRpcClientProxy proxy, IWallet wallet) + { + _proxy = proxy; + _wallet = wallet; + } - public ResultWrapper eth_mining() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_chainId() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_feeHistory(long blockCount, BlockParameter newestBlock, - double[]? rewardPercentiles = null) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_protocolVersion() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_snapshot() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_syncing() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_hashrate() - { - throw new NotSupportedException(); - } + public ResultWrapper
eth_coinbase() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_maxPriorityFeePerGas() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_mining() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_gasPrice() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_feeHistory(long blockCount, BlockParameter newestBlock, double[]? rewardPercentiles = null) + { + throw new NotSupportedException(); + } - public ResultWrapper> eth_accounts() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_snapshot() + { + throw new NotSupportedException(); + } - public async Task> eth_blockNumber() - { - return ResultWrapper.From(await _proxy.eth_blockNumber()); - } + public ResultWrapper eth_hashrate() + { + throw new NotSupportedException(); + } - public async Task> eth_getBalance(Address address, BlockParameter blockParameter) - { - return ResultWrapper.From(await _proxy.eth_getBalance(address, - MapBlockParameter(blockParameter))); - } + public ResultWrapper eth_maxPriorityFeePerGas() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getStorageAt(Address address, UInt256 positionIndex, - BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_gasPrice() + { + throw new NotSupportedException(); + } - public async Task> eth_getTransactionCount(Address address, BlockParameter blockParameter) - { - return ResultWrapper.From( - await _proxy.eth_getTransactionCount(address, MapBlockParameter(blockParameter))); - } + public ResultWrapper> eth_accounts() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getBlockTransactionCountByHash(Keccak blockHash) - { - throw new NotSupportedException(); - } + public async Task> eth_blockNumber() + => ResultWrapper.From(await _proxy.eth_blockNumber()); - public ResultWrapper eth_getBlockTransactionCountByNumber(BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public async Task> eth_getBalance(Address address, BlockParameter blockParameter) + => ResultWrapper.From(await _proxy.eth_getBalance(address, MapBlockParameter(blockParameter))); - public ResultWrapper eth_getUncleCountByBlockHash(Keccak blockHash) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getStorageAt(Address address, UInt256 positionIndex, + BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getUncleCountByBlockNumber(BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public async Task> eth_getTransactionCount(Address address, BlockParameter blockParameter) + => ResultWrapper.From(await _proxy.eth_getTransactionCount(address, MapBlockParameter(blockParameter))); - public ResultWrapper eth_getCode(Address address, BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getBlockTransactionCountByHash(Keccak blockHash) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_sign(Address addressData, byte[] message) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getBlockTransactionCountByNumber(BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - public async Task> eth_sendTransaction(TransactionForRpc rpcTx) - { - Transaction transaction = rpcTx.ToTransactionWithDefaults(); - if (transaction.Signature is null) + public ResultWrapper eth_getUncleCountByBlockHash(Keccak blockHash) { - RpcResult chainIdResult = await _proxy.eth_chainId(); - ulong chainId = chainIdResult?.IsValid == true ? (ulong)chainIdResult.Result : 0; - RpcResult nonceResult = - await _proxy.eth_getTransactionCount(transaction.SenderAddress, BlockParameterModel.Pending); - transaction.Nonce = nonceResult?.IsValid == true ? nonceResult.Result : UInt256.Zero; - _wallet.Sign(transaction, chainId); + throw new NotSupportedException(); } - return ResultWrapper.From(await _proxy.eth_sendRawTransaction(Rlp.Encode(transaction).Bytes)); - } + public ResultWrapper eth_getUncleCountByBlockNumber(BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - public async Task> eth_sendRawTransaction(byte[] transaction) - { - return ResultWrapper.From(await _proxy.eth_sendRawTransaction(Rlp.Encode(transaction).Bytes)); - } + public ResultWrapper eth_getCode(Address address, BlockParameter blockParameter) + { + throw new NotSupportedException(); + } + public ResultWrapper eth_sign(Address addressData, byte[] message) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockParameter? blockParameter = null) - { - throw new NotSupportedException(); - } + public async Task> eth_sendTransaction(TransactionForRpc rpcTx) + { + Transaction transaction = rpcTx.ToTransactionWithDefaults(); + if (transaction.Signature is null) + { + RpcResult chainIdResult = await _proxy.eth_chainId(); + ulong chainId = chainIdResult?.IsValid == true ? (ulong)chainIdResult.Result : 0; + RpcResult nonceResult = + await _proxy.eth_getTransactionCount(transaction.SenderAddress, BlockParameterModel.Pending); + transaction.Nonce = nonceResult?.IsValid == true ? nonceResult.Result : UInt256.Zero; + _wallet.Sign(transaction, chainId); + } + + return ResultWrapper.From(await _proxy.eth_sendRawTransaction(Rlp.Encode(transaction).Bytes)); + } - public ResultWrapper eth_multicall(ulong version, - MultiCallBlockStateCallsModel[] blockCalls, - BlockParameter? blockParameter = null, bool traceTransfers = true) - { - throw new NotSupportedException(); - } + public async Task> eth_sendRawTransaction(byte[] transaction) + => ResultWrapper.From(await _proxy.eth_sendRawTransaction(Rlp.Encode(transaction).Bytes)); - public ResultWrapper eth_multicallV1(MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null, - bool traceTransfers = true) - { - throw new NotImplementedException(); - } - public ResultWrapper eth_estimateGas( - TransactionForRpc transactionCall, - BlockParameter? blockParameter = null) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockParameter? blockParameter = null) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_createAccessList(TransactionForRpc transactionCall, - BlockParameter? blockParameter = null, bool optimize = true) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_multicall(ulong version, + MultiCallBlockStateCallsModel[] blockCalls, + BlockParameter? blockParameter = null, bool traceTransfers = true) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getBlockByHash(Keccak blockHash, bool returnFullTransactionObjects) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_multicallV1(MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null, + bool traceTransfers = true) + { + throw new NotImplementedException(); + } - public ResultWrapper eth_getBlockByNumber(BlockParameter blockParameter, - bool returnFullTransactionObjects) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_estimateGas( + TransactionForRpc transactionCall, + BlockParameter? blockParameter = null) + { + throw new NotSupportedException(); + } - public async Task> eth_getTransactionByHash(Keccak transactionHash) - { - RpcResult result = await _proxy.eth_getTransactionByHash(transactionHash); - TransactionForRpc? transaction = MapTransaction(result.Result); - return transaction is null - ? ResultWrapper.Fail("Transaction was not found.") - : ResultWrapper.Success(transaction); - } + public ResultWrapper eth_createAccessList(TransactionForRpc transactionCall, BlockParameter? blockParameter = null, bool optimize = true) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_pendingTransactions() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getBlockByHash(Keccak blockHash, bool returnFullTransactionObjects) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getTransactionByBlockHashAndIndex(Keccak blockHash, - UInt256 positionIndex) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getBlockByNumber(BlockParameter blockParameter, + bool returnFullTransactionObjects) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getTransactionByBlockNumberAndIndex(BlockParameter blockParameter, - UInt256 positionIndex) - { - throw new NotSupportedException(); - } + public async Task> eth_getTransactionByHash(Keccak transactionHash) + { + RpcResult result = await _proxy.eth_getTransactionByHash(transactionHash); + TransactionForRpc? transaction = MapTransaction(result.Result); + return transaction is null + ? ResultWrapper.Fail("Transaction was not found.") + : ResultWrapper.Success(transaction); + } - public async Task> eth_getTransactionReceipt(Keccak txHashData) - { - RpcResult result = await _proxy.eth_getTransactionReceipt(txHashData); - ReceiptForRpc? receipt = MapReceipt(result.Result); + public ResultWrapper eth_pendingTransactions() + { + throw new NotSupportedException(); + } - return receipt is null - ? ResultWrapper.Fail("Receipt was not found.") - : ResultWrapper.Success(receipt); - } + public ResultWrapper eth_getTransactionByBlockHashAndIndex(Keccak blockHash, + UInt256 positionIndex) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getUncleByBlockHashAndIndex(Keccak blockHashData, UInt256 positionIndex) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getTransactionByBlockNumberAndIndex(BlockParameter blockParameter, + UInt256 positionIndex) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getUncleByBlockNumberAndIndex(BlockParameter blockParameter, - UInt256 positionIndex) - { - throw new NotSupportedException(); - } + public async Task> eth_getTransactionReceipt(Keccak txHashData) + { + RpcResult result = await _proxy.eth_getTransactionReceipt(txHashData); + ReceiptForRpc? receipt = MapReceipt(result.Result); - public ResultWrapper eth_newFilter(Filter filter) - { - throw new NotSupportedException(); - } + return receipt is null + ? ResultWrapper.Fail("Receipt was not found.") + : ResultWrapper.Success(receipt); + } - public ResultWrapper eth_newBlockFilter() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getUncleByBlockHashAndIndex(Keccak blockHashData, UInt256 positionIndex) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_newPendingTransactionFilter() - { - throw new NotSupportedException(); - } + public ResultWrapper eth_getUncleByBlockNumberAndIndex(BlockParameter blockParameter, + UInt256 positionIndex) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_uninstallFilter(UInt256 filterId) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_newFilter(Filter filter) + { + throw new NotSupportedException(); + } - public ResultWrapper> eth_getFilterChanges(UInt256 filterId) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_newBlockFilter() + { + throw new NotSupportedException(); + } - public ResultWrapper> eth_getFilterLogs(UInt256 filterId) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_newPendingTransactionFilter() + { + throw new NotSupportedException(); + } - public ResultWrapper> eth_getLogs(Filter filter) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_uninstallFilter(UInt256 filterId) + { + throw new NotSupportedException(); + } - public ResultWrapper> eth_getWork() - { - throw new NotSupportedException(); - } + public ResultWrapper> eth_getFilterChanges(UInt256 filterId) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_submitWork(byte[] nonce, Keccak headerPowHash, byte[] mixDigest) - { - throw new NotSupportedException(); - } + public ResultWrapper> eth_getFilterLogs(UInt256 filterId) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_submitHashrate(string hashRate, string id) - { - throw new NotSupportedException(); - } + public ResultWrapper> eth_getLogs(Filter filter) + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getProof(Address accountAddress, UInt256[] hashRate, - BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public ResultWrapper> eth_getWork() + { + throw new NotSupportedException(); + } - public ResultWrapper eth_getAccount(Address accountAddress, BlockParameter blockParameter) - { - throw new NotSupportedException(); - } + public ResultWrapper eth_submitWork(byte[] nonce, Keccak headerPowHash, byte[] mixDigest) + { + throw new NotSupportedException(); + } - private static TransactionForRpc? MapTransaction(TransactionModel? transaction) - { - if (transaction is null) return null; - - return new TransactionForRpc - { - BlockHash = transaction.BlockHash, - BlockNumber = (long)transaction.BlockNumber, - From = transaction.From, - To = transaction.To, - Gas = (long)transaction.Gas, - GasPrice = transaction.GasPrice, - Hash = transaction.Hash, - Input = transaction.Input, - Nonce = transaction.Nonce, - Value = transaction.Value - }; - } + public ResultWrapper eth_submitHashrate(string hashRate, string id) + { + throw new NotSupportedException(); + } - private static ReceiptForRpc? MapReceipt(ReceiptModel? receipt) - { - if (receipt is null) return null; - - return new ReceiptForRpc - { - BlockHash = receipt.BlockHash, - BlockNumber = (long)receipt.BlockNumber, - ContractAddress = receipt.ContractAddress, - CumulativeGasUsed = (long)receipt.CumulativeGasUsed, - From = receipt.From, - GasUsed = (long)receipt.GasUsed, - Logs = receipt.Logs?.Select(MapLogEntry).ToArray() ?? Array.Empty(), - Status = (long)receipt.Status, - To = receipt.To, - TransactionHash = receipt.TransactionHash, - TransactionIndex = (long)receipt.TransactionIndex, - LogsBloom = receipt.LogsBloom is null ? null : new Bloom(receipt.LogsBloom), - EffectiveGasPrice = receipt.EffectiveGasPrice - }; - } + public ResultWrapper eth_getProof(Address accountAddress, UInt256[] hashRate, + BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - private static LogEntryForRpc MapLogEntry(LogModel log) - { - return new() - { - Address = log.Address, - Data = log.Data, - Removed = log.Removed, - Topics = log.Topics, - BlockHash = log.BlockHash, - BlockNumber = (long)log.BlockNumber, - LogIndex = (long)log.LogIndex, - TransactionHash = log.TransactionHash, - TransactionIndex = (long)log.TransactionIndex - }; - } + public ResultWrapper eth_getAccount(Address accountAddress, BlockParameter blockParameter) + { + throw new NotSupportedException(); + } - private static BlockParameterModel? MapBlockParameter(BlockParameter? blockParameter) - { - if (blockParameter is null) return null; + private static TransactionForRpc? MapTransaction(TransactionModel? transaction) + { + if (transaction is null) + { + return null; + } + + return new TransactionForRpc + { + BlockHash = transaction.BlockHash, + BlockNumber = (long)transaction.BlockNumber, + From = transaction.From, + To = transaction.To, + Gas = (long)transaction.Gas, + GasPrice = transaction.GasPrice, + Hash = transaction.Hash, + Input = transaction.Input, + Nonce = transaction.Nonce, + Value = transaction.Value + }; + } - if (blockParameter.Type == BlockParameterType.BlockNumber && blockParameter.BlockNumber.HasValue) - return BlockParameterModel.FromNumber(blockParameter.BlockNumber.Value); + private static ReceiptForRpc? MapReceipt(ReceiptModel? receipt) + { + if (receipt is null) + { + return null; + } + + return new ReceiptForRpc + { + BlockHash = receipt.BlockHash, + BlockNumber = (long)receipt.BlockNumber, + ContractAddress = receipt.ContractAddress, + CumulativeGasUsed = (long)receipt.CumulativeGasUsed, + From = receipt.From, + GasUsed = (long)receipt.GasUsed, + Logs = receipt.Logs?.Select(MapLogEntry).ToArray() ?? Array.Empty(), + Status = (long)receipt.Status, + To = receipt.To, + TransactionHash = receipt.TransactionHash, + TransactionIndex = (long)receipt.TransactionIndex, + LogsBloom = receipt.LogsBloom is null ? null : new Bloom(receipt.LogsBloom), + EffectiveGasPrice = receipt.EffectiveGasPrice + }; + } - return new BlockParameterModel { Type = blockParameter.Type.ToString() }; + private static LogEntryForRpc MapLogEntry(LogModel log) + => new() + { + Address = log.Address, + Data = log.Data, + Removed = log.Removed, + Topics = log.Topics, + BlockHash = log.BlockHash, + BlockNumber = (long)log.BlockNumber, + LogIndex = (long)log.LogIndex, + TransactionHash = log.TransactionHash, + TransactionIndex = (long)log.TransactionIndex + }; + + private static BlockParameterModel? MapBlockParameter(BlockParameter? blockParameter) + { + if (blockParameter is null) + { + return null; + } + + if (blockParameter.Type == BlockParameterType.BlockNumber && blockParameter.BlockNumber.HasValue) + { + return BlockParameterModel.FromNumber(blockParameter.BlockNumber.Value); + } + + return new BlockParameterModel + { + Type = blockParameter.Type.ToString() + }; + } } } diff --git a/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs b/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs index 5523dcaf9be..92cdb19e917 100644 --- a/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs +++ b/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs @@ -34,8 +34,7 @@ public class StateTestTxTracer : ITxTracer public bool IsTracingBlockHash { get; } = false; public bool IsTracingAccess { get; } = false; public bool IsTracingFees => false; - public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees || IsTracingEventLogs; - public bool IsTracingEventLogs => false; + public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak stateRoot = null) @@ -248,10 +247,5 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) { throw new NotImplementedException(); } - - public void ReportEvent(LogEntry logEntry) - { - throw new NotImplementedException(); - } } } From e4b680f683f72011dc87e96d3b010bd4ab6dd815 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 3 Aug 2023 13:45:59 +0100 Subject: [PATCH 036/213] Fixing tests --- .../Nethermind.Api/NethermindApi.cs | 3 +- .../IMultiCallBlocksProcessingEnv.cs | 4 +- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 22 +- .../IMultiCallVirtualMachine.cs | 15 ++ .../Nethermind.Evm/MultiCallVirtualMachine.cs | 37 ++-- .../MultiCallVirtualMachineImpl.cs | 37 ++++ .../Nethermind.Evm/Nethermind.Evm.csproj | 1 + .../Nethermind.Evm/VirtualMachine.cs | 44 ++-- .../BlockchainBridgeTests.cs | 2 + .../Proxy/EthJsonRpcClientProxyTests.cs | 26 ++- .../Nethermind.Facade/BlockchainBridge.cs | 53 +++-- .../Nethermind.Facade/IBlockchainBridge.cs | 10 +- .../Nethermind.Facade/MultiCallBlockTracer.cs | 42 ++-- .../Nethermind.Facade/MultiCallTxTracer.cs | 202 +----------------- .../Proxy/EthJsonRpcClientProxy.cs | 16 +- .../Proxy/IEthJsonRpcClientProxy.cs | 6 +- .../Proxy/Models/CallTransactionModel.cs | 2 + ...ckStateCallsModel.cs => BlockStateCall.cs} | 4 +- .../Models/MultiCall/MultiCallPayload.cs | 17 ++ .../Steps/RegisterRpcModules.cs | 5 +- .../JsonRpcServiceTests.cs | 28 +-- ...ulticallTestsPrecompilesWithRedirection.cs | 20 +- .../EthMulticallTestsBlocksAndTransactions.cs | 159 +++++++------- .../EthMulticallTestsSimplePrecompiles.cs | 23 +- .../Modules/SingletonModulePoolTests.cs | 3 +- .../Modules/TestRpcBlockchain.cs | 4 +- .../Nethermind.JsonRpc/JsonRpcService.cs | 13 +- .../Modules/Eth/EthModuleFactory.cs | 9 +- .../Eth/EthRpcModule.TransactionExecutor.cs | 54 +++-- .../Modules/Eth/EthRpcModule.cs | 22 +- .../Modules/Eth/EthRpcModuleProxy.cs | 10 +- .../Modules/Eth/ExecutorBase.cs | 52 +++++ .../Modules/Eth/IEthRpcModule.cs | 21 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 57 +---- 34 files changed, 431 insertions(+), 592 deletions(-) create mode 100644 src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs create mode 100644 src/Nethermind/Nethermind.Evm/MultiCallVirtualMachineImpl.cs rename src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/{MultiCallBlockStateCallsModel.cs => BlockStateCall.cs} (73%) create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs create mode 100644 src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index d27ef1d1872..070658aaefd 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -86,7 +86,8 @@ public IBlockchainBridge CreateBlockchainBridge() readOnlyTree, SpecProvider, LogManager); - IMultiCallBlocksProcessingEnv multiCallReadOnlyBlocksProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + + IMultiCallBlocksProcessingEnv multiCallReadOnlyBlocksProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create(false, _multiCallReadOnlyDbProvider, SpecProvider, LogManager); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs index 05481061812..5e8c136e01f 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs @@ -14,10 +14,10 @@ public interface IMultiCallBlocksProcessingEnv : IReadOnlyTxProcessingEnvBase, I { //Instance VM can be edited during processing ISpecProvider SpecProvider { get; } - MultiCallVirtualMachine Machine { get; } + IMultiCallVirtualMachine VirtualMachine { get; } //We need abilety to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning - IMultiCallBlocksProcessingEnv Clone(); + IMultiCallBlocksProcessingEnv Clone(bool TraceTransfers); //We keep original ProcessingEnv spirit with Build() that can start from any stateRoot IBlockProcessor GetProcessor(); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs index 968a4d35a1f..a623936b934 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -29,10 +29,11 @@ public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, private readonly InMemoryReceiptStorage _receiptStorage; public ITransactionProcessor TransactionProcessor { get; } public ISpecProvider SpecProvider { get; } - public MultiCallVirtualMachine Machine { get; } + public IMultiCallVirtualMachine VirtualMachine { get; } + public bool TraceTransfers { get; set; } //We need ability to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning - public static IMultiCallBlocksProcessingEnv Create(IReadOnlyDbProvider? readOnlyDbProvider, + public static IMultiCallBlocksProcessingEnv Create(bool TraceTransfers, IReadOnlyDbProvider? readOnlyDbProvider, ISpecProvider? specProvider, ILogManager? logManager ) @@ -47,6 +48,7 @@ public static IMultiCallBlocksProcessingEnv Create(IReadOnlyDbProvider? readOnly logManager); return new MultiCallReadOnlyBlocksProcessingEnv( + TraceTransfers, DbProvider, trieStore, BlockTree, @@ -54,12 +56,13 @@ public static IMultiCallBlocksProcessingEnv Create(IReadOnlyDbProvider? readOnly logManager); } - public IMultiCallBlocksProcessingEnv Clone() + public IMultiCallBlocksProcessingEnv Clone(bool TraceTransfers) { - return Create(DbProvider, SpecProvider, _logManager); + return Create(TraceTransfers, DbProvider, SpecProvider, _logManager); } private MultiCallReadOnlyBlocksProcessingEnv( + bool TraceTransfers, IReadOnlyDbProvider? readOnlyDbProvider, ITrieStore? trieStore, IBlockTree? blockTree, @@ -75,7 +78,14 @@ private MultiCallReadOnlyBlocksProcessingEnv( _receiptStorage = new InMemoryReceiptStorage(); - Machine = new MultiCallVirtualMachine(BlockhashProvider, specProvider, logManager); + if (TraceTransfers) + { + VirtualMachine = new MultiCallVirtualMachine(BlockhashProvider, specProvider, logManager); + } + else + { + VirtualMachine = new MultiCallVirtualMachine(BlockhashProvider, specProvider, logManager); + } HeaderValidator headerValidator = new( BlockTree, @@ -93,7 +103,7 @@ private MultiCallReadOnlyBlocksProcessingEnv( public IBlockProcessor GetProcessor() { - var yransactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, Machine, _logManager); + var yransactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, _logManager); return new BlockProcessor(SpecProvider, _blockValidator, diff --git a/src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs b/src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs new file mode 100644 index 00000000000..491e1e5d346 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.State; + +namespace Nethermind.Evm; + +public interface IMultiCallVirtualMachine : IVirtualMachine +{ + public void SetOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, + Address? redirectAddress = null); +} diff --git a/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs b/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs index c6af4f3f8d0..9290f0c4513 100644 --- a/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs @@ -10,28 +10,38 @@ namespace Nethermind.Evm; -public class MultiCallVirtualMachine : VirtualMachine +public struct MultiCallDoNotTraceTransfers { } +public struct MultiCallDoTraceTransfers { } + +public class MultiCallVirtualMachine : VirtualMachine, IMultiCallVirtualMachine + { - private readonly IBlockhashProvider? _blockhashProvider; - private readonly ILogManager? _logManager; private readonly Dictionary _overloaded = new(); - private readonly ISpecProvider? _specProvider; - - public MultiCallVirtualMachine(MultiCallVirtualMachine vm) : - this(vm._blockhashProvider, vm._specProvider, vm._logManager) - { - _overloaded = vm._overloaded; - } public MultiCallVirtualMachine(IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, ILogManager? logManager) : base(blockhashProvider, specProvider, logManager) { - _blockhashProvider = blockhashProvider; - _specProvider = specProvider; - _logManager = logManager; } + protected override IVirtualMachine CreateVirtualMachine(IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, + ILogger? logger) + { + bool traceTransfers = typeof(TTraceTransfers) == typeof(MultiCallDoTraceTransfers); + + + IVirtualMachine result; + if (!logger.IsTrace) + { + result = new MultiCallVirtualMachineImpl(traceTransfers, blockhashProvider, specProvider, logger); + } + else + { + result = new MultiCallVirtualMachineImpl(traceTransfers, blockhashProvider, specProvider, logger); + } + + return result; + } public void SetOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, Address? redirectAddress = null) @@ -46,4 +56,5 @@ public override CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeS return result; return base.GetCachedCodeInfo(worldState, codeSource, vmSpec); } + } diff --git a/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachineImpl.cs b/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachineImpl.cs new file mode 100644 index 00000000000..07d4896dcb1 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachineImpl.cs @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Abi; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; +using Nethermind.Logging; + +namespace Nethermind.Evm; + +internal class MultiCallVirtualMachineImpl : VirtualMachine + where TLogger : struct, VirtualMachine.IIsTracing +{ + private readonly bool _traceTransfers; + + public MultiCallVirtualMachineImpl(bool traceTransfers, IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, ILogger? logger) : base(blockhashProvider, specProvider, logger) + { + _traceTransfers = traceTransfers; + } + + protected override void TraceAction(EvmState currentState) + { + if (_traceTransfers) + { + //Log action + byte[]? data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, + new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256), currentState.From, + currentState.To, currentState.Env.Value); + LogEntry? result = new(Address.Zero, data, new[] { Keccak.Zero }); + currentState.Logs.Add(result); + } + + //Do default stuff + base.TraceAction(currentState); + } +} diff --git a/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj b/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj index bf4f06ca167..5666d09c57a 100644 --- a/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj +++ b/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj @@ -8,6 +8,7 @@ + diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 24485afe261..f1239c40d3d 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -32,29 +32,39 @@ namespace Nethermind.Evm; using Int256; +using Microsoft.Extensions.Logging; public class VirtualMachine : IVirtualMachine { public const int MaxCallDepth = 1024; - private readonly IVirtualMachine _evm; + protected readonly IVirtualMachine _evm; public VirtualMachine( IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, ILogManager? logManager) { - ILogger logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); + var logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); + _evm = CreateVirtualMachine(blockhashProvider, specProvider, logger); + } + + protected virtual IVirtualMachine CreateVirtualMachine(IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, Logging.ILogger? logger) + { + IVirtualMachine result; if (!logger.IsTrace) { - _evm = new VirtualMachine(blockhashProvider, specProvider, logger); + result = new VirtualMachine(blockhashProvider, specProvider, logger); } else { - _evm = new VirtualMachine(blockhashProvider, specProvider, logger); + result = new VirtualMachine(blockhashProvider, specProvider, logger); } + + return result; } + public virtual CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec spec) => _evm.GetCachedCodeInfo(worldState, codeSource, spec); @@ -125,7 +135,7 @@ public interface IIsTracing { } public readonly struct IsTracing : IIsTracing { } } -internal sealed class VirtualMachine : IVirtualMachine +internal class VirtualMachine : IVirtualMachine where TLogger : struct, IIsTracing { private UInt256 P255Int = (UInt256)System.Numerics.BigInteger.Pow(2, 255); @@ -156,7 +166,7 @@ internal sealed class VirtualMachine : IVirtualMachine private readonly IBlockhashProvider _blockhashProvider; private readonly ISpecProvider _specProvider; private static readonly LruCache _codeCache = new(MemoryAllowance.CodeCacheSize, MemoryAllowance.CodeCacheSize, "VM bytecodes"); - private readonly ILogger _logger; + private readonly Logging.ILogger _logger; private IWorldState _worldState; private IWorldState _state; private readonly Stack _stateStack = new(); @@ -168,7 +178,7 @@ internal sealed class VirtualMachine : IVirtualMachine public VirtualMachine( IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, - ILogger? logger) + Logging.ILogger? logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _blockhashProvider = blockhashProvider ?? throw new ArgumentNullException(nameof(blockhashProvider)); @@ -227,8 +237,7 @@ public TransactionSubstate Run(EvmState state, IWorldState worl { if (typeof(TTracingActions) == typeof(IsTracing) && !currentState.IsContinuation) { - _txTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, currentState.ExecutionType); - if (_txTracer.IsTracingCode) _txTracer.ReportByteCode(currentState.Env.CodeInfo.MachineCode); + TraceAction(currentState); } if (!_txTracer.IsTracingInstructions) @@ -465,6 +474,14 @@ public TransactionSubstate Run(EvmState state, IWorldState worl } } + protected virtual void TraceAction(EvmState currentState) where TTracingActions : struct, IIsTracing + { + _txTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, + currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, + currentState.ExecutionType); + if (_txTracer.IsTracingCode) _txTracer.ReportByteCode(currentState.Env.CodeInfo.MachineCode); + } + private void RevertParityTouchBugAccount(IReleaseSpec spec) { if (_parityTouchBugAccount.ShouldDelete) @@ -1791,7 +1808,7 @@ private CallResult ExecuteCode(EvmState vmState, ref EvmStack(EvmState vmState, ref EvmStack stack, ref long gasAvailable, Instruction instruction, ITxTracer _txTracer) + private static bool InstructionLog(EvmState vmState, ref EvmStack stack, ref long gasAvailable, Instruction instruction) where TTracing : struct, IIsTracing { stack.PopUInt256(out UInt256 position); @@ -2536,10 +2553,7 @@ private static bool InstructionLog(EvmState vmState, ref EvmStack(nameof(_proxy.eth_call), [Test] - public async Task eth_multicall_should_invoke_client_method() + public async Task eth_multicall_should_invoke_client_method_even_empty() { - var multyCallTransaction = new MultiCallBlockStateCallsModel[] { }; + MultiCallPayload payload = new(); var blockParameter = BlockParameterModel.Latest; - var traceTransactions = true; - await _proxy.eth_multicall(1, multyCallTransaction, blockParameter, traceTransactions); + await _proxy.eth_multicallV1(payload, blockParameter); var calls = _client.ReceivedCalls().ToList(); - await _client.Received().SendAsync(nameof(_proxy.eth_multicall), - (ulong)1, multyCallTransaction, blockParameter.Type, traceTransactions); + await _client.Received().SendAsync(nameof(_proxy.eth_multicallV1), + payload, blockParameter.Type); } [Test] public async Task eth_multicallV1_should_invoke_client_method() { - var multyCallTransaction = new MultiCallBlockStateCallsModel[] { }; + MultiCallPayload payload = new() + { + BlockStateCalls = new BlockStateCalls[] { }, + TraceTransfers = true + }; + var blockParameter = BlockParameterModel.Latest; - var traceTransactions = true; - await _proxy.eth_multicallV1(multyCallTransaction, blockParameter, traceTransactions); + + await _proxy.eth_multicallV1(payload, blockParameter); var calls = _client.ReceivedCalls().ToList(); - await _client.Received().SendAsync(nameof(_proxy.eth_multicall), - 1, multyCallTransaction, blockParameter.Type, traceTransactions); + await _client.Received().SendAsync(nameof(_proxy.eth_multicallV1), + payload, blockParameter.Type); } [Test] diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 5cd15122e00..957e9836aff 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -186,13 +186,13 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can - public MultiCallOutput MultiCall(BlockHeader header, MultiCallBlockStateCallsModel[] blocks, CancellationToken cancellationToken) + public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken) { MultiCallBlockTracer multiCallOutputTracer = new(); MultiCallOutput result = new(); try { - (bool Success, string Error) tryMultiCallResult = TryMultiCallTrace(header, blocks, + (bool Success, string Error) tryMultiCallResult = TryMultiCallTrace(header, payload, multiCallOutputTracer.WithCancellation(cancellationToken)); if (!tryMultiCallResult.Success) @@ -324,30 +324,30 @@ private void CallAndRestore( transactionProcessor.CallAndRestore(transaction, callHeader, tracer); } - private (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallBlockStateCallsModel[] blocks, + private (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) { - using (IMultiCallBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone()) + using (IMultiCallBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers)) { var processor = env.GetProcessor(); - var firstBlock = blocks.FirstOrDefault(); + var firstBlock = payload.BlockStateCalls.FirstOrDefault(); var startStateRoot = parent.StateRoot; - if (firstBlock?.BlockOverride?.Number != null - && firstBlock?.BlockOverride?.Number > UInt256.Zero - && firstBlock?.BlockOverride?.Number < (ulong)long.MaxValue) + if (firstBlock?.BlockOverrides?.Number != null + && firstBlock?.BlockOverrides?.Number > UInt256.Zero + && firstBlock?.BlockOverrides?.Number < (ulong)long.MaxValue) { BlockHeader? searchResult = - _multiCallProcessingEnv.BlockTree.FindHeader((long)firstBlock?.BlockOverride.Number); + _multiCallProcessingEnv.BlockTree.FindHeader((long)firstBlock?.BlockOverrides.Number); if (searchResult != null) { startStateRoot = searchResult.StateRoot; } } - foreach (MultiCallBlockStateCallsModel? callInputBlock in blocks) + foreach (BlockStateCalls? callInputBlock in payload.BlockStateCalls) { BlockHeader callHeader = null; - if (callInputBlock.BlockOverride == null) + if (callInputBlock.BlockOverrides == null) { callHeader = new BlockHeader( parent.Hash, @@ -362,19 +362,11 @@ private void CallAndRestore( } else { - callHeader = callInputBlock.BlockOverride.GetBlockHeader(parent, _blocksConfig); + callHeader = callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig); } env.StateProvider.StateRoot = parent.StateRoot; - IReleaseSpec releaseSpec = _specProvider.GetSpec(parent); - - if (releaseSpec.IsEip4844Enabled) - { - // TODO: Calculate ExcessDataGas depending on parent ExcessDataGas and number of blobs in txs - callHeader.ExcessDataGas = 0; - } - callHeader.MixHash = parent.MixHash; callHeader.IsPostMerge = parent.Difficulty == 0; Block? currentBlock = new(callHeader, Array.Empty(), Array.Empty()); @@ -418,16 +410,19 @@ private void CallAndRestore( currentBlock.Header.IsPostMerge = true; //ToDo: Seal if necessary before merge 192 BPB currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); + ProcessingOptions processingFlags = ProcessingOptions.ForceProcessing | + ProcessingOptions.DoNotVerifyNonce | + ProcessingOptions.IgnoreParentNotOnMainChain | + ProcessingOptions.MarkAsProcessed | + ProcessingOptions.StoreReceipts; + + if (!payload.Validation) + { + processingFlags |= ProcessingOptions.NoValidation; + } Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, - new List { currentBlock }, - ProcessingOptions.ForceProcessing | - // ProcessingOptions.NoValidation | - ProcessingOptions.DoNotVerifyNonce | - ProcessingOptions.IgnoreParentNotOnMainChain | - ProcessingOptions.MarkAsProcessed | - ProcessingOptions.StoreReceipts - , tracer); + new List { currentBlock }, processingFlags, tracer); var processedBlock = currentBlocks.FirstOrDefault(); if (processedBlock != null) @@ -482,7 +477,7 @@ private void ModifyAccounts(AccountOverride[] StateOverrides, IWorldState? State StateProvider.DecrementNonce(address); else if (accNonce < accountOverride.Nonce) StateProvider.IncrementNonce(address); - _multiCallProcessingEnv.Machine.SetOverwrite(StateProvider, CurrentSpec, address, + _multiCallProcessingEnv.VirtualMachine.SetOverwrite(StateProvider, CurrentSpec, address, new CodeInfo(accountOverride.Code), accountOverride.MoveToAddress); diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index e9e42924bcb..26bfdfd05f7 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -12,6 +12,7 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.Trie; +using static Nethermind.Facade.BlockchainBridge; using Block = Nethermind.Core.Block; namespace Nethermind.Facade @@ -25,11 +26,10 @@ public interface IBlockchainBridge : ILogFinder TxReceipt GetReceipt(Keccak txHash); (TxReceipt? Receipt, TxGasInfo? GasInfo, int LogIndexStart) GetReceiptAndGasInfo(Keccak txHash); (TxReceipt? Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Keccak txHash); - BlockchainBridge.MultiCallOutput MultiCall(BlockHeader header, MultiCallBlockStateCallsModel[] blocks, - CancellationToken cancellationToken); - BlockchainBridge.CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken); - BlockchainBridge.CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken); - BlockchainBridge.CallOutput CreateAccessList(BlockHeader header, Transaction tx, CancellationToken cancellationToken, bool optimize); + MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken); + CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken); + CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken); + CallOutput CreateAccessList(BlockHeader header, Transaction tx, CancellationToken cancellationToken, bool optimize); ulong GetChainId(); int NewBlockFilter(); diff --git a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs index 7e5b4735a3c..a3650a63396 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs @@ -1,50 +1,35 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using Nethermind.Core; using Nethermind.Core.Collections; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.MultiCall; -using Nethermind.Int256; +using ResultType = Nethermind.Facade.Proxy.Models.MultiCall.ResultType; namespace Nethermind.Facade; -public class MultiCallBlockTracer : IBlockTracer +public class MultiCallBlockTracer : BlockTracer { public List _results = new(); private List _txTracers = new(); private Block currentBlock; - public bool TraceDetails { get; set; } - public bool IsTracingRewards => false; - public MultiCallBlockTracer(bool traceDetails = true) - { - TraceDetails = traceDetails; - } - - - public void ReportReward(Address author, string rewardType, UInt256 rewardValue) - { - throw new NotImplementedException(); - } - - public void StartNewBlockTrace(Block block) + public override void StartNewBlockTrace(Block block) { _txTracers.Clear(); currentBlock = block; } - public ITxTracer StartNewTxTrace(Transaction? tx) + public override ITxTracer StartNewTxTrace(Transaction? tx) { if (tx != null && tx.Hash != null) { - MultiCallTxTracer result = new(tx, TraceDetails); + MultiCallTxTracer result = new(); _txTracers.Add(result); return result; } @@ -52,11 +37,7 @@ public ITxTracer StartNewTxTrace(Transaction? tx) return NullTxTracer.Instance; } - public void EndTxTrace() - { - } - - public void EndBlockTrace() + public override void EndBlockTrace() { MultiCallBlockResult? result = new() { @@ -72,11 +53,14 @@ public void EndBlockTrace() }; result.Calls.ForEach(callResult => { - callResult.Logs.ForEach(log => + if (callResult.Type == ResultType.Success) { - log.BlockHash = currentBlock.Hash; - log.BlockNumber = (ulong)currentBlock.Number; - }); + callResult.Logs.ForEach(log => + { + log.BlockHash = currentBlock.Hash; + log.BlockNumber = (ulong)currentBlock.Number; + }); + } }); _results.Add(result); diff --git a/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs index fc7a7e3411f..978dc0eb468 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs @@ -1,87 +1,26 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; -using System.Collections.Generic; using System.Linq; -using Nethermind.Abi; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.MultiCall; -using Nethermind.Int256; namespace Nethermind.Facade; -internal class MultiCallTxTracer : ITxTracer +internal class MultiCallTxTracer : TxTracer { - private readonly List _extendedLogs; - - public MultiCallCallResult TraceResult { get; set; } - - public MultiCallTxTracer(Transaction t, bool logEvents = true) - { - _extendedLogs = new(); - IsTracingEventLogs = logEvents; - } - - public bool IsTracingState { get; } - - public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) - { - throw new NotImplementedException(); - } - - public void ReportCodeChange(Address address, byte[]? before, byte[]? after) - { - throw new NotImplementedException(); - } - - public void ReportNonceChange(Address address, UInt256? before, UInt256? after) - { - throw new NotImplementedException(); - } - - public void ReportAccountRead(Address address) - { - throw new NotImplementedException(); - } - - public bool IsTracingStorage { get; } - - public void ReportStorageChange(in ReadOnlySpan key, in ReadOnlySpan value) - { - throw new NotImplementedException(); - } - - public void ReportStorageChange(in StorageCell storageCell, byte[] before, byte[] after) - { - throw new NotImplementedException(); - } - - public void ReportStorageRead(in StorageCell storageCell) + public MultiCallTxTracer() { - throw new NotImplementedException(); + IsTracingReceipt = true; } - public bool IsTracingReceipt => true; - public bool IsTracingActions => true; - public bool IsTracingOpLevelStorage { get; } - public bool IsTracingMemory { get; } - public bool IsTracingInstructions { get; } - public bool IsTracingRefunds { get; } - public bool IsTracingCode { get; } - public bool IsTracingStack { get; } - public bool IsTracingBlockHash { get; } - public bool IsTracingAccess { get; } - public bool IsTracingFees { get; } - - public bool IsTracingEventLogs { get; } + public MultiCallCallResult TraceResult { get; set; } - public bool IsTracing => IsTracingActions || IsTracingEventLogs; - public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, + public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) { TraceResult = new MultiCallCallResult() @@ -89,7 +28,7 @@ public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEn GasUsed = (ulong)gasSpent, Return = output, Status = StatusCode.Success.ToString(), - Logs = _extendedLogs.Select((entry, i) => new Log + Logs = logs.Select((entry, i) => new Log { Data = entry.Data, Address = entry.LoggersAddress, @@ -99,7 +38,7 @@ public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEn }; } - public void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Keccak? stateRoot = null) + public override void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Keccak? stateRoot = null) { TraceResult = new MultiCallCallResult() { @@ -111,132 +50,7 @@ public void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string Message = error }, Return = output, - Status = StatusCode.Failure.ToString(), - Logs = _extendedLogs.Select((entry, i) => new Log - { - Data = entry.Data, - Address = entry.LoggersAddress, - Topics = entry.Topics, - LogIndex = (ulong)i - }).ToArray() + Status = StatusCode.Failure.ToString() }; } - - public void StartOperation(int depth, long gas, Instruction opcode, int pc, bool isPostMerge = false) - { - throw new NotImplementedException(); - } - - public void ReportOperationError(EvmExceptionType error) - { - throw new NotImplementedException(); - } - - public void ReportOperationRemainingGas(long gas) - { - throw new NotImplementedException(); - } - - public void SetOperationStack(List stackTrace) - { - throw new NotImplementedException(); - } - - public void ReportStackPush(in ReadOnlySpan stackItem) - { - throw new NotImplementedException(); - } - - public void SetOperationMemory(List memoryTrace) - { - throw new NotImplementedException(); - } - - public void SetOperationMemorySize(ulong newSize) - { - throw new NotImplementedException(); - } - - public void ReportMemoryChange(long offset, in ReadOnlySpan data) - { - throw new NotImplementedException(); - } - - public void SetOperationStorage(Address address, UInt256 storageIndex, ReadOnlySpan newValue, - ReadOnlySpan currentValue) - { - throw new NotImplementedException(); - } - - public void LoadOperationStorage(Address address, UInt256 storageIndex, ReadOnlySpan value) - { - throw new NotImplementedException(); - } - - public void ReportSelfDestruct(Address address, UInt256 balance, Address refundAddress) - { - } - - public void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, - ExecutionType callType, - bool isPrecompileCall = false) - { - byte[]? data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, - new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256), from, to, value); - LogEntry? result = new(Address.Zero, data, new[] { Keccak.Zero }); - _extendedLogs.Add(result); - } - - public void ReportActionEnd(long gas, ReadOnlyMemory output) - { - } - - public void ReportActionError(EvmExceptionType evmExceptionType) - { - } - - public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) - { - throw new NotImplementedException(); - } - - public void ReportBlockHash(Keccak blockHash) - { - throw new NotImplementedException(); - } - - public void ReportByteCode(byte[] byteCode) - { - throw new NotImplementedException(); - } - - public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) - { - throw new NotImplementedException(); - } - - public void ReportRefund(long refund) - { - throw new NotImplementedException(); - } - - public void ReportExtraGasPressure(long extraGasPressure) - { - throw new NotImplementedException(); - } - - public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) - { - throw new NotImplementedException(); - } - - public void ReportFees(UInt256 fees, UInt256 burntFees) - { - throw new NotImplementedException(); - } - - public void ReportEvent(LogEntry logEntry) - { - _extendedLogs.Add(logEntry); - } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index 7709db00019..a7649386c03 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -3,6 +3,7 @@ using System; using System.Threading.Tasks; +using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Int256; @@ -39,19 +40,8 @@ public Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_call), transaction, MapBlockParameter(blockParameter)); - public Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, - BlockParameterModel blockParameter = null, bool traceTransfers = true) => _proxy.SendAsync( - nameof(eth_multicall), - version, blockCalls, - MapBlockParameter(blockParameter), - traceTransfers); - - public Task> eth_multicallV1(MultiCallBlockStateCallsModel[] blockCalls, - BlockParameterModel blockParameter = null, bool traceTransfers = true) => _proxy.SendAsync( - nameof(eth_multicall), - 1, blockCalls, - MapBlockParameter(blockParameter), - traceTransfers); + public Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null) + => _proxy.SendAsync(nameof(eth_multicallV1), blockCalls, MapBlockParameter(blockParameter)); public Task> eth_getCode(Address address, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_getCode), address, MapBlockParameter(blockParameter)); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs index c5ad13c7487..d9293362c6e 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs @@ -7,6 +7,7 @@ using Nethermind.Int256; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Blockchain.Find; namespace Nethermind.Facade.Proxy { @@ -18,10 +19,7 @@ public interface IEthJsonRpcClientProxy Task> eth_getTransactionCount(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionReceipt(Keccak transactionHash); Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null); - - //TODO:add tests - Task> eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, BlockParameterModel blockParameter = null, bool traceTransfers = true); - Task> eth_multicallV1(MultiCallBlockStateCallsModel[] blockCalls, BlockParameterModel blockParameter = null, bool traceTransfers = true); + Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null); Task> eth_getCode(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionByHash(Keccak transactionHash); Task> eth_pendingTransactions(); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs index ce407d04d5b..86d6ac341ff 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs @@ -1,7 +1,9 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Nethermind.Core; +using Nethermind.Crypto; using Nethermind.Int256; using static Nethermind.Core.Extensions.MemoryExtensions; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs similarity index 73% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs index 6c1f7b16a15..c0d48decd38 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockStateCallsModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs @@ -3,9 +3,9 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; -public class MultiCallBlockStateCallsModel +public class BlockStateCalls { - public BlockOverride? BlockOverride { get; set; } + public BlockOverride? BlockOverrides { get; set; } public AccountOverride[] StateOverrides { get; set; } public CallTransactionModel[] Calls { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs new file mode 100644 index 00000000000..830711ca7b5 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public class MultiCallPayload +{ + //Definition of blocks that can contain calls and overrides + public BlockStateCalls[] BlockStateCalls { get; set; } + + //Trace ETH Transfers + public bool TraceTransfers { get; set; } = false; + + //When true, the multicall does all validations that a normal EVM would do, except contract sender and signature checks. When false, multicall behaves like eth_call. + public bool Validation { get; set; } = false; + +} diff --git a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs index 99ec3525c90..dbba92b64aa 100644 --- a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs +++ b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs @@ -93,7 +93,6 @@ public virtual async Task Execute(CancellationToken cancellationToken) if (_api.GasPriceOracle is null) throw new StepDependencyException(nameof(_api.GasPriceOracle)); if (_api.EthSyncingInfo is null) throw new StepDependencyException(nameof(_api.EthSyncingInfo)); if (_api.ReadOnlyTrieStore is null) throw new StepDependencyException(nameof(_api.ReadOnlyTrieStore)); - if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider)); EthModuleFactory ethModuleFactory = new( _api.TxPool, @@ -107,11 +106,11 @@ public virtual async Task Execute(CancellationToken cancellationToken) _api.SpecProvider, _api.ReceiptStorage, _api.GasPriceOracle, - _api.EthSyncingInfo, - _api.DbProvider); + _api.EthSyncingInfo); rpcModuleProvider.RegisterBounded(ethModuleFactory, rpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, rpcConfig.Timeout, _api.LogManager, rpcConfig.RequestQueueLimit); + if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider)); if (_api.BlockPreprocessor is null) throw new StepDependencyException(nameof(_api.BlockPreprocessor)); if (_api.BlockValidator is null) throw new StepDependencyException(nameof(_api.BlockValidator)); if (_api.RewardCalculatorSource is null) throw new StepDependencyException(nameof(_api.RewardCalculatorSource)); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 3b04ca6e842..b18371c7a5c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -87,39 +87,17 @@ public void Eth_module_populates_size_when_returning_block_data() } - [Test] - public void CanRunEthMulticallEmpty() - { - ulong version = 0; - MultiCallBlockStateCallsModel[] blockCalls = Array.Empty(); - - EthereumJsonSerializer serializer = new(); - - string serializedVersion = serializer.Serialize(version); - string serializedCall = serializer.Serialize(blockCalls); - - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_multicall(version, blockCalls).ReturnsForAnyArgs(x => - ResultWrapper.Success(Array.Empty())); - JsonRpcSuccessResponse? response = - TestRequest(ethRpcModule, "eth_multicall", serializedVersion, serializedCall) as JsonRpcSuccessResponse; - Assert.IsTrue(response != null); - Assert.That(response?.Result, Is.EqualTo(Array.Empty())); - } - - [Test] public void CanRunEthMulticallV1Empty() { - ulong version = 0; - MultiCallBlockStateCallsModel[] blockCalls = Array.Empty(); + MultiCallPayload payload = new() { BlockStateCalls = Array.Empty() }; EthereumJsonSerializer serializer = new(); - string serializedCall = serializer.Serialize(blockCalls); + string serializedCall = serializer.Serialize(payload); IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_multicallV1(blockCalls).ReturnsForAnyArgs(x => + ethRpcModule.eth_multicallV1(payload).ReturnsForAnyArgs(x => ResultWrapper.Success(Array.Empty())); JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_multicallV1", serializedCall) as JsonRpcSuccessResponse; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index e624af33b7e..3fc356cc6da 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -12,7 +12,6 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Modules.Eth; using NUnit.Framework; -using static Nethermind.TxPool.TransactionExtensions; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -89,7 +88,8 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( { Data = transactionData, To = contractAddress, - SenderAddress = TestItem.PublicKeyB.Address + SenderAddress = TestItem.PublicKeyB.Address, + GasLimit = 50_000 }; @@ -101,34 +101,36 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( systemTransactionForModifiedVM.GasPrice = header.BaseFeePerGas >= 1 ? header.BaseFeePerGas : 1; systemTransactionForModifiedVM.GasLimit = (long)systemTransactionForModifiedVM.CalculateTransactionPotentialCost(spec.IsEip1559Enabled, header.BaseFeePerGas); - MultiCallBlockStateCallsModel requestMultiCall = new() + MultiCallPayload payload = new() + { + BlockStateCalls = new BlockStateCalls[] { new() { StateOverrides = new[] { new AccountOverride { - Address = EcRecoverPrecompile.Instance.Address, + Address = EcRecoverPrecompile.Address, Code = code, MoveToAddress = new Address("0x0000000000000000000000000000000000000666") } }, Calls = new[] { - systemTransactionForModifiedVM.FromTransaction() + CallTransactionModel.FromTransaction(systemTransactionForModifiedVM), } + }}, + TraceTransfers = true }; - //Force persistancy of head block in main chain chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper result = - executor.Execute(1, new[] { requestMultiCall }, BlockParameter.Latest, true); - + executor.Execute(payload, BlockParameter.Latest); //Check results byte[] addressBytes = result.Data[0].Calls[0].Return diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 070d1f9ed59..0eed123d189 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -27,7 +27,7 @@ private Transaction GetTransferTxData(UInt256 Nonce, IEthereumEcdsa ethereumEcds { Value = ammount, Nonce = Nonce, - GasLimit = 3_000_000, + GasLimit = 50_000, SenderAddress = From.Address, To = To, GasPrice = 20.GWei() @@ -56,33 +56,33 @@ public async Task Test_eth_multicall_serialisation() GetTransferTxData(nextNonceA, chain.EthereumEcdsa, pk, new Address("0xA143c0eA6f8059f7B3651417ccD2bAA80FC2d4Ab"), 4_000_000); - - MultiCallBlockStateCallsModel[] requestMultiCall = + MultiCallPayload payload = new() { - new() + BlockStateCalls = new BlockStateCalls[] { - BlockOverride = new BlockOverride() - { - Number = 18000000 - }, - Calls = new[] + new() { - txMainnetAtoBtoFail.FromTransaction(), - txMainnetAtoBToComplete.FromTransaction(), - }, - StateOverrides = new[] - { - new AccountOverride() + BlockOverrides = new BlockOverride() { Number = 18000000 }, + Calls = new[] + { + CallTransactionModel.FromTransaction(txMainnetAtoBtoFail), + CallTransactionModel.FromTransaction(txMainnetAtoBToComplete), + }, + StateOverrides = new[] { - Address = pk.Address, - Balance = Math.Max(420_000_004_000_001UL, 1_000_000_004_000_001UL) + new AccountOverride() + { + Address = pk.Address, + Balance = Math.Max(420_000_004_000_001UL, 1_000_000_004_000_001UL) + } } } - } + }, + TraceTransfers = true }; EthereumJsonSerializer serializer = new(); - string serializedCall = serializer.Serialize(requestMultiCall); + string serializedCall = serializer.Serialize(payload); Console.WriteLine(serializedCall); @@ -90,9 +90,9 @@ public async Task Test_eth_multicall_serialisation() chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper result = - executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); + executor.Execute(payload, BlockParameter.Latest); MultiCallBlockResult[] data = result.Data; Assert.AreEqual(1, data.Length); @@ -100,8 +100,8 @@ public async Task Test_eth_multicall_serialisation() foreach (MultiCallBlockResult blockResult in data) { Assert.AreEqual(2, blockResult.Calls.Length); - Assert.AreEqual(blockResult.Calls[0].Type, ResultType.Failure); - Assert.AreEqual(blockResult.Calls[1].Type, ResultType.Success); + Assert.AreEqual(ResultType.Failure, blockResult.Calls[0].Type); + Assert.AreEqual(ResultType.Success, blockResult.Calls[1].Type); } } @@ -128,38 +128,36 @@ public async Task Test_eth_multicall_eth_moved() Transaction txAtoB4 = GetTransferTxData(nonceA + 4, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); - MultiCallBlockStateCallsModel[] requestMultiCall = + MultiCallPayload payload = new() { - new() + BlockStateCalls = new BlockStateCalls[] { - BlockOverride = - new BlockOverride - { - Number = (UInt256)new decimal(2), - GasLimit = 5_000_000, - FeeRecipient = TestItem.AddressC, - BaseFee = 0 - }, - Calls = new[] + new() { - txAtoB1.FromTransaction(), txAtoB2.FromTransaction() - } - }, - new() - { - BlockOverride = - new BlockOverride - { - Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10000), - GasLimit = 5_000_000, - FeeRecipient = TestItem.AddressC, - BaseFee = 0 - }, - Calls = new[] + BlockOverrides = + new BlockOverride + { + Number = (UInt256)new decimal(2), + GasLimit = 5_000_000, + FeeRecipient = TestItem.AddressC, + BaseFee = 0 + }, + Calls = new[] { CallTransactionModel.FromTransaction(txAtoB1), CallTransactionModel.FromTransaction(txAtoB2) } + }, + new() { - txAtoB3.FromTransaction(), txAtoB4.FromTransaction() + BlockOverrides = + new BlockOverride + { + Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10000), + GasLimit = 5_000_000, + FeeRecipient = TestItem.AddressC, + BaseFee = 0 + }, + Calls = new[] { CallTransactionModel.FromTransaction(txAtoB3), CallTransactionModel.FromTransaction(txAtoB4) } } - } + }, + TraceTransfers = true }; //Test that transfer tx works on mainchain @@ -176,9 +174,9 @@ public async Task Test_eth_multicall_eth_moved() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper result = - executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); + executor.Execute(payload, BlockParameter.Latest); MultiCallBlockResult[] data = result.Data; Assert.AreEqual(data.Length, 2); @@ -208,39 +206,36 @@ public async Task Test_eth_multicall_transactions_forced_fail() //shall fail Transaction txAtoB2 = GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, UInt256.MaxValue); - - MultiCallBlockStateCallsModel[] requestMultiCall = + MultiCallPayload payload = new() { - new() + BlockStateCalls = new BlockStateCalls[] { - BlockOverride = - new BlockOverride - { - Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10), - GasLimit = 5_000_000, - FeeRecipient = TestItem.AddressC, - BaseFee = 0 - }, - Calls = new[] + new() { - txAtoB1.FromTransaction() - } - }, - new() - { - BlockOverride = - new BlockOverride - { - Number = (UInt256)new decimal(123), - GasLimit = 5_000_000, - FeeRecipient = TestItem.AddressC, - BaseFee = 0 - }, - Calls = new[] + BlockOverrides = + new BlockOverride + { + Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10), + GasLimit = 5_000_000, + FeeRecipient = TestItem.AddressC, + BaseFee = 0 + }, + Calls = new[] { CallTransactionModel.FromTransaction(txAtoB1) } + }, + new() { - txAtoB2.FromTransaction() + BlockOverrides = + new BlockOverride + { + Number = (UInt256)new decimal(123), + GasLimit = 5_000_000, + FeeRecipient = TestItem.AddressC, + BaseFee = 0 + }, + Calls = new[] { CallTransactionModel.FromTransaction(txAtoB2) } } - } + }, + TraceTransfers = true }; //Test that transfer tx works on mainchain @@ -257,10 +252,10 @@ public async Task Test_eth_multicall_transactions_forced_fail() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - MultiCallTxExecutor executor = new(chain.DbProvider, chain.Bridge, chain.BlockFinder, chain.SpecProvider, new JsonRpcConfig()); + MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper result = - executor.Execute(1, requestMultiCall, BlockParameter.Latest, true); + executor.Execute(payload, BlockParameter.Latest); Assert.IsTrue(result.Data[1].Calls[0].Error.Message.StartsWith("insufficient")); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 81cc4fe1e0e..950c33ab574 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -82,19 +82,28 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe }; systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); - MultiCallBlockStateCallsModel requestMultiCall = new() + + MultiCallPayload payload = new() { - StateOverrides = new[] + BlockStateCalls = new[] { - new AccountOverride { Address = EcRecoverPrecompile.Instance.Address, Code = code } - + new BlockStateCalls() + { + StateOverrides = new[] + { + new AccountOverride + { + Address = EcRecoverPrecompile.Address, Code = code + } + }, + Calls = new[] { CallTransactionModel.FromTransaction(systemTransactionForModifiedVM) } + } }, - Calls = new[] { systemTransactionForModifiedVM.FromTransaction() } + TraceTransfers = true }; - // Act - BlockchainBridge.MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, new[] { requestMultiCall }, CancellationToken.None); + BlockchainBridge.MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, payload, CancellationToken.None); Log[]? logs = result.items.First().Calls.First().Logs; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs index c101c287c9a..a0ffde60192 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs @@ -51,8 +51,7 @@ public async Task Initialize() Substitute.For(), Substitute.For(), Substitute.For(), - Substitute.For(), - dbProvider); + Substitute.For()); } [Test] diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 40e06b8627d..b332ad88374 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -123,6 +123,7 @@ protected override async Task Build(ISpecProvider? specProvider LimboLogs.Instance); IMultiCallBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + false, new ReadOnlyDbProvider(dbProvider, true), SpecProvider, LimboLogs.Instance); @@ -151,8 +152,7 @@ protected override async Task Build(ISpecProvider? specProvider SpecProvider, GasPriceOracle, new EthSyncingInfo(BlockTree, ReceiptStorage, syncConfig, new StaticSelector(SyncMode.All), LogManager), - FeeHistoryOracle, - dbProvider); + FeeHistoryOracle); return this; } diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs index 7405583e414..784a64cbabe 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs @@ -328,18 +328,7 @@ private void LogRequest(string methodName, string?[] providedParameters, Paramet } else { - if (providedParameter.StartsWith("\"") && providedParameter.EndsWith("\"")) - { - executionParam = - _serializer.Deserialize( - new JsonTextReader(new StringReader(providedParameter)), paramType); - } - else - { - executionParam = - _serializer.Deserialize( - new JsonTextReader(new StringReader($"\"{providedParameter}\"")), paramType); - } + executionParam = _serializer.Deserialize(new JsonTextReader(new StringReader($"\"{providedParameter}\"")), paramType); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs index 73b062bbf45..9ee7d1c9455 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs @@ -7,7 +7,6 @@ using Nethermind.Blockchain.Receipts; using Nethermind.Consensus; using Nethermind.Core.Specs; -using Nethermind.Db; using Nethermind.Facade; using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; @@ -35,7 +34,6 @@ public class EthModuleFactory : ModuleFactoryBase private readonly IReceiptStorage _receiptStorage; private readonly IGasPriceOracle _gasPriceOracle; private readonly IEthSyncingInfo _ethSyncingInfo; - private readonly IDbProvider _dbProvider; public EthModuleFactory( ITxPool txPool, @@ -49,8 +47,7 @@ public EthModuleFactory( ISpecProvider specProvider, IReceiptStorage receiptStorage, IGasPriceOracle gasPriceOracle, - IEthSyncingInfo ethSyncingInfo, - IDbProvider dbProvider) + IEthSyncingInfo ethSyncingInfo) { _txPool = txPool ?? throw new ArgumentNullException(nameof(txPool)); _txSender = txSender ?? throw new ArgumentNullException(nameof(txSender)); @@ -61,7 +58,6 @@ public EthModuleFactory( _blockchainBridgeFactory = blockchainBridgeFactory ?? throw new ArgumentNullException(nameof(blockchainBridgeFactory)); _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _ethSyncingInfo = ethSyncingInfo ?? throw new ArgumentNullException(nameof(ethSyncingInfo)); - _dbProvider = dbProvider ?? throw new ArgumentNullException(nameof(dbProvider)); _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage)); _gasPriceOracle = gasPriceOracle ?? throw new ArgumentNullException(nameof(gasPriceOracle)); _blockTree = blockTree.AsReadOnly(); @@ -81,8 +77,7 @@ public override IEthRpcModule Create() _specProvider, _gasPriceOracle, _ethSyncingInfo, - new FeeHistoryOracle(_blockTree, _receiptStorage, _specProvider), - _dbProvider); + new FeeHistoryOracle(_blockTree, _receiptStorage, _specProvider)); } public static List Converters = new() diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 8ff24d73ed1..65c869fb4de 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -3,6 +3,7 @@ using System; using System.Threading; +using System.Xml; using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Eip2930; @@ -15,49 +16,45 @@ namespace Nethermind.JsonRpc.Modules.Eth { + //General executor public partial class EthRpcModule { - private abstract class TxExecutor + + + + // Single call executor + private abstract class TxExecutor : ExecutorBase { - protected readonly IBlockchainBridge _blockchainBridge; - private readonly IBlockFinder _blockFinder; - private readonly IJsonRpcConfig _rpcConfig; + protected TxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : + base(blockchainBridge, blockFinder, rpcConfig) + { } + + protected override Transaction Prepare(TransactionForRpc call) + { + return call.ToTransaction(_blockchainBridge.GetChainId()); - protected TxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) + } + protected override ResultWrapper Execute(BlockHeader header, Transaction tx, CancellationToken token) { - _blockchainBridge = blockchainBridge; - _blockFinder = blockFinder; - _rpcConfig = rpcConfig; + return ExecuteTx(header, tx, token); } - public ResultWrapper ExecuteTx( + public override ResultWrapper Execute( TransactionForRpc transactionCall, BlockParameter? blockParameter) { - SearchResult searchResult = _blockFinder.SearchForHeader(blockParameter); - if (searchResult.IsError) - { - return ResultWrapper.Fail(searchResult); - } - - BlockHeader header = searchResult.Object; - if (!HasStateForBlock(_blockchainBridge, header)) - { - return ResultWrapper.Fail($"No state available for block {header.Hash}", - ErrorCodes.ResourceUnavailable); - } - transactionCall.EnsureDefaults(_rpcConfig.GasCap); + return base.Execute(transactionCall, blockParameter); + } - using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); - Transaction tx = transactionCall.ToTransaction(_blockchainBridge.GetChainId()); - return ExecuteTx(header.Clone(), tx, cancellationTokenSource.Token); + public ResultWrapper ExecuteTx( + TransactionForRpc transactionCall, + BlockParameter? blockParameter) + { + return Execute(transactionCall, blockParameter); } protected abstract ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token); - - protected ResultWrapper GetInputError(BlockchainBridge.CallOutput result) => - ResultWrapper.Fail(result.Error, ErrorCodes.InvalidInput); } private class CallTxExecutor : TxExecutor @@ -80,6 +77,7 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, Transacti ? GetInputError(result) : ResultWrapper.Fail("VM execution error.", ErrorCodes.ExecutionError, result.Error); } + } private class EstimateGasTxExecutor : TxExecutor diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 30d5fda626d..d4674d67b3c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -14,7 +14,6 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; -using Nethermind.Db; using Nethermind.Evm; using Nethermind.Facade; using Nethermind.Facade.Eth; @@ -56,9 +55,7 @@ public partial class EthRpcModule : IEthRpcModule private readonly IEthSyncingInfo _ethSyncingInfo; private readonly IFeeHistoryOracle _feeHistoryOracle; - private readonly IDbProvider _dbProvider; - - public static bool HasStateForBlock(IBlockchainBridge blockchainBridge, BlockHeader header) + internal static bool HasStateForBlock(IBlockchainBridge blockchainBridge, BlockHeader header) { RootCheckVisitor rootCheckVisitor = new(); blockchainBridge.RunTreeVisitor(rootCheckVisitor, header.StateRoot!); @@ -77,8 +74,7 @@ public EthRpcModule( ISpecProvider specProvider, IGasPriceOracle gasPriceOracle, IEthSyncingInfo ethSyncingInfo, - IFeeHistoryOracle feeHistoryOracle, - IDbProvider dbProvider) + IFeeHistoryOracle feeHistoryOracle) { _logger = logManager.GetClassLogger(); _rpcConfig = rpcConfig ?? throw new ArgumentNullException(nameof(rpcConfig)); @@ -92,7 +88,6 @@ public EthRpcModule( _gasPriceOracle = gasPriceOracle ?? throw new ArgumentNullException(nameof(gasPriceOracle)); _ethSyncingInfo = ethSyncingInfo ?? throw new ArgumentNullException(nameof(ethSyncingInfo)); _feeHistoryOracle = feeHistoryOracle ?? throw new ArgumentNullException(nameof(feeHistoryOracle)); - _dbProvider = dbProvider ?? throw new ArgumentNullException(nameof(dbProvider)); ; } public ResultWrapper eth_protocolVersion() @@ -354,17 +349,10 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); - public ResultWrapper eth_multicall(ulong version, MultiCallBlockStateCallsModel[] blockCalls, - BlockParameter? blockParameter = null, bool traceTransfers = true) - { - return new MultiCallTxExecutor(_dbProvider, _blockchainBridge, _blockFinder, _specProvider, _rpcConfig) - .Execute(version, blockCalls, blockParameter, traceTransfers); - } - - public ResultWrapper eth_multicallV1(MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null, - bool traceTransfers = true) + public ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) { - return eth_multicall(1, blockCalls, blockParameter, traceTransfers); + return new MultiCallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) + .Execute(payload, blockParameter); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs index e85fbfb9044..83585d4810d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs @@ -157,15 +157,7 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa throw new NotSupportedException(); } - public ResultWrapper eth_multicall(ulong version, - MultiCallBlockStateCallsModel[] blockCalls, - BlockParameter? blockParameter = null, bool traceTransfers = true) - { - throw new NotSupportedException(); - } - - public ResultWrapper eth_multicallV1(MultiCallBlockStateCallsModel[] blockCalls, BlockParameter? blockParameter = null, - bool traceTransfers = true) + public ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) { throw new NotImplementedException(); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs new file mode 100644 index 00000000000..c59c69dca23 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Threading; +using Nethermind.Blockchain.Find; +using Nethermind.Core; +using Nethermind.Facade; + +namespace Nethermind.JsonRpc.Modules.Eth; + +public abstract class ExecutorBase +{ + protected readonly IBlockchainBridge _blockchainBridge; + protected readonly IBlockFinder _blockFinder; + protected readonly IJsonRpcConfig _rpcConfig; + + protected ExecutorBase(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) + { + _blockchainBridge = blockchainBridge; + _blockFinder = blockFinder; + _rpcConfig = rpcConfig; + } + + public virtual ResultWrapper Execute( + TRequest call, + BlockParameter? blockParameter) + { + SearchResult searchResult = _blockFinder.SearchForHeader(blockParameter); + if (searchResult.IsError) + { + return ResultWrapper.Fail(searchResult); + } + + BlockHeader header = searchResult.Object; + if (!EthRpcModule.HasStateForBlock(_blockchainBridge, header)) + { + return ResultWrapper.Fail($"No state available for block {header.Hash}", + ErrorCodes.ResourceUnavailable); + } + + using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); + TProcessing? toProcess = Prepare(call); + return Execute(header.Clone(), toProcess, cancellationTokenSource.Token); + } + + protected abstract TProcessing Prepare(TRequest call); + + protected abstract ResultWrapper Execute(BlockHeader header, TProcessing tx, CancellationToken token); + + protected ResultWrapper GetInputError(BlockchainBridge.CallOutput result) => + ResultWrapper.Fail(result.Error, ErrorCodes.InvalidInput); +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 18b891d765b..de8f5a86d1f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -151,28 +151,11 @@ public interface IEthRpcModule : IRpcModule 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 (does not create a transaction)", + Description = "Executes a simulation across multiple blocks (does not create a transaction or block)", IsSharable = false, ExampleResponse = "0x")] - ResultWrapper eth_multicall(ulong version, - [JsonRpcParameter(ExampleValue = - "[{\"stateOverrides\":[{\"nonce\":\"0x1\", \"address\": \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\", \"balance\": \"0xde0b6b3a7640000\", \"state\": {\"0x2292f0db49e1af24fbcac7f32b7537f334244455ad0ed0b46a78202982e7b70d\": \"0xde0b6b3a7640000\", \"0x0x877bd4632ef8c8ddc43b67e5a4511d939eadb612553c8a060670e05ebb1bb83c\": \"0xde0b6b3a7640000\"}}],\"calls\":[{\"from\":\"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"to\":\"0x6b175474e89094c44da98b954eedeac495271d0f\",\"data\":\"0x18160ddd\"}]}]")] - MultiCallBlockStateCallsModel[] blockCalls, - BlockParameter? blockParameter = null, bool traceTransfers = true); - - [JsonRpcMethod(IsImplemented = true, - Description = "Executes a tx call (does not create a transaction)", - IsSharable = false, - ExampleResponse = "0x")] - ResultWrapper eth_multicallV1( - [JsonRpcParameter(ExampleValue = - "[{\"stateOverrides\":[{\"nonce\":\"0x1\", \"address\": \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\", \"balance\": \"0xde0b6b3a7640000\", \"state\": {\"0x2292f0db49e1af24fbcac7f32b7537f334244455ad0ed0b46a78202982e7b70d\": \"0xde0b6b3a7640000\", \"0x0x877bd4632ef8c8ddc43b67e5a4511d939eadb612553c8a060670e05ebb1bb83c\": \"0xde0b6b3a7640000\"}}],\"calls\":[{\"from\":\"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"to\":\"0x6b175474e89094c44da98b954eedeac495271d0f\",\"data\":\"0x18160ddd\"}]}]")] - MultiCallBlockStateCallsModel[] blockCalls, - BlockParameter? blockParameter = null, bool traceTransfers = true); - - + ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null); [JsonRpcMethod(IsImplemented = true, Description = "Executes a tx call and returns gas used (does not create a transaction)", diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 55047e78be3..e775cf3bd4a 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -1,64 +1,28 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System.Collections.Generic; using System.Threading; using Nethermind.Blockchain.Find; using Nethermind.Core; -using Nethermind.Core.Specs; -using Nethermind.Db; using Nethermind.Facade; using Nethermind.Facade.Proxy.Models.MultiCall; -using Nethermind.Int256; namespace Nethermind.JsonRpc.Modules.Eth; -public class MultiCallTxExecutor -{ - private readonly IDbProvider _dbProvider; - private readonly IBlockchainBridge _blockchainBridge; - private readonly IBlockFinder _blockFinder; - private readonly IJsonRpcConfig _rpcConfig; - private readonly ISpecProvider _specProvider; - - public MultiCallTxExecutor(IDbProvider DbProvider, - IBlockchainBridge blockchainBridge, - IBlockFinder blockFinder, - ISpecProvider specProvider, - IJsonRpcConfig rpcConfig) - { - _dbProvider = DbProvider; - _blockchainBridge = blockchainBridge; - _blockFinder = blockFinder; - _specProvider = specProvider; - _rpcConfig = rpcConfig; - } - private UInt256 MaxGas => GetMaxGas(_rpcConfig); +public class MultiCallTxExecutor : ExecutorBase +{ + public MultiCallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : + base(blockchainBridge, blockFinder, rpcConfig) + { } - public static UInt256 GetMaxGas(IJsonRpcConfig config) + protected override MultiCallPayload Prepare(MultiCallPayload call) { - return (UInt256)config.GasCap * (UInt256)config.GasCapMultiplier; + return call; } - public ResultWrapper Execute(ulong version, - MultiCallBlockStateCallsModel[] blockCallsToProcess, - BlockParameter? blockParameter, bool traceTransfers) + protected override ResultWrapper Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) { - SearchResult searchResult = _blockFinder.SearchForHeader(blockParameter); - if (searchResult.IsError) return ResultWrapper.Fail(searchResult); - - BlockHeader header = searchResult.Object; - if (!EthRpcModule.HasStateForBlock(_blockchainBridge, header)) - { - return ResultWrapper.Fail($"No state available for block {header.Hash}", - ErrorCodes.ResourceUnavailable); - } - - using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); - - BlockchainBridge.MultiCallOutput results = _blockchainBridge.MultiCall(header.Clone(), - blockCallsToProcess, - cancellationTokenSource.Token); + BlockchainBridge.MultiCallOutput results = _blockchainBridge.MultiCall(header.Clone(), tx, token); if (results.Error == null) { @@ -67,6 +31,7 @@ public ResultWrapper Execute(ulong version, return ResultWrapper.Fail(results.Error, results.items.ToArray()); - } } + + From c30bf1d406d1ac2db6cc3ba0362f56a6d69287bb Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 3 Aug 2023 13:58:43 +0100 Subject: [PATCH 037/213] fixing benchmarks --- .../Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index bfcd56feeaa..ec91be62f22 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -116,6 +116,7 @@ TransactionProcessor transactionProcessor specProvider, LimboLogs.Instance), MultiCallReadOnlyBlocksProcessingEnv.Create( + false, new ReadOnlyDbProvider(dbProvider, true), specProvider, LimboLogs.Instance), @@ -149,8 +150,7 @@ TransactionProcessor transactionProcessor specProvider, gasPriceOracle, ethSyncingInfo, - feeHistoryOracle, - dbProvider); + feeHistoryOracle); } [Benchmark] From 4407a1b638c78b74edb5ce037fefe46629528cd0 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 3 Aug 2023 16:58:51 +0100 Subject: [PATCH 038/213] minor protocol update --- .../Nethermind.Facade/BlockchainBridge.cs | 12 +- .../Proxy/Models/MultiCall/AccountOverride.cs | 3 - .../Proxy/Models/MultiCall/BlockOverride.cs | 4 +- .../Proxy/Models/MultiCall/BlockStateCall.cs | 5 +- .../JsonRpcServiceTests.cs | 366 +++++++++--------- ...ulticallTestsPrecompilesWithRedirection.cs | 19 +- .../Modules/Eth/EthRpcMulticallTestsBase.cs | 2 +- .../EthMulticallTestsBlocksAndTransactions.cs | 39 +- .../EthMulticallTestsSimplePrecompiles.cs | 13 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 4 +- 10 files changed, 227 insertions(+), 240 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 957e9836aff..a38a9198c17 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -142,7 +142,7 @@ public class MultiCallOutput { public string? Error { get; set; } - public List items; + public List Items { get; set; } } public class CallOutput @@ -205,7 +205,7 @@ public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, C result.Error = ex.ToString(); } - result.items = multiCallOutputTracer._results; + result.Items = multiCallOutputTracer._results; return result; } @@ -450,13 +450,15 @@ private UInt256 GetNonce(Keccak stateRoot, Address address) } //Apply changes to accounts and contracts states including precompiles - private void ModifyAccounts(AccountOverride[] StateOverrides, IWorldState? StateProvider, IReleaseSpec? CurrentSpec) + private void ModifyAccounts(Dictionary StateOverrides, IWorldState? StateProvider, IReleaseSpec? CurrentSpec) { Account? acc; - foreach (AccountOverride accountOverride in StateOverrides) + foreach (KeyValuePair overrideData in StateOverrides) { - Address address = accountOverride.Address; + Address address = overrideData.Key; + AccountOverride? accountOverride = overrideData.Value; + bool accExists = StateProvider.AccountExists(address); if (!accExists) { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs index d4c1a8e0002..57500aa6560 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs @@ -16,9 +16,6 @@ public class AccountOverride public bool IsState => Type == AccountOverrideType.AccountOverrideState; public bool IsStateDiff => Type == AccountOverrideType.AccountOverrideStateDiff; - /// AccountOverrideState and AccountOverrideStateDiff base - public Address Address { get; set; } - public Address? MoveToAddress { get; set; } public UInt256 Nonce { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index 1b140418feb..588feedf8bf 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -18,7 +18,7 @@ public class BlockOverride public UInt256 Time { get; set; } public ulong GasLimit { get; set; } public Address FeeRecipient { get; set; } = Address.Zero; - public UInt256 BaseFee { get; set; } + public UInt256 BaseFeePerGas { get; set; } public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) { @@ -62,7 +62,7 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) result.MixHash = PrevRandao; //Note we treet parent block as such - result.BaseFeePerGas = BaseFee != 0 ? BaseFee : parent.BaseFeePerGas; + result.BaseFeePerGas = BaseFeePerGas != 0 ? BaseFeePerGas : parent.BaseFeePerGas; UInt256 difficulty = ConstantDifficulty.One.Calculate(result, parent); result.Difficulty = difficulty; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs index c0d48decd38..2ace0b0f540 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs @@ -1,11 +1,14 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.Collections.Generic; +using Nethermind.Core; + namespace Nethermind.Facade.Proxy.Models.MultiCall; public class BlockStateCalls { public BlockOverride? BlockOverrides { get; set; } - public AccountOverride[] StateOverrides { get; set; } + public Dictionary StateOverrides { get; set; } public CallTransactionModel[] Calls { get; set; } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index b18371c7a5c..11f3127a1d6 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -27,233 +27,217 @@ using NSubstitute; using NUnit.Framework; -namespace Nethermind.JsonRpc.Test; - -[Parallelizable(ParallelScope.Self)] -[TestFixture] -public class JsonRpcServiceTests +namespace Nethermind.JsonRpc.Test { - [SetUp] - public void Initialize() - { - Assembly jConfig = typeof(JsonRpcConfig).Assembly; - _configurationProvider = new ConfigProvider(); - _logManager = LimboLogs.Instance; - _context = new JsonRpcContext(RpcEndpoint.Http); - } - - private IJsonRpcService _jsonRpcService = null!; - private IConfigProvider _configurationProvider = null!; - private ILogManager _logManager = null!; - private JsonRpcContext _context = null!; - - private JsonRpcResponse TestRequest(T module, string method, params string[] parameters) where T : IRpcModule - { - RpcModuleProvider moduleProvider = new(new FileSystem(), _configurationProvider.GetConfig(), - LimboLogs.Instance); - moduleProvider.Register(new SingletonModulePool(new SingletonFactory(module))); - _jsonRpcService = - new JsonRpcService(moduleProvider, _logManager, _configurationProvider.GetConfig()); - JsonRpcRequest request = RpcTest.GetJsonRequest(method, parameters); - JsonRpcResponse response = _jsonRpcService.SendRequestAsync(request, _context).Result; - Assert.That(response.Id, Is.EqualTo(request.Id)); - return response; - } - - [Test] - public void GetBlockByNumberTest() - { - IEthRpcModule ethRpcModule = Substitute.For(); - ISpecProvider specProvider = Substitute.For(); - ethRpcModule.eth_getBlockByNumber(Arg.Any(), true).ReturnsForAnyArgs(x => - ResultWrapper.Success(new BlockForRpc(Build.A.Block.WithNumber(2).TestObject, true, - specProvider))); - JsonRpcSuccessResponse? response = - TestRequest(ethRpcModule, "eth_getBlockByNumber", "0x1b4", "true") as JsonRpcSuccessResponse; - Assert.That((response?.Result as BlockForRpc)?.Number, Is.EqualTo(2L)); - } - - [Test] - public void Eth_module_populates_size_when_returning_block_data() - { - IEthRpcModule ethRpcModule = Substitute.For(); - ISpecProvider specProvider = Substitute.For(); - ethRpcModule.eth_getBlockByNumber(Arg.Any(), true).ReturnsForAnyArgs(x => - ResultWrapper.Success(new BlockForRpc(Build.A.Block.WithNumber(2).TestObject, true, - specProvider))); - JsonRpcSuccessResponse? response = - TestRequest(ethRpcModule, "eth_getBlockByNumber", "0x1b4", "true") as JsonRpcSuccessResponse; - Assert.That((response?.Result as BlockForRpc)?.Size, Is.EqualTo(513L)); - } - - - [Test] - public void CanRunEthMulticallV1Empty() + [Parallelizable(ParallelScope.Self)] + [TestFixture] + public class JsonRpcServiceTests { - MultiCallPayload payload = new() { BlockStateCalls = Array.Empty() }; - - EthereumJsonSerializer serializer = new(); + [SetUp] + public void Initialize() + { + Assembly jConfig = typeof(JsonRpcConfig).Assembly; + _configurationProvider = new ConfigProvider(); + _logManager = LimboLogs.Instance; + _context = new JsonRpcContext(RpcEndpoint.Http); + } + + private IJsonRpcService _jsonRpcService = null!; + private IConfigProvider _configurationProvider = null!; + private ILogManager _logManager = null!; + private JsonRpcContext _context = null!; + + private JsonRpcResponse TestRequest(T module, string method, params string[] parameters) where T : IRpcModule + { + RpcModuleProvider moduleProvider = new(new FileSystem(), _configurationProvider.GetConfig(), LimboLogs.Instance); + moduleProvider.Register(new SingletonModulePool(new SingletonFactory(module), true)); + _jsonRpcService = new JsonRpcService(moduleProvider, _logManager, _configurationProvider.GetConfig()); + JsonRpcRequest request = RpcTest.GetJsonRequest(method, parameters); + JsonRpcResponse response = _jsonRpcService.SendRequestAsync(request, _context).Result; + Assert.That(response.Id, Is.EqualTo(request.Id)); + return response; + } + + [Test] + public void GetBlockByNumberTest() + { + IEthRpcModule ethRpcModule = Substitute.For(); + ISpecProvider specProvider = Substitute.For(); + ethRpcModule.eth_getBlockByNumber(Arg.Any(), true).ReturnsForAnyArgs(x => ResultWrapper.Success(new BlockForRpc(Build.A.Block.WithNumber(2).TestObject, true, specProvider))); + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_getBlockByNumber", "0x1b4", "true") as JsonRpcSuccessResponse; + Assert.That((response?.Result as BlockForRpc)?.Number, Is.EqualTo(2L)); + } + + [Test] + public void Eth_module_populates_size_when_returning_block_data() + { + IEthRpcModule ethRpcModule = Substitute.For(); + ISpecProvider specProvider = Substitute.For(); + ethRpcModule.eth_getBlockByNumber(Arg.Any(), true).ReturnsForAnyArgs(x => ResultWrapper.Success(new BlockForRpc(Build.A.Block.WithNumber(2).TestObject, true, specProvider))); + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_getBlockByNumber", "0x1b4", "true") as JsonRpcSuccessResponse; + Assert.That((response?.Result as BlockForRpc)?.Size, Is.EqualTo(513L)); + } - string serializedCall = serializer.Serialize(payload); - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_multicallV1(payload).ReturnsForAnyArgs(x => - ResultWrapper.Success(Array.Empty())); - JsonRpcSuccessResponse? response = - TestRequest(ethRpcModule, "eth_multicallV1", serializedCall) as JsonRpcSuccessResponse; - Assert.IsTrue(response != null); - Assert.That(response?.Result, Is.EqualTo(Array.Empty())); - } + [Test] + public void CanRunEthMulticallV1Empty() + { + MultiCallPayload payload = new() { BlockStateCalls = Array.Empty() }; + EthereumJsonSerializer serializer = new(); - [Test] - public void CanHandleOptionalArguments() - { - EthereumJsonSerializer serializer = new(); - string serialized = serializer.Serialize(new TransactionForRpc()); - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_call(Arg.Any()) - .ReturnsForAnyArgs(x => ResultWrapper.Success("0x1")); - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized) as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo("0x1")); - } + string serializedCall = serializer.Serialize(payload); - [Test] - public void Case_sensitivity_test() - { - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_chainId().ReturnsForAnyArgs(ResultWrapper.Success(1ul)); - TestRequest(ethRpcModule, "eth_chainID").Should().BeOfType(); - TestRequest(ethRpcModule, "eth_chainId").Should().BeOfType(); - } + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_multicallV1(payload).ReturnsForAnyArgs(x => + ResultWrapper.Success(Array.Empty())); + JsonRpcSuccessResponse? response = + TestRequest(ethRpcModule, "eth_multicallV1", serializedCall) as JsonRpcSuccessResponse; + Assert.IsTrue(response != null); + Assert.That(response?.Result, Is.EqualTo(Array.Empty())); + } - [Test] - public void GetNewFilterTest() - { - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_newFilter(Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success(1)); - var parameters = new + [Test] + public void CanHandleOptionalArguments() + { + EthereumJsonSerializer serializer = new(); + string serialized = serializer.Serialize(new TransactionForRpc()); + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_call(Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success("0x1")); + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized) as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo("0x1")); + } + + [Test] + public void Case_sensitivity_test() + { + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_chainId().ReturnsForAnyArgs(ResultWrapper.Success(1ul)); + TestRequest(ethRpcModule, "eth_chainID").Should().BeOfType(); + TestRequest(ethRpcModule, "eth_chainId").Should().BeOfType(); + } + + [Test] + public void GetNewFilterTest() { - fromBlock = "0x1", - toBlock = "latest", - address = "0x1f88f1f195afa192cfee860698584c030f4c9db2", - topics = new List + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_newFilter(Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success(1)); + + var parameters = new + { + fromBlock = "0x1", + toBlock = "latest", + address = "0x1f88f1f195afa192cfee860698584c030f4c9db2", + topics = new List { - "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", - null!, + "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", null!, new[] { "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x0000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc" } } - }; + }; - JsonRpcSuccessResponse? response = - TestRequest(ethRpcModule, "eth_newFilter", JsonConvert.SerializeObject(parameters)) as - JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo(UInt256.One)); - } + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_newFilter", JsonConvert.SerializeObject(parameters)) as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo(UInt256.One)); + } - [Test] - public void Eth_call_is_working_with_implicit_null_as_the_last_argument() - { - EthereumJsonSerializer serializer = new(); - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_call(Arg.Any(), Arg.Any()) - .ReturnsForAnyArgs(x => ResultWrapper.Success("0x")); + [Test] + public void Eth_call_is_working_with_implicit_null_as_the_last_argument() + { + EthereumJsonSerializer serializer = new(); + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_call(Arg.Any(), Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success("0x")); - string serialized = serializer.Serialize(new TransactionForRpc()); + string serialized = serializer.Serialize(new TransactionForRpc()); - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized) as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo("0x")); - } + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized) as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo("0x")); + } - [TestCase("")] - [TestCase(null)] - public void Eth_call_is_working_with_explicit_null_as_the_last_argument(string nullValue) - { - EthereumJsonSerializer serializer = new(); - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_call(Arg.Any(), Arg.Any()) - .ReturnsForAnyArgs(x => ResultWrapper.Success("0x")); + [TestCase("")] + [TestCase(null)] + public void Eth_call_is_working_with_explicit_null_as_the_last_argument(string nullValue) + { + EthereumJsonSerializer serializer = new(); + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_call(Arg.Any(), Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success("0x")); - string serialized = serializer.Serialize(new TransactionForRpc()); + string serialized = serializer.Serialize(new TransactionForRpc()); - JsonRpcSuccessResponse? response = - TestRequest(ethRpcModule, "eth_call", serialized, nullValue) as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo("0x")); - } + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized, nullValue) as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo("0x")); + } - [Test] - public void GetWorkTest() - { - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_getWork().ReturnsForAnyArgs(x => - ResultWrapper>.Success(new[] { Bytes.FromHexString("aa"), Bytes.FromHexString("01") })); - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_getWork") as JsonRpcSuccessResponse; - byte[][]? dataList = response?.Result as byte[][]; - Assert.NotNull(dataList?.SingleOrDefault(d => d.ToHexString(true) == "0xaa")); - Assert.NotNull(dataList?.SingleOrDefault(d => d.ToHexString(true) == "0x01")); - } - - [Test] - public void IncorrectMethodNameTest() - { - JsonRpcErrorResponse? response = - TestRequest(Substitute.For(), "incorrect_method") as JsonRpcErrorResponse; - Assert.That(response?.Error?.Code, Is.EqualTo(ErrorCodes.MethodNotFound)); - } - - [Test] - public void NetVersionTest() - { - INetRpcModule netRpcModule = Substitute.For(); - netRpcModule.net_version().ReturnsForAnyArgs(x => ResultWrapper.Success("1")); - JsonRpcSuccessResponse? response = TestRequest(netRpcModule, "net_version") as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo("1")); - Assert.IsNotInstanceOf(response); - } - - [Test] - public void Web3ShaTest() - { - IWeb3RpcModule web3RpcModule = Substitute.For(); - web3RpcModule.web3_sha3(Arg.Any()) - .ReturnsForAnyArgs(x => ResultWrapper.Success(TestItem.KeccakA)); - JsonRpcSuccessResponse? response = - TestRequest(web3RpcModule, "web3_sha3", "0x68656c6c6f20776f726c64") as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo(TestItem.KeccakA)); - } + [Test] + public void GetWorkTest() + { + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_getWork().ReturnsForAnyArgs(x => ResultWrapper>.Success(new[] { Bytes.FromHexString("aa"), Bytes.FromHexString("01") })); + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_getWork") as JsonRpcSuccessResponse; + byte[][]? dataList = response?.Result as byte[][]; + Assert.NotNull(dataList?.SingleOrDefault(d => d.ToHexString(true) == "0xaa")); + Assert.NotNull(dataList?.SingleOrDefault(d => d.ToHexString(true) == "0x01")); + } + + [Test] + public void IncorrectMethodNameTest() + { + JsonRpcErrorResponse? response = TestRequest(Substitute.For(), "incorrect_method") as JsonRpcErrorResponse; + Assert.That(response?.Error?.Code, Is.EqualTo(ErrorCodes.MethodNotFound)); + } - [TestCaseSource(nameof(BlockForRpcTestSource))] - public void BlockForRpc_should_expose_withdrawals_if_any((bool Expected, Core.Block Block) item) - { - ISpecProvider? specProvider = Substitute.For(); - BlockForRpc rpcBlock = new BlockForRpc(item.Block, false, specProvider); + [Test] + public void NetVersionTest() + { + INetRpcModule netRpcModule = Substitute.For(); + netRpcModule.net_version().ReturnsForAnyArgs(x => ResultWrapper.Success("1")); + JsonRpcSuccessResponse? response = TestRequest(netRpcModule, "net_version") as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo("1")); + Assert.IsNotInstanceOf(response); + } + + [Test] + public void Web3ShaTest() + { + IWeb3RpcModule web3RpcModule = Substitute.For(); + web3RpcModule.web3_sha3(Arg.Any()).ReturnsForAnyArgs(x => ResultWrapper.Success(TestItem.KeccakA)); + JsonRpcSuccessResponse? response = TestRequest(web3RpcModule, "web3_sha3", "0x68656c6c6f20776f726c64") as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo(TestItem.KeccakA)); + } + + [TestCaseSource(nameof(BlockForRpcTestSource))] + public void BlockForRpc_should_expose_withdrawals_if_any((bool Expected, Block Block) item) + { + var specProvider = Substitute.For(); + var rpcBlock = new BlockForRpc(item.Block, false, specProvider); - rpcBlock.WithdrawalsRoot.Should().BeEquivalentTo(item.Block.WithdrawalsRoot); - rpcBlock.Withdrawals.Should().BeEquivalentTo(item.Block.Withdrawals); + rpcBlock.WithdrawalsRoot.Should().BeEquivalentTo(item.Block.WithdrawalsRoot); + rpcBlock.Withdrawals.Should().BeEquivalentTo(item.Block.Withdrawals); - string? json = new EthereumJsonSerializer().Serialize(rpcBlock); + var json = new EthereumJsonSerializer().Serialize(rpcBlock); - json.Contains("withdrawals\"", StringComparison.Ordinal).Should().Be(item.Expected); - json.Contains("withdrawalsRoot", StringComparison.Ordinal).Should().Be(item.Expected); - } + json.Contains("withdrawals\"", StringComparison.Ordinal).Should().Be(item.Expected); + json.Contains("withdrawalsRoot", StringComparison.Ordinal).Should().Be(item.Expected); + } - // With (Block, bool), tests don't run for some reason. Flipped to (bool, Block). - private static IEnumerable<(bool, Block)> BlockForRpcTestSource() + // With (Block, bool), tests don't run for some reason. Flipped to (bool, Block). + private static IEnumerable<(bool, Block)> BlockForRpcTestSource() => + new[] { - return new[] + (true, Build.A.Block + .WithWithdrawals(new[] { - (true, Build.A.Block - .WithWithdrawals(Build.A.Withdrawal + Build.A.Withdrawal .WithAmount(1) .WithRecipient(TestItem.AddressA) - .TestObject) + .TestObject + }) .TestObject ), + (false, Build.A.Block.WithWithdrawals(null).TestObject) }; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 3fc356cc6da..4922eb9caa0 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -1,10 +1,12 @@ // SPDX-FileCopyrightText: 2023 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.Extensions; +using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Evm; using Nethermind.Evm.Precompiles; @@ -81,8 +83,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( Address? contractAddress = await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EthMulticallTestsSimplePrecompiles.EcRecoverCallerContractBytecode); - Address? mainChainRpcAddress = - EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); Transaction systemTransactionForModifiedVM = new() { @@ -96,8 +97,8 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); - var header = chain.BlockFinder.Head.Header; - var spec = chain.SpecProvider.GetSpec(header); + BlockHeader header = chain.BlockFinder.Head.Header; + IReleaseSpec spec = chain.SpecProvider.GetSpec(header); systemTransactionForModifiedVM.GasPrice = header.BaseFeePerGas >= 1 ? header.BaseFeePerGas : 1; systemTransactionForModifiedVM.GasLimit = (long)systemTransactionForModifiedVM.CalculateTransactionPotentialCost(spec.IsEip1559Enabled, header.BaseFeePerGas); @@ -105,21 +106,21 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( { BlockStateCalls = new BlockStateCalls[] { new() { - StateOverrides = new[] - { + StateOverrides = new Dictionary() + { {EcRecoverPrecompile.Address, new AccountOverride { - Address = EcRecoverPrecompile.Address, Code = code, MoveToAddress = new Address("0x0000000000000000000000000000000000000666") - } + }} }, Calls = new[] { CallTransactionModel.FromTransaction(systemTransactionForModifiedVM), } }}, - TraceTransfers = true + TraceTransfers = true, + Validation = true }; //Force persistancy of head block in main chain diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs index a386cfc2144..f7852cdb7bf 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs @@ -139,7 +139,7 @@ public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, stri //createContractTxReceipt2.ContractAddress // .Should().NotBeNull($"Contract transaction {tx.Hash} was not deployed."); - Address contractAddress1 = null; + Address contractAddress1; using (SecureStringWrapper pass = new("testB")) { wallet.Import(fromPrivateKey.KeyBytes, pass.SecureData); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 0eed123d189..0df164e793a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Generic; using System.Threading.Tasks; using Nethermind.Blockchain.Find; using Nethermind.Core; @@ -20,16 +21,15 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; public class EthMulticallTestsBlocksAndTransactions { - private Transaction GetTransferTxData(UInt256 Nonce, IEthereumEcdsa ethereumEcdsa, PrivateKey From, Address To, - UInt256 ammount) + private static Transaction GetTransferTxData(UInt256 nonce, IEthereumEcdsa ethereumEcdsa, PrivateKey from, Address to, UInt256 ammount) { Transaction tx = new() { Value = ammount, - Nonce = Nonce, + Nonce = nonce, GasLimit = 50_000, - SenderAddress = From.Address, - To = To, + SenderAddress = from.Address, + To = to, GasPrice = 20.GWei() }; @@ -44,7 +44,7 @@ public async Task Test_eth_multicall_serialisation() TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - var pk = new PrivateKey("0xc7ba1a2892ec0ea1940eebeae739b1effe0543b3104469d5b66625f49ca86e94"); + PrivateKey pk = new("0xc7ba1a2892ec0ea1940eebeae739b1effe0543b3104469d5b66625f49ca86e94"); UInt256 nonceA = chain.State.GetNonce(pk.Address); Transaction txMainnetAtoBtoFail = @@ -68,17 +68,20 @@ public async Task Test_eth_multicall_serialisation() CallTransactionModel.FromTransaction(txMainnetAtoBtoFail), CallTransactionModel.FromTransaction(txMainnetAtoBToComplete), }, - StateOverrides = new[] + StateOverrides = new Dictionary() { - new AccountOverride() { - Address = pk.Address, - Balance = Math.Max(420_000_004_000_001UL, 1_000_000_004_000_001UL) + pk.Address, + new AccountOverride() + { + Balance = Math.Max(420_000_004_000_001UL, 1_000_000_004_000_001UL) + } } } } }, - TraceTransfers = true + TraceTransfers = true, + Validation = true }; EthereumJsonSerializer serializer = new(); @@ -140,7 +143,7 @@ public async Task Test_eth_multicall_eth_moved() Number = (UInt256)new decimal(2), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, - BaseFee = 0 + BaseFeePerGas = 0 }, Calls = new[] { CallTransactionModel.FromTransaction(txAtoB1), CallTransactionModel.FromTransaction(txAtoB2) } }, @@ -152,7 +155,7 @@ public async Task Test_eth_multicall_eth_moved() Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10000), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, - BaseFee = 0 + BaseFeePerGas = 0 }, Calls = new[] { CallTransactionModel.FromTransaction(txAtoB3), CallTransactionModel.FromTransaction(txAtoB4) } } @@ -166,8 +169,7 @@ public async Task Test_eth_multicall_eth_moved() UInt256 after = chain.State.GetAccount(TestItem.AddressA).Balance; Assert.Less(after, before); - TxReceipt recept = chain.Bridge.GetReceipt(txMainnetAtoB.Hash); - LogEntry[]? ls = recept.Logs; + chain.Bridge.GetReceipt(txMainnetAtoB.Hash); //Force persistancy of head block in main chain chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); @@ -218,7 +220,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, - BaseFee = 0 + BaseFeePerGas = 0 }, Calls = new[] { CallTransactionModel.FromTransaction(txAtoB1) } }, @@ -230,7 +232,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() Number = (UInt256)new decimal(123), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, - BaseFee = 0 + BaseFeePerGas = 0 }, Calls = new[] { CallTransactionModel.FromTransaction(txAtoB2) } } @@ -244,8 +246,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() UInt256 after = chain.State.GetAccount(TestItem.AddressA).Balance; Assert.Less(after, before); - TxReceipt recept = chain.Bridge.GetReceipt(txMainnetAtoB.Hash); - LogEntry[]? ls = recept.Logs; + chain.Bridge.GetReceipt(txMainnetAtoB.Hash); //Force persistancy of head block in main chain chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 950c33ab574..4360afdf15e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -89,22 +90,20 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe { new BlockStateCalls() { - StateOverrides = new[] + StateOverrides = new Dictionary() { - new AccountOverride - { - Address = EcRecoverPrecompile.Address, Code = code - } + { EcRecoverPrecompile.Address, new AccountOverride { Code = code } } }, Calls = new[] { CallTransactionModel.FromTransaction(systemTransactionForModifiedVM) } } }, - TraceTransfers = true + TraceTransfers = true, + Validation = true }; // Act BlockchainBridge.MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, payload, CancellationToken.None); - Log[]? logs = result.items.First().Calls.First().Logs; + Log[]? logs = result.Items.First().Calls.First().Logs; //Check that initial VM is intact diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index e775cf3bd4a..9722479b64c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -26,10 +26,10 @@ protected override ResultWrapper Execute(BlockHeader hea if (results.Error == null) { - return ResultWrapper.Success(results.items.ToArray()); + return ResultWrapper.Success(results.Items.ToArray()); } - return ResultWrapper.Fail(results.Error, results.items.ToArray()); + return ResultWrapper.Fail(results.Error, results.Items.ToArray()); } } From 9430acc1b0c07b1a76deffdc4c768922cde06c04 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 3 Aug 2023 17:42:16 +0100 Subject: [PATCH 039/213] Fixing Nonce --- .../Nethermind.Facade/BlockchainBridge.cs | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 64eeade83d4..eb855f10ddc 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -270,6 +270,8 @@ public CallOutput CreateAccessList(BlockHeader header, Transaction tx, Cancellat } } + + private Dictionary NonceDictionary = new(); private void CallAndRestore( BlockHeader blockHeader, Transaction transaction, @@ -446,7 +448,27 @@ public ulong GetChainId() private UInt256 GetNonce(Keccak stateRoot, Address address) { - return _processingEnv.StateReader.GetNonce(stateRoot, address); + UInt256 nonce = 0; + if (!NonceDictionary.TryGetValue(address, out nonce)) + { + try + { + nonce = _processingEnv.StateReader.GetNonce(stateRoot, address); + } + catch (Exception) + { + // TODO: handle missing state exception, may be account needs to be created + } + + NonceDictionary[address] = nonce; + } + else + { + nonce += 1; + NonceDictionary[address] = nonce; + } + + return nonce; } //Apply changes to accounts and contracts states including precompiles @@ -459,7 +481,16 @@ private void ModifyAccounts(Dictionary StateOverrides, Address address = overrideData.Key; AccountOverride? accountOverride = overrideData.Value; - bool accExists = StateProvider.AccountExists(address); + bool accExists = false; + try + { + accExists = StateProvider.AccountExists(address); + } + catch (Exception) + { + // TODO: handle missing block without exceptions + } + if (!accExists) { StateProvider.CreateAccount(address, accountOverride.Balance, accountOverride.Nonce); From fda6c87c020bd14c4a00760419986089b691f211 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 11:05:50 +0100 Subject: [PATCH 040/213] Softer defaults --- .../Proxy/Models/CallTransactionModel.cs | 16 ++++++++-------- .../Proxy/Models/MultiCall/BlockOverride.cs | 10 +++++----- .../Proxy/Models/MultiCall/BlockStateCall.cs | 4 ++-- .../Proxy/Models/MultiCall/MultiCallPayload.cs | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs index 86d6ac341ff..5484c31d95f 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs @@ -11,12 +11,12 @@ namespace Nethermind.Facade.Proxy.Models { public class CallTransactionModel { - public Address From { get; set; } - public Address To { get; set; } - public UInt256 Gas { get; set; } - public UInt256 GasPrice { get; set; } - public UInt256 Value { get; set; } - public byte[] Data { get; set; } + public Address? From { get; set; } = Address.SystemUser; + public Address? To { get; set; } = Address.Zero; + public UInt256? Gas { get; set; } = 0; + public UInt256? GasPrice { get; set; } = 0; + public UInt256? Value { get; set; } = 0; + public byte[]? Data { get; set; } = { }; public static CallTransactionModel FromTransaction(Transaction transaction) => new() @@ -40,9 +40,9 @@ public Transaction GetTransaction() SenderAddress = From, To = To, Data = Data, - Value = Value, + Value = Value.Value, GasLimit = (long)Gas, - GasPrice = GasPrice + GasPrice = GasPrice.Value }; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index 588feedf8bf..d0ba2ea7e9b 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -14,11 +14,11 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class BlockOverride { public Keccak PrevRandao { get; set; } = Keccak.Zero; - public UInt256 Number { get; set; } - public UInt256 Time { get; set; } - public ulong GasLimit { get; set; } + public UInt256? Number { get; set; } = 0; + public UInt256? Time { get; set; } = 0; + public ulong? GasLimit { get; set; } = 0; public Address FeeRecipient { get; set; } = Address.Zero; - public UInt256 BaseFeePerGas { get; set; } + public UInt256? BaseFeePerGas { get; set; } = 0; public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) { @@ -62,7 +62,7 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) result.MixHash = PrevRandao; //Note we treet parent block as such - result.BaseFeePerGas = BaseFeePerGas != 0 ? BaseFeePerGas : parent.BaseFeePerGas; + result.BaseFeePerGas = BaseFeePerGas.Value != 0 ? BaseFeePerGas.Value : parent.BaseFeePerGas; UInt256 difficulty = ConstantDifficulty.One.Calculate(result, parent); result.Difficulty = difficulty; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs index 2ace0b0f540..580f97d685a 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs @@ -9,6 +9,6 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class BlockStateCalls { public BlockOverride? BlockOverrides { get; set; } - public Dictionary StateOverrides { get; set; } - public CallTransactionModel[] Calls { get; set; } + public Dictionary? StateOverrides { get; set; } = new Dictionary(); + public CallTransactionModel[]? Calls { get; set; } = { }; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs index 830711ca7b5..67dc6f51e48 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs @@ -6,7 +6,7 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class MultiCallPayload { //Definition of blocks that can contain calls and overrides - public BlockStateCalls[] BlockStateCalls { get; set; } + public BlockStateCalls[]? BlockStateCalls { get; set; } //Trace ETH Transfers public bool TraceTransfers { get; set; } = false; From 58b1c7517bd9ce7bd0c062167f8e4dde9098e5da Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 17:03:57 +0100 Subject: [PATCH 041/213] Minor refactoring following the review --- .../Nethermind.Cli/Modules/EthCliModule.cs | 5 -- .../Proxy/EthJsonRpcClientProxyTests.cs | 7 +-- .../Nethermind.Facade/BlockchainBridge.cs | 8 +-- .../Nethermind.Facade/IBlockchainBridge.cs | 2 +- .../Proxy/EthJsonRpcClientProxy.cs | 2 +- .../Proxy/IEthJsonRpcClientProxy.cs | 2 +- .../Proxy/Models/CallTransactionModel.cs | 36 +++---------- .../Proxy/Models/MultiCall/BlockOverride.cs | 51 ++++++++----------- .../Proxy/Models/MultiCall/BlockStateCall.cs | 4 +- .../Models/MultiCall/MultiCallPayload.cs | 5 +- .../JsonRpcServiceTests.cs | 2 +- ...ulticallTestsPrecompilesWithRedirection.cs | 7 +-- .../EthMulticallTestsBlocksAndTransactions.cs | 25 ++++----- .../Eth/EthRpcModule.TransactionExecutor.cs | 3 -- .../Modules/Eth/EthRpcModule.cs | 2 +- .../Modules/Eth/EthRpcModuleProxy.cs | 2 +- .../Modules/Eth/IEthRpcModule.cs | 2 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 27 ++++++++-- 18 files changed, 85 insertions(+), 107 deletions(-) diff --git a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs index d4e22ed132a..af6a65c7903 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs @@ -49,11 +49,6 @@ public JsValue GetProof(string address, string[] storageKeys, string? blockParam return NodeManager.Post("eth_call", tx, blockParameter ?? "latest").Result; } - [CliFunction("eth", "multicall")] - public JsValue MultiCall(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) - { - return NodeManager.PostJint("eth_multicall", version, blockCalls, blockParameter ?? "latest", traceTransfers).Result; - } [CliFunction("eth", "multicallV1")] public JsValue MultiCallV1(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) diff --git a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs index 8183c582989..c48cba3b47a 100644 --- a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using FluentAssertions; +using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Test.Builders; using Nethermind.Int256; @@ -91,7 +92,7 @@ await _client.Received().SendAsync(nameof(_proxy.eth_call), [Test] public async Task eth_multicall_should_invoke_client_method_even_empty() { - MultiCallPayload payload = new(); + MultiCallPayload payload = new(); var blockParameter = BlockParameterModel.Latest; await _proxy.eth_multicallV1(payload, blockParameter); @@ -103,9 +104,9 @@ await _client.Received().SendAsync(nameof(_proxy.eth_mul [Test] public async Task eth_multicallV1_should_invoke_client_method() { - MultiCallPayload payload = new() + MultiCallPayload payload = new() { - BlockStateCalls = new BlockStateCalls[] { }, + BlockStateCalls = new BlockStateCall[] { }, TraceTransfers = true }; diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 19bffb629f5..6f49961bb8e 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -186,7 +186,7 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can - public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken) + public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken) { MultiCallBlockTracer multiCallOutputTracer = new(); MultiCallOutput result = new(); @@ -326,7 +326,7 @@ private void CallAndRestore( transactionProcessor.CallAndRestore(transaction, callHeader, tracer); } - private (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, + private (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) { using (IMultiCallBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers)) @@ -346,7 +346,7 @@ private void CallAndRestore( } } - foreach (BlockStateCalls? callInputBlock in payload.BlockStateCalls) + foreach (BlockStateCall? callInputBlock in payload.BlockStateCalls) { BlockHeader callHeader = null; if (callInputBlock.BlockOverrides == null) @@ -383,7 +383,7 @@ private void CallAndRestore( env.StateProvider.CommitTree(currentBlock.Number); env.StateProvider.RecalculateStateRoot(); - var transactions = callInputBlock.Calls.Select(model => model.GetTransaction()).ToList(); + var transactions = callInputBlock.Calls; foreach (Transaction transaction in transactions) { transaction.SenderAddress ??= Address.SystemUser; diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index 26bfdfd05f7..1e095258bd3 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -26,7 +26,7 @@ public interface IBlockchainBridge : ILogFinder TxReceipt GetReceipt(Keccak txHash); (TxReceipt? Receipt, TxGasInfo? GasInfo, int LogIndexStart) GetReceiptAndGasInfo(Keccak txHash); (TxReceipt? Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Keccak txHash); - MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken); + MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken); CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken); CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken); CallOutput CreateAccessList(BlockHeader header, Transaction tx, CancellationToken cancellationToken, bool optimize); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index a7649386c03..2e3df575ffb 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -40,7 +40,7 @@ public Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_call), transaction, MapBlockParameter(blockParameter)); - public Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null) + public Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_multicallV1), blockCalls, MapBlockParameter(blockParameter)); public Task> eth_getCode(Address address, BlockParameterModel blockParameter = null) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs index d9293362c6e..c3db5a46a2b 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs @@ -19,7 +19,7 @@ public interface IEthJsonRpcClientProxy Task> eth_getTransactionCount(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionReceipt(Keccak transactionHash); Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null); - Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null); + Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null); Task> eth_getCode(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionByHash(Keccak transactionHash); Task> eth_pendingTransactions(); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs index 5484c31d95f..697b11eb3d7 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs @@ -1,9 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using Nethermind.Core; -using Nethermind.Crypto; using Nethermind.Int256; using static Nethermind.Core.Extensions.MemoryExtensions; @@ -11,12 +9,12 @@ namespace Nethermind.Facade.Proxy.Models { public class CallTransactionModel { - public Address? From { get; set; } = Address.SystemUser; - public Address? To { get; set; } = Address.Zero; - public UInt256? Gas { get; set; } = 0; - public UInt256? GasPrice { get; set; } = 0; - public UInt256? Value { get; set; } = 0; - public byte[]? Data { get; set; } = { }; + public Address From { get; set; } + public Address To { get; set; } + public UInt256 Gas { get; set; } + public UInt256 GasPrice { get; set; } + public UInt256 Value { get; set; } + public byte[] Data { get; set; } public static CallTransactionModel FromTransaction(Transaction transaction) => new() @@ -28,27 +26,5 @@ public static CallTransactionModel FromTransaction(Transaction transaction) Gas = (UInt256)transaction.GasLimit, GasPrice = transaction.GasPrice }; - - public Transaction GetTransaction() - { - if (Gas > long.MaxValue) throw new OverflowException("Gas value is too large to be converted to long we use."); - - From ??= Address.SystemUser; - - Transaction? result = new Transaction - { - SenderAddress = From, - To = To, - Data = Data, - Value = Value.Value, - GasLimit = (long)Gas, - GasPrice = GasPrice.Value - - }; - - result.Hash = result.CalculateHash(); - return result; - } - } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index d0ba2ea7e9b..a54ee184e77 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -14,40 +14,31 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class BlockOverride { public Keccak PrevRandao { get; set; } = Keccak.Zero; - public UInt256? Number { get; set; } = 0; - public UInt256? Time { get; set; } = 0; - public ulong? GasLimit { get; set; } = 0; - public Address FeeRecipient { get; set; } = Address.Zero; - public UInt256? BaseFeePerGas { get; set; } = 0; + public ulong? Number { get; set; } + public ulong? Time { get; set; } + public ulong? GasLimit { get; set; } + public Address? FeeRecipient { get; set; } + public UInt256? BaseFeePerGas { get; set; } public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) { - ulong newTime = parent.Timestamp + cfg.SecondsPerSlot; - if (0 == Time) { } - else if (Time <= ulong.MaxValue) - newTime = (ulong)Time; - else - throw new OverflowException("Time value is too large to be converted to ulong we use."); + ulong newTime = Time ?? parent.Timestamp + cfg.SecondsPerSlot; - long newGasLimit = parent.GasLimit; - if (0 == GasLimit) { } - else if (GasLimit <= long.MaxValue) - newGasLimit = (long)GasLimit; - else - throw new OverflowException("GasLimit value is too large to be converted to long we use."); - - long newBlockNumber = parent.Number + 1; - if (0 == Number) { } - else if (Number <= long.MaxValue) - newBlockNumber = (long)Number; - else - throw new OverflowException("Block Number value is too large to be converted to long we use."); + long newGasLimit = GasLimit switch + { + null => parent.GasLimit, + <= long.MaxValue => (long)GasLimit, + _ => throw new OverflowException($"GasLimit value is too large, max value {ulong.MaxValue}") + }; - Address newFeeRecipientAddress = parent.Beneficiary; - if (FeeRecipient != Address.Zero) + long newBlockNumber = Number switch { - newFeeRecipientAddress = FeeRecipient; - } + null => parent.Number + 1, + <= long.MaxValue => (long)Number, + _ => throw new OverflowException($"Block Number value is too large, max value {ulong.MaxValue}") + }; + + Address newFeeRecipientAddress = FeeRecipient != null ? FeeRecipient : parent.Beneficiary; var result = new BlockHeader( parent.Hash, @@ -60,9 +51,7 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) Array.Empty()); result.MixHash = PrevRandao; - - //Note we treet parent block as such - result.BaseFeePerGas = BaseFeePerGas.Value != 0 ? BaseFeePerGas.Value : parent.BaseFeePerGas; + result.BaseFeePerGas = BaseFeePerGas != null ? BaseFeePerGas.Value : parent.BaseFeePerGas; UInt256 difficulty = ConstantDifficulty.One.Calculate(result, parent); result.Difficulty = difficulty; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs index 580f97d685a..7bce55c3e31 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs @@ -6,9 +6,9 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; -public class BlockStateCalls +public class BlockStateCall { public BlockOverride? BlockOverrides { get; set; } public Dictionary? StateOverrides { get; set; } = new Dictionary(); - public CallTransactionModel[]? Calls { get; set; } = { }; + public T[]? Calls { get; set; } = { }; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs index 67dc6f51e48..16d504b757a 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs @@ -3,15 +3,14 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; -public class MultiCallPayload +public class MultiCallPayload { //Definition of blocks that can contain calls and overrides - public BlockStateCalls[]? BlockStateCalls { get; set; } + public BlockStateCall[]? BlockStateCalls { get; set; } //Trace ETH Transfers public bool TraceTransfers { get; set; } = false; //When true, the multicall does all validations that a normal EVM would do, except contract sender and signature checks. When false, multicall behaves like eth_call. public bool Validation { get; set; } = false; - } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 11f3127a1d6..af0cf835b2c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -82,7 +82,7 @@ public void Eth_module_populates_size_when_returning_block_data() [Test] public void CanRunEthMulticallV1Empty() { - MultiCallPayload payload = new() { BlockStateCalls = Array.Empty() }; + MultiCallPayload payload = new() { BlockStateCalls = Array.Empty>() }; EthereumJsonSerializer serializer = new(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 4922eb9caa0..3c3105bfe89 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -12,6 +12,7 @@ using Nethermind.Evm.Precompiles; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; using NUnit.Framework; @@ -102,9 +103,9 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( systemTransactionForModifiedVM.GasPrice = header.BaseFeePerGas >= 1 ? header.BaseFeePerGas : 1; systemTransactionForModifiedVM.GasLimit = (long)systemTransactionForModifiedVM.CalculateTransactionPotentialCost(spec.IsEip1559Enabled, header.BaseFeePerGas); - MultiCallPayload payload = new() + MultiCallPayload payload = new() { - BlockStateCalls = new BlockStateCalls[] { new() + BlockStateCalls = new BlockStateCall[] { new() { StateOverrides = new Dictionary() { {EcRecoverPrecompile.Address, @@ -116,7 +117,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( }, Calls = new[] { - CallTransactionModel.FromTransaction(systemTransactionForModifiedVM), + new TransactionForRpc(systemTransactionForModifiedVM), } }}, TraceTransfers = true, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 0df164e793a..96e05ec6ba3 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -12,6 +12,7 @@ using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; +using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Serialization.Json; using NUnit.Framework; @@ -56,17 +57,17 @@ public async Task Test_eth_multicall_serialisation() GetTransferTxData(nextNonceA, chain.EthereumEcdsa, pk, new Address("0xA143c0eA6f8059f7B3651417ccD2bAA80FC2d4Ab"), 4_000_000); - MultiCallPayload payload = new() + MultiCallPayload payload = new() { - BlockStateCalls = new BlockStateCalls[] + BlockStateCalls = new BlockStateCall[] { new() { BlockOverrides = new BlockOverride() { Number = 18000000 }, Calls = new[] { - CallTransactionModel.FromTransaction(txMainnetAtoBtoFail), - CallTransactionModel.FromTransaction(txMainnetAtoBToComplete), + new TransactionForRpc(txMainnetAtoBtoFail), + new TransactionForRpc(txMainnetAtoBToComplete), }, StateOverrides = new Dictionary() { @@ -131,9 +132,9 @@ public async Task Test_eth_multicall_eth_moved() Transaction txAtoB4 = GetTransferTxData(nonceA + 4, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); - MultiCallPayload payload = new() + MultiCallPayload payload = new() { - BlockStateCalls = new BlockStateCalls[] + BlockStateCalls = new BlockStateCall[] { new() { @@ -145,7 +146,7 @@ public async Task Test_eth_multicall_eth_moved() FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 }, - Calls = new[] { CallTransactionModel.FromTransaction(txAtoB1), CallTransactionModel.FromTransaction(txAtoB2) } + Calls = new[] { new TransactionForRpc(txAtoB1), new TransactionForRpc(txAtoB2) } }, new() { @@ -157,7 +158,7 @@ public async Task Test_eth_multicall_eth_moved() FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 }, - Calls = new[] { CallTransactionModel.FromTransaction(txAtoB3), CallTransactionModel.FromTransaction(txAtoB4) } + Calls = new[] { new TransactionForRpc(txAtoB3), new TransactionForRpc(txAtoB4) } } }, TraceTransfers = true @@ -208,9 +209,9 @@ public async Task Test_eth_multicall_transactions_forced_fail() //shall fail Transaction txAtoB2 = GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, UInt256.MaxValue); - MultiCallPayload payload = new() + MultiCallPayload payload = new() { - BlockStateCalls = new BlockStateCalls[] + BlockStateCalls = new BlockStateCall[] { new() { @@ -222,7 +223,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 }, - Calls = new[] { CallTransactionModel.FromTransaction(txAtoB1) } + Calls = new[] { new TransactionForRpc(txAtoB1) } }, new() { @@ -234,7 +235,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 }, - Calls = new[] { CallTransactionModel.FromTransaction(txAtoB2) } + Calls = new[] { new TransactionForRpc(txAtoB2) } } }, TraceTransfers = true diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 65c869fb4de..592f69cccf0 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -19,9 +19,6 @@ namespace Nethermind.JsonRpc.Modules.Eth //General executor public partial class EthRpcModule { - - - // Single call executor private abstract class TxExecutor : ExecutorBase { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index d4674d67b3c..7392b01d52a 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -349,7 +349,7 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); - public ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) + public ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) { return new MultiCallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .Execute(payload, blockParameter); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs index 83585d4810d..f3224c4247b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs @@ -157,7 +157,7 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa throw new NotSupportedException(); } - public ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) + public ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) { throw new NotImplementedException(); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index de8f5a86d1f..464dc4206ec 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -155,7 +155,7 @@ public interface IEthRpcModule : IRpcModule Description = "Executes a simulation across multiple blocks (does not create a transaction or block)", IsSharable = false, ExampleResponse = "0x")] - ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null); + ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null); [JsonRpcMethod(IsImplemented = true, Description = "Executes a tx call and returns gas used (does not create a transaction)", diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 9722479b64c..6718c5ca4c7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -1,26 +1,45 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.Linq; using System.Threading; using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Facade; +using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.JsonRpc.Data; namespace Nethermind.JsonRpc.Modules.Eth; -public class MultiCallTxExecutor : ExecutorBase +public class MultiCallTxExecutor : ExecutorBase, MultiCallPayload> { public MultiCallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : base(blockchainBridge, blockFinder, rpcConfig) { } - protected override MultiCallPayload Prepare(MultiCallPayload call) + protected override MultiCallPayload Prepare(MultiCallPayload call) { - return call; + var result = new MultiCallPayload + { + TraceTransfers = call.TraceTransfers, + Validation = call.Validation, + BlockStateCalls = call.BlockStateCalls?.Select(blockStateCall => new BlockStateCall + { + BlockOverrides = blockStateCall.BlockOverrides, + StateOverrides = blockStateCall.StateOverrides, + Calls = blockStateCall.Calls?.Select(callTransactionModel => + { + callTransactionModel.EnsureDefaults(_rpcConfig.GasCap); + return callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()); + }).ToArray() + }).ToArray() + }; + + return result; } - protected override ResultWrapper Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) + protected override ResultWrapper Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) { BlockchainBridge.MultiCallOutput results = _blockchainBridge.MultiCall(header.Clone(), tx, token); From fb2d8617aea137feb03708c550999f08938f793f Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 17:05:15 +0100 Subject: [PATCH 042/213] Fixing Spaces --- .../Proxy/Models/MultiCall/BlockOverride.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index a54ee184e77..0bd3737e4b3 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -14,9 +14,9 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class BlockOverride { public Keccak PrevRandao { get; set; } = Keccak.Zero; - public ulong? Number { get; set; } - public ulong? Time { get; set; } - public ulong? GasLimit { get; set; } + public ulong? Number { get; set; } + public ulong? Time { get; set; } + public ulong? GasLimit { get; set; } public Address? FeeRecipient { get; set; } public UInt256? BaseFeePerGas { get; set; } From c893254a09ad13bd230636f59597627631e7904f Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 17:08:02 +0100 Subject: [PATCH 043/213] Spec ordering --- .../Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index 0bd3737e4b3..7893b289ca0 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -13,8 +13,8 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class BlockOverride { - public Keccak PrevRandao { get; set; } = Keccak.Zero; public ulong? Number { get; set; } + public Keccak PrevRandao { get; set; } = Keccak.Zero; public ulong? Time { get; set; } public ulong? GasLimit { get; set; } public Address? FeeRecipient { get; set; } From 43009d4d17e65cfb5aad27c24e2a2547b8ccd918 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 17:18:42 +0100 Subject: [PATCH 044/213] Added checked longs --- .../Proxy/Models/MultiCall/BlockOverride.cs | 4 ++-- .../Multicall/EthMulticallTestsBlocksAndTransactions.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index 7893b289ca0..ebaa70316c6 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -22,7 +22,7 @@ public class BlockOverride public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) { - ulong newTime = Time ?? parent.Timestamp + cfg.SecondsPerSlot; + ulong newTime = Time ?? checked(parent.Timestamp + cfg.SecondsPerSlot); long newGasLimit = GasLimit switch { @@ -33,7 +33,7 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) long newBlockNumber = Number switch { - null => parent.Number + 1, + null => checked(parent.Number + 1), <= long.MaxValue => (long)Number, _ => throw new OverflowException($"Block Number value is too large, max value {ulong.MaxValue}") }; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 96e05ec6ba3..efaa170b8a5 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -141,7 +141,7 @@ public async Task Test_eth_multicall_eth_moved() BlockOverrides = new BlockOverride { - Number = (UInt256)new decimal(2), + Number = 2, GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 @@ -153,7 +153,7 @@ public async Task Test_eth_multicall_eth_moved() BlockOverrides = new BlockOverride { - Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10000), + Number = (ulong)checked(chain.Bridge.HeadBlock.Number + 10000), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 @@ -218,7 +218,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() BlockOverrides = new BlockOverride { - Number = (UInt256)new decimal(chain.Bridge.HeadBlock.Number + 10), + Number = (ulong)checked(chain.Bridge.HeadBlock.Number + 10), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 @@ -230,7 +230,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() BlockOverrides = new BlockOverride { - Number = (UInt256)new decimal(123), + Number = 123, GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 From c99343a3dd632a86fb27e127ac3ce9dc3046bee8 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 17:23:26 +0100 Subject: [PATCH 045/213] Moving stuff to initialiser --- .../Proxy/Models/MultiCall/BlockOverride.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index ebaa70316c6..6f605d517e6 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -40,7 +40,7 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) Address newFeeRecipientAddress = FeeRecipient != null ? FeeRecipient : parent.Beneficiary; - var result = new BlockHeader( + BlockHeader? result = new( parent.Hash, Keccak.OfAnEmptySequenceRlp, newFeeRecipientAddress, @@ -48,10 +48,9 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) newBlockNumber, newGasLimit, newTime, - Array.Empty()); - - result.MixHash = PrevRandao; - result.BaseFeePerGas = BaseFeePerGas != null ? BaseFeePerGas.Value : parent.BaseFeePerGas; + Array.Empty()) { + MixHash = PrevRandao, BaseFeePerGas = BaseFeePerGas ?? parent.BaseFeePerGas, + }; UInt256 difficulty = ConstantDifficulty.One.Calculate(result, parent); result.Difficulty = difficulty; From 202484fad28627a7ab7d523a79ad2723f0500789 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 17:49:33 +0100 Subject: [PATCH 046/213] Account Overrides ordering --- .../Nethermind.Facade/BlockchainBridge.cs | 53 +++++++++++++++---- .../Proxy/Models/MultiCall/AccountOverride.cs | 22 ++++---- ...ulticallTestsPrecompilesWithRedirection.cs | 2 +- 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 6f49961bb8e..6fb9ba00935 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -488,30 +488,61 @@ private void ModifyAccounts(Dictionary StateOverrides, } catch (Exception) { - // TODO: handle missing block without exceptions + // ignored } + UInt256 balance = 0; + if (accountOverride.Balance != null) + { + balance = accountOverride.Balance.Value; + } + + UInt256 nonce = 0; + if (accountOverride.Nonce != null) + { + nonce = accountOverride.Nonce.Value; + } + + if (!accExists) { - StateProvider.CreateAccount(address, accountOverride.Balance, accountOverride.Nonce); + StateProvider.CreateAccount(address, balance, nonce); acc = StateProvider.GetAccount(address); } else acc = StateProvider.GetAccount(address); UInt256 accBalance = acc.Balance; - if (accBalance > accountOverride.Balance) - StateProvider.SubtractFromBalance(address, accBalance - accountOverride.Balance, CurrentSpec); - else if (accBalance < accountOverride.Nonce) - StateProvider.AddToBalance(address, accountOverride.Balance - accBalance, CurrentSpec); + if (accountOverride.Balance != null && accBalance > balance) + StateProvider.SubtractFromBalance(address, accBalance - balance, CurrentSpec); + + else if (accountOverride.Balance != null && accBalance < balance) + StateProvider.AddToBalance(address, balance - accBalance, CurrentSpec); + UInt256 accNonce = acc.Nonce; - if (accNonce > accountOverride.Nonce) - StateProvider.DecrementNonce(address); - else if (accNonce < accountOverride.Nonce) StateProvider.IncrementNonce(address); + if (accountOverride.Nonce != null && accNonce > nonce) + { + UInt256 iters = accNonce - nonce; + for (UInt256 i = 0; i < iters; i++) + { + StateProvider.DecrementNonce(address); + } + } + else if (accountOverride.Nonce != null && accNonce < accountOverride.Nonce) + { + UInt256 iters = nonce - accNonce; + for (UInt256 i = 0; i < iters; i++) + { + StateProvider.IncrementNonce(address); + } + } - _multiCallProcessingEnv.VirtualMachine.SetOverwrite(StateProvider, CurrentSpec, address, - new CodeInfo(accountOverride.Code), accountOverride.MoveToAddress); + if (accountOverride.Code != null) + { + _multiCallProcessingEnv.VirtualMachine.SetOverwrite(StateProvider, CurrentSpec, address, + new CodeInfo(accountOverride.Code), accountOverride.MovePrecompileToAddress); + } if (accountOverride.State is not null) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs index 57500aa6560..6ce356ad018 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs @@ -9,22 +9,22 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class AccountOverride { - public AccountOverrideType Type => State != null - ? AccountOverrideType.AccountOverrideState - : AccountOverrideType.AccountOverrideStateDiff; - - public bool IsState => Type == AccountOverrideType.AccountOverrideState; - public bool IsStateDiff => Type == AccountOverrideType.AccountOverrideStateDiff; - - public Address? MoveToAddress { get; set; } - public UInt256 Nonce { get; set; } + public UInt256? Nonce { get; set; } + public UInt256? Balance { get; set; } + public byte[]? Code { get; set; } + public Address? MovePrecompileToAddress { get; set; } - public UInt256 Balance { get; set; } - public byte[] Code { get; set; } //Storage for AccountOverrideState public Dictionary? State { get; set; } //Storage difference for AccountOverrideStateDiff public Dictionary? StateDiff { get; set; } + + public AccountOverrideType Type => State != null + ? AccountOverrideType.AccountOverrideState + : AccountOverrideType.AccountOverrideStateDiff; + + public bool IsState => Type == AccountOverrideType.AccountOverrideState; + public bool IsStateDiff => Type == AccountOverrideType.AccountOverrideStateDiff; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 3c3105bfe89..e716ac487d1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -112,7 +112,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( new AccountOverride { Code = code, - MoveToAddress = new Address("0x0000000000000000000000000000000000000666") + MovePrecompileToAddress = new Address("0x0000000000000000000000000000000000000666") }} }, Calls = new[] From da4c347a2aabfafd7e441f5d1d02feefe876d216 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 17:50:04 +0100 Subject: [PATCH 047/213] fix spaces --- .../Proxy/Models/MultiCall/AccountOverride.cs | 2 +- .../Proxy/Models/MultiCall/BlockOverride.cs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs index 6ce356ad018..14dda398bf2 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs @@ -9,7 +9,7 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class AccountOverride { - public UInt256? Nonce { get; set; } + public UInt256? Nonce { get; set; } public UInt256? Balance { get; set; } public byte[]? Code { get; set; } public Address? MovePrecompileToAddress { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index 6f605d517e6..2dddca38031 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -48,8 +48,10 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) newBlockNumber, newGasLimit, newTime, - Array.Empty()) { - MixHash = PrevRandao, BaseFeePerGas = BaseFeePerGas ?? parent.BaseFeePerGas, + Array.Empty()) + { + MixHash = PrevRandao, + BaseFeePerGas = BaseFeePerGas ?? parent.BaseFeePerGas, }; UInt256 difficulty = ConstantDifficulty.One.Calculate(result, parent); From 1faa5b9309e938ed843090d12eca45ed17ff1997 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 18:57:44 +0100 Subject: [PATCH 048/213] Restricting DB set operations to 32b --- src/Nethermind/Nethermind.Facade/BlockchainBridge.cs | 11 +++++------ .../Proxy/Models/MultiCall/AccountOverride.cs | 5 +++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 6fb9ba00935..711e67ace94 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -544,20 +544,19 @@ private void ModifyAccounts(Dictionary StateOverrides, new CodeInfo(accountOverride.Code), accountOverride.MovePrecompileToAddress); } - + //TODO: discuss if clean slate is a must if (accountOverride.State is not null) { - accountOverride.State = new Dictionary(); - foreach (KeyValuePair storage in accountOverride.State) + foreach (KeyValuePair storage in accountOverride.State) StateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.WithoutLeadingZeros().ToArray()); + storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); } if (accountOverride.StateDiff is not null) { - foreach (KeyValuePair storage in accountOverride.StateDiff) + foreach (KeyValuePair storage in accountOverride.StateDiff) StateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.WithoutLeadingZeros().ToArray()); + storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); } StateProvider.Commit(CurrentSpec); } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs index 14dda398bf2..aa0b51a6e97 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Nethermind.Core; +using Nethermind.Core.Crypto; using Nethermind.Int256; namespace Nethermind.Facade.Proxy.Models.MultiCall; @@ -16,10 +17,10 @@ public class AccountOverride //Storage for AccountOverrideState - public Dictionary? State { get; set; } + public Dictionary? State { get; set; } //Storage difference for AccountOverrideStateDiff - public Dictionary? StateDiff { get; set; } + public Dictionary? StateDiff { get; set; } public AccountOverrideType Type => State != null ? AccountOverrideType.AccountOverrideState From d822593df86e62982f9ba1a6114b7e0e21038308 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 18:59:58 +0100 Subject: [PATCH 049/213] enum only --- .../Proxy/Models/MultiCall/AccountOverride.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs index aa0b51a6e97..d6c2decdd4b 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs @@ -25,7 +25,4 @@ public class AccountOverride public AccountOverrideType Type => State != null ? AccountOverrideType.AccountOverrideState : AccountOverrideType.AccountOverrideStateDiff; - - public bool IsState => Type == AccountOverrideType.AccountOverrideState; - public bool IsStateDiff => Type == AccountOverrideType.AccountOverrideStateDiff; } From 00d4db33d48a51dc9d0f993f73056b396569e96c Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 19:13:13 +0100 Subject: [PATCH 050/213] Result structure reordering following the protocol --- .../Nethermind.Facade/MultiCallBlockTracer.cs | 6 ++++-- .../Proxy/Models/MultiCall/MultiCallBlockResult.cs | 10 ++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs index a3650a63396..abe3d845e25 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs @@ -7,6 +7,7 @@ using Nethermind.Core.Collections; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Int256; using ResultType = Nethermind.Facade.Proxy.Models.MultiCall.ResultType; namespace Nethermind.Facade; @@ -48,9 +49,10 @@ public override void EndBlockTrace() GasUsed = (ulong)currentBlock.GasUsed, Timestamp = currentBlock.Timestamp, FeeRecipient = currentBlock.Beneficiary, - baseFeePerGas = currentBlock.BaseFeePerGas, - + BaseFeePerGas = currentBlock.BaseFeePerGas, + PrevRandao = new UInt256(currentBlock.Header.Random.Bytes) }; + result.Calls.ForEach(callResult => { if (callResult.Type == ResultType.Success) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs index 6a4b287f594..c3443cede18 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs @@ -9,12 +9,14 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class MultiCallBlockResult { - public MultiCallCallResult[] Calls { get; set; } - public Keccak Hash { get; set; } public ulong Number { get; set; } - public UInt256 Timestamp { get; set; } + public Keccak Hash { get; set; } + public ulong Timestamp { get; set; } public ulong GasLimit { get; set; } public ulong GasUsed { get; set; } public Address FeeRecipient { get; set; } - public UInt256 baseFeePerGas { get; set; } + public UInt256 BaseFeePerGas { get; set; } + public MultiCallCallResult[] Calls { get; set; } + public UInt256 PrevRandao { get; set; } + } From 8bbe975a10b578859d0c2cd73712642960cbce73 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 19:17:38 +0100 Subject: [PATCH 051/213] Ordering following protocoll --- .../Proxy/Models/MultiCall/MultiCallCallResult.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs index 776717d4500..04be85d8feb 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs @@ -11,15 +11,15 @@ public ResultType Type { if (Error is null) return ResultType.Success; - if (Return is not null) return ResultType.Failure; + if (ReturnData is not null) return ResultType.Failure; return ResultType.Invalid; } } - public Log[]? Logs { get; set; } public string Status { get; set; } - public byte[]? Return { get; set; } - public Error? Error { get; set; } + public byte[]? ReturnData { get; set; } public ulong? GasUsed { get; set; } + public Error? Error { get; set; } + public Log[]? Logs { get; set; } } From 59de531455ec3d682e362e16fedc82b8983e9d38 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 19:29:24 +0100 Subject: [PATCH 052/213] Minor naming refactoring --- .../Proxy/EthJsonRpcClientProxyTests.cs | 8 ++++---- src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs | 4 ++-- .../Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs | 4 ++-- .../Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs | 4 ++-- .../CallTransaction.cs} | 6 +++--- .../Eth/EthMulticallTestsPrecompilesWithRedirection.cs | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) rename src/Nethermind/Nethermind.Facade/Proxy/Models/{CallTransactionModel.cs => MultiCall/CallTransaction.cs} (83%) diff --git a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs index c48cba3b47a..53e994721e2 100644 --- a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs @@ -81,7 +81,7 @@ public async Task eth_getTransactionReceipt_should_invoke_client_method() [Test] public async Task eth_call_should_invoke_client_method() { - var callTransaction = new CallTransactionModel(); + var callTransaction = new CallTransaction(); var blockParameter = BlockParameterModel.Latest; await _proxy.eth_call(callTransaction, blockParameter); await _client.Received().SendAsync(nameof(_proxy.eth_call), @@ -92,7 +92,7 @@ await _client.Received().SendAsync(nameof(_proxy.eth_call), [Test] public async Task eth_multicall_should_invoke_client_method_even_empty() { - MultiCallPayload payload = new(); + MultiCallPayload payload = new(); var blockParameter = BlockParameterModel.Latest; await _proxy.eth_multicallV1(payload, blockParameter); @@ -104,9 +104,9 @@ await _client.Received().SendAsync(nameof(_proxy.eth_mul [Test] public async Task eth_multicallV1_should_invoke_client_method() { - MultiCallPayload payload = new() + MultiCallPayload payload = new() { - BlockStateCalls = new BlockStateCall[] { }, + BlockStateCalls = new BlockStateCall[] { }, TraceTransfers = true }; diff --git a/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs index 978dc0eb468..a49db1b769f 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs @@ -26,7 +26,7 @@ public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] outp TraceResult = new MultiCallCallResult() { GasUsed = (ulong)gasSpent, - Return = output, + ReturnData = output, Status = StatusCode.Success.ToString(), Logs = logs.Select((entry, i) => new Log { @@ -49,7 +49,7 @@ public override void MarkAsFailed(Address recipient, long gasSpent, byte[] outpu Code = StatusCode.Failure, Message = error }, - Return = output, + ReturnData = output, Status = StatusCode.Failure.ToString() }; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index 2e3df575ffb..f886846a8ae 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -36,11 +36,11 @@ public Task> eth_getTransactionCount(Address address, BlockPa public Task> eth_getTransactionReceipt(Keccak transactionHash) => _proxy.SendAsync(nameof(eth_getTransactionReceipt), transactionHash); - public Task> eth_call(CallTransactionModel transaction, + public Task> eth_call(CallTransaction transaction, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_call), transaction, MapBlockParameter(blockParameter)); - public Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null) + public Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_multicallV1), blockCalls, MapBlockParameter(blockParameter)); public Task> eth_getCode(Address address, BlockParameterModel blockParameter = null) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs index c3db5a46a2b..66ffbefb5db 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs @@ -18,8 +18,8 @@ public interface IEthJsonRpcClientProxy Task> eth_getBalance(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionCount(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionReceipt(Keccak transactionHash); - Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null); - Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null); + Task> eth_call(CallTransaction transaction, BlockParameterModel blockParameter = null); + Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null); Task> eth_getCode(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionByHash(Keccak transactionHash); Task> eth_pendingTransactions(); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs similarity index 83% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs index 697b11eb3d7..f3b4be89bca 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/CallTransactionModel.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs @@ -5,9 +5,9 @@ using Nethermind.Int256; using static Nethermind.Core.Extensions.MemoryExtensions; -namespace Nethermind.Facade.Proxy.Models +namespace Nethermind.Facade.Proxy.Models.MultiCall { - public class CallTransactionModel + public class CallTransaction { public Address From { get; set; } public Address To { get; set; } @@ -16,7 +16,7 @@ public class CallTransactionModel public UInt256 Value { get; set; } public byte[] Data { get; set; } - public static CallTransactionModel FromTransaction(Transaction transaction) + public static CallTransaction FromTransaction(Transaction transaction) => new() { From = transaction.SenderAddress, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index e716ac487d1..3608ca3236a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -135,7 +135,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( executor.Execute(payload, BlockParameter.Latest); //Check results - byte[] addressBytes = result.Data[0].Calls[0].Return + byte[] addressBytes = result.Data[0].Calls[0].ReturnData .SliceWithZeroPaddingEmptyOnError(12, 20); Address resultingAddress = new(addressBytes); Assert.AreEqual(realSenderAccount, resultingAddress); From 044bc9353b3e34c292bd40931512af02d59e7b81 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 19:37:27 +0100 Subject: [PATCH 053/213] Minor refactoring of a stub class unused fields --- .../Proxy/Models/MultiCall/CallTransaction.cs | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs index f3b4be89bca..ba646f63809 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs @@ -7,24 +7,6 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall { - public class CallTransaction - { - public Address From { get; set; } - public Address To { get; set; } - public UInt256 Gas { get; set; } - public UInt256 GasPrice { get; set; } - public UInt256 Value { get; set; } - public byte[] Data { get; set; } - - public static CallTransaction FromTransaction(Transaction transaction) - => new() - { - From = transaction.SenderAddress, - To = transaction.To, - Data = transaction.Data.AsArray(), - Value = transaction.Value, - Gas = (UInt256)transaction.GasLimit, - GasPrice = transaction.GasPrice - }; - } + //A stub + public class CallTransaction { } } From 0b22f188bfe2ac814d0e1cec9c1b0c4d14b4b018 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 11 Sep 2023 19:42:52 +0100 Subject: [PATCH 054/213] removed unused flag --- src/Nethermind/Nethermind.Blockchain/BlockTree.cs | 3 +-- .../Nethermind.Blockchain/BlockTreeMethodOptions.cs | 5 ----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index 7242c1a6b6e..8ef3b90d8f0 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -372,7 +372,6 @@ public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBloc private AddBlockResult Suggest(Block? block, BlockHeader header, BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) { bool shouldProcess = options.ContainsFlag(BlockTreeSuggestOptions.ShouldProcess); - bool noParentCheck = options.ContainsFlag(BlockTreeSuggestOptions.ForceDontValidateParent); bool fillBeaconBlock = options.ContainsFlag(BlockTreeSuggestOptions.FillBeaconBlock); bool setAsMain = options.ContainsFlag(BlockTreeSuggestOptions.ForceSetAsMain) || !options.ContainsFlag(BlockTreeSuggestOptions.ForceDontSetAsMain) && !shouldProcess; @@ -411,7 +410,7 @@ private AddBlockResult Suggest(Block? block, BlockHeader header, BlockTreeSugges bool parentExists = IsKnownBlock(header.Number - 1, header.ParentHash!) || IsKnownBeaconBlock(header.Number - 1, header.ParentHash!); - if (!header.IsGenesis && !noParentCheck && !parentExists) + if (!header.IsGenesis && !parentExists) { if (_logger.IsTrace) _logger.Trace($"Could not find parent ({header.ParentHash}) of block {header.Hash}"); return AddBlockResult.UnknownParent; diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTreeMethodOptions.cs b/src/Nethermind/Nethermind.Blockchain/BlockTreeMethodOptions.cs index f5cdf862024..2eaab2ba9be 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTreeMethodOptions.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTreeMethodOptions.cs @@ -69,11 +69,6 @@ public enum BlockTreeSuggestOptions /// Force not to set as main block /// ForceDontSetAsMain = 8, - - /// - /// Force skip parent number is known checks - /// - ForceDontValidateParent = 8, } public static class BlockTreeSuggestOptionsExtensions From d5e9ce5608d47840e3d9d764e10795b331b65adb Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 11:39:04 +0100 Subject: [PATCH 055/213] removing some of the interfaces implemented only once --- .../Nethermind.Api/NethermindApi.cs | 2 +- .../IMultiCallBlocksProcessingEnv.cs | 24 ------------------- .../Processing/IReadOnlyTxProcessingEnv.cs | 11 --------- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 6 ++--- .../Processing/ReadOnlyChainProcessingEnv.cs | 21 +--------------- .../ReadOnlyChainProcessingEnvBase.cs | 4 ++-- .../Processing/ReadOnlyTxProcessingEnv.cs | 3 +-- .../BlockchainBridgeTests.cs | 4 ++-- .../Nethermind.Facade/BlockchainBridge.cs | 12 +++++----- .../Modules/TestRpcBlockchain.cs | 2 +- 10 files changed, 17 insertions(+), 72 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs delete mode 100644 src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 070658aaefd..da520128aec 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -87,7 +87,7 @@ public IBlockchainBridge CreateBlockchainBridge() SpecProvider, LogManager); - IMultiCallBlocksProcessingEnv multiCallReadOnlyBlocksProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create(false, + MultiCallReadOnlyBlocksProcessingEnv multiCallReadOnlyBlocksProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create(false, _multiCallReadOnlyDbProvider, SpecProvider, LogManager); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs deleted file mode 100644 index 5e8c136e01f..00000000000 --- a/src/Nethermind/Nethermind.Consensus/Processing/IMultiCallBlocksProcessingEnv.cs +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using Nethermind.Core.Crypto; -using Nethermind.Core.Specs; -using Nethermind.Db; -using Nethermind.Evm; -using Nethermind.Logging; - -namespace Nethermind.Consensus.Processing; - -public interface IMultiCallBlocksProcessingEnv : IReadOnlyTxProcessingEnvBase, IDisposable -{ - //Instance VM can be edited during processing - ISpecProvider SpecProvider { get; } - IMultiCallVirtualMachine VirtualMachine { get; } - - //We need abilety to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning - IMultiCallBlocksProcessingEnv Clone(bool TraceTransfers); - - //We keep original ProcessingEnv spirit with Build() that can start from any stateRoot - IBlockProcessor GetProcessor(); -} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs deleted file mode 100644 index a3b84331ed0..00000000000 --- a/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnv.cs +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Evm.TransactionProcessing; - -namespace Nethermind.Consensus.Processing; - -public interface IReadOnlyTxProcessingEnv : IReadOnlyTxProcessorSource, IReadOnlyTxProcessingEnvBase -{ - ITransactionProcessor TransactionProcessor { get; set; } -} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs index a623936b934..de24fd4e32a 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -21,7 +21,7 @@ namespace Nethermind.Consensus.Processing; -public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IMultiCallBlocksProcessingEnv +public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IDisposable { private readonly ITrieStore? _trieStore; private readonly ILogManager? _logManager; @@ -33,7 +33,7 @@ public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, public bool TraceTransfers { get; set; } //We need ability to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning - public static IMultiCallBlocksProcessingEnv Create(bool TraceTransfers, IReadOnlyDbProvider? readOnlyDbProvider, + public static MultiCallReadOnlyBlocksProcessingEnv Create(bool TraceTransfers, IReadOnlyDbProvider? readOnlyDbProvider, ISpecProvider? specProvider, ILogManager? logManager ) @@ -56,7 +56,7 @@ public static IMultiCallBlocksProcessingEnv Create(bool TraceTransfers, IReadOnl logManager); } - public IMultiCallBlocksProcessingEnv Clone(bool TraceTransfers) + public MultiCallReadOnlyBlocksProcessingEnv Clone(bool TraceTransfers) { return Create(TraceTransfers, DbProvider, SpecProvider, _logManager); } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs index ae56a709a33..c1ca1efee4f 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs @@ -18,7 +18,7 @@ public class ReadOnlyChainProcessingEnv : ReadOnlyChainProcessingEnvBase public IBlockchainProcessor ChainProcessor { get; } public ReadOnlyChainProcessingEnv( - IReadOnlyTxProcessingEnv txEnv, + ReadOnlyTxProcessingEnv txEnv, IBlockValidator blockValidator, IBlockPreprocessorStep recoveryStep, IRewardCalculator rewardCalculator, @@ -31,23 +31,4 @@ public ReadOnlyChainProcessingEnv( ChainProcessor = new OneTimeChainProcessor(dbProvider, _blockProcessingQueue); } } - - public class MultiCallReadOnlyChainProcessingEnv : ReadOnlyChainProcessingEnvBase - { - public IBlockchainProcessor ChainProcessor { get; } - - public MultiCallReadOnlyChainProcessingEnv( - IReadOnlyTxProcessingEnv txEnv, - IBlockValidator blockValidator, - IBlockPreprocessorStep recoveryStep, - IRewardCalculator rewardCalculator, - IReceiptStorage receiptStorage, - IReadOnlyDbProvider dbProvider, - ISpecProvider specProvider, - ILogManager logManager, - IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) : base(txEnv, blockValidator, recoveryStep, rewardCalculator, receiptStorage, dbProvider, specProvider, logManager, blockTransactionsExecutor) - { - ChainProcessor = new MultiCallChainProcessor(dbProvider, _blockProcessingQueue); - } - } } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs index 66249042070..63ad58d4ff6 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs @@ -17,7 +17,7 @@ namespace Nethermind.Consensus.Processing; /// public class ReadOnlyChainProcessingEnvBase : IDisposable { - protected readonly IReadOnlyTxProcessingEnv _txEnv; + protected readonly ReadOnlyTxProcessingEnv _txEnv; protected readonly BlockchainProcessor _blockProcessingQueue; public IBlockProcessor BlockProcessor { get; } @@ -25,7 +25,7 @@ public class ReadOnlyChainProcessingEnvBase : IDisposable public IWorldState StateProvider => _txEnv.StateProvider; public ReadOnlyChainProcessingEnvBase( - IReadOnlyTxProcessingEnv txEnv, + ReadOnlyTxProcessingEnv txEnv, IBlockValidator blockValidator, IBlockPreprocessorStep recoveryStep, IRewardCalculator rewardCalculator, diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index ed2c10249ac..19fc0653fca 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -15,8 +15,7 @@ // ReSharper disable UnusedAutoPropertyAccessor.Global namespace Nethermind.Consensus.Processing { - public class ReadOnlyTxProcessingEnv : ReadOnlyTxProcessingEnvBase, IReadOnlyTxProcessingEnv - + public class ReadOnlyTxProcessingEnv : ReadOnlyTxProcessingEnvBase, IReadOnlyTxProcessorSource { public ITransactionProcessor TransactionProcessor { get; set; } diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index 7c34f462217..5a452acae3e 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -67,7 +67,7 @@ public async Task SetUp() _specProvider, LimboLogs.Instance); - IMultiCallBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( false, new ReadOnlyDbProvider(_dbProvider, true), _specProvider, @@ -217,7 +217,7 @@ public void Bridge_head_is_correct(long headNumber) _specProvider, LimboLogs.Instance); - IMultiCallBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( false, new ReadOnlyDbProvider(_dbProvider, true), _specProvider, diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 711e67ace94..a2ae6f83531 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -44,8 +44,8 @@ public interface IBlockchainBridgeFactory [Todo(Improve.Refactor, "I want to remove BlockchainBridge, split it into something with logging, state and tx processing. Then we can start using independent modules.")] public class BlockchainBridge : IBlockchainBridge { - private readonly IReadOnlyTxProcessingEnv _processingEnv; - private readonly IMultiCallBlocksProcessingEnv _multiCallProcessingEnv; + private readonly ReadOnlyTxProcessingEnv _processingEnv; + private readonly MultiCallReadOnlyBlocksProcessingEnv _multiCallProcessingEnv; private readonly ITxPool _txPool; private readonly IFilterStore _filterStore; private readonly IEthereumEcdsa _ecdsa; @@ -55,9 +55,9 @@ public class BlockchainBridge : IBlockchainBridge private readonly ILogFinder _logFinder; private readonly ISpecProvider _specProvider; private readonly IBlocksConfig _blocksConfig; - - public BlockchainBridge(IReadOnlyTxProcessingEnv processingEnv, - IMultiCallBlocksProcessingEnv multiCallProcessingEnv, + + public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, + MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv, ITxPool? txPool, IReceiptFinder? receiptStorage, IFilterStore? filterStore, @@ -329,7 +329,7 @@ private void CallAndRestore( private (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) { - using (IMultiCallBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers)) + using (MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers)) { var processor = env.GetProcessor(); var firstBlock = payload.BlockStateCalls.FirstOrDefault(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 4bed5647bfd..5a844116384 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -130,7 +130,7 @@ protected override async Task Build(ISpecProvider? specProvider SpecProvider, LimboLogs.Instance); - IMultiCallBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( false, new ReadOnlyDbProvider(dbProvider, true), SpecProvider, From a6e13980b1acf5b9911f785b026eb1392d7bfe14 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 11:39:53 +0100 Subject: [PATCH 056/213] Spaces fixing --- src/Nethermind/Nethermind.Facade/BlockchainBridge.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index a2ae6f83531..b71e2cf4f8d 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -55,7 +55,7 @@ public class BlockchainBridge : IBlockchainBridge private readonly ILogFinder _logFinder; private readonly ISpecProvider _specProvider; private readonly IBlocksConfig _blocksConfig; - + public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv, ITxPool? txPool, From d05e4669e951b3c766b28593dda416615e693a00 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 11:56:07 +0100 Subject: [PATCH 057/213] inheritance into composition --- .../Processing/MultiCallChainProcessor.cs | 31 -------------- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 4 +- .../Validators/MultiCallBlockValidator.cs | 21 ---------- .../MultiCallBlockValidatorProxy.cs | 41 +++++++++++++++++++ 4 files changed, 44 insertions(+), 53 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Consensus/Processing/MultiCallChainProcessor.cs delete mode 100644 src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidator.cs create mode 100644 src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallChainProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallChainProcessor.cs deleted file mode 100644 index a94e7490226..00000000000 --- a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallChainProcessor.cs +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Core; -using Nethermind.Db; -using Nethermind.Evm.Tracing; - -namespace Nethermind.Consensus.Processing; - -public class MultiCallChainProcessor : OneTimeChainProcessor -{ - public MultiCallChainProcessor(IReadOnlyDbProvider readOnlyDbProvider, IBlockchainProcessor processor) : base(readOnlyDbProvider, processor) - { - } - - public override Block? Process(Block block, ProcessingOptions options, IBlockTracer tracer) - { - lock (_lock) - { - Block result; - result = _processor.Process(block, options, tracer); - return result; - } - } - - public override void Dispose() - { - _readOnlyDbProvider.ClearTempChanges(); - base.Dispose(); - } -} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs index de24fd4e32a..9f4f59143f0 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -93,12 +93,14 @@ private MultiCallReadOnlyBlocksProcessingEnv( SpecProvider, _logManager); - _blockValidator = new MultiCallBlockValidator(new TxValidator(SpecProvider.ChainId), + BlockValidator? blockValidator = new( + new TxValidator(SpecProvider.ChainId), headerValidator, Always.Valid, SpecProvider, _logManager); + _blockValidator = new MultiCallBlockValidatorProxy(blockValidator); } public IBlockProcessor GetProcessor() diff --git a/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidator.cs deleted file mode 100644 index 92801666519..00000000000 --- a/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidator.cs +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Core; -using Nethermind.Core.Specs; -using Nethermind.Logging; -using Nethermind.TxPool; - -namespace Nethermind.Consensus.Validators; - -public class MultiCallBlockValidator : BlockValidator -{ - public MultiCallBlockValidator(ITxValidator? txValidator, IHeaderValidator? headerValidator, IUnclesValidator? unclesValidator, ISpecProvider? specProvider, ILogManager? logManager) : base(txValidator, headerValidator, unclesValidator, specProvider, logManager) - { - } - - public override bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) - { - return true; - } -} diff --git a/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs b/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs new file mode 100644 index 00000000000..b242c986888 --- /dev/null +++ b/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; + +namespace Nethermind.Consensus.Validators; + +public class MultiCallBlockValidatorProxy : IBlockValidator +{ + private readonly IBlockValidator _baseBlockValidator; + + public MultiCallBlockValidatorProxy(IBlockValidator baseBlockValidator) + { + _baseBlockValidator = baseBlockValidator; + } + + public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle = false) + { + return _baseBlockValidator.Validate(header, parent, isUncle); + } + + public bool Validate(BlockHeader header, bool isUncle = false) + { + return _baseBlockValidator.Validate(header, isUncle); + } + + public bool ValidateWithdrawals(Block block, out string? error) + { + return _baseBlockValidator.ValidateWithdrawals(block, out error); + } + + public bool ValidateSuggestedBlock(Block block) + { + return _baseBlockValidator.ValidateSuggestedBlock(block); + } + + public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) + { + return true; + } +} From 819d0c50aedd103b4cde1697714305bf5ea9dd39 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 12:00:48 +0100 Subject: [PATCH 058/213] removing unused parameter --- .../Processing/ReadOnlyChainProcessingEnv.cs | 2 +- .../Processing/ReadOnlyChainProcessingEnvBase.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs index c1ca1efee4f..a596ad4d32a 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs @@ -26,7 +26,7 @@ public ReadOnlyChainProcessingEnv( IReadOnlyDbProvider dbProvider, ISpecProvider specProvider, ILogManager logManager, - IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) : base(txEnv, blockValidator, recoveryStep, rewardCalculator, receiptStorage, dbProvider, specProvider, logManager, blockTransactionsExecutor) + IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) : base(txEnv, blockValidator, recoveryStep, rewardCalculator, receiptStorage, specProvider, logManager, blockTransactionsExecutor) { ChainProcessor = new OneTimeChainProcessor(dbProvider, _blockProcessingQueue); } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs index 63ad58d4ff6..4cf8bc8eea9 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs @@ -6,7 +6,6 @@ using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; using Nethermind.Core.Specs; -using Nethermind.Db; using Nethermind.Logging; using Nethermind.State; @@ -30,7 +29,6 @@ public ReadOnlyChainProcessingEnvBase( IBlockPreprocessorStep recoveryStep, IRewardCalculator rewardCalculator, IReceiptStorage receiptStorage, - IReadOnlyDbProvider dbProvider, ISpecProvider specProvider, ILogManager logManager, IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) From 634e41e17a9dc4fa0d8ab5f2e30bf2b604df590a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 12:36:01 +0100 Subject: [PATCH 059/213] minor clean up --- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 20 +++++++++---------- .../BlockchainBridgeExtensions.cs | 17 ++++++++++++++++ .../Modules/Eth/EthRpcModule.cs | 16 +++++---------- .../Modules/Eth/ExecutorBase.cs | 2 +- 4 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs index 9f4f59143f0..8430f49979a 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -33,14 +33,14 @@ public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, public bool TraceTransfers { get; set; } //We need ability to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning - public static MultiCallReadOnlyBlocksProcessingEnv Create(bool TraceTransfers, IReadOnlyDbProvider? readOnlyDbProvider, + public static MultiCallReadOnlyBlocksProcessingEnv Create(bool traceTransfers, IReadOnlyDbProvider? readOnlyDbProvider, ISpecProvider? specProvider, ILogManager? logManager ) { - ReadOnlyDbProvider? DbProvider = new(readOnlyDbProvider, true); + ReadOnlyDbProvider? dbProvider = new(readOnlyDbProvider, true); TrieStore trieStore = new(readOnlyDbProvider.StateDb, logManager); - BlockTree BlockTree = new(readOnlyDbProvider, + BlockTree blockTree = new(readOnlyDbProvider, new ChainLevelInfoRepository(readOnlyDbProvider.BlockInfosDb), specProvider, NullBloomStorage.Instance, @@ -48,21 +48,21 @@ public static MultiCallReadOnlyBlocksProcessingEnv Create(bool TraceTransfers, I logManager); return new MultiCallReadOnlyBlocksProcessingEnv( - TraceTransfers, - DbProvider, + traceTransfers, + dbProvider, trieStore, - BlockTree, + blockTree, specProvider, logManager); } - public MultiCallReadOnlyBlocksProcessingEnv Clone(bool TraceTransfers) + public MultiCallReadOnlyBlocksProcessingEnv Clone(bool traceTransfers) { - return Create(TraceTransfers, DbProvider, SpecProvider, _logManager); + return Create(traceTransfers, DbProvider, SpecProvider, _logManager); } private MultiCallReadOnlyBlocksProcessingEnv( - bool TraceTransfers, + bool traceTransfers, IReadOnlyDbProvider? readOnlyDbProvider, ITrieStore? trieStore, IBlockTree? blockTree, @@ -78,7 +78,7 @@ private MultiCallReadOnlyBlocksProcessingEnv( _receiptStorage = new InMemoryReceiptStorage(); - if (TraceTransfers) + if (traceTransfers) { VirtualMachine = new MultiCallVirtualMachine(BlockhashProvider, specProvider, logManager); } diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs new file mode 100644 index 00000000000..462cb6e211a --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; +using Nethermind.Trie; + +namespace Nethermind.Facade; + +public static class BlockchainBridgeExtensions +{ + public static bool HasStateForBlock(this IBlockchainBridge blockchainBridge, BlockHeader header) + { + RootCheckVisitor rootCheckVisitor = new(); + blockchainBridge.RunTreeVisitor(rootCheckVisitor, header.StateRoot!); + return rootCheckVisitor.HasRoot; + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 7392b01d52a..ac5e36006f5 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -55,12 +55,6 @@ public partial class EthRpcModule : IEthRpcModule private readonly IEthSyncingInfo _ethSyncingInfo; private readonly IFeeHistoryOracle _feeHistoryOracle; - internal static bool HasStateForBlock(IBlockchainBridge blockchainBridge, BlockHeader header) - { - RootCheckVisitor rootCheckVisitor = new(); - blockchainBridge.RunTreeVisitor(rootCheckVisitor, header.StateRoot!); - return rootCheckVisitor.HasRoot; - } public EthRpcModule( IJsonRpcConfig rpcConfig, @@ -166,7 +160,7 @@ public ResultWrapper> eth_accounts() } BlockHeader header = searchResult.Object; - if (!HasStateForBlock(_blockchainBridge, header!)) + if (!_blockchainBridge.HasStateForBlock(header!)) { return Task.FromResult(GetStateFailureResult(header)); } @@ -210,7 +204,7 @@ public Task> eth_getTransactionCount(Address address, Blo } BlockHeader header = searchResult.Object; - if (!HasStateForBlock(_blockchainBridge, header!)) + if (!_blockchainBridge.HasStateForBlock(header!)) { return Task.FromResult(GetStateFailureResult(header)); } @@ -262,7 +256,7 @@ public ResultWrapper eth_getCode(Address address, BlockParameter? blockP } BlockHeader header = searchResult.Object; - if (!HasStateForBlock(_blockchainBridge, header!)) + if (!_blockchainBridge.HasStateForBlock(header!)) { return GetStateFailureResult(header); } @@ -687,7 +681,7 @@ public ResultWrapper eth_getProof(Address accountAddress, UInt256[ BlockHeader header = searchResult.Object; - if (!HasStateForBlock(_blockchainBridge, header!)) + if (!_blockchainBridge.HasStateForBlock(header!)) { return GetStateFailureResult(header); } @@ -735,7 +729,7 @@ public ResultWrapper eth_getAccount(Address accountAddress, Block } BlockHeader header = searchResult.Object; - if (!HasStateForBlock(_blockchainBridge, header!)) + if (!_blockchainBridge.HasStateForBlock(header!)) { return GetStateFailureResult(header); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs index c59c69dca23..6f3188c88c8 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs @@ -32,7 +32,7 @@ public virtual ResultWrapper Execute( } BlockHeader header = searchResult.Object; - if (!EthRpcModule.HasStateForBlock(_blockchainBridge, header)) + if (!_blockchainBridge.HasStateForBlock(header!)) { return ResultWrapper.Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable); From f9a6e9177a4ef689a594b1a453bee46e4732d6ef Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 12:47:39 +0100 Subject: [PATCH 060/213] Use of IReadOnlyList of MultiCallBlockResults --- .../Proxy/EthJsonRpcClientProxy.cs | 5 +++-- .../Proxy/IEthJsonRpcClientProxy.cs | 3 ++- .../Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs | 2 +- .../EthMulticallTestsPrecompilesWithRedirection.cs | 2 +- .../EthMulticallTestsBlocksAndTransactions.cs | 14 +++++++------- .../Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs | 2 +- .../Modules/Eth/EthRpcModuleProxy.cs | 3 ++- .../Modules/Eth/IEthRpcModule.cs | 3 ++- .../Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs | 9 +++++---- 9 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs index f886846a8ae..caf0f63fba2 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/EthJsonRpcClientProxy.cs @@ -9,6 +9,7 @@ using Nethermind.Int256; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; +using System.Collections.Generic; namespace Nethermind.Facade.Proxy { @@ -40,8 +41,8 @@ public Task> eth_call(CallTransaction transaction, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_call), transaction, MapBlockParameter(blockParameter)); - public Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null) - => _proxy.SendAsync(nameof(eth_multicallV1), blockCalls, MapBlockParameter(blockParameter)); + public Task>> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null) + => _proxy.SendAsync>(nameof(eth_multicallV1), blockCalls, MapBlockParameter(blockParameter)); public Task> eth_getCode(Address address, BlockParameterModel blockParameter = null) => _proxy.SendAsync(nameof(eth_getCode), address, MapBlockParameter(blockParameter)); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs index 66ffbefb5db..35e4a060b09 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.Collections.Generic; using System.Threading.Tasks; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -19,7 +20,7 @@ public interface IEthJsonRpcClientProxy Task> eth_getTransactionCount(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionReceipt(Keccak transactionHash); Task> eth_call(CallTransaction transaction, BlockParameterModel blockParameter = null); - Task> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null); + Task>> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null); Task> eth_getCode(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionByHash(Keccak transactionHash); Task> eth_pendingTransactions(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index af0cf835b2c..8625256d249 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -90,7 +90,7 @@ public void CanRunEthMulticallV1Empty() IEthRpcModule ethRpcModule = Substitute.For(); ethRpcModule.eth_multicallV1(payload).ReturnsForAnyArgs(x => - ResultWrapper.Success(Array.Empty())); + ResultWrapper>.Success(Array.Empty())); JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_multicallV1", serializedCall) as JsonRpcSuccessResponse; Assert.IsTrue(response != null); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 3608ca3236a..3fc514cdcdd 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -131,7 +131,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - ResultWrapper result = + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); //Check results diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index efaa170b8a5..729220220bb 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -95,11 +95,11 @@ public async Task Test_eth_multicall_serialisation() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - ResultWrapper result = + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); - MultiCallBlockResult[] data = result.Data; + IReadOnlyList data = result.Data; - Assert.AreEqual(1, data.Length); + Assert.AreEqual(1, data.Count); foreach (MultiCallBlockResult blockResult in data) { @@ -178,11 +178,11 @@ public async Task Test_eth_multicall_eth_moved() //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - ResultWrapper result = + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); - MultiCallBlockResult[] data = result.Data; + IReadOnlyList data = result.Data; - Assert.AreEqual(data.Length, 2); + Assert.AreEqual(data.Count, 2); foreach (MultiCallBlockResult blockResult in data) { @@ -256,7 +256,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - ResultWrapper result = + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); Assert.IsTrue(result.Data[1].Calls[0].Error.Message.StartsWith("insufficient")); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index ac5e36006f5..a2bc8e4ff5a 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -343,7 +343,7 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); - public ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) + public ResultWrapper> eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) { return new MultiCallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .Execute(payload, blockParameter); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs index f3224c4247b..d761c5eb89e 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModuleProxy.cs @@ -157,7 +157,8 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa throw new NotSupportedException(); } - public ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) + public ResultWrapper> eth_multicallV1( + MultiCallPayload payload, BlockParameter? blockParameter = null) { throw new NotImplementedException(); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 464dc4206ec..58674f31fa1 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -155,7 +155,8 @@ public interface IEthRpcModule : IRpcModule Description = "Executes a simulation across multiple blocks (does not create a transaction or block)", IsSharable = false, ExampleResponse = "0x")] - ResultWrapper eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null); + ResultWrapper> eth_multicallV1(MultiCallPayload payload, + BlockParameter? blockParameter = null); [JsonRpcMethod(IsImplemented = true, Description = "Executes a tx call and returns gas used (does not create a transaction)", diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 6718c5ca4c7..44c3691f1d7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.Collections.Generic; using System.Linq; using System.Threading; using Nethermind.Blockchain.Find; @@ -12,7 +13,7 @@ namespace Nethermind.JsonRpc.Modules.Eth; -public class MultiCallTxExecutor : ExecutorBase, MultiCallPayload> +public class MultiCallTxExecutor : ExecutorBase, MultiCallPayload, MultiCallPayload> { public MultiCallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : base(blockchainBridge, blockFinder, rpcConfig) @@ -39,16 +40,16 @@ protected override MultiCallPayload Prepare(MultiCallPayload Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) + protected override ResultWrapper> Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) { BlockchainBridge.MultiCallOutput results = _blockchainBridge.MultiCall(header.Clone(), tx, token); if (results.Error == null) { - return ResultWrapper.Success(results.Items.ToArray()); + return ResultWrapper>.Success(results.Items); } - return ResultWrapper.Fail(results.Error, results.Items.ToArray()); + return ResultWrapper>.Fail(results.Error, results.Items); } } From 62348dc2d7466bdca83a7ab75e457909c570a1e6 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 13:03:04 +0100 Subject: [PATCH 061/213] minor refactoring --- .../Nethermind.Evm/IMultiCallVirtualMachine.cs | 2 +- .../Nethermind.Evm/MultiCallVirtualMachine.cs | 14 +++++++------- .../Nethermind.Facade/BlockchainBridge.cs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs b/src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs index 491e1e5d346..b9d89ed0981 100644 --- a/src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs @@ -10,6 +10,6 @@ namespace Nethermind.Evm; public interface IMultiCallVirtualMachine : IVirtualMachine { - public void SetOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, + public void SetCodeOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, Address? redirectAddress = null); } diff --git a/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs b/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs index 9290f0c4513..e801c05acdb 100644 --- a/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs @@ -16,7 +16,7 @@ public struct MultiCallDoTraceTransfers { } public class MultiCallVirtualMachine : VirtualMachine, IMultiCallVirtualMachine { - private readonly Dictionary _overloaded = new(); + private readonly Dictionary _codeOverwrites = new(); public MultiCallVirtualMachine(IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, ILogManager? logManager) : @@ -43,18 +43,18 @@ protected override IVirtualMachine CreateVirtualMachine(IBlockhashProvider? bloc return result; } - public void SetOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, + public void SetCodeOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, Address? redirectAddress = null) { - if (redirectAddress != null) _overloaded[redirectAddress] = base.GetCachedCodeInfo(worldState, key, vmSpec); - _overloaded[key] = value; + if (redirectAddress != null) _codeOverwrites[redirectAddress] = base.GetCachedCodeInfo(worldState, key, vmSpec); + _codeOverwrites[key] = value; } public override CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) { - if (_overloaded.TryGetValue(codeSource, out CodeInfo result)) - return result; - return base.GetCachedCodeInfo(worldState, codeSource, vmSpec); + return _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) + ? result + : base.GetCachedCodeInfo(worldState, codeSource, vmSpec); } } diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index b71e2cf4f8d..6a7e45203dc 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -540,7 +540,7 @@ private void ModifyAccounts(Dictionary StateOverrides, if (accountOverride.Code != null) { - _multiCallProcessingEnv.VirtualMachine.SetOverwrite(StateProvider, CurrentSpec, address, + _multiCallProcessingEnv.VirtualMachine.SetCodeOverwrite(StateProvider, CurrentSpec, address, new CodeInfo(accountOverride.Code), accountOverride.MovePrecompileToAddress); } From 8619dc5ff87c853db45296c4877c623e388357ed Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 13:12:59 +0100 Subject: [PATCH 062/213] minor clean-up --- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs index 8430f49979a..655e7611b94 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -27,10 +27,8 @@ public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, private readonly ILogManager? _logManager; private readonly IBlockValidator _blockValidator; private readonly InMemoryReceiptStorage _receiptStorage; - public ITransactionProcessor TransactionProcessor { get; } public ISpecProvider SpecProvider { get; } public IMultiCallVirtualMachine VirtualMachine { get; } - public bool TraceTransfers { get; set; } //We need ability to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning public static MultiCallReadOnlyBlocksProcessingEnv Create(bool traceTransfers, IReadOnlyDbProvider? readOnlyDbProvider, @@ -38,6 +36,15 @@ public static MultiCallReadOnlyBlocksProcessingEnv Create(bool traceTransfers, I ILogManager? logManager ) { + if (specProvider == null) + { + throw new ArgumentNullException(nameof(specProvider)); + } + if (readOnlyDbProvider == null) + { + throw new ArgumentNullException(nameof(readOnlyDbProvider)); + } + ReadOnlyDbProvider? dbProvider = new(readOnlyDbProvider, true); TrieStore trieStore = new(readOnlyDbProvider.StateDb, logManager); BlockTree blockTree = new(readOnlyDbProvider, @@ -105,12 +112,12 @@ private MultiCallReadOnlyBlocksProcessingEnv( public IBlockProcessor GetProcessor() { - var yransactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, _logManager); + TransactionProcessor? transactionProcessor = new(SpecProvider, StateProvider, VirtualMachine, _logManager); return new BlockProcessor(SpecProvider, _blockValidator, NoBlockRewards.Instance, - new BlockProcessor.BlockValidationTransactionsExecutor(yransactionProcessor, StateProvider), + new BlockProcessor.BlockValidationTransactionsExecutor(transactionProcessor, StateProvider), StateProvider, _receiptStorage, NullWitnessCollector.Instance, From 30f5743df6fc37991a29a350c07d231a8698d20d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 13:24:47 +0100 Subject: [PATCH 063/213] Inheritance simplified --- .../IReadOnlyTxProcessingEnvBase.cs | 14 ----- .../Processing/ReadOnlyChainProcessingEnv.cs | 21 ++++++- .../ReadOnlyChainProcessingEnvBase.cs | 60 ------------------- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 2 +- 4 files changed, 19 insertions(+), 78 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnvBase.cs delete mode 100644 src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnvBase.cs deleted file mode 100644 index 49f16df8dbf..00000000000 --- a/src/Nethermind/Nethermind.Consensus/Processing/IReadOnlyTxProcessingEnvBase.cs +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Blockchain; -using Nethermind.State; - -namespace Nethermind.Consensus.Processing; - -public interface IReadOnlyTxProcessingEnvBase -{ - IStateReader StateReader { get; } - IWorldState StateProvider { get; } - IBlockTree BlockTree { get; } -} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs index a596ad4d32a..b9043d22f95 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnv.cs @@ -7,13 +7,14 @@ using Nethermind.Core.Specs; using Nethermind.Db; using Nethermind.Logging; +using Nethermind.State; namespace Nethermind.Consensus.Processing { /// /// Not thread safe. /// - public class ReadOnlyChainProcessingEnv : ReadOnlyChainProcessingEnvBase + public class ReadOnlyChainProcessingEnv { public IBlockchainProcessor ChainProcessor { get; } @@ -26,9 +27,23 @@ public ReadOnlyChainProcessingEnv( IReadOnlyDbProvider dbProvider, ISpecProvider specProvider, ILogManager logManager, - IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) : base(txEnv, blockValidator, recoveryStep, rewardCalculator, receiptStorage, specProvider, logManager, blockTransactionsExecutor) + IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) { - ChainProcessor = new OneTimeChainProcessor(dbProvider, _blockProcessingQueue); + IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor = + blockTransactionsExecutor ?? new BlockProcessor.BlockValidationTransactionsExecutor(txEnv.TransactionProcessor, txEnv.StateProvider); + + BlockProcessor? blockProcessor = new( + specProvider, + blockValidator, + rewardCalculator, + transactionsExecutor, + txEnv.StateProvider, + receiptStorage, + NullWitnessCollector.Instance, + logManager); + + BlockchainProcessor? blockProcessingQueue = new(txEnv.BlockTree, blockProcessor, recoveryStep, txEnv.StateReader, logManager, BlockchainProcessor.Options.NoReceipts); + ChainProcessor = new OneTimeChainProcessor(dbProvider, blockProcessingQueue); } } } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs deleted file mode 100644 index 4cf8bc8eea9..00000000000 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyChainProcessingEnvBase.cs +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using Nethermind.Blockchain.Receipts; -using Nethermind.Consensus.Rewards; -using Nethermind.Consensus.Validators; -using Nethermind.Core.Specs; -using Nethermind.Logging; -using Nethermind.State; - -namespace Nethermind.Consensus.Processing; - -/// -/// Not thread safe. -/// -public class ReadOnlyChainProcessingEnvBase : IDisposable -{ - protected readonly ReadOnlyTxProcessingEnv _txEnv; - - protected readonly BlockchainProcessor _blockProcessingQueue; - public IBlockProcessor BlockProcessor { get; } - public IBlockProcessingQueue BlockProcessingQueue { get; } - public IWorldState StateProvider => _txEnv.StateProvider; - - public ReadOnlyChainProcessingEnvBase( - ReadOnlyTxProcessingEnv txEnv, - IBlockValidator blockValidator, - IBlockPreprocessorStep recoveryStep, - IRewardCalculator rewardCalculator, - IReceiptStorage receiptStorage, - ISpecProvider specProvider, - ILogManager logManager, - IBlockProcessor.IBlockTransactionsExecutor? blockTransactionsExecutor = null) - { - _txEnv = txEnv; - - IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor = - blockTransactionsExecutor ?? new BlockProcessor.BlockValidationTransactionsExecutor(_txEnv.TransactionProcessor, StateProvider); - - BlockProcessor = new BlockProcessor( - specProvider, - blockValidator, - rewardCalculator, - transactionsExecutor, - StateProvider, - receiptStorage, - NullWitnessCollector.Instance, - logManager); - - _blockProcessingQueue = new BlockchainProcessor(_txEnv.BlockTree, BlockProcessor, recoveryStep, _txEnv.StateReader, logManager, BlockchainProcessor.Options.NoReceipts); - BlockProcessingQueue = _blockProcessingQueue; - - } - - public void Dispose() - { - _blockProcessingQueue?.Dispose(); - } -} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index 1a307217c82..01a77381c0d 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -11,7 +11,7 @@ namespace Nethermind.Consensus.Processing; -public class ReadOnlyTxProcessingEnvBase : IReadOnlyTxProcessingEnvBase +public class ReadOnlyTxProcessingEnvBase { public IStateReader StateReader { get; } public IWorldState StateProvider { get; } From e09142d4600fbef0f6351f0e729a0760895e012f Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 13:37:43 +0100 Subject: [PATCH 064/213] Classes extraction --- .../Executor/IUserOperationSimulator.cs | 2 +- .../Executor/UserOperationSimulator.cs | 4 +-- .../Source/UserOperationTxSource.cs | 2 +- .../Nethermind.Facade/BlockchainBridge.cs | 31 ------------------- .../Nethermind.Facade/CallOutput.cs | 19 ++++++++++++ .../Nethermind.Facade/MultiCallOutput.cs | 14 +++++++++ .../Eth/EthRpcModule.TransactionExecutor.cs | 10 +++--- .../Modules/Eth/ExecutorBase.cs | 2 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 2 +- .../Execution/TxBundleExecutor.cs | 2 +- 10 files changed, 45 insertions(+), 43 deletions(-) create mode 100644 src/Nethermind/Nethermind.Facade/CallOutput.cs create mode 100644 src/Nethermind/Nethermind.Facade/MultiCallOutput.cs diff --git a/src/Nethermind/Nethermind.AccountAbstraction/Executor/IUserOperationSimulator.cs b/src/Nethermind/Nethermind.AccountAbstraction/Executor/IUserOperationSimulator.cs index a2d08270b1e..4811b81a9ce 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction/Executor/IUserOperationSimulator.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction/Executor/IUserOperationSimulator.cs @@ -18,7 +18,7 @@ ResultWrapper Simulate(UserOperation userOperation, UInt256? timestamp = null, CancellationToken cancellationToken = default); - BlockchainBridge.CallOutput EstimateGas(BlockHeader header, Transaction tx, + CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken); } } diff --git a/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationSimulator.cs b/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationSimulator.cs index 37ed9593d29..849e17a50a2 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationSimulator.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationSimulator.cs @@ -184,7 +184,7 @@ private Transaction BuildSimulateValidationTransaction( } [Todo("Refactor once BlockchainBridge is separated")] - public BlockchainBridge.CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken) + public CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken) { ReadOnlyTxProcessingEnv txProcessingEnv = _readOnlyTxProcessingEnvFactory.Create(); using IReadOnlyTransactionProcessor transactionProcessor = txProcessingEnv.Build(header.StateRoot!); @@ -201,7 +201,7 @@ public BlockchainBridge.CallOutput EstimateGas(BlockHeader header, Transaction t GasEstimator gasEstimator = new(transactionProcessor, _stateProvider, _specProvider, _blocksConfig); long estimate = gasEstimator.Estimate(tx, header, estimateGasTracer, cancellationToken); - return new BlockchainBridge.CallOutput + return new CallOutput { Error = tryCallResult.Success ? estimateGasTracer.Error : tryCallResult.Error, GasSpent = estimate, diff --git a/src/Nethermind/Nethermind.AccountAbstraction/Source/UserOperationTxSource.cs b/src/Nethermind/Nethermind.AccountAbstraction/Source/UserOperationTxSource.cs index 49907f5fed1..203133a2981 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction/Source/UserOperationTxSource.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction/Source/UserOperationTxSource.cs @@ -171,7 +171,7 @@ public IEnumerable GetTransactions(BlockHeader parent, long gasLimi // TODO: Remove logging, just for testing _logger.Info($"Constructed tx from {userOperationsToInclude!.Count} userOperations: {userOperationTransaction.Hash}"); - BlockchainBridge.CallOutput callOutput = _userOperationSimulators[entryPoint].EstimateGas(parent, userOperationTransaction, CancellationToken.None); + CallOutput callOutput = _userOperationSimulators[entryPoint].EstimateGas(parent, userOperationTransaction, CancellationToken.None); FailedOp? failedOp = txBuilder.DecodeEntryPointOutputError(callOutput.OutputData); if (failedOp is not null) { diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 6a7e45203dc..1b552188ad0 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -20,7 +20,6 @@ using Block = Nethermind.Core.Block; using System.Threading; using Nethermind.Consensus.Processing; -using Nethermind.Core.Eip2930; using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade.Filters; @@ -138,37 +137,7 @@ public Block? HeadBlock } - public class MultiCallOutput - { - public string? Error { get; set; } - - public List Items { get; set; } - } - - public class CallOutput - { - public CallOutput() - { - } - public CallOutput(byte[] outputData, long gasSpent, string error, bool inputError = false) - { - Error = error; - OutputData = outputData; - GasSpent = gasSpent; - InputError = inputError; - } - - public string? Error { get; set; } - - public byte[] OutputData { get; set; } - - public long GasSpent { get; set; } - - public bool InputError { get; set; } - - public AccessList? AccessList { get; set; } - } public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken) { diff --git a/src/Nethermind/Nethermind.Facade/CallOutput.cs b/src/Nethermind/Nethermind.Facade/CallOutput.cs new file mode 100644 index 00000000000..a9bba48ef75 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/CallOutput.cs @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core.Eip2930; + +namespace Nethermind.Facade; + +public class CallOutput +{ + public string? Error { get; set; } + + public byte[] OutputData { get; set; } + + public long GasSpent { get; set; } + + public bool InputError { get; set; } + + public AccessList? AccessList { get; set; } +} diff --git a/src/Nethermind/Nethermind.Facade/MultiCallOutput.cs b/src/Nethermind/Nethermind.Facade/MultiCallOutput.cs new file mode 100644 index 00000000000..5bebc7ebf8e --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/MultiCallOutput.cs @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using Nethermind.Facade.Proxy.Models.MultiCall; + +namespace Nethermind.Facade; + +public class MultiCallOutput +{ + public string? Error { get; set; } + + public List Items { get; set; } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 592f69cccf0..00f6b8801d7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -63,7 +63,7 @@ public CallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFind protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token) { - BlockchainBridge.CallOutput result = _blockchainBridge.Call(header, tx, token); + CallOutput result = _blockchainBridge.Call(header, tx, token); if (result.Error is null) { @@ -86,7 +86,7 @@ public EstimateGasTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder bl protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token) { - BlockchainBridge.CallOutput result = _blockchainBridge.EstimateGas(header, tx, token); + CallOutput result = _blockchainBridge.EstimateGas(header, tx, token); if (result.Error is null) { @@ -111,7 +111,7 @@ public CreateAccessListTxExecutor(IBlockchainBridge blockchainBridge, IBlockFind protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token) { - BlockchainBridge.CallOutput result = _blockchainBridge.CreateAccessList(header, tx, token, _optimize); + CallOutput result = _blockchainBridge.CreateAccessList(header, tx, token, _optimize); if (result.Error is null) { @@ -123,13 +123,13 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, : ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError, new AccessListForRpc(GetResultAccessList(tx, result), GetResultGas(tx, result))); } - private static AccessListItemForRpc[] GetResultAccessList(Transaction tx, BlockchainBridge.CallOutput result) + private static AccessListItemForRpc[] GetResultAccessList(Transaction tx, CallOutput result) { AccessList? accessList = result.AccessList ?? tx.AccessList; return accessList is null ? Array.Empty() : AccessListItemForRpc.FromAccessList(accessList); } - private static UInt256 GetResultGas(Transaction transaction, BlockchainBridge.CallOutput result) + private static UInt256 GetResultGas(Transaction transaction, CallOutput result) { long gas = result.GasSpent; if (result.AccessList is not null) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs index 6f3188c88c8..52b5c334372 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs @@ -47,6 +47,6 @@ public virtual ResultWrapper Execute( protected abstract ResultWrapper Execute(BlockHeader header, TProcessing tx, CancellationToken token); - protected ResultWrapper GetInputError(BlockchainBridge.CallOutput result) => + protected ResultWrapper GetInputError(CallOutput result) => ResultWrapper.Fail(result.Error, ErrorCodes.InvalidInput); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 44c3691f1d7..ebc62808fa7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -42,7 +42,7 @@ protected override MultiCallPayload Prepare(MultiCallPayload> Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) { - BlockchainBridge.MultiCallOutput results = _blockchainBridge.MultiCall(header.Clone(), tx, token); + MultiCallOutput results = _blockchainBridge.MultiCall(header.Clone(), tx, token); if (results.Error == null) { diff --git a/src/Nethermind/Nethermind.Mev/Execution/TxBundleExecutor.cs b/src/Nethermind/Nethermind.Mev/Execution/TxBundleExecutor.cs index 17688769cdc..9791875b94c 100644 --- a/src/Nethermind/Nethermind.Mev/Execution/TxBundleExecutor.cs +++ b/src/Nethermind/Nethermind.Mev/Execution/TxBundleExecutor.cs @@ -68,7 +68,7 @@ private Block BuildBlock(MevBundle bundle, BlockHeader parent, ulong? timestamp) protected abstract TBlockTracer CreateBlockTracer(MevBundle mevBundle); - protected ResultWrapper GetInputError(BlockchainBridge.CallOutput result) => + protected ResultWrapper GetInputError(CallOutput result) => ResultWrapper.Fail(result.Error ?? string.Empty, ErrorCodes.InvalidInput); From d72c8e6d39ea31ce81211178b2f9b0afa6f20557 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 14:40:32 +0100 Subject: [PATCH 065/213] important refactoring --- .../Nethermind.Facade/BlockchainBridge.cs | 170 ++++++++---------- .../Nethermind.Facade/MultiCallBlockTracer.cs | 30 ++-- .../Nethermind.Facade/MultiCallOutput.cs | 2 +- .../Proxy/Models/MultiCall/BlockOverride.cs | 4 +- 4 files changed, 97 insertions(+), 109 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 1b552188ad0..c03193789d3 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -136,9 +136,6 @@ public Block? HeadBlock return blockHash is not null ? _receiptFinder.Get(blockHash).ForTransaction(txHash) : null; } - - - public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken) { CallOutputTracer callOutputTracer = new(); @@ -153,8 +150,6 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can }; } - - public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken) { MultiCallBlockTracer multiCallOutputTracer = new(); @@ -174,7 +169,7 @@ public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload NonceDictionary = new(); private void CallAndRestore( BlockHeader blockHeader, @@ -298,115 +292,109 @@ private void CallAndRestore( private (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) { - using (MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers)) + using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers); + + IBlockProcessor? processor = env.GetProcessor(); + BlockStateCall? firstBlock = payload.BlockStateCalls.FirstOrDefault(); + if (firstBlock?.BlockOverrides?.Number != null + && firstBlock?.BlockOverrides?.Number > UInt256.Zero + && firstBlock?.BlockOverrides?.Number < (ulong)long.MaxValue) { - var processor = env.GetProcessor(); - var firstBlock = payload.BlockStateCalls.FirstOrDefault(); - var startStateRoot = parent.StateRoot; - if (firstBlock?.BlockOverrides?.Number != null - && firstBlock?.BlockOverrides?.Number > UInt256.Zero - && firstBlock?.BlockOverrides?.Number < (ulong)long.MaxValue) + BlockHeader? searchResult = + _multiCallProcessingEnv.BlockTree.FindHeader((long)firstBlock?.BlockOverrides.Number); + if (searchResult != null) { - BlockHeader? searchResult = - _multiCallProcessingEnv.BlockTree.FindHeader((long)firstBlock?.BlockOverrides.Number); - if (searchResult != null) - { - startStateRoot = searchResult.StateRoot; - } + parent = searchResult; } + } - foreach (BlockStateCall? callInputBlock in payload.BlockStateCalls) - { - BlockHeader callHeader = null; - if (callInputBlock.BlockOverrides == null) - { - callHeader = new BlockHeader( - parent.Hash, - Keccak.OfAnEmptySequenceRlp, - Address.Zero, - UInt256.Zero, - parent.Number + 1, - parent.GasLimit, - parent.Timestamp + 1, - Array.Empty()); - callHeader.BaseFeePerGas = BaseFeeCalculator.Calculate(parent, _specProvider.GetSpec(parent)); - } - else + foreach (BlockStateCall? callInputBlock in payload.BlockStateCalls) + { + env.StateProvider.StateRoot = parent.StateRoot!; + + BlockHeader callHeader = callInputBlock.BlockOverrides is not null + ? callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig) + : new BlockHeader( + parent.Hash, + Keccak.OfAnEmptySequenceRlp, + Address.Zero, + UInt256.Zero, + parent.Number + 1, + parent.GasLimit, + parent.Timestamp + 1, + Array.Empty()) { - callHeader = callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig); - } + BaseFeePerGas = BaseFeeCalculator.Calculate(parent, _specProvider.GetSpec(parent)), + MixHash = parent.MixHash, + IsPostMerge = parent.Difficulty == 0 + }; - env.StateProvider.StateRoot = parent.StateRoot; - callHeader.MixHash = parent.MixHash; - callHeader.IsPostMerge = parent.Difficulty == 0; - Block? currentBlock = new(callHeader, Array.Empty(), Array.Empty()); + var currentSpec = env.SpecProvider.GetSpec(callHeader); + if (callInputBlock.StateOverrides != null) + { + ModifyAccounts(callInputBlock.StateOverrides, env.StateProvider, currentSpec); + } - var currentSpec = env.SpecProvider.GetSpec(currentBlock.Header); - if (callInputBlock.StateOverrides != null) - { - ModifyAccounts(callInputBlock.StateOverrides, env.StateProvider, currentSpec); - } + env.StateProvider.Commit(currentSpec); + env.StateProvider.CommitTree(callHeader.Number); + env.StateProvider.RecalculateStateRoot(); + callHeader.StateRoot = env.StateProvider.StateRoot; - env.StateProvider.Commit(currentSpec); - env.StateProvider.CommitTree(currentBlock.Number); - env.StateProvider.RecalculateStateRoot(); - var transactions = callInputBlock.Calls; - foreach (Transaction transaction in transactions) - { - transaction.SenderAddress ??= Address.SystemUser; + Transaction SetTxHash(Transaction transaction1) + { + transaction1.SenderAddress ??= Address.SystemUser; - Keccak stateRoot = callHeader.StateRoot!; + Keccak stateRoot = callHeader.StateRoot!; - if (transaction.Nonce == 0) + if (transaction1.Nonce == 0) + { + try { - try - { - transaction.Nonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; - } - catch (TrieException) - { - // Transaction from unknown account - } + transaction1.Nonce = env.StateProvider.GetAccount(transaction1.SenderAddress).Nonce; + } + catch (TrieException) + { + // Transaction from unknown account } - - transaction.Hash = transaction.CalculateHash(); } - currentBlock = currentBlock.WithReplacedBody(currentBlock.Body.WithChangedTransactions(transactions.ToArray())); + transaction1.Hash = transaction1.CalculateHash(); + return transaction1; + } + var transactions = callInputBlock.Calls.Select(SetTxHash).ToArray(); - currentBlock.Header.StateRoot = env.StateProvider.StateRoot; - currentBlock.Header.IsPostMerge = true; //ToDo: Seal if necessary before merge 192 BPB - currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); + Block? currentBlock = new(callHeader, transactions, Array.Empty()); + currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); - ProcessingOptions processingFlags = ProcessingOptions.ForceProcessing | - ProcessingOptions.DoNotVerifyNonce | - ProcessingOptions.IgnoreParentNotOnMainChain | - ProcessingOptions.MarkAsProcessed | - ProcessingOptions.StoreReceipts; + ProcessingOptions processingFlags = ProcessingOptions.ForceProcessing | + ProcessingOptions.DoNotVerifyNonce | + ProcessingOptions.IgnoreParentNotOnMainChain | + ProcessingOptions.MarkAsProcessed | + ProcessingOptions.StoreReceipts; - if (!payload.Validation) - { - processingFlags |= ProcessingOptions.NoValidation; - } + if (!payload.Validation) + { + processingFlags |= ProcessingOptions.NoValidation; + } - Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, - new List { currentBlock }, processingFlags, tracer); + Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, + new List { currentBlock }, processingFlags, tracer); - var processedBlock = currentBlocks.FirstOrDefault(); - if (processedBlock != null) - { - parent = processedBlock.Header; - } - else - { - return (false, $"Processing failed at block {currentBlock.Number}"); - } + var processedBlock = currentBlocks.FirstOrDefault(); + if (processedBlock != null) + { + parent = processedBlock.Header; + } + else + { + return (false, $"Processing failed at block {currentBlock.Number}"); } } + return (true, ""); } diff --git a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs index abe3d845e25..37ddd78915d 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs @@ -14,16 +14,16 @@ namespace Nethermind.Facade; public class MultiCallBlockTracer : BlockTracer { - public List _results = new(); + public List Results { get; } = new(); - private List _txTracers = new(); + private readonly List _txTracers = new(); - private Block currentBlock; + private Block _currentBlock; public override void StartNewBlockTrace(Block block) { _txTracers.Clear(); - currentBlock = block; + _currentBlock = block; } public override ITxTracer StartNewTxTrace(Transaction? tx) @@ -43,14 +43,14 @@ public override void EndBlockTrace() MultiCallBlockResult? result = new() { Calls = _txTracers.Select(t => t.TraceResult).ToArray(), - Number = (ulong)currentBlock.Number, - Hash = currentBlock.Hash, - GasLimit = (ulong)currentBlock.GasLimit, - GasUsed = (ulong)currentBlock.GasUsed, - Timestamp = currentBlock.Timestamp, - FeeRecipient = currentBlock.Beneficiary, - BaseFeePerGas = currentBlock.BaseFeePerGas, - PrevRandao = new UInt256(currentBlock.Header.Random.Bytes) + Number = (ulong)_currentBlock.Number, + Hash = _currentBlock.Hash, + GasLimit = (ulong)_currentBlock.GasLimit, + GasUsed = (ulong)_currentBlock.GasUsed, + Timestamp = _currentBlock.Timestamp, + FeeRecipient = _currentBlock.Beneficiary, + BaseFeePerGas = _currentBlock.BaseFeePerGas, + PrevRandao = new UInt256(_currentBlock.Header.Random.Bytes) }; result.Calls.ForEach(callResult => @@ -59,13 +59,13 @@ public override void EndBlockTrace() { callResult.Logs.ForEach(log => { - log.BlockHash = currentBlock.Hash; - log.BlockNumber = (ulong)currentBlock.Number; + log.BlockHash = _currentBlock.Hash; + log.BlockNumber = (ulong)_currentBlock.Number; }); } }); - _results.Add(result); + Results.Add(result); } } diff --git a/src/Nethermind/Nethermind.Facade/MultiCallOutput.cs b/src/Nethermind/Nethermind.Facade/MultiCallOutput.cs index 5bebc7ebf8e..fb24e9e7c89 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallOutput.cs +++ b/src/Nethermind/Nethermind.Facade/MultiCallOutput.cs @@ -10,5 +10,5 @@ public class MultiCallOutput { public string? Error { get; set; } - public List Items { get; set; } + public IReadOnlyList Items { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index 2dddca38031..a117dc565cb 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -6,7 +6,6 @@ using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Core.Specs; using Nethermind.Int256; namespace Nethermind.Facade.Proxy.Models.MultiCall; @@ -50,8 +49,9 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) newTime, Array.Empty()) { - MixHash = PrevRandao, BaseFeePerGas = BaseFeePerGas ?? parent.BaseFeePerGas, + MixHash = PrevRandao, + IsPostMerge = parent.Difficulty == 0 }; UInt256 difficulty = ConstantDifficulty.One.Calculate(result, parent); From fd5ce5dac1c621da5a62490e2f26276c63dc2003 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 12 Sep 2023 17:14:00 +0100 Subject: [PATCH 066/213] extracting Multicall Bridge Helper --- .../Processing/OneTimeProcessor.cs | 10 +- .../Nethermind.Facade/BlockchainBridge.cs | 240 +---------------- .../MultycallBridgeHelper.cs | 253 ++++++++++++++++++ 3 files changed, 269 insertions(+), 234 deletions(-) create mode 100644 src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs diff --git a/src/Nethermind/Nethermind.Consensus/Processing/OneTimeProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/OneTimeProcessor.cs index 7f0c5309b35..dba8eecce74 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/OneTimeProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/OneTimeProcessor.cs @@ -13,10 +13,10 @@ public class OneTimeChainProcessor : IBlockchainProcessor { public ITracerBag Tracers => _processor.Tracers; - protected readonly IBlockchainProcessor _processor; - protected readonly IReadOnlyDbProvider _readOnlyDbProvider; + private readonly IBlockchainProcessor _processor; + private readonly IReadOnlyDbProvider _readOnlyDbProvider; - protected object _lock = new(); + private object _lock = new(); public OneTimeChainProcessor(IReadOnlyDbProvider readOnlyDbProvider, IBlockchainProcessor processor) { @@ -34,7 +34,7 @@ public Task StopAsync(bool processRemainingBlocks = false) return _processor.StopAsync(processRemainingBlocks); } - public virtual Block? Process(Block block, ProcessingOptions options, IBlockTracer tracer) + public Block? Process(Block block, ProcessingOptions options, IBlockTracer tracer) { lock (_lock) { @@ -63,7 +63,7 @@ public bool IsProcessingBlocks(ulong? maxProcessingInterval) public event EventHandler? InvalidBlock; #pragma warning restore 67 - public virtual void Dispose() + public void Dispose() { _processor?.Dispose(); _readOnlyDbProvider?.Dispose(); diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index c03193789d3..07d38cea60d 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using Nethermind.Blockchain; using Nethermind.Blockchain.Filters; using Nethermind.Blockchain.Find; @@ -26,7 +25,6 @@ using Nethermind.State; using Nethermind.Core.Extensions; using Nethermind.Config; -using Nethermind.Evm.CodeAnalysis; using Nethermind.Facade.Proxy.Models.MultiCall; using System.Transactions; using Microsoft.CSharp.RuntimeBinder; @@ -44,7 +42,6 @@ public interface IBlockchainBridgeFactory public class BlockchainBridge : IBlockchainBridge { private readonly ReadOnlyTxProcessingEnv _processingEnv; - private readonly MultiCallReadOnlyBlocksProcessingEnv _multiCallProcessingEnv; private readonly ITxPool _txPool; private readonly IFilterStore _filterStore; private readonly IEthereumEcdsa _ecdsa; @@ -54,6 +51,7 @@ public class BlockchainBridge : IBlockchainBridge private readonly ILogFinder _logFinder; private readonly ISpecProvider _specProvider; private readonly IBlocksConfig _blocksConfig; + private readonly MultycallBridgeHelper _multycallBridgeHelper; public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv, @@ -69,7 +67,6 @@ public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, bool isMining) { _processingEnv = processingEnv ?? throw new ArgumentNullException(nameof(processingEnv)); - _multiCallProcessingEnv = multiCallProcessingEnv ?? throw new ArgumentNullException(nameof(multiCallProcessingEnv)); _txPool = txPool ?? throw new ArgumentNullException(nameof(_txPool)); _receiptFinder = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage)); _filterStore = filterStore ?? throw new ArgumentNullException(nameof(filterStore)); @@ -80,6 +77,7 @@ public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _blocksConfig = blocksConfig; IsMining = isMining; + _multycallBridgeHelper = new MultycallBridgeHelper(multiCallProcessingEnv ?? throw new ArgumentNullException(nameof(multiCallProcessingEnv)), _specProvider, _blocksConfig); } public Block? HeadBlock @@ -156,7 +154,7 @@ public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload NonceDictionary = new(); private void CallAndRestore( BlockHeader blockHeader, Transaction transaction, @@ -248,7 +245,14 @@ private void CallAndRestore( if (transaction.Nonce == 0) { - transaction.Nonce = GetNonce(stateRoot, transaction.SenderAddress); + try + { + transaction.Nonce = _processingEnv.StateReader.GetNonce(stateRoot, transaction.SenderAddress); + } + catch (Exception) + { + // TODO: handle missing state exception, may be account needs to be created + } } BlockHeader callHeader = treatBlockHeaderAsParentBlock @@ -289,235 +293,13 @@ private void CallAndRestore( transactionProcessor.CallAndRestore(transaction, callHeader, tracer); } - private (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, - IBlockTracer tracer) - { - using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers); - - IBlockProcessor? processor = env.GetProcessor(); - BlockStateCall? firstBlock = payload.BlockStateCalls.FirstOrDefault(); - if (firstBlock?.BlockOverrides?.Number != null - && firstBlock?.BlockOverrides?.Number > UInt256.Zero - && firstBlock?.BlockOverrides?.Number < (ulong)long.MaxValue) - { - BlockHeader? searchResult = - _multiCallProcessingEnv.BlockTree.FindHeader((long)firstBlock?.BlockOverrides.Number); - if (searchResult != null) - { - parent = searchResult; - } - } - - foreach (BlockStateCall? callInputBlock in payload.BlockStateCalls) - { - env.StateProvider.StateRoot = parent.StateRoot!; - - BlockHeader callHeader = callInputBlock.BlockOverrides is not null - ? callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig) - : new BlockHeader( - parent.Hash, - Keccak.OfAnEmptySequenceRlp, - Address.Zero, - UInt256.Zero, - parent.Number + 1, - parent.GasLimit, - parent.Timestamp + 1, - Array.Empty()) - { - BaseFeePerGas = BaseFeeCalculator.Calculate(parent, _specProvider.GetSpec(parent)), - MixHash = parent.MixHash, - IsPostMerge = parent.Difficulty == 0 - }; - - - var currentSpec = env.SpecProvider.GetSpec(callHeader); - if (callInputBlock.StateOverrides != null) - { - ModifyAccounts(callInputBlock.StateOverrides, env.StateProvider, currentSpec); - } - - env.StateProvider.Commit(currentSpec); - env.StateProvider.CommitTree(callHeader.Number); - env.StateProvider.RecalculateStateRoot(); - callHeader.StateRoot = env.StateProvider.StateRoot; - - - Transaction SetTxHash(Transaction transaction1) - { - transaction1.SenderAddress ??= Address.SystemUser; - - Keccak stateRoot = callHeader.StateRoot!; - - if (transaction1.Nonce == 0) - { - try - { - transaction1.Nonce = env.StateProvider.GetAccount(transaction1.SenderAddress).Nonce; - } - catch (TrieException) - { - // Transaction from unknown account - } - } - - transaction1.Hash = transaction1.CalculateHash(); - return transaction1; - } - - var transactions = callInputBlock.Calls.Select(SetTxHash).ToArray(); - - Block? currentBlock = new(callHeader, transactions, Array.Empty()); - currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); - - ProcessingOptions processingFlags = ProcessingOptions.ForceProcessing | - ProcessingOptions.DoNotVerifyNonce | - ProcessingOptions.IgnoreParentNotOnMainChain | - ProcessingOptions.MarkAsProcessed | - ProcessingOptions.StoreReceipts; - - if (!payload.Validation) - { - processingFlags |= ProcessingOptions.NoValidation; - } - - Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, - new List { currentBlock }, processingFlags, tracer); - - var processedBlock = currentBlocks.FirstOrDefault(); - if (processedBlock != null) - { - parent = processedBlock.Header; - } - else - { - return (false, $"Processing failed at block {currentBlock.Number}"); - } - } - - - return (true, ""); - } public ulong GetChainId() { return _processingEnv.BlockTree.ChainId; } - private UInt256 GetNonce(Keccak stateRoot, Address address) - { - UInt256 nonce = 0; - if (!NonceDictionary.TryGetValue(address, out nonce)) - { - try - { - nonce = _processingEnv.StateReader.GetNonce(stateRoot, address); - } - catch (Exception) - { - // TODO: handle missing state exception, may be account needs to be created - } - - NonceDictionary[address] = nonce; - } - else - { - nonce += 1; - NonceDictionary[address] = nonce; - } - - return nonce; - } - //Apply changes to accounts and contracts states including precompiles - private void ModifyAccounts(Dictionary StateOverrides, IWorldState? StateProvider, IReleaseSpec? CurrentSpec) - { - Account? acc; - - foreach (KeyValuePair overrideData in StateOverrides) - { - Address address = overrideData.Key; - AccountOverride? accountOverride = overrideData.Value; - - bool accExists = false; - try - { - accExists = StateProvider.AccountExists(address); - } - catch (Exception) - { - // ignored - } - - UInt256 balance = 0; - if (accountOverride.Balance != null) - { - balance = accountOverride.Balance.Value; - } - - UInt256 nonce = 0; - if (accountOverride.Nonce != null) - { - nonce = accountOverride.Nonce.Value; - } - - - if (!accExists) - { - StateProvider.CreateAccount(address, balance, nonce); - acc = StateProvider.GetAccount(address); - } - else - acc = StateProvider.GetAccount(address); - - UInt256 accBalance = acc.Balance; - if (accountOverride.Balance != null && accBalance > balance) - StateProvider.SubtractFromBalance(address, accBalance - balance, CurrentSpec); - - else if (accountOverride.Balance != null && accBalance < balance) - StateProvider.AddToBalance(address, balance - accBalance, CurrentSpec); - - - UInt256 accNonce = acc.Nonce; - if (accountOverride.Nonce != null && accNonce > nonce) - { - UInt256 iters = accNonce - nonce; - for (UInt256 i = 0; i < iters; i++) - { - StateProvider.DecrementNonce(address); - } - } - else if (accountOverride.Nonce != null && accNonce < accountOverride.Nonce) - { - UInt256 iters = nonce - accNonce; - for (UInt256 i = 0; i < iters; i++) - { - StateProvider.IncrementNonce(address); - } - } - - if (accountOverride.Code != null) - { - _multiCallProcessingEnv.VirtualMachine.SetCodeOverwrite(StateProvider, CurrentSpec, address, - new CodeInfo(accountOverride.Code), accountOverride.MovePrecompileToAddress); - } - - //TODO: discuss if clean slate is a must - if (accountOverride.State is not null) - { - foreach (KeyValuePair storage in accountOverride.State) - StateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); - } - - if (accountOverride.StateDiff is not null) - { - foreach (KeyValuePair storage in accountOverride.StateDiff) - StateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); - } - StateProvider.Commit(CurrentSpec); - } - } public bool FilterExists(int filterId) => _filterStore.FilterExists(filterId); public FilterType GetFilterType(int filterId) => _filterStore.GetFilterType(filterId); diff --git a/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs new file mode 100644 index 00000000000..52020528667 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs @@ -0,0 +1,253 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using System.Linq; +using Nethermind.Config; +using Nethermind.Consensus.Processing; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Crypto; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Evm.Tracing; +using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Int256; +using Nethermind.State; +using Nethermind.Trie; + +namespace Nethermind.Facade; + +public class MultycallBridgeHelper +{ + private readonly MultiCallReadOnlyBlocksProcessingEnv _multiCallProcessingEnv; + private readonly ISpecProvider _specProvider; + private readonly IBlocksConfig _blocksConfig; + + public MultycallBridgeHelper(MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv, ISpecProvider specProvider, IBlocksConfig blocksConfig) + { + _multiCallProcessingEnv = multiCallProcessingEnv; + _specProvider = specProvider; + _blocksConfig = blocksConfig; + } + + void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall? blockStateCall, MultiCallReadOnlyBlocksProcessingEnv env) + { + IReleaseSpec? currentSpec = env.SpecProvider.GetSpec(blockHeader); + if (blockStateCall!.StateOverrides != null) + { + ModifyAccounts(blockStateCall.StateOverrides, env.StateProvider, currentSpec); + } + + env.StateProvider.Commit(currentSpec); + env.StateProvider.CommitTree(blockHeader.Number); + env.StateProvider.RecalculateStateRoot(); + blockHeader.StateRoot = env.StateProvider.StateRoot; + } + + public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, + IBlockTracer tracer) + { + using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers); + + IBlockProcessor? processor = env.GetProcessor(); + BlockStateCall? firstBlock = payload.BlockStateCalls.FirstOrDefault(); + if (firstBlock?.BlockOverrides?.Number != null + && firstBlock?.BlockOverrides?.Number > UInt256.Zero + && firstBlock?.BlockOverrides?.Number < (ulong)long.MaxValue) + { + BlockHeader? searchResult = + env.BlockTree.FindHeader((long)firstBlock?.BlockOverrides.Number); + if (searchResult != null) + { + parent = searchResult; + } + } + + Dictionary _nonceCache = new(); + + + List suggestedBlocks = new(); + + foreach (BlockStateCall? callInputBlock in payload.BlockStateCalls) + { + env.StateProvider.StateRoot = parent.StateRoot!; + + BlockHeader callHeader = callInputBlock.BlockOverrides is not null + ? callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig) + : new BlockHeader( + parent.Hash, + Keccak.OfAnEmptySequenceRlp, + Address.Zero, + UInt256.Zero, + parent.Number + 1, + parent.GasLimit, + parent.Timestamp + 1, + Array.Empty()) + { + BaseFeePerGas = BaseFeeCalculator.Calculate(parent, _specProvider.GetSpec(parent)), + MixHash = parent.MixHash, + IsPostMerge = parent.Difficulty == 0 + }; + + + UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); + + + Transaction SetTxHash(Transaction transaction1) + { + transaction1.SenderAddress ??= Address.SystemUser; + + Keccak stateRoot = callHeader.StateRoot!; + + if (transaction1.Nonce == 0) + { + try + { + if (!_nonceCache.TryGetValue(transaction1.SenderAddress, out UInt256 cachedNonce)) + { + cachedNonce = env.StateProvider.GetAccount(transaction1.SenderAddress).Nonce; + _nonceCache[transaction1.SenderAddress] = cachedNonce; + } + + else + { + cachedNonce++; + _nonceCache[transaction1.SenderAddress] = cachedNonce; + } + + transaction1.Nonce = cachedNonce; + } + catch (TrieException) + { + // ignore + // Transaction from unknown account + } + } + + transaction1.Hash = transaction1.CalculateHash(); + return transaction1; + } + + Transaction[]? transactions = callInputBlock.Calls.Select(SetTxHash).ToArray(); + + Block? currentBlock = new(callHeader, transactions, Array.Empty()); + currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); + + ProcessingOptions processingFlags = ProcessingOptions.ForceProcessing | + ProcessingOptions.DoNotVerifyNonce | + ProcessingOptions.IgnoreParentNotOnMainChain | + ProcessingOptions.MarkAsProcessed | + ProcessingOptions.StoreReceipts; + + if (!payload.Validation) + { + processingFlags |= ProcessingOptions.NoValidation; + } + + suggestedBlocks.Clear(); + suggestedBlocks.Add(currentBlock); + + Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, + suggestedBlocks, processingFlags, tracer); + + Block? processedBlock = currentBlocks[0]; + parent = processedBlock.Header; + } + + + return (true, ""); + } + + private void ModifyAccounts(Dictionary stateOverrides, IWorldState? stateProvider, IReleaseSpec? currentSpec) + { + Account? acc; + + foreach (KeyValuePair overrideData in stateOverrides) + { + Address address = overrideData.Key; + AccountOverride? accountOverride = overrideData.Value; + + bool accExists = false; + try + { + accExists = stateProvider.AccountExists(address); + } + catch (Exception) + { + // ignored + } + + UInt256 balance = 0; + if (accountOverride.Balance != null) + { + balance = accountOverride.Balance.Value; + } + + UInt256 nonce = 0; + if (accountOverride.Nonce != null) + { + nonce = accountOverride.Nonce.Value; + } + + + if (!accExists) + { + stateProvider.CreateAccount(address, balance, nonce); + acc = stateProvider.GetAccount(address); + } + else + acc = stateProvider.GetAccount(address); + + UInt256 accBalance = acc.Balance; + if (accountOverride.Balance != null && accBalance > balance) + stateProvider.SubtractFromBalance(address, accBalance - balance, currentSpec); + + else if (accountOverride.Balance != null && accBalance < balance) + stateProvider.AddToBalance(address, balance - accBalance, currentSpec); + + + UInt256 accNonce = acc.Nonce; + if (accountOverride.Nonce != null && accNonce > nonce) + { + UInt256 iters = accNonce - nonce; + for (UInt256 i = 0; i < iters; i++) + { + stateProvider.DecrementNonce(address); + } + } + else if (accountOverride.Nonce != null && accNonce < accountOverride.Nonce) + { + UInt256 iters = nonce - accNonce; + for (UInt256 i = 0; i < iters; i++) + { + stateProvider.IncrementNonce(address); + } + } + + if (accountOverride.Code != null) + { + _multiCallProcessingEnv.VirtualMachine.SetCodeOverwrite(stateProvider, currentSpec, address, + new CodeInfo(accountOverride.Code), accountOverride.MovePrecompileToAddress); + } + + //TODO: discuss if clean slate is a must + if (accountOverride.State is not null) + { + foreach (KeyValuePair storage in accountOverride.State) + stateProvider.Set(new StorageCell(address, storage.Key), + storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); + } + + if (accountOverride.StateDiff is not null) + { + foreach (KeyValuePair storage in accountOverride.StateDiff) + stateProvider.Set(new StorageCell(address, storage.Key), + storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); + } + stateProvider.Commit(currentSpec); + } + } +} From 474066e1d2233469fac9e84efb2997858ed49829 Mon Sep 17 00:00:00 2001 From: Ruben Buniatyan Date: Wed, 13 Sep 2023 16:11:41 +0200 Subject: [PATCH 067/213] Publish draft releases as the latest (#6058) --- scripts/deployment/publish-github.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/scripts/deployment/publish-github.sh b/scripts/deployment/publish-github.sh index cc97dedddd4..2c6eb72fa00 100755 --- a/scripts/deployment/publish-github.sh +++ b/scripts/deployment/publish-github.sh @@ -5,7 +5,6 @@ set -e echo "Publishing packages to GitHub" -echo "Drafting release $GIT_TAG" release_id=$(curl https://api.github.com/repos/$GITHUB_REPOSITORY/releases \ -X GET \ @@ -14,6 +13,8 @@ release_id=$(curl https://api.github.com/repos/$GITHUB_REPOSITORY/releases \ if [ "$release_id" == "" ] then + echo "Drafting release $GIT_TAG" + body=$(printf \ '{"tag_name": "%s", "target_commitish": "%s", "name": "v%s", "body": "## Release notes\\n\\n", "draft": true, "prerelease": %s}' \ $GIT_TAG $GITHUB_SHA $GIT_TAG $PRERELEASE) @@ -25,9 +26,13 @@ then -H "Authorization: Bearer $GITHUB_TOKEN" \ -d "$body" | jq -r '.id') else + echo "Publishing release $GIT_TAG" + + make_latest=$([ $PRERELEASE = 'true' ] && echo "false" || echo "true") + body=$(printf \ - '{"target_commitish": "%s", "name": "v%s", "draft": false, "prerelease": %s}' \ - $GITHUB_SHA $GIT_TAG $PRERELEASE) + '{"target_commitish": "%s", "name": "v%s", "draft": false, "make_latest": "%s", "prerelease": %s}' \ + $GITHUB_SHA $GIT_TAG $make_latest $PRERELEASE) curl https://api.github.com/repos/$GITHUB_REPOSITORY/releases/$release_id \ -X PATCH \ From add699c6872b318407500392be0f43d1c91423df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Chodo=C5=82a?= Date: Wed, 13 Sep 2023 16:13:14 +0200 Subject: [PATCH 068/213] Change version suffix from unstable to rc --- src/Nethermind/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Directory.Build.props b/src/Nethermind/Directory.Build.props index 671224eecec..95d50853899 100644 --- a/src/Nethermind/Directory.Build.props +++ b/src/Nethermind/Directory.Build.props @@ -10,7 +10,7 @@ Nethermind $(Commit.Substring(0, 8)) 1.21.0 - unstable + rc From 26189fe105f02c663d12938acf644376e7a4b70d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 13 Sep 2023 15:36:08 +0100 Subject: [PATCH 069/213] minor refactorings --- .../Nethermind.Facade/BlockchainBridge.cs | 6 +- .../Nethermind.Facade/MultiCallBlockTracer.cs | 2 +- .../Nethermind.Facade/MultiCallTxTracer.cs | 1 - .../MultycallBridgeHelper.cs | 133 ++++++++++-------- .../Proxy/Models/MultiCall/BlockStateCall.cs | 2 +- 5 files changed, 82 insertions(+), 62 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 07d38cea60d..3f991cfd015 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -51,7 +51,7 @@ public class BlockchainBridge : IBlockchainBridge private readonly ILogFinder _logFinder; private readonly ISpecProvider _specProvider; private readonly IBlocksConfig _blocksConfig; - private readonly MultycallBridgeHelper _multycallBridgeHelper; + private readonly MultycallBridgeHelper _multicallBridgeHelper; public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv, @@ -77,7 +77,7 @@ public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _blocksConfig = blocksConfig; IsMining = isMining; - _multycallBridgeHelper = new MultycallBridgeHelper(multiCallProcessingEnv ?? throw new ArgumentNullException(nameof(multiCallProcessingEnv)), _specProvider, _blocksConfig); + _multicallBridgeHelper = new MultycallBridgeHelper(multiCallProcessingEnv ?? throw new ArgumentNullException(nameof(multiCallProcessingEnv)), _specProvider, _blocksConfig); } public Block? HeadBlock @@ -154,7 +154,7 @@ public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload _nonceCache = new(); - List suggestedBlocks = new(); foreach (BlockStateCall? callInputBlock in payload.BlockStateCalls) @@ -92,10 +91,8 @@ void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall stateOverrides, IWorldState? stateProvider, IReleaseSpec? currentSpec) { Account? acc; @@ -170,16 +183,6 @@ private void ModifyAccounts(Dictionary stateOverrides, Address address = overrideData.Key; AccountOverride? accountOverride = overrideData.Value; - bool accExists = false; - try - { - accExists = stateProvider.AccountExists(address); - } - catch (Exception) - { - // ignored - } - UInt256 balance = 0; if (accountOverride.Balance != null) { @@ -192,62 +195,80 @@ private void ModifyAccounts(Dictionary stateOverrides, nonce = accountOverride.Nonce.Value; } - - if (!accExists) + if (!TryGetAccount(stateProvider, address, out acc)) { stateProvider.CreateAccount(address, balance, nonce); - acc = stateProvider.GetAccount(address); } else - acc = stateProvider.GetAccount(address); - - UInt256 accBalance = acc.Balance; - if (accountOverride.Balance != null && accBalance > balance) - stateProvider.SubtractFromBalance(address, accBalance - balance, currentSpec); + { + UpdateBalance(stateProvider, currentSpec, acc, accountOverride, balance, address); + UpdataNonce(stateProvider, acc, accountOverride, nonce, address); + } - else if (accountOverride.Balance != null && accBalance < balance) - stateProvider.AddToBalance(address, balance - accBalance, currentSpec); + UpdateCode(stateProvider, currentSpec, accountOverride, address); + UpdateState(stateProvider, accountOverride, address); + } + stateProvider.Commit(currentSpec); + } + private static void UpdateState(IWorldState? stateProvider, AccountOverride? accountOverride, Address address) + { + //TODO: discuss if clean slate is a must + if (accountOverride.State is not null) + { + foreach (KeyValuePair storage in accountOverride.State) + stateProvider.Set(new StorageCell(address, storage.Key), + storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); + } - UInt256 accNonce = acc.Nonce; - if (accountOverride.Nonce != null && accNonce > nonce) - { - UInt256 iters = accNonce - nonce; - for (UInt256 i = 0; i < iters; i++) - { - stateProvider.DecrementNonce(address); - } - } - else if (accountOverride.Nonce != null && accNonce < accountOverride.Nonce) - { - UInt256 iters = nonce - accNonce; - for (UInt256 i = 0; i < iters; i++) - { - stateProvider.IncrementNonce(address); - } - } + if (accountOverride.StateDiff is not null) + { + foreach (KeyValuePair storage in accountOverride.StateDiff) + stateProvider.Set(new StorageCell(address, storage.Key), + storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); + } + } - if (accountOverride.Code != null) - { - _multiCallProcessingEnv.VirtualMachine.SetCodeOverwrite(stateProvider, currentSpec, address, - new CodeInfo(accountOverride.Code), accountOverride.MovePrecompileToAddress); - } + private void UpdateCode(IWorldState? stateProvider, IReleaseSpec? currentSpec, AccountOverride? accountOverride, + Address address) + { + if (accountOverride.Code != null) + { + _multiCallProcessingEnv.VirtualMachine.SetCodeOverwrite(stateProvider, currentSpec, address, + new CodeInfo(accountOverride.Code), accountOverride.MovePrecompileToAddress); + } + } - //TODO: discuss if clean slate is a must - if (accountOverride.State is not null) + private static void UpdataNonce(IWorldState? stateProvider, Account? acc, AccountOverride? accountOverride, + UInt256 nonce, Address address) + { + UInt256 accNonce = acc.Nonce; + if (accountOverride.Nonce != null && accNonce > nonce) + { + UInt256 iters = accNonce - nonce; + for (UInt256 i = 0; i < iters; i++) { - foreach (KeyValuePair storage in accountOverride.State) - stateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); + stateProvider.DecrementNonce(address); } - - if (accountOverride.StateDiff is not null) + } + else if (accountOverride.Nonce != null && accNonce < accountOverride.Nonce) + { + UInt256 iters = nonce - accNonce; + for (UInt256 i = 0; i < iters; i++) { - foreach (KeyValuePair storage in accountOverride.StateDiff) - stateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); + stateProvider.IncrementNonce(address); } - stateProvider.Commit(currentSpec); } } + + private static void UpdateBalance(IWorldState? stateProvider, IReleaseSpec? currentSpec, Account? acc, + AccountOverride? accountOverride, UInt256 balance, Address address) + { + UInt256 accBalance = acc.Balance; + if (accountOverride.Balance != null && accBalance > balance) + stateProvider.SubtractFromBalance(address, accBalance - balance, currentSpec); + + else if (accountOverride.Balance != null && accBalance < balance) + stateProvider.AddToBalance(address, balance - accBalance, currentSpec); + } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs index 7bce55c3e31..dca1ed9682e 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs @@ -9,6 +9,6 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class BlockStateCall { public BlockOverride? BlockOverrides { get; set; } - public Dictionary? StateOverrides { get; set; } = new Dictionary(); + public Dictionary? StateOverrides { get; set; } public T[]? Calls { get; set; } = { }; } From edb0490f90f5afbb1aeea9f32a4e477f116b15f6 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 13 Sep 2023 15:42:28 +0100 Subject: [PATCH 070/213] using NullReceiptStorage --- .../Processing/MultiCallReadOnlyBlocksProcessingEnv.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs index 655e7611b94..b6c92890d48 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -26,7 +26,6 @@ public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, private readonly ITrieStore? _trieStore; private readonly ILogManager? _logManager; private readonly IBlockValidator _blockValidator; - private readonly InMemoryReceiptStorage _receiptStorage; public ISpecProvider SpecProvider { get; } public IMultiCallVirtualMachine VirtualMachine { get; } @@ -77,14 +76,10 @@ private MultiCallReadOnlyBlocksProcessingEnv( ILogManager? logManager) : base(readOnlyDbProvider, trieStore, blockTree, logManager) { - _trieStore = trieStore; _logManager = logManager; SpecProvider = specProvider; - - _receiptStorage = new InMemoryReceiptStorage(); - if (traceTransfers) { VirtualMachine = new MultiCallVirtualMachine(BlockhashProvider, specProvider, logManager); @@ -119,7 +114,7 @@ public IBlockProcessor GetProcessor() NoBlockRewards.Instance, new BlockProcessor.BlockValidationTransactionsExecutor(transactionProcessor, StateProvider), StateProvider, - _receiptStorage, + NullReceiptStorage.Instance, NullWitnessCollector.Instance, _logManager); } From 8a04905700f1e45557eeeb70afe582393afba403 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 18 Sep 2023 11:55:07 +0100 Subject: [PATCH 071/213] minor test fixes --- src/Nethermind/Nethermind.Db.Test/DbOnTheRocksTests.cs | 2 +- .../Proxy/EthJsonRpcClientProxyTests.cs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Db.Test/DbOnTheRocksTests.cs b/src/Nethermind/Nethermind.Db.Test/DbOnTheRocksTests.cs index b29e0304284..9e2d9e476d1 100644 --- a/src/Nethermind/Nethermind.Db.Test/DbOnTheRocksTests.cs +++ b/src/Nethermind/Nethermind.Db.Test/DbOnTheRocksTests.cs @@ -45,7 +45,7 @@ public void TearDown() public void WriteOptions_is_correct() { IDbConfig config = new DbConfig(); - DbOnTheRocks db = new(DbPath, GetRocksDbSettings(DbPath, "Blocks"), config, LimboLogs.Instance); + using DbOnTheRocks db = new(DbPath, GetRocksDbSettings(DbPath, "Blocks"), config, LimboLogs.Instance); WriteOptions? options = db.WriteFlagsToWriteOptions(WriteFlags.LowPriority); Native.Instance.rocksdb_writeoptions_get_low_pri(options.Handle).Should().BeTrue(); diff --git a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs index 53e994721e2..c81ed0e76d5 100644 --- a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs @@ -15,6 +15,7 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using NSubstitute; using NUnit.Framework; +using System.Collections.Generic; namespace Nethermind.Facade.Test.Proxy { @@ -97,7 +98,7 @@ public async Task eth_multicall_should_invoke_client_method_even_empty() await _proxy.eth_multicallV1(payload, blockParameter); var calls = _client.ReceivedCalls().ToList(); - await _client.Received().SendAsync(nameof(_proxy.eth_multicallV1), + await _client.Received().SendAsync>(nameof(_proxy.eth_multicallV1), payload, blockParameter.Type); } @@ -115,7 +116,7 @@ public async Task eth_multicallV1_should_invoke_client_method() await _proxy.eth_multicallV1(payload, blockParameter); var calls = _client.ReceivedCalls().ToList(); - await _client.Received().SendAsync(nameof(_proxy.eth_multicallV1), + await _client.Received().SendAsync>(nameof(_proxy.eth_multicallV1), payload, blockParameter.Type); } From b30d3771a6e42527b7ea7c5996a3b17d460a4b0b Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 18 Sep 2023 12:03:39 +0100 Subject: [PATCH 072/213] minor test fixes --- .../Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 4360afdf15e..9492c09fa8b 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -84,17 +84,17 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); - MultiCallPayload payload = new() + MultiCallPayload payload = new() { BlockStateCalls = new[] { - new BlockStateCalls() + new BlockStateCall() { StateOverrides = new Dictionary() { { EcRecoverPrecompile.Address, new AccountOverride { Code = code } } }, - Calls = new[] { CallTransactionModel.FromTransaction(systemTransactionForModifiedVM) } + Calls = new[] { systemTransactionForModifiedVM } } }, TraceTransfers = true, @@ -102,7 +102,8 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe }; // Act - BlockchainBridge.MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, payload, CancellationToken.None); + + MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, payload, CancellationToken.None); Log[]? logs = result.Items.First().Calls.First().Logs; From bce00e48108e70f90ac686914b745a6ec4eeef39 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 18 Sep 2023 12:42:24 +0100 Subject: [PATCH 073/213] Setting correct Tx type defaults --- .../MultycallBridgeHelper.cs | 25 +++++++++++-------- .../Data/TransactionForRpc.cs | 8 +++--- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 1 + 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs index 046f75d174e..e993873e661 100644 --- a/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs @@ -8,6 +8,7 @@ using Nethermind.Consensus.Processing; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Eip2930; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Crypto; @@ -93,29 +94,31 @@ void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall.Empty; Keccak stateRoot = callHeader.StateRoot!; - if (transaction1.Nonce == 0) + if (transaction.Nonce == 0) { try { - if (!_nonceCache.TryGetValue(transaction1.SenderAddress, out UInt256 cachedNonce)) + if (!_nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) { - cachedNonce = env.StateProvider.GetAccount(transaction1.SenderAddress).Nonce; - _nonceCache[transaction1.SenderAddress] = cachedNonce; + cachedNonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; + _nonceCache[transaction.SenderAddress] = cachedNonce; } else { cachedNonce++; - _nonceCache[transaction1.SenderAddress] = cachedNonce; + _nonceCache[transaction.SenderAddress] = cachedNonce; } - transaction1.Nonce = cachedNonce; + transaction.Nonce = cachedNonce; } catch (TrieException) { @@ -124,11 +127,11 @@ Transaction SetTxHash(Transaction transaction1) } } - transaction1.Hash = transaction1.CalculateHash(); - return transaction1; + transaction.Hash = transaction.CalculateHash(); + return transaction; } - Transaction[]? transactions = callInputBlock.Calls.Select(SetTxHash).ToArray(); + Transaction[]? transactions = callInputBlock.Calls.Select(SetTxHashAndMissingDefaults).ToArray(); Block? currentBlock = new(callHeader, transactions, Array.Empty()); currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs index 4b4eabe1f18..384770d488f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs @@ -103,7 +103,7 @@ public TransactionForRpc() public UInt256? ChainId { get; set; } - public TxType Type { get; set; } + public TxType? Type { get; set; } public AccessListItemForRpc[]? AccessList { get; set; } @@ -136,7 +136,7 @@ public TransactionForRpc() SenderAddress = From, Value = Value ?? 0, Data = Input, - Type = Type, + Type = Type ?? TxType.Legacy, AccessList = TryGetAccessList(), ChainId = chainId, DecodedMaxFeePerGas = MaxFeePerGas ?? 0, @@ -172,7 +172,7 @@ public TransactionForRpc() SenderAddress = From, Value = Value ?? 0, Data = (Memory?)data, - Type = Type, + Type = Type ?? TxType.Legacy, AccessList = TryGetAccessList(), ChainId = chainId, }; @@ -198,7 +198,7 @@ public TransactionForRpc() } private AccessList? TryGetAccessList() => - !Type.IsTxTypeWithAccessList() || AccessList is null + Type != null && (!Type.Value.IsTxTypeWithAccessList() || AccessList is null) ? null : AccessListItemForRpc.ToAccessList(AccessList); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index ebc62808fa7..70ab4f27297 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -32,6 +32,7 @@ protected override MultiCallPayload Prepare(MultiCallPayload { callTransactionModel.EnsureDefaults(_rpcConfig.GasCap); + callTransactionModel.Type ??= TxType.EIP1559; return callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()); }).ToArray() }).ToArray() From 20fade3a39de5c34ea2ddd9d3b9fa6c722de05b7 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 18 Sep 2023 22:08:41 +0100 Subject: [PATCH 074/213] minor tests fix --- src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs index 384770d488f..67644291b7e 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs @@ -198,7 +198,7 @@ public TransactionForRpc() } private AccessList? TryGetAccessList() => - Type != null && (!Type.Value.IsTxTypeWithAccessList() || AccessList is null) + Type is null || (Type != null && (!Type.Value.IsTxTypeWithAccessList())) || AccessList is null ? null : AccessListItemForRpc.ToAccessList(AccessList); From a1423648fa9bb8e97aa45f22d79e38c178862e09 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 19 Sep 2023 01:29:34 +0100 Subject: [PATCH 075/213] clean up txTypes diff --- .../Nethermind.JsonRpc/Data/TransactionForRpc.cs | 8 ++++---- .../Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs index 01a872dbd5f..ca340403e22 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs @@ -116,7 +116,7 @@ public TransactionForRpc() public UInt256? ChainId { get; set; } - public TxType? Type { get; set; } + public TxType Type { get; set; } public AccessListItemForRpc[]? AccessList { get; set; } @@ -149,7 +149,7 @@ public TransactionForRpc() SenderAddress = From, Value = Value ?? 0, Data = Input, - Type = Type ?? TxType.Legacy, + Type = Type, AccessList = TryGetAccessList(), ChainId = chainId, DecodedMaxFeePerGas = MaxFeePerGas ?? 0, @@ -185,7 +185,7 @@ public TransactionForRpc() SenderAddress = From, Value = Value ?? 0, Data = (Memory?)data, - Type = Type ?? TxType.Legacy, + Type = Type, AccessList = TryGetAccessList(), ChainId = chainId, }; @@ -211,7 +211,7 @@ public TransactionForRpc() } private AccessList? TryGetAccessList() => - Type is null || (Type != null && (!Type.Value.IsTxTypeWithAccessList())) || AccessList is null + !Type.IsTxTypeWithAccessList() || AccessList is null ? null : AccessListItemForRpc.ToAccessList(AccessList); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 70ab4f27297..e476bc2c7fd 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -32,7 +32,7 @@ protected override MultiCallPayload Prepare(MultiCallPayload { callTransactionModel.EnsureDefaults(_rpcConfig.GasCap); - callTransactionModel.Type ??= TxType.EIP1559; + //callTransactionModel.Type ??= TxType.EIP1559; return callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()); }).ToArray() }).ToArray() From 81f52a27d135bb4341a5b582839989324df49b07 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 27 Sep 2023 02:54:49 +0100 Subject: [PATCH 076/213] fixing missing state on "latest" --- .../Nethermind.Facade/MultycallBridgeHelper.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs index e993873e661..8da4a101800 100644 --- a/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs @@ -52,12 +52,18 @@ void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall? firstBlock = payload.BlockStateCalls.FirstOrDefault(); if (firstBlock?.BlockOverrides?.Number != null && firstBlock?.BlockOverrides?.Number > UInt256.Zero - && firstBlock?.BlockOverrides?.Number < (ulong)long.MaxValue) + && firstBlock?.BlockOverrides?.Number < long.MaxValue) { BlockHeader? searchResult = env.BlockTree.FindHeader((long)firstBlock?.BlockOverrides.Number); @@ -73,8 +79,6 @@ void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall? callInputBlock in payload.BlockStateCalls) { - env.StateProvider.StateRoot = parent.StateRoot!; - BlockHeader callHeader = callInputBlock.BlockOverrides is not null ? callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig) : new BlockHeader( @@ -211,7 +215,6 @@ private void ModifyAccounts(Dictionary stateOverrides, UpdateCode(stateProvider, currentSpec, accountOverride, address); UpdateState(stateProvider, accountOverride, address); } - stateProvider.Commit(currentSpec); } private static void UpdateState(IWorldState? stateProvider, AccountOverride? accountOverride, Address address) From f5e616e2b4e1abca8a2d1670b3a07789a41030d4 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 27 Sep 2023 03:07:39 +0100 Subject: [PATCH 077/213] updated interface --- .../Validators/MultiCallBlockValidatorProxy.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs b/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs index b242c986888..ba6ab6fc80e 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs @@ -29,6 +29,11 @@ public bool ValidateWithdrawals(Block block, out string? error) return _baseBlockValidator.ValidateWithdrawals(block, out error); } + public bool ValidateOrphanedBlock(Block block, out string? error) + { + return _baseBlockValidator.ValidateOrphanedBlock(block, out error); + } + public bool ValidateSuggestedBlock(Block block) { return _baseBlockValidator.ValidateSuggestedBlock(block); From 1c7c4bf8dc5db3b5772ed62d784ceb6265e725bc Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 27 Sep 2023 03:42:59 +0100 Subject: [PATCH 078/213] updating tests --- .../JsonRpcServiceTests.cs | 2 +- ...ulticallTestsPrecompilesWithRedirection.cs | 11 ++++--- .../Modules/Eth/EthRpcMulticallTestsBase.cs | 12 ++++---- .../EthMulticallTestsBlocksAndTransactions.cs | 30 +++++++++---------- .../EthMulticallTestsSimplePrecompiles.cs | 4 +-- 5 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 6154fcd510a..0caff7522b6 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -80,7 +80,7 @@ public void Eth_module_populates_size_when_returning_block_data() [Test] public void CanRunEthMulticallV1Empty() { - MultiCallPayload payload = new() { BlockStateCalls = Array.Empty>() }; + MultiCallPayload? payload = new() { BlockStateCalls = Array.Empty>() }; EthereumJsonSerializer serializer = new(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 3fc514cdcdd..516d53516a9 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -10,7 +10,6 @@ using Nethermind.Core.Test.Builders; using Nethermind.Evm; using Nethermind.Evm.Precompiles; -using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; @@ -95,8 +94,8 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( }; - chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); - chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); BlockHeader header = chain.BlockFinder.Head.Header; IReleaseSpec spec = chain.SpecProvider.GetSpec(header); @@ -126,7 +125,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( //Force persistancy of head block in main chain chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); - chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); @@ -135,10 +134,10 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( executor.Execute(payload, BlockParameter.Latest); //Check results - byte[] addressBytes = result.Data[0].Calls[0].ReturnData + byte[] addressBytes = result.Data[0].Calls[0].ReturnData! .SliceWithZeroPaddingEmptyOnError(12, 20); Address resultingAddress = new(addressBytes); - Assert.AreEqual(realSenderAccount, resultingAddress); + Assert.That(resultingAddress, Is.EqualTo(realSenderAccount)); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs index f7852cdb7bf..a0b4740f4f4 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs @@ -139,7 +139,7 @@ public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, stri //createContractTxReceipt2.ContractAddress // .Should().NotBeNull($"Contract transaction {tx.Hash} was not deployed."); - Address contractAddress1; + Address? contractAddress1; using (SecureStringWrapper pass = new("testB")) { wallet.Import(fromPrivateKey.KeyBytes, pass.SecureData); @@ -147,20 +147,20 @@ public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, stri (Keccak hash, AcceptTxResult? code) = await txSender.SendTransaction(tx, TxHandlingOptions.ManagedNonce | TxHandlingOptions.PersistentBroadcast); - code.Value.Should().Be(AcceptTxResult.Accepted); + code?.Should().Be(AcceptTxResult.Accepted); Transaction[] txs = chain1.TxPool.GetPendingTransactions(); await chain1.AddBlock(true, txs); - TxReceipt createContractTxReceipt = null; - while (createContractTxReceipt == null) + TxReceipt createContractTxReceipt = new(); + while (createContractTxReceipt.Equals(default(TxReceipt))) { await Task.Delay(100); // wait... todo enforce! - createContractTxReceipt = chain1.Bridge.GetReceipt(tx.Hash); + createContractTxReceipt = chain1.Bridge.GetReceipt(tx.Hash!); } createContractTxReceipt.ContractAddress.Should() - .NotBeNull($"Contract transaction {tx.Hash} was not deployed."); + .NotBeNull($"Contract transaction {tx.Hash!} was not deployed."); contractAddress1 = createContractTxReceipt.ContractAddress; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 729220220bb..22d6654bf13 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -91,21 +91,21 @@ public async Task Test_eth_multicall_serialisation() //Force persistancy of head block in main chain - chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); - chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; - Assert.AreEqual(1, data.Count); + Assert.That(data.Count, Is.EqualTo(1)); foreach (MultiCallBlockResult blockResult in data) { - Assert.AreEqual(2, blockResult.Calls.Length); - Assert.AreEqual(ResultType.Failure, blockResult.Calls[0].Type); - Assert.AreEqual(ResultType.Success, blockResult.Calls[1].Type); + Assert.That(blockResult.Calls.Length, Is.EqualTo(2)); + Assert.That(blockResult.Calls[0].Type, Is.EqualTo(ResultType.Failure)); + Assert.That(blockResult.Calls[1].Type, Is.EqualTo(ResultType.Success)); } } @@ -170,11 +170,11 @@ public async Task Test_eth_multicall_eth_moved() UInt256 after = chain.State.GetAccount(TestItem.AddressA).Balance; Assert.Less(after, before); - chain.Bridge.GetReceipt(txMainnetAtoB.Hash); + chain.Bridge.GetReceipt(txMainnetAtoB.Hash!); //Force persistancy of head block in main chain - chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); - chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); @@ -182,11 +182,11 @@ public async Task Test_eth_multicall_eth_moved() executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; - Assert.AreEqual(data.Count, 2); + Assert.That(data.Count, Is.EqualTo(2)); foreach (MultiCallBlockResult blockResult in data) { - Assert.AreEqual(blockResult.Calls.Length, 2); + Assert.That(blockResult.Calls.Length, Is.EqualTo(2)); } } @@ -247,17 +247,17 @@ public async Task Test_eth_multicall_transactions_forced_fail() UInt256 after = chain.State.GetAccount(TestItem.AddressA).Balance; Assert.Less(after, before); - chain.Bridge.GetReceipt(txMainnetAtoB.Hash); + chain.Bridge.GetReceipt(txMainnetAtoB.Hash!); //Force persistancy of head block in main chain - chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); - chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash); + chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); - Assert.IsTrue(result.Data[1].Calls[0].Error.Message.StartsWith("insufficient")); + Assert.IsTrue(result.Data[1].Calls[0].Error?.Message.StartsWith("insufficient")); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 9492c09fa8b..1705041b232 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -103,7 +103,7 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe // Act - MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head.Header, payload, CancellationToken.None); + MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head?.Header!, payload, CancellationToken.None); Log[]? logs = result.Items.First().Calls.First().Logs; @@ -112,7 +112,7 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); Assert.NotNull(mainChainRpcAddress); - Assert.AreEqual(TestItem.AddressA, mainChainRpcAddress); + Assert.That(mainChainRpcAddress, Is.EqualTo(TestItem.AddressA)); } } From 2a70ac4a14c9db91d05c56d000ed5a69f99e394d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Chodo=C5=82a?= <43241881+kamilchodola@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:55:11 +0200 Subject: [PATCH 079/213] Change TuneDb default to HeavyWrite (#6136) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Chodoła --- .../Nethermind.Blockchain/Synchronization/ISyncConfig.cs | 2 +- .../Nethermind.Blockchain/Synchronization/SyncConfig.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs index 5ec311eb5cc..45c7a1120da 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs @@ -104,7 +104,7 @@ public interface ISyncConfig : IConfig [ConfigItem(Description = "[EXPERIMENTAL] Only for non validator nodes! If set to true, DownloadReceiptsInFastSync and/or DownloadBodiesInFastSync can be set to false.", DefaultValue = "false")] public bool NonValidatorNode { get; set; } - [ConfigItem(Description = "[EXPERIMENTAL] Optimize db for write during sync. Significantly reduce total writes written and some sync time if you are not network limited.", DefaultValue = "Default")] + [ConfigItem(Description = "[EXPERIMENTAL] Optimize db for write during sync. Significantly reduce total writes written and some sync time if you are not network limited.", DefaultValue = "HeavyWrite")] public ITunableDb.TuneType TuneDbMode { get; set; } [ConfigItem(Description = "[EXPERIMENTAL] Optimize db for write during sync just for blocks db. Useful for turning on blobs file.", DefaultValue = "EnableBlobFiles")] diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs index 2a6b154502e..38e8cc0a026 100644 --- a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs +++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs @@ -60,7 +60,7 @@ public string? PivotHash public bool StrictMode { get; set; } = false; public bool BlockGossipEnabled { get; set; } = true; public bool NonValidatorNode { get; set; } = false; - public ITunableDb.TuneType TuneDbMode { get; set; } = ITunableDb.TuneType.Default; + public ITunableDb.TuneType TuneDbMode { get; set; } = ITunableDb.TuneType.HeavyWrite; public ITunableDb.TuneType BlocksDbTuneDbMode { get; set; } = ITunableDb.TuneType.EnableBlobFiles; public int MaxProcessingThreads { get; set; } public bool ExitOnSynced { get; set; } = false; From a7850441ca7046cd9791dfe36c8ac228ad43c227 Mon Sep 17 00:00:00 2001 From: Ahmad Bitar <33181301+smartprogrammer93@users.noreply.github.com> Date: Thu, 21 Sep 2023 13:09:03 +0300 Subject: [PATCH 080/213] [Fix][Holesky] timestamps and genesis updates (#6112) * holesky timestamps and genesis updates * fix genesis hash for archive * add fork info tests for holesky --- src/Nethermind/Chains/holesky.json | 12 +++++----- .../Nethermind.Network.Test/ForkInfoTests.cs | 23 ++++--------------- .../Nethermind.Runner/configs/holesky.cfg | 2 +- .../configs/holesky_archive.cfg | 2 +- .../ChainSpecBasedSpecProviderTests.cs | 5 ++-- .../Nethermind.Specs/HoleskySpecProvider.cs | 4 ++-- .../Nethermind.Specs/KnownHashes.cs | 1 + 7 files changed, 19 insertions(+), 30 deletions(-) diff --git a/src/Nethermind/Chains/holesky.json b/src/Nethermind/Chains/holesky.json index e32cd82ae7e..a06501a813c 100644 --- a/src/Nethermind/Chains/holesky.json +++ b/src/Nethermind/Chains/holesky.json @@ -35,10 +35,10 @@ "eip3198Transition": "0x0", "eip3529Transition": "0x0", "eip3541Transition": "0x0", - "eip3651TransitionTimestamp": "0x6505e360", - "eip3855TransitionTimestamp": "0x6505e360", - "eip3860TransitionTimestamp": "0x6505e360", - "eip4895TransitionTimestamp": "0x6505e360", + "eip3651TransitionTimestamp": "0x6516eac0", + "eip3855TransitionTimestamp": "0x6516eac0", + "eip3860TransitionTimestamp": "0x6516eac0", + "eip4895TransitionTimestamp": "0x6516eac0", "terminalTotalDifficulty": "0x0", "gasLimitBoundDivisor": "0x400", "maxCodeSize": "0x6000", @@ -57,10 +57,10 @@ }, "difficulty": "0x01", "author": "0x0000000000000000000000000000000000000000", - "extraData": "0x686f77206d7563682069732074686520666973683f", + "extraData": "", "gasLimit": "0x17D7840", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "0x65046234" + "timestamp": "0x65156994" }, "nodes": [ "enode://ac906289e4b7f12df423d654c5a962b6ebe5b3a74cc9e06292a85221f9a64a6f1cfdd6b714ed6dacef51578f92b34c60ee91e9ede9c7f8fadc4d347326d95e2b@146.190.13.128:30303", diff --git a/src/Nethermind/Nethermind.Network.Test/ForkInfoTests.cs b/src/Nethermind/Nethermind.Network.Test/ForkInfoTests.cs index 6a5ee7a3995..804f492e84b 100644 --- a/src/Nethermind/Nethermind.Network.Test/ForkInfoTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/ForkInfoTests.cs @@ -112,25 +112,12 @@ public void Fork_id_and_hash_as_expected_on_goerli(long head, ulong headTimestam Test(head, headTimestamp, KnownHashes.GoerliGenesis, forkHashHex, next, description, GoerliSpecProvider.Instance, "goerli.json"); } - [TestCase(0, 0ul, "0x3b8e0691", 1ul, "Unsynced, last Frontier block")] - [TestCase(1, 0ul, "0x60949295", 2ul, "First and last Homestead block")] - [TestCase(2, 0ul, "0x8bde40dd", 3ul, "First and last Tangerine block")] - [TestCase(3, 0ul, "0xcb3a64bb", 1035301ul, "First Spurious block")] - [TestCase(1_035_300L, 0ul, "0xcb3a64bb", 1_035_301ul, "Last Spurious block")] - [TestCase(1_035_301L, 0ul, "0x8d748b57", 3_660_663ul, "First Byzantium block")] - [TestCase(3_660_662L, 0ul, "0x8d748b57", 3_660_663ul, "Last Byzantium block")] - [TestCase(3_660_663L, 0ul, "0xe49cab14", 4_321_234ul, "First Constantinople block")] - [TestCase(4_321_233L, 0ul, "0xe49cab14", 4_321_234ul, "Last Constantinople block")] - [TestCase(4_321_234L, 0ul, "0xafec6b27", 5_435_345ul, "First Petersburg block")] - [TestCase(5_435_344L, 0ul, "0xafec6b27", 5_435_345ul, "Last Petersburg block")] - [TestCase(5_435_345L, 0ul, "0xcbdb8838", 8_290_928ul, "First Istanbul block")] - [TestCase(8_290_928L, 0ul, "0x6910c8bd", 8_897_988ul, "First Berlin block")] - [TestCase(8_700_000L, 0ul, "0x6910c8bd", 8_897_988ul, "Future Berlin block")] - [TestCase(8_897_988L, 0ul, "0x8E29F2F3", 0ul, "First London block")] - [TestCase(9_000_000L, 0ul, "0x8E29F2F3", 0ul, "Future London block")] - public void Fork_id_and_hash_as_expected_on_rinkeby(long head, ulong headTimestamp, string forkHashHex, ulong next, string description) + [TestCase(0, 0ul, "0xc61a6098", 1_696_000_704ul, "Unsynced")] + [TestCase(1, 1_696_000_703ul, "0xc61a6098", 1_696_000_704ul, "Last genesis spec block")] + [TestCase(2, 1_696_000_704ul, "0xfd4f016b", 0ul, "First Shanghai block")] + public void Fork_id_and_hash_as_expected_on_holesky(long head, ulong headTimestamp, string forkHashHex, ulong next, string description) { - Test(head, headTimestamp, KnownHashes.RinkebyGenesis, forkHashHex, next, description, RinkebySpecProvider.Instance, "rinkeby.json"); + Test(head, headTimestamp, KnownHashes.HoleskyGenesis, forkHashHex, next, description, HoleskySpecProvider.Instance, "holesky.json"); } [TestCase(0, 0ul, "0xFE3366E7", 1735371ul, "Sepolia genesis")] diff --git a/src/Nethermind/Nethermind.Runner/configs/holesky.cfg b/src/Nethermind/Nethermind.Runner/configs/holesky.cfg index c6de49ac1bf..a66c834aeda 100644 --- a/src/Nethermind/Nethermind.Runner/configs/holesky.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/holesky.cfg @@ -1,7 +1,7 @@ { "Init": { "ChainSpecPath": "chainspec/holesky.json", - "GenesisHash": "0xff9006519a8ce843ac9c28549d24211420b546e12ce2d170c77a8cca7964f23d", + "GenesisHash": "0xb5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4", "BaseDbPath": "nethermind_db/holesky", "LogFileName": "holesky.logs.txt" }, diff --git a/src/Nethermind/Nethermind.Runner/configs/holesky_archive.cfg b/src/Nethermind/Nethermind.Runner/configs/holesky_archive.cfg index 5f3da6cd660..ebd9b36add2 100644 --- a/src/Nethermind/Nethermind.Runner/configs/holesky_archive.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/holesky_archive.cfg @@ -1,7 +1,7 @@ { "Init": { "ChainSpecPath": "chainspec/holesky.json", - "GenesisHash": "0xff9006519a8ce843ac9c28549d24211420b546e12ce2d170c77a8cca7964f23d", + "GenesisHash": "0xb5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4", "BaseDbPath": "nethermind_db/holesky_archive", "LogFileName": "holesky_archive.logs.txt" }, diff --git a/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs b/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs index 555fb8faa9b..b5180ea82c6 100644 --- a/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs +++ b/src/Nethermind/Nethermind.Specs.Test/ChainSpecStyle/ChainSpecBasedSpecProviderTests.cs @@ -166,8 +166,9 @@ public void Holesky_loads_properly() Assert.That(provider.ChainId, Is.EqualTo(BlockchainIds.Holesky)); Assert.That(provider.NetworkId, Is.EqualTo(BlockchainIds.Holesky)); - GetTransitionTimestamps(chainSpec.Parameters).Should().AllSatisfy( - t => ValidateSlotByTimestamp(t, HoleskySpecProvider.GenesisTimestamp).Should().BeTrue()); + // because genesis time for holesky is set 5 minutes before the launch of the chain. this test fails. + //GetTransitionTimestamps(chainSpec.Parameters).Should().AllSatisfy( + // t => ValidateSlotByTimestamp(t, HoleskySpecProvider.GenesisTimestamp).Should().BeTrue()); } [Test] diff --git a/src/Nethermind/Nethermind.Specs/HoleskySpecProvider.cs b/src/Nethermind/Nethermind.Specs/HoleskySpecProvider.cs index 8d6f75754db..006460e0490 100644 --- a/src/Nethermind/Nethermind.Specs/HoleskySpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/HoleskySpecProvider.cs @@ -10,8 +10,8 @@ namespace Nethermind.Specs; public class HoleskySpecProvider : ISpecProvider { - public const ulong GenesisTimestamp = 0x65046360; - public const ulong ShanghaiTimestamp = 0x6505e360; + public const ulong GenesisTimestamp = 0x65156994; + public const ulong ShanghaiTimestamp = 0x6516eac0; // public const ulong CancunTimestamp = 0x77359400; private HoleskySpecProvider() { } diff --git a/src/Nethermind/Nethermind.Specs/KnownHashes.cs b/src/Nethermind/Nethermind.Specs/KnownHashes.cs index 5e1623d0c4f..437fe89fdcc 100644 --- a/src/Nethermind/Nethermind.Specs/KnownHashes.cs +++ b/src/Nethermind/Nethermind.Specs/KnownHashes.cs @@ -13,5 +13,6 @@ public static class KnownHashes public static readonly Keccak SepoliaGenesis = new("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9"); public static readonly Keccak GnosisGenesis = new("0x4f1dd23188aab3a76b463e4af801b52b1248ef073c648cbdc4c9333d3da79756"); public static readonly Keccak ChiadoGenesis = new("0xada44fd8d2ecab8b08f256af07ad3e777f17fb434f8f8e678b312f576212ba9a"); + public static readonly Keccak HoleskyGenesis = new("0xb5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4"); } } From f02c69043f9bb74163a487e3b8406a814451cb2b Mon Sep 17 00:00:00 2001 From: Ruben Buniatyan Date: Thu, 28 Sep 2023 23:00:57 +0200 Subject: [PATCH 081/213] Fix PPA package post-install script (#5991) * Fix PPA post install script to download from the latest release branch * Remove redundant space * Update Nethermind executable name --- scripts/deployment/debian/postinst | 10 ++++++---- scripts/execution.sh | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/scripts/deployment/debian/postinst b/scripts/deployment/debian/postinst index 303c1b7d234..2a279274886 100644 --- a/scripts/deployment/debian/postinst +++ b/scripts/deployment/debian/postinst @@ -1,12 +1,14 @@ #!/bin/bash arch=$(uname -m) +json=$(curl -sSL https://api.github.com/repos/NethermindEth/nethermind/releases/latest) +tag_name=$(echo $json | jq -r '.tag_name') if [[ $arch == x86_64* ]]; then - curl -s https://api.github.com/repos/NethermindEth/nethermind/releases/latest | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux-x64 | xargs wget -O nethermind.zip -q + echo $json | jq -r '.assets[].browser_download_url | select(contains("linux-x64"))' | xargs -I % curl -sSL % -o nethermind.zip ln -s /usr/lib/x86_64-linux-gnu/libdl.so.2 /usr/lib/x86_64-linux-gnu/libdl.so > /dev/null 2>&1 -elif [[ $arch == arm* ]] || [[ $arch = aarch64 ]]; then - curl -s https://api.github.com/repos/NethermindEth/nethermind/releases/latest | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux-arm64 | xargs wget -O nethermind.zip -q +elif [[ $arch == arm* ]] || [[ $arch = aarch64 ]]; then + echo $json | jq -r '.assets[].browser_download_url | select(contains("linux-arm64"))' | xargs -I % curl -sSL % -o nethermind.zip ln -s /usr/lib/aarch64-linux-gnu/libdl.so.2 /usr/lib/aarch64-linux-gnu/libdl.so > /dev/null 2>&1 apt update > /dev/null 2>&1 && apt install libgflags-dev -y > /dev/null 2>&1 fi @@ -17,5 +19,5 @@ mkdir -p /usr/share/nethermind cp -r nethermind/* /usr/share/nethermind rm -rf nethermind -wget https://raw.githubusercontent.com/NethermindEth/nethermind/master/scripts/execution.sh -O /usr/bin/nethermind +curl -sSL https://raw.githubusercontent.com/NethermindEth/nethermind/release/$tag_name/scripts/execution.sh -o /usr/bin/nethermind chmod +x /usr/bin/nethermind diff --git a/scripts/execution.sh b/scripts/execution.sh index 6869c15af3c..ebb8c54f2fe 100644 --- a/scripts/execution.sh +++ b/scripts/execution.sh @@ -7,9 +7,9 @@ opts=$@ if [ ${#opts} -gt 0 ] then echo 'Executing Nethermind' - sudo /usr/share/nethermind/Nethermind.Runner $@ + sudo /usr/share/nethermind/nethermind $@ else - echo 'Executing Nethermind Launcher' + echo 'Executing Nethermind launcher' cd /usr/share/nethermind - sudo /usr/share/nethermind/Nethermind.Launcher + sudo /usr/share/nethermind/nethermind-launcher fi From 92c8f8172479e4fa237547aff1b57435c939de31 Mon Sep 17 00:00:00 2001 From: Ruben Buniatyan Date: Thu, 28 Sep 2023 23:01:08 +0200 Subject: [PATCH 082/213] Update executable and networks (#6141) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 80bf4b60c8e..03068c709ec 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Nethermind documentation is available at [docs.nethermind.io](https://docs.nethe ### Supported networks -**`Mainnet`** **`Goerli`** **`Sepolia`** **`Gnosis (xDai)`** **`Energy Web`** **`Volta`** +**`Mainnet`** **`Goerli`** **`Sepolia`** **`Holesky`** **`Gnosis (xDai)`** **`Chiado`** **`Energy Web`** **`Volta`** ## Download and run @@ -65,8 +65,8 @@ winget install Microsoft.VCRedist.2015+.x64 #### Install using Windows Package Manager 1. `winget install nethermind` -2. To run directly: `nethermind.runner.exe -c mainnet` \ - or with the assistant: `nethermind.launcher.exe` +2. To run directly: `nethermind.exe -c mainnet` \ + or with the assistant: `nethermind-launcher.exe` ### On macOS @@ -106,7 +106,7 @@ Install [.NET SDK](https://dotnet.microsoft.com/en-us/download) ### Clone the repository ```sh -git clone https://github.com/nethermindeth/nethermind --recursive +git clone --recursive https://github.com/nethermindeth/nethermind.git ``` ### Build and run From bb9b72c059ede128efde04a0f319f2e6f035a1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Chodo=C5=82a?= Date: Thu, 28 Sep 2023 23:04:09 +0200 Subject: [PATCH 083/213] Bump client version to 1.21.0 --- src/Nethermind/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Directory.Build.props b/src/Nethermind/Directory.Build.props index 95d50853899..eb51d4e9a9f 100644 --- a/src/Nethermind/Directory.Build.props +++ b/src/Nethermind/Directory.Build.props @@ -10,7 +10,7 @@ Nethermind $(Commit.Substring(0, 8)) 1.21.0 - rc + From 42b2e3ab778a4114c4f052e057559ca839c2a123 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 2 Oct 2023 12:18:51 +0100 Subject: [PATCH 084/213] Minor test fixes --- .../EthMulticallTestsPrecompilesWithRedirection.cs | 13 ++++++++----- .../Modules/Eth/EthRpcMulticallTestsBase.cs | 4 ++-- .../Multicall/EthMulticallTestsSimplePrecompiles.cs | 7 +++++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 516d53516a9..a4e2654014c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -89,8 +89,10 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( { Data = transactionData, To = contractAddress, - SenderAddress = TestItem.PublicKeyB.Address, - GasLimit = 50_000 + SenderAddress = TestItem.PublicKeyA.Address, + GasLimit = 50_000, + GasPrice = 20.GWei() + }; @@ -99,8 +101,8 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( BlockHeader header = chain.BlockFinder.Head.Header; IReleaseSpec spec = chain.SpecProvider.GetSpec(header); - systemTransactionForModifiedVM.GasPrice = header.BaseFeePerGas >= 1 ? header.BaseFeePerGas : 1; - systemTransactionForModifiedVM.GasLimit = (long)systemTransactionForModifiedVM.CalculateTransactionPotentialCost(spec.IsEip1559Enabled, header.BaseFeePerGas); + //systemTransactionForModifiedVM.GasPrice = header.BaseFeePerGas >= 1 ? header.BaseFeePerGas : 1; + //systemTransactionForModifiedVM.GasLimit = (long)systemTransactionForModifiedVM.CalculateTransactionPotentialCost(spec.IsEip1559Enabled, header.BaseFeePerGas); MultiCallPayload payload = new() { @@ -116,11 +118,12 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( }, Calls = new[] { + new TransactionForRpc(systemTransactionForModifiedVM), } }}, TraceTransfers = true, - Validation = true + Validation = false }; //Force persistancy of head block in main chain diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs index a0b4740f4f4..d8dc67df066 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs @@ -152,8 +152,8 @@ public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, stri await chain1.AddBlock(true, txs); - TxReceipt createContractTxReceipt = new(); - while (createContractTxReceipt.Equals(default(TxReceipt))) + TxReceipt? createContractTxReceipt = null; + while (createContractTxReceipt == null) { await Task.Delay(100); // wait... todo enforce! createContractTxReceipt = chain1.Bridge.GetReceipt(tx.Hash!); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 1705041b232..5239dd3b3aa 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -98,14 +98,17 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe } }, TraceTransfers = true, - Validation = true + Validation = false }; // Act MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head?.Header!, payload, CancellationToken.None); Log[]? logs = result.Items.First().Calls.First().Logs; - + byte[] addressBytes = result.Items.First().Calls.First().ReturnData! + .SliceWithZeroPaddingEmptyOnError(12, 20); + //Address resultingAddress = new(addressBytes); + //Assert.That(resultingAddress, Is.EqualTo(TestItem.AddressE)); //Check that initial VM is intact Address? mainChainRpcAddress = From b6c3b21fe510a4c1f058e4811946a7b73a77cb6a Mon Sep 17 00:00:00 2001 From: Lukasz Rozmej Date: Wed, 11 Oct 2023 10:38:54 +0200 Subject: [PATCH 085/213] Feature/eth multicall refactor (#6175) * refactor * refactoring * More refactoring and fixes * whitespace * fix tests * more fix * more improvements --- .../Ethereum.Test.Base/BlockchainTestBase.cs | 3 + .../Ethereum.Test.Base/GeneralTestBase.cs | 3 + .../StandardTests.cs | 1 + .../Extensions/IConsensusPlugin.cs | 4 +- src/Nethermind/Nethermind.Api/IBasicApi.cs | 4 +- .../Nethermind.Api/NethermindApi.cs | 39 +-- .../Producers/DevBlockproducerTests.cs | 3 + .../Nethermind.Blockchain.Test/ReorgTests.cs | 3 + .../CliqueBlockProducerTests.cs | 8 +- .../Nethermind.Clique.Test/StandardTests.cs | 1 + .../InitializationSteps/AuRaNethermindApi.cs | 7 +- ...sor.BlockValidationTransactionsExecutor.cs | 2 +- .../Processing/ProcessingOptions.cs | 2 +- .../Processing/ReadOnlyTxProcessingEnv.cs | 5 +- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 12 +- .../Validators/BlockValidator.cs | 2 +- .../MultiCallBlockValidatorProxy.cs | 51 ++-- .../Blockchain/TestBlockchain.cs | 5 +- .../Nethermind.Core/Extensions/Bytes.cs | 9 + .../Nethermind.Core/SealEngineType.cs | 12 +- .../Eip3198BaseFeeTests.cs | 2 +- .../Eip3529RefundsTests.cs | 2 +- .../Nethermind.Evm.Test/Eip3541Tests.cs | 2 +- .../Eip7516BlobBaseFeeTests.cs | 2 +- .../Tracing/GasEstimationTests.cs | 6 +- .../TransactionProcessorEip4844Tests.cs | 13 +- .../TransactionProcessorFeeTests.cs | 5 +- .../TransactionProcessorTests.cs | 5 +- .../VirtualMachineTestsBase.cs | 6 +- .../Nethermind.Evm/CodeInfoRepository.cs | 96 ++++++ ...rtualMachine.cs => ICodeInfoRepository.cs} | 8 +- .../Nethermind.Evm/IVirtualMachine.cs | 2 - .../Nethermind.Evm/MultiCallVirtualMachine.cs | 60 ---- .../MultiCallVirtualMachineImpl.cs | 37 --- .../Nethermind.Evm/Nethermind.Evm.csproj | 1 - .../Tracing/CallOutputTracer.cs | 2 +- .../Nethermind.Evm/Tracing/ITxTracer.cs | 21 +- .../TransactionProcessor.cs | 13 +- .../Nethermind.Evm/TxExecutionContext.cs | 2 +- .../Nethermind.Evm/VirtualMachine.cs | 171 +++-------- .../BlockchainBridgeTests.cs | 1 + .../Proxy/EthJsonRpcClientProxyTests.cs | 11 +- .../Nethermind.Facade/BlockchainBridge.cs | 17 +- .../Nethermind.Facade/CallOutput.cs | 3 +- .../Nethermind.Facade/IBlockchainBridge.cs | 1 + .../{ => Multicall}/MultiCallBlockTracer.cs | 27 +- .../{ => Multicall}/MultiCallOutput.cs | 2 +- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 67 ++--- .../{ => Multicall}/MultiCallTxTracer.cs | 35 ++- .../Multicall/MulticallBridgeHelper.cs | 275 +++++++++++++++++ .../MultycallBridgeHelper.cs | 280 ------------------ .../OverridableCodeInfoRepository.cs | 47 +++ .../Proxy/Models/MultiCall/AccountOverride.cs | 11 +- .../Proxy/Models/MultiCall/BlockOverride.cs | 15 +- .../Proxy/Models/MultiCall/BlockStateCall.cs | 3 +- .../Models/MultiCall/MultiCallBlockResult.cs | 11 +- .../Models/MultiCall/MultiCallCallResult.cs | 22 +- .../Models/MultiCall/MultiCallPayload.cs | 16 +- .../NodeHealthServiceTests.cs | 3 - .../Nethermind.Hive.Test/PluginTests.cs | 1 + .../Steps/InitializeBlockchain.cs | 4 + ...ulticallTestsPrecompilesWithRedirection.cs | 87 +++--- .../Modules/Eth/EthRpcMulticallTestsBase.cs | 60 ++-- .../EthMulticallTestsBlocksAndTransactions.cs | 10 +- .../EthMulticallTestsSimplePrecompiles.cs | 1 + .../Modules/TestRpcBlockchain.cs | 1 + .../Modules/Trace/ParityStyleTracerTests.cs | 5 +- .../Eth/EthRpcModule.TransactionExecutor.cs | 55 +--- .../Modules/Eth/EthRpcModule.cs | 6 +- .../Modules/Eth/ExecutorBase.cs | 9 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 15 +- .../AuRaMergeBlockProducerEnvFactory.cs | 4 - .../MergePluginTests.cs | 3 +- .../PluginTests.cs | 1 + .../Nethermind.Mev.Test/PluginTests.cs | 1 + .../Ethereum/ContextWithMocks.cs | 11 +- .../Nethermind.Runner.Test/StandardTests.cs | 1 + .../Ethereum/Api/ApiBuilder.cs | 6 +- .../ChainSpecStyle/ChainSpec.cs | 4 +- .../ChainSpecBasedSpecProvider.cs | 18 +- .../SyncThreadTests.cs | 9 +- .../TransactionExtensions.cs | 2 +- 82 files changed, 891 insertions(+), 902 deletions(-) create mode 100644 src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs rename src/Nethermind/Nethermind.Evm/{IMultiCallVirtualMachine.cs => ICodeInfoRepository.cs} (50%) delete mode 100644 src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs delete mode 100644 src/Nethermind/Nethermind.Evm/MultiCallVirtualMachineImpl.cs rename src/Nethermind/Nethermind.Facade/{ => Multicall}/MultiCallBlockTracer.cs (72%) rename src/Nethermind/Nethermind.Facade/{ => Multicall}/MultiCallOutput.cs (89%) rename src/Nethermind/{Nethermind.Consensus/Processing => Nethermind.Facade/Multicall}/MultiCallReadOnlyBlocksProcessingEnv.cs (58%) rename src/Nethermind/Nethermind.Facade/{ => Multicall}/MultiCallTxTracer.cs (50%) create mode 100644 src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs delete mode 100644 src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs create mode 100644 src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs diff --git a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs index 8e3e3a147db..41f38b2d9bc 100644 --- a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs @@ -141,9 +141,11 @@ protected async Task RunTest(BlockchainTest test, Stopwatch? IHeaderValidator headerValidator = new HeaderValidator(blockTree, Sealer, specProvider, _logManager); IUnclesValidator unclesValidator = new UnclesValidator(blockTree, headerValidator, _logManager); IBlockValidator blockValidator = new BlockValidator(txValidator, headerValidator, unclesValidator, specProvider, _logManager); + CodeInfoRepository codeInfoRepository = new(); IVirtualMachine virtualMachine = new VirtualMachine( blockhashProvider, specProvider, + codeInfoRepository, _logManager); IBlockProcessor blockProcessor = new BlockProcessor( @@ -155,6 +157,7 @@ protected async Task RunTest(BlockchainTest test, Stopwatch? specProvider, stateProvider, virtualMachine, + codeInfoRepository, _logManager), stateProvider), stateProvider, diff --git a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs index fad444b47ce..9b0d2dd4080 100644 --- a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs @@ -67,15 +67,18 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) TrieStore trieStore = new(stateDb, _logManager); WorldState stateProvider = new(trieStore, codeDb, _logManager); IBlockhashProvider blockhashProvider = new TestBlockhashProvider(); + CodeInfoRepository codeInfoRepository = new(); IVirtualMachine virtualMachine = new VirtualMachine( blockhashProvider, specProvider, + codeInfoRepository, _logManager); TransactionProcessor transactionProcessor = new( specProvider, stateProvider, virtualMachine, + codeInfoRepository, _logManager); InitializeTestState(test, stateProvider, specProvider); diff --git a/src/Nethermind/Nethermind.AccountAbstraction.Test/StandardTests.cs b/src/Nethermind/Nethermind.AccountAbstraction.Test/StandardTests.cs index c7078dd6283..97abeac35f9 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction.Test/StandardTests.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction.Test/StandardTests.cs @@ -8,6 +8,7 @@ namespace Nethermind.AccountAbstraction.Test { [TestFixture] [Parallelizable(ParallelScope.All)] + [SetCulture("en-US")] public class StandardTests { [Test] diff --git a/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs index abb29c5981d..3f0277f4de5 100644 --- a/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs +++ b/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs @@ -36,7 +36,7 @@ Task InitBlockProducer( /// IBlockProductionTrigger DefaultBlockProductionTrigger { get; } - INethermindApi CreateApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, - ILogManager logManager, ChainSpec chainSpec) => new NethermindApi(configProvider, jsonSerializer, logManager, chainSpec); + INethermindApi CreateApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec) => + new NethermindApi(configProvider, jsonSerializer, logManager, chainSpec); } } diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs index 9677d0a67b1..aea1608f6b5 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -39,8 +39,8 @@ public interface IBasicApi ILogManager LogManager { get; set; } ProtectedPrivateKey? OriginalSignerKey { get; set; } IReadOnlyList Plugins { get; } - string SealEngineType { get; set; } - ISpecProvider? SpecProvider { get; set; } + string SealEngineType => ChainSpec.SealEngineType; + ISpecProvider SpecProvider { get; } ISyncModeSelector? SyncModeSelector { get; set; } ISyncProgressResolver? SyncProgressResolver { get; set; } IBetterPeerStrategy? BetterPeerStrategy { get; set; } diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index da520128aec..89961ff9415 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -30,6 +30,7 @@ using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; using Nethermind.Facade.Eth; +using Nethermind.Facade.Multicall; using Nethermind.Grpc; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; @@ -60,9 +61,15 @@ namespace Nethermind.Api { public class NethermindApi : INethermindApi { - public NethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec) + public NethermindApi( + IConfigProvider configProvider, + IJsonSerializer jsonSerializer, + ILogManager logManager, + ChainSpec chainSpec, + ISpecProvider? specProvider = null) { ConfigProvider = configProvider; + SpecProvider = specProvider ?? new ChainSpecBasedSpecProvider(chainSpec, logManager); EthereumJsonSerializer = jsonSerializer; LogManager = logManager; ChainSpec = chainSpec; @@ -72,6 +79,8 @@ public NethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSeriali private IReadOnlyDbProvider? _readOnlyDbProvider; private IReadOnlyDbProvider? _multiCallReadOnlyDbProvider; + private ISealEngine? _sealEngine; + private IGasLimitCalculator? _gasLimitCalculator; public IBlockchainBridge CreateBlockchainBridge() { @@ -169,27 +178,18 @@ public IBlockchainBridge CreateBlockchainBridge() public IRpcAuthentication? RpcAuthentication { get; set; } public IJsonRpcLocalStats? JsonRpcLocalStats { get; set; } public ISealer? Sealer { get; set; } = NullSealEngine.Instance; - public string SealEngineType { get; set; } = Nethermind.Core.SealEngineType.None; public ISealValidator? SealValidator { get; set; } = NullSealEngine.Instance; - private ISealEngine? _sealEngine; + public ISealEngine SealEngine { - get - { - return _sealEngine ??= new SealEngine(Sealer, SealValidator); - } - - set - { - _sealEngine = value; - } + get => _sealEngine ??= new SealEngine(Sealer, SealValidator); + set => _sealEngine = value; } public ISessionMonitor? SessionMonitor { get; set; } - public ISpecProvider? SpecProvider { get; set; } + public ISpecProvider SpecProvider { get; set; } public IPoSSwitcher PoSSwitcher { get; set; } = NoPoS.Instance; public ISyncModeSelector? SyncModeSelector { get; set; } - public ISyncProgressResolver? SyncProgressResolver { get; set; } public IBetterPeerStrategy? BetterPeerStrategy { get; set; } public IBlockDownloaderFactory? BlockDownloaderFactory { get; set; } @@ -202,8 +202,8 @@ public ISealEngine SealEngine public IReadOnlyStateProvider? ChainHeadStateProvider { get; set; } public IStateReader? StateReader { get; set; } public IStaticNodesManager? StaticNodesManager { get; set; } - public ITimestamper Timestamper { get; } = Core.Timestamper.Default; - public ITimerFactory TimerFactory { get; } = Core.Timers.TimerFactory.Default; + public ITimestamper Timestamper => Core.Timestamper.Default; + public ITimerFactory TimerFactory => Core.Timers.TimerFactory.Default; public ITransactionProcessor? TransactionProcessor { get; set; } public ITrieStore? TrieStore { get; set; } public IReadOnlyTrieStore? ReadOnlyTrieStore { get; set; } @@ -215,7 +215,12 @@ public ISealEngine SealEngine public IRpcCapabilitiesProvider? RpcCapabilitiesProvider { get; set; } public TxValidator? TxValidator { get; set; } public IBlockFinalizationManager? FinalizationManager { get; set; } - public IGasLimitCalculator? GasLimitCalculator { get; set; } + + public IGasLimitCalculator? GasLimitCalculator + { + get => _gasLimitCalculator ??= new FollowOtherMiners(SpecProvider); + set => _gasLimitCalculator = value; + } public IBlockProducerEnvFactory? BlockProducerEnvFactory { get; set; } public IGasPriceOracle? GasPriceOracle { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs index d4167162e52..d13fb112928 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs @@ -58,14 +58,17 @@ public void Test() LimboLogs.Instance); StateReader stateReader = new(trieStore, dbProvider.GetDb(DbNames.State), LimboLogs.Instance); BlockhashProvider blockhashProvider = new(blockTree, LimboLogs.Instance); + CodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( blockhashProvider, specProvider, + codeInfoRepository, LimboLogs.Instance); TransactionProcessor txProcessor = new( specProvider, stateProvider, virtualMachine, + codeInfoRepository, LimboLogs.Instance); BlockProcessor blockProcessor = new( specProvider, diff --git a/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs index fc8005305ee..9a43113e38d 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs @@ -62,14 +62,17 @@ public void Setup() LimboLogs.Instance, transactionComparerProvider.GetDefaultComparer()); BlockhashProvider blockhashProvider = new(_blockTree, LimboLogs.Instance); + CodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( blockhashProvider, specProvider, + codeInfoRepository, LimboLogs.Instance); TransactionProcessor transactionProcessor = new( specProvider, stateProvider, virtualMachine, + codeInfoRepository, LimboLogs.Instance); BlockProcessor blockProcessor = new( diff --git a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs index b905d8e6a49..7eee27d8141 100644 --- a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs @@ -121,8 +121,10 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f _genesis.Header.Hash = _genesis.Header.CalculateHash(); _genesis3Validators.Header.Hash = _genesis3Validators.Header.CalculateHash(); + CodeInfoRepository codeInfoRepository = new(); TransactionProcessor transactionProcessor = new(goerliSpecProvider, stateProvider, - new VirtualMachine(blockhashProvider, specProvider, nodeLogManager), + new VirtualMachine(blockhashProvider, specProvider, codeInfoRepository, nodeLogManager), + codeInfoRepository, nodeLogManager); BlockProcessor blockProcessor = new( goerliSpecProvider, @@ -140,8 +142,8 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f IReadOnlyTrieStore minerTrieStore = trieStore.AsReadOnly(); WorldState minerStateProvider = new(minerTrieStore, codeDb, nodeLogManager); - VirtualMachine minerVirtualMachine = new(blockhashProvider, specProvider, nodeLogManager); - TransactionProcessor minerTransactionProcessor = new(goerliSpecProvider, minerStateProvider, minerVirtualMachine, nodeLogManager); + VirtualMachine minerVirtualMachine = new(blockhashProvider, specProvider, codeInfoRepository, nodeLogManager); + TransactionProcessor minerTransactionProcessor = new(goerliSpecProvider, minerStateProvider, minerVirtualMachine, codeInfoRepository, nodeLogManager); BlockProcessor minerBlockProcessor = new( goerliSpecProvider, diff --git a/src/Nethermind/Nethermind.Clique.Test/StandardTests.cs b/src/Nethermind/Nethermind.Clique.Test/StandardTests.cs index fb07a001abe..214480380d0 100644 --- a/src/Nethermind/Nethermind.Clique.Test/StandardTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/StandardTests.cs @@ -8,6 +8,7 @@ namespace Nethermind.Clique.Test { [TestFixture] [Parallelizable(ParallelScope.All)] + [SetCulture("en-US")] public class StandardTests { [Test] diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs index 52a9c1ecade..0d1b06ef1bf 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs @@ -8,6 +8,7 @@ using Nethermind.Consensus.AuRa.Validators; using Nethermind.Core.Caching; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Serialization.Json; @@ -17,7 +18,11 @@ namespace Nethermind.Consensus.AuRa.InitializationSteps { public class AuRaNethermindApi : NethermindApi { - public AuRaNethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec) + public AuRaNethermindApi( + IConfigProvider configProvider, + IJsonSerializer jsonSerializer, + ILogManager logManager, + ChainSpec chainSpec) : base(configProvider, jsonSerializer, logManager, chainSpec) { } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs index 116ba87a90c..6c6d480ff26 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs @@ -34,7 +34,7 @@ public BlockValidationTransactionsExecutor(ITransactionProcessorAdapter transact public TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processingOptions, BlockReceiptsTracer receiptsTracer, IReleaseSpec spec) { - Evm.Metrics.ResetBlockStats(); + Metrics.ResetBlockStats(); BlockExecutionContext blkCtx = new(block.Header); for (int i = 0; i < block.Transactions.Length; i++) { diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingOptions.cs b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingOptions.cs index 555e1c9e1dd..f1faafb7b06 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingOptions.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingOptions.cs @@ -66,7 +66,7 @@ public enum ProcessingOptions /// /// Processing options for engine_NewPayload /// - EthereumMerge = MarkAsProcessed | DoNotUpdateHead | IgnoreParentNotOnMainChain + EthereumMerge = MarkAsProcessed | DoNotUpdateHead | IgnoreParentNotOnMainChain, } public static class ProcessingOptionsExtensions diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index 19fc0653fca..6494e4a341d 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -37,8 +37,9 @@ public ReadOnlyTxProcessingEnv( ILogManager? logManager ) : base(readOnlyDbProvider, trieStore, blockTree, logManager) { - IVirtualMachine machine = new VirtualMachine(BlockhashProvider, specProvider, logManager); - TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, machine, logManager); + CodeInfoRepository codeInfoRepository = new(); + IVirtualMachine machine = new VirtualMachine(BlockhashProvider, specProvider, codeInfoRepository, logManager); + TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, machine, codeInfoRepository, logManager); } public IReadOnlyTransactionProcessor Build(Keccak stateRoot) => new ReadOnlyTransactionProcessor(TransactionProcessor, StateProvider, stateRoot); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index 01a77381c0d..7e4f1ad7f7b 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -19,20 +19,18 @@ public class ReadOnlyTxProcessingEnvBase public IReadOnlyDbProvider DbProvider { get; } public IBlockhashProvider BlockhashProvider { get; } - public ReadOnlyTxProcessingEnvBase( - IReadOnlyDbProvider? readOnlyDbProvider, + protected ReadOnlyTxProcessingEnvBase( + IReadOnlyDbProvider readOnlyDbProvider, ITrieStore? trieStore, - IBlockTree? blockTree, + IBlockTree blockTree, ILogManager? logManager ) { - DbProvider = readOnlyDbProvider ?? throw new ArgumentNullException(nameof(readOnlyDbProvider)); + DbProvider = readOnlyDbProvider; ReadOnlyDb codeDb = readOnlyDbProvider.CodeDb.AsReadOnly(true); - StateReader = new StateReader(trieStore, codeDb, logManager); StateProvider = new WorldState(trieStore, codeDb, logManager); - - BlockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); + BlockTree = blockTree; BlockhashProvider = new BlockhashProvider(BlockTree, logManager); } diff --git a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs index 8b23965899e..575393308d3 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs @@ -126,7 +126,7 @@ public bool ValidateSuggestedBlock(Block block) /// List of tx receipts from the processed block (required only for better diagnostics when the receipt root is invalid). /// Block received from the network - unchanged. /// true if the is valid; otherwise, false. - public virtual bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) + public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) { bool isValid = processedBlock.Header.Hash == suggestedBlock.Header.Hash; if (!isValid) diff --git a/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs b/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs index ba6ab6fc80e..5d8f60d6495 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs @@ -9,38 +9,23 @@ public class MultiCallBlockValidatorProxy : IBlockValidator { private readonly IBlockValidator _baseBlockValidator; - public MultiCallBlockValidatorProxy(IBlockValidator baseBlockValidator) - { + public MultiCallBlockValidatorProxy(IBlockValidator baseBlockValidator) => _baseBlockValidator = baseBlockValidator; - } - - public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle = false) - { - return _baseBlockValidator.Validate(header, parent, isUncle); - } - - public bool Validate(BlockHeader header, bool isUncle = false) - { - return _baseBlockValidator.Validate(header, isUncle); - } - - public bool ValidateWithdrawals(Block block, out string? error) - { - return _baseBlockValidator.ValidateWithdrawals(block, out error); - } - - public bool ValidateOrphanedBlock(Block block, out string? error) - { - return _baseBlockValidator.ValidateOrphanedBlock(block, out error); - } - - public bool ValidateSuggestedBlock(Block block) - { - return _baseBlockValidator.ValidateSuggestedBlock(block); - } - - public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) - { - return true; - } + + public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle = false) => + _baseBlockValidator.Validate(header, parent, isUncle); + + public bool Validate(BlockHeader header, bool isUncle = false) => + _baseBlockValidator.Validate(header, isUncle); + + public bool ValidateWithdrawals(Block block, out string? error) => + _baseBlockValidator.ValidateWithdrawals(block, out error); + + public bool ValidateOrphanedBlock(Block block, out string? error) => + _baseBlockValidator.ValidateOrphanedBlock(block, out error); + + public bool ValidateSuggestedBlock(Block block) => + _baseBlockValidator.ValidateSuggestedBlock(block); + + public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) => true; } diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index 4dc9df53cca..a8d73510ab1 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -161,8 +161,9 @@ protected virtual async Task Build(ISpecProvider? specProvider = _trieStoreWatcher = new TrieStoreBoundaryWatcher(TrieStore, BlockTree, LogManager); ReceiptStorage = new InMemoryReceiptStorage(); - VirtualMachine virtualMachine = new(new BlockhashProvider(BlockTree, LogManager), SpecProvider, LogManager); - TxProcessor = new TransactionProcessor(SpecProvider, State, virtualMachine, LogManager); + CodeInfoRepository codeInfoRepository = new(); + VirtualMachine virtualMachine = new(new BlockhashProvider(BlockTree, LogManager), SpecProvider, codeInfoRepository, LogManager); + TxProcessor = new TransactionProcessor(SpecProvider, State, virtualMachine, codeInfoRepository, LogManager); BlockPreprocessorStep = new RecoverSignatures(EthereumEcdsa, TxPool, SpecProvider, LogManager); HeaderValidator = new HeaderValidator(BlockTree, Always.Valid, SpecProvider, LogManager); diff --git a/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs b/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs index 7ae6370774f..b8f27d734df 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs @@ -224,6 +224,15 @@ public static Span WithoutLeadingZeros(this Span bytes) return nonZeroIndex < 0 ? bytes[^1..] : bytes[nonZeroIndex..]; } + public static ReadOnlySpan WithoutLeadingZeros(this ReadOnlySpan bytes) + { + if (bytes.Length == 0) return new byte[] { 0 }; + + int nonZeroIndex = bytes.IndexOfAnyExcept((byte)0); + // Keep one or it will be interpreted as null + return nonZeroIndex < 0 ? bytes[^1..] : bytes[nonZeroIndex..]; + } + public static byte[] Concat(byte prefix, byte[] bytes) { byte[] result = new byte[1 + bytes.Length]; diff --git a/src/Nethermind/Nethermind.Core/SealEngineType.cs b/src/Nethermind/Nethermind.Core/SealEngineType.cs index 709671f3b6a..e36051bb4ee 100644 --- a/src/Nethermind/Nethermind.Core/SealEngineType.cs +++ b/src/Nethermind/Nethermind.Core/SealEngineType.cs @@ -5,11 +5,11 @@ namespace Nethermind.Core { public static class SealEngineType { - public static readonly string None = nameof(None); - public static readonly string AuRa = nameof(AuRa); - public static readonly string Clique = nameof(Clique); - public static readonly string NethDev = nameof(NethDev); - public static readonly string Ethash = nameof(Ethash); - public static readonly string BeaconChain = nameof(BeaconChain); + public const string None = nameof(None); + public const string AuRa = nameof(AuRa); + public const string Clique = nameof(Clique); + public const string NethDev = nameof(NethDev); + public const string Ethash = nameof(Ethash); + public const string BeaconChain = nameof(BeaconChain); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs index 6b20654a11f..75430c258c1 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3198BaseFeeTests.cs @@ -26,7 +26,7 @@ public class Eip3198BaseFeeTests : VirtualMachineTestsBase [TestCase(false, 0, false)] public void Base_fee_opcode_should_return_expected_results(bool eip3198Enabled, int baseFee, bool send1559Tx) { - _processor = new TransactionProcessor(SpecProvider, TestState, Machine, LimboLogs.Instance); + _processor = new TransactionProcessor(SpecProvider, TestState, Machine, CodeInfoRepository, LimboLogs.Instance); byte[] code = Prepare.EvmCode .Op(Instruction.BASEFEE) .PushData(0) diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3529RefundsTests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3529RefundsTests.cs index fe3e7a58e32..81c276ef05d 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3529RefundsTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3529RefundsTests.cs @@ -73,7 +73,7 @@ private void Test(string codeHex, long gasUsed, long refund, byte originalValue, TestState.CreateAccount(Recipient, 1.Ether()); TestState.Set(new StorageCell(Recipient, 0), new[] { originalValue }); TestState.Commit(eip3529Enabled ? London.Instance : Berlin.Instance); - _processor = new TransactionProcessor(SpecProvider, TestState, Machine, LimboLogs.Instance); + _processor = new TransactionProcessor(SpecProvider, TestState, Machine, CodeInfoRepository, LimboLogs.Instance); long blockNumber = eip3529Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; (Block block, Transaction transaction) = PrepareTx(blockNumber, 100000, Bytes.FromHexString(codeHex)); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip3541Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip3541Tests.cs index 4154e94f095..0c5f2219dd3 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip3541Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip3541Tests.cs @@ -96,7 +96,7 @@ void DeployCodeAndAssertTx(string code, bool eip3541Enabled, ContractDeployment break; } - _processor = new TransactionProcessor(SpecProvider, TestState, Machine, LimboLogs.Instance); + _processor = new TransactionProcessor(SpecProvider, TestState, Machine, CodeInfoRepository, LimboLogs.Instance); long blockNumber = eip3541Enabled ? MainnetSpecProvider.LondonBlockNumber : MainnetSpecProvider.LondonBlockNumber - 1; (Block block, Transaction transaction) = PrepareTx(blockNumber, 100000, createContract); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7516BlobBaseFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7516BlobBaseFeeTests.cs index 1a1036de336..f62d8c595f6 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7516BlobBaseFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7516BlobBaseFeeTests.cs @@ -27,7 +27,7 @@ public class Eip7516BlobBaseFeeTests : VirtualMachineTestsBase [TestCase(false, 0ul)] public void Blob_Base_fee_opcode_should_return_expected_results(bool eip7516Enabled, ulong excessBlobGas) { - _processor = new TransactionProcessor(SpecProvider, TestState, Machine, LimboLogs.Instance); + _processor = new TransactionProcessor(SpecProvider, TestState, Machine, CodeInfoRepository, LimboLogs.Instance); byte[] code = Prepare.EvmCode .Op(Instruction.BLOBBASEFEE) .PushData(0) diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs index 28ef63cc595..dd0e6448235 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs @@ -268,9 +268,9 @@ public TestEnvironment() _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(0); - VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, LimboLogs.Instance); - _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, - virtualMachine, LimboLogs.Instance); + CodeInfoRepository codeInfoRepository = new(); + VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); tracer = new(); diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs index 278dde24f1f..b8c97441c90 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs @@ -23,10 +23,10 @@ namespace Nethermind.Evm.Test; [TestFixture] internal class TransactionProcessorEip4844Tests { - private ISpecProvider _specProvider; - private IEthereumEcdsa _ethereumEcdsa; - private TransactionProcessor _transactionProcessor; - private IWorldState _stateProvider; + private ISpecProvider _specProvider = null!; + private IEthereumEcdsa _ethereumEcdsa = null!; + private TransactionProcessor _transactionProcessor = null!; + private IWorldState _stateProvider = null!; [SetUp] public void Setup() @@ -35,8 +35,9 @@ public void Setup() _specProvider = new TestSpecProvider(Cancun.Instance); TrieStore trieStore = new(stateDb, LimboLogs.Instance); _stateProvider = new WorldState(trieStore, new MemDb(), LimboLogs.Instance); - VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, LimboLogs.Instance); - _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, LimboLogs.Instance); + CodeInfoRepository codeInfoRepository = new(); + VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); } diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs index d7f530768f3..3cf8e81c276 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -42,8 +42,9 @@ public void Setup() _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(0); - VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, LimboLogs.Instance); - _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, LimboLogs.Instance); + CodeInfoRepository codeInfoRepository = new(); + VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); } diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs index 13159d48f24..dce3f94ba7c 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs @@ -55,8 +55,9 @@ public void Setup() _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(0); - VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, LimboLogs.Instance); - _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, LimboLogs.Instance); + CodeInfoRepository codeInfoRepository = new(); + VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); } diff --git a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs index 0a902722594..f28a6d7f2e5 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs @@ -34,6 +34,7 @@ public class VirtualMachineTestsBase private IDb _stateDb; protected VirtualMachine Machine { get; private set; } + protected CodeInfoRepository CodeInfoRepository { get; private set; } protected IWorldState TestState { get; private set; } protected static Address Contract { get; } = new("0xd75a3a95360e44a3874e691fb48d77855f127069"); protected static Address Sender { get; } = TestItem.AddressA; @@ -66,8 +67,9 @@ public virtual void Setup() TestState = new WorldState(trieStore, codeDb, logManager); _ethereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId, logManager); IBlockhashProvider blockhashProvider = TestBlockhashProvider.Instance; - Machine = new VirtualMachine(blockhashProvider, SpecProvider, logManager); - _processor = new TransactionProcessor(SpecProvider, TestState, Machine, logManager); + CodeInfoRepository = new CodeInfoRepository(); + Machine = new VirtualMachine(blockhashProvider, SpecProvider, CodeInfoRepository, logManager); + _processor = new TransactionProcessor(SpecProvider, TestState, Machine, CodeInfoRepository, logManager); } protected GethLikeTxTrace ExecuteAndTrace(params byte[] code) diff --git a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs new file mode 100644 index 00000000000..ef62d9e45d0 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -0,0 +1,96 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using Nethermind.Core; +using Nethermind.Core.Caching; +using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Evm.Precompiles; +using Nethermind.Evm.Precompiles.Bls; +using Nethermind.Evm.Precompiles.Snarks; +using Nethermind.State; + +namespace Nethermind.Evm; + +public class CodeInfoRepository : ICodeInfoRepository +{ + private static readonly Dictionary? _precompiles; + private static readonly LruCache _codeCache = new(MemoryAllowance.CodeCacheSize, MemoryAllowance.CodeCacheSize, "VM bytecodes"); + + static CodeInfoRepository() + { + _precompiles = new Dictionary + { + [EcRecoverPrecompile.Address] = new(EcRecoverPrecompile.Instance), + [Sha256Precompile.Address] = new(Sha256Precompile.Instance), + [Ripemd160Precompile.Address] = new(Ripemd160Precompile.Instance), + [IdentityPrecompile.Address] = new(IdentityPrecompile.Instance), + [Bn254AddPrecompile.Address] = new(Bn254AddPrecompile.Instance), + [Bn254MulPrecompile.Address] = new(Bn254MulPrecompile.Instance), + [Bn254PairingPrecompile.Address] = new(Bn254PairingPrecompile.Instance), + [ModExpPrecompile.Address] = new(ModExpPrecompile.Instance), + [Blake2FPrecompile.Address] = new(Blake2FPrecompile.Instance), + [G1AddPrecompile.Address] = new(G1AddPrecompile.Instance), + [G1MulPrecompile.Address] = new(G1MulPrecompile.Instance), + [G1MultiExpPrecompile.Address] = new(G1MultiExpPrecompile.Instance), + [G2AddPrecompile.Address] = new(G2AddPrecompile.Instance), + [G2MulPrecompile.Address] = new(G2MulPrecompile.Instance), + [G2MultiExpPrecompile.Address] = new(G2MultiExpPrecompile.Instance), + [PairingPrecompile.Address] = new(PairingPrecompile.Instance), + [MapToG1Precompile.Address] = new(MapToG1Precompile.Instance), + [MapToG2Precompile.Address] = new(MapToG2Precompile.Instance), + [PointEvaluationPrecompile.Address] = new(PointEvaluationPrecompile.Instance), + }; + } + + public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) + { + if (codeSource.IsPrecompile(vmSpec)) + { + if (_precompiles is null) + { + throw new InvalidOperationException("EVM precompile have not been initialized properly."); + } + + return _precompiles[codeSource]; + } + + Keccak codeHash = worldState.GetCodeHash(codeSource); + CodeInfo cachedCodeInfo = _codeCache.Get(codeHash); + if (cachedCodeInfo is null) + { + byte[] code = worldState.GetCode(codeHash); + + if (code is null) + { + throw new NullReferenceException($"Code {codeHash} missing in the state for address {codeSource}"); + } + + cachedCodeInfo = new CodeInfo(code); + _codeCache.Set(codeHash, cachedCodeInfo); + } + else + { + // need to touch code so that any collectors that track database access are informed + worldState.TouchCode(codeHash); + } + + return cachedCodeInfo; + } + + public CodeInfo GetOrAdd(ValueKeccak codeHash, Span initCode) + { + if (!_codeCache.TryGet(codeHash, out CodeInfo codeInfo)) + { + codeInfo = new(initCode.ToArray()); + + // Prime the code cache as likely to be used by more txs + _codeCache.Set(codeHash, codeInfo); + } + + return codeInfo; + } +} diff --git a/src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs b/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs similarity index 50% rename from src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs rename to src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs index b9d89ed0981..89bcfc43737 100644 --- a/src/Nethermind/Nethermind.Evm/IMultiCallVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs @@ -1,15 +1,17 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Nethermind.Core; +using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Evm.CodeAnalysis; using Nethermind.State; namespace Nethermind.Evm; -public interface IMultiCallVirtualMachine : IVirtualMachine +public interface ICodeInfoRepository { - public void SetCodeOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, - Address? redirectAddress = null); + CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec); + CodeInfo GetOrAdd(ValueKeccak codeHash, Span initCode); } diff --git a/src/Nethermind/Nethermind.Evm/IVirtualMachine.cs b/src/Nethermind/Nethermind.Evm/IVirtualMachine.cs index 2a8188828b3..2bc92d27de1 100644 --- a/src/Nethermind/Nethermind.Evm/IVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/IVirtualMachine.cs @@ -15,7 +15,5 @@ public interface IVirtualMachine { TransactionSubstate Run(EvmState state, IWorldState worldState, ITxTracer txTracer) where TTracingActions : struct, IIsTracing; - - CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec spec); } } diff --git a/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs b/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs deleted file mode 100644 index e801c05acdb..00000000000 --- a/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachine.cs +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System.Collections.Generic; -using Nethermind.Core; -using Nethermind.Core.Specs; -using Nethermind.Evm.CodeAnalysis; -using Nethermind.Logging; -using Nethermind.State; - -namespace Nethermind.Evm; - -public struct MultiCallDoNotTraceTransfers { } -public struct MultiCallDoTraceTransfers { } - -public class MultiCallVirtualMachine : VirtualMachine, IMultiCallVirtualMachine - -{ - private readonly Dictionary _codeOverwrites = new(); - - public MultiCallVirtualMachine(IBlockhashProvider? blockhashProvider, - ISpecProvider? specProvider, ILogManager? logManager) : - base(blockhashProvider, specProvider, logManager) - { - } - - protected override IVirtualMachine CreateVirtualMachine(IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, - ILogger? logger) - { - bool traceTransfers = typeof(TTraceTransfers) == typeof(MultiCallDoTraceTransfers); - - - IVirtualMachine result; - if (!logger.IsTrace) - { - result = new MultiCallVirtualMachineImpl(traceTransfers, blockhashProvider, specProvider, logger); - } - else - { - result = new MultiCallVirtualMachineImpl(traceTransfers, blockhashProvider, specProvider, logger); - } - - return result; - } - - public void SetCodeOverwrite(IWorldState worldState, IReleaseSpec vmSpec, Address key, CodeInfo value, - Address? redirectAddress = null) - { - if (redirectAddress != null) _codeOverwrites[redirectAddress] = base.GetCachedCodeInfo(worldState, key, vmSpec); - _codeOverwrites[key] = value; - } - - public override CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) - { - return _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) - ? result - : base.GetCachedCodeInfo(worldState, codeSource, vmSpec); - } - -} diff --git a/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachineImpl.cs b/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachineImpl.cs deleted file mode 100644 index 07d4896dcb1..00000000000 --- a/src/Nethermind/Nethermind.Evm/MultiCallVirtualMachineImpl.cs +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Abi; -using Nethermind.Core; -using Nethermind.Core.Crypto; -using Nethermind.Core.Specs; -using Nethermind.Logging; - -namespace Nethermind.Evm; - -internal class MultiCallVirtualMachineImpl : VirtualMachine - where TLogger : struct, VirtualMachine.IIsTracing -{ - private readonly bool _traceTransfers; - - public MultiCallVirtualMachineImpl(bool traceTransfers, IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, ILogger? logger) : base(blockhashProvider, specProvider, logger) - { - _traceTransfers = traceTransfers; - } - - protected override void TraceAction(EvmState currentState) - { - if (_traceTransfers) - { - //Log action - byte[]? data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, - new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256), currentState.From, - currentState.To, currentState.Env.Value); - LogEntry? result = new(Address.Zero, data, new[] { Keccak.Zero }); - currentState.Logs.Add(result); - } - - //Do default stuff - base.TraceAction(currentState); - } -} diff --git a/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj b/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj index 5666d09c57a..bf4f06ca167 100644 --- a/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj +++ b/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj @@ -8,7 +8,6 @@ - diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs index 96b28eaffd0..cfe02bd8ada 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs @@ -9,7 +9,7 @@ namespace Nethermind.Evm.Tracing public class CallOutputTracer : TxTracer { public override bool IsTracingReceipt => true; - public byte[]? ReturnValue { get; set; } + public byte[] ReturnValue { get; set; } = null!; public long GasSpent { get; set; } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index 9de921c9797..7f50aceebde 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -334,7 +334,7 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// /// /// Depends on - void ReportAction(long gas, UInt256 value, Address @from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); + void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); /// /// @@ -420,3 +420,22 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// Depends on void ReportFees(UInt256 fees, UInt256 burntFees); } + +public interface ILogsTxTracer +{ + bool IsTracingLogs { get; } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Created logs to be added, only when is true + /// Depends on + IEnumerable ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); +} diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 5ee2d4f5181..c83b848467a 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -29,6 +29,7 @@ public class TransactionProcessor : ITransactionProcessor private readonly ISpecProvider _specProvider; private readonly IWorldState _worldState; private readonly IVirtualMachine _virtualMachine; + private readonly ICodeInfoRepository _codeInfoRepository; [Flags] protected enum ExecutionOptions @@ -63,12 +64,14 @@ public TransactionProcessor( ISpecProvider? specProvider, IWorldState? worldState, IVirtualMachine? virtualMachine, + ICodeInfoRepository? codeInfoRepository, ILogManager? logManager) { _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _worldState = worldState ?? throw new ArgumentNullException(nameof(worldState)); _virtualMachine = virtualMachine ?? throw new ArgumentNullException(nameof(virtualMachine)); + _codeInfoRepository = codeInfoRepository ?? throw new ArgumentNullException(nameof(codeInfoRepository)); _ecdsa = new EthereumEcdsa(specProvider.ChainId, logManager); } @@ -436,15 +439,15 @@ protected virtual ExecutionEnvironment BuildExecutionEnvironmnet( Transaction tx, BlockExecutionContext blCtx, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts, in UInt256 effectiveGasPrice) { - Address recipient = tx.GetRecipient(tx.IsContractCreation ? _worldState.GetNonce(tx.SenderAddress) : 0) ?? + Address recipient = tx.GetRecipient(tx.IsContractCreation ? _worldState.GetNonce(tx.SenderAddress!) : 0) ?? // this transaction is not a contract creation so it should have the recipient known and not null throw new InvalidDataException("Recipient has not been resolved properly before tx execution"); TxExecutionContext executionContext = - new(blCtx, tx.SenderAddress, effectiveGasPrice, tx.BlobVersionedHashes); + new(blCtx, tx.SenderAddress!, effectiveGasPrice, tx.BlobVersionedHashes); - CodeInfo codeInfo = tx.IsContractCreation ? new(tx.Data.AsArray()) - : _virtualMachine.GetCachedCodeInfo(_worldState, recipient, spec); + CodeInfo codeInfo = tx.IsContractCreation ? new(tx.Data.AsArray()!) + : _codeInfoRepository.GetCachedCodeInfo(_worldState, recipient, spec); byte[] inputData = tx.IsMessageCall ? tx.Data.AsArray() ?? Array.Empty() : Array.Empty(); @@ -615,7 +618,7 @@ private void PrepareAccountForContractDeployment(Address contractAddress, IRelea { if (_worldState.AccountExists(contractAddress)) { - CodeInfo codeInfo = _virtualMachine.GetCachedCodeInfo(_worldState, contractAddress, spec); + CodeInfo codeInfo = _codeInfoRepository.GetCachedCodeInfo(_worldState, contractAddress, spec); bool codeIsNotEmpty = codeInfo.MachineCode.Length != 0; bool accountNonceIsNotZero = _worldState.GetNonce(contractAddress) != 0; diff --git a/src/Nethermind/Nethermind.Evm/TxExecutionContext.cs b/src/Nethermind/Nethermind.Evm/TxExecutionContext.cs index 2e00bddb906..4178b700f07 100644 --- a/src/Nethermind/Nethermind.Evm/TxExecutionContext.cs +++ b/src/Nethermind/Nethermind.Evm/TxExecutionContext.cs @@ -13,7 +13,7 @@ public readonly struct TxExecutionContext public UInt256 GasPrice { get; } public byte[][]? BlobVersionedHashes { get; } - public TxExecutionContext(BlockExecutionContext blockExecutionContext, Address origin, in UInt256 gasPrice, byte[][] blobVersionedHashes) + public TxExecutionContext(BlockExecutionContext blockExecutionContext, Address origin, in UInt256 gasPrice, byte[][]? blobVersionedHashes) { BlockExecutionContext = blockExecutionContext; Origin = origin; diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index c87e0156522..867469f206e 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -20,6 +20,7 @@ using System.Diagnostics.CodeAnalysis; using System.Diagnostics; using System.Runtime.Intrinsics; +using Nethermind.Core.Collections; using static Nethermind.Evm.VirtualMachine; using static System.Runtime.CompilerServices.Unsafe; @@ -33,42 +34,25 @@ namespace Nethermind.Evm; using System.Linq; using Int256; -using Microsoft.Extensions.Logging; public class VirtualMachine : IVirtualMachine { public const int MaxCallDepth = 1024; - protected readonly IVirtualMachine _evm; + private readonly IVirtualMachine _evm; public VirtualMachine( IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, + ICodeInfoRepository codeInfoRepository, ILogManager? logManager) { - var logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - _evm = CreateVirtualMachine(blockhashProvider, specProvider, logger); + ILogger logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); + _evm = logger.IsTrace + ? new VirtualMachine(blockhashProvider, specProvider, codeInfoRepository, logger) + : new VirtualMachine(blockhashProvider, specProvider, codeInfoRepository, logger); } - protected virtual IVirtualMachine CreateVirtualMachine(IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, Logging.ILogger? logger) - { - IVirtualMachine result; - if (!logger.IsTrace) - { - result = new VirtualMachine(blockhashProvider, specProvider, logger); - } - else - { - result = new VirtualMachine(blockhashProvider, specProvider, logger); - } - - return result; - } - - - public virtual CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec spec) - => _evm.GetCachedCodeInfo(worldState, codeSource, spec); - public TransactionSubstate Run(EvmState state, IWorldState worldState, ITxTracer txTracer) where TTracingActions : struct, IIsTracing => _evm.Run(state, worldState, txTracer); @@ -136,7 +120,7 @@ public interface IIsTracing { } public readonly struct IsTracing : IIsTracing { } } -internal class VirtualMachine : IVirtualMachine +internal sealed class VirtualMachine : IVirtualMachine where TLogger : struct, IIsTracing { private UInt256 P255Int = (UInt256)System.Numerics.BigInteger.Pow(2, 255); @@ -166,26 +150,25 @@ internal class VirtualMachine : IVirtualMachine private readonly IBlockhashProvider _blockhashProvider; private readonly ISpecProvider _specProvider; - private static readonly LruCache _codeCache = new(MemoryAllowance.CodeCacheSize, MemoryAllowance.CodeCacheSize, "VM bytecodes"); - private readonly Logging.ILogger _logger; - private IWorldState _worldState; - private IWorldState _state; + private readonly ILogger _logger; + private IWorldState _state = null!; private readonly Stack _stateStack = new(); private (Address Address, bool ShouldDelete) _parityTouchBugAccount = (Address.FromNumber(3), false); - private Dictionary? _precompiles; private byte[] _returnDataBuffer = Array.Empty(); private ITxTracer _txTracer = NullTxTracer.Instance; + private readonly ICodeInfoRepository _codeInfoRepository; public VirtualMachine( IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, - Logging.ILogger? logger) + ICodeInfoRepository codeInfoRepository, + ILogger? logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _blockhashProvider = blockhashProvider ?? throw new ArgumentNullException(nameof(blockhashProvider)); _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); + _codeInfoRepository = codeInfoRepository ?? throw new ArgumentNullException(nameof(codeInfoRepository)); _chainId = ((UInt256)specProvider.ChainId).ToBigEndian(); - InitializePrecompiledContracts(); } public TransactionSubstate Run(EvmState state, IWorldState worldState, ITxTracer txTracer) @@ -193,7 +176,6 @@ public TransactionSubstate Run(EvmState state, IWorldState worl { _txTracer = txTracer; _state = worldState; - _worldState = worldState; IReleaseSpec spec = _specProvider.GetSpec(state.Env.TxExecutionContext.BlockExecutionContext.Header.Number, state.Env.TxExecutionContext.BlockExecutionContext.Header.Timestamp); EvmState currentState = state; @@ -238,17 +220,12 @@ public TransactionSubstate Run(EvmState state, IWorldState worl { if (typeof(TTracingActions) == typeof(IsTracing) && !currentState.IsContinuation) { - TraceAction(currentState); + TraceAction(currentState); } - if (!_txTracer.IsTracingInstructions) - { - callResult = ExecuteCall(currentState, previousCallResult, previousCallOutput, previousCallOutputDestination, spec); - } - else - { - callResult = ExecuteCall(currentState, previousCallResult, previousCallOutput, previousCallOutputDestination, spec); - } + callResult = !_txTracer.IsTracingInstructions + ? ExecuteCall(currentState, previousCallResult, previousCallOutput, previousCallOutputDestination, spec) + : ExecuteCall(currentState, previousCallResult, previousCallOutput, previousCallOutputDestination, spec); if (!callResult.IsReturn) { @@ -263,7 +240,7 @@ public TransactionSubstate Run(EvmState state, IWorldState worl if (callResult.IsException) { if (typeof(TTracingActions) == typeof(IsTracing)) _txTracer.ReportActionError(callResult.ExceptionType); - _worldState.Restore(currentState.Snapshot); + _state.Restore(currentState.Snapshot); RevertParityTouchBugAccount(spec); @@ -442,7 +419,7 @@ public TransactionSubstate Run(EvmState state, IWorldState worl { if (typeof(TLogger) == typeof(IsTracing)) _logger.Trace($"exception ({ex.GetType().Name}) in {currentState.ExecutionType} at depth {currentState.Env.CallDepth} - restoring snapshot"); - _worldState.Restore(currentState.Snapshot); + _state.Restore(currentState.Snapshot); RevertParityTouchBugAccount(spec); @@ -475,11 +452,23 @@ public TransactionSubstate Run(EvmState state, IWorldState worl } } - protected virtual void TraceAction(EvmState currentState) where TTracingActions : struct, IIsTracing + private void TraceAction(EvmState currentState) { - _txTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, - currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, - currentState.ExecutionType); + if (_txTracer is ILogsTxTracer { IsTracingLogs: true } logsTxTracer) + { + IEnumerable logs = logsTxTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, + currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, + currentState.ExecutionType); + + currentState.Logs.AddRange(logs); + } + else + { + _txTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, + currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, + currentState.ExecutionType); + } + if (_txTracer.IsTracingCode) _txTracer.ReportByteCode(currentState.Env.CodeInfo.MachineCode); } @@ -496,71 +485,6 @@ private void RevertParityTouchBugAccount(IReleaseSpec spec) } } - public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) - { - if (codeSource.IsPrecompile(vmSpec)) - { - if (_precompiles is null) - { - throw new InvalidOperationException("EVM precompile have not been initialized properly."); - } - - return _precompiles[codeSource]; - } - - Keccak codeHash = worldState.GetCodeHash(codeSource); - CodeInfo cachedCodeInfo = _codeCache.Get(codeHash); - if (cachedCodeInfo is null) - { - byte[] code = worldState.GetCode(codeHash); - - if (code is null) - { - throw new NullReferenceException($"Code {codeHash} missing in the state for address {codeSource}"); - } - - cachedCodeInfo = new CodeInfo(code); - _codeCache.Set(codeHash, cachedCodeInfo); - } - else - { - // need to touch code so that any collectors that track database access are informed - worldState.TouchCode(codeHash); - } - - return cachedCodeInfo; - } - - private void InitializePrecompiledContracts() - { - _precompiles = new Dictionary - { - [EcRecoverPrecompile.Address] = new(EcRecoverPrecompile.Instance), - [Sha256Precompile.Address] = new(Sha256Precompile.Instance), - [Ripemd160Precompile.Address] = new(Ripemd160Precompile.Instance), - [IdentityPrecompile.Address] = new(IdentityPrecompile.Instance), - - [Bn254AddPrecompile.Address] = new(Bn254AddPrecompile.Instance), - [Bn254MulPrecompile.Address] = new(Bn254MulPrecompile.Instance), - [Bn254PairingPrecompile.Address] = new(Bn254PairingPrecompile.Instance), - [ModExpPrecompile.Address] = new(ModExpPrecompile.Instance), - - [Blake2FPrecompile.Address] = new(Blake2FPrecompile.Instance), - - [G1AddPrecompile.Address] = new(G1AddPrecompile.Instance), - [G1MulPrecompile.Address] = new(G1MulPrecompile.Instance), - [G1MultiExpPrecompile.Address] = new(G1MultiExpPrecompile.Instance), - [G2AddPrecompile.Address] = new(G2AddPrecompile.Instance), - [G2MulPrecompile.Address] = new(G2MulPrecompile.Instance), - [G2MultiExpPrecompile.Address] = new(G2MultiExpPrecompile.Instance), - [PairingPrecompile.Address] = new(PairingPrecompile.Instance), - [MapToG1Precompile.Address] = new(MapToG1Precompile.Instance), - [MapToG2Precompile.Address] = new(MapToG2Precompile.Instance), - - [PointEvaluationPrecompile.Address] = new(PointEvaluationPrecompile.Instance), - }; - } - private static bool UpdateGas(long gasCost, ref long gasAvailable) { if (gasAvailable < gasCost) @@ -647,7 +571,7 @@ private CallResult ExecutePrecompile(EvmState state, IReleaseSpec spec) UInt256 transferValue = state.Env.TransferValue; long gasAvailable = state.GasAvailable; - IPrecompile precompile = state.Env.CodeInfo.Precompile; + IPrecompile precompile = state.Env.CodeInfo.Precompile!; long baseGasCost = precompile.BaseGasCost(spec); long blobGasCost = precompile.DataGasCost(callData, spec); @@ -1398,7 +1322,7 @@ private CallResult ExecuteCode(Address address, ref EvmStack stack, IReleaseSpec spec) where TTracingInstructions : struct, IIsTracing { - byte[] accountCode = GetCachedCodeInfo(_worldState, address, spec).MachineCode; + byte[] accountCode = _codeInfoRepository.GetCachedCodeInfo(_state, address, spec).MachineCode; UInt256 result = (UInt256)accountCode.Length; stack.PushUInt256(in result); } @@ -2283,7 +2207,7 @@ private EvmExceptionType InstructionCall( ReadOnlyMemory callData = vmState.Memory.Load(in dataOffset, dataLength); - Snapshot snapshot = _worldState.TakeSnapshot(); + Snapshot snapshot = _state.TakeSnapshot(); _state.SubtractFromBalance(caller, transferValue, spec); ExecutionEnvironment callEnv = new @@ -2296,7 +2220,7 @@ private EvmExceptionType InstructionCall( transferValue: transferValue, value: callValue, inputData: callData, - codeInfo: GetCachedCodeInfo(_worldState, codeSource, spec) + codeInfo: _codeInfoRepository.GetCachedCodeInfo(_state, codeSource, spec) ); if (typeof(TLogger) == typeof(IsTracing)) _logger.Trace($"Tx call gas {gasLimitUl}"); if (outputLength == 0) @@ -2484,10 +2408,10 @@ private bool InstructionSelfDestruct(EvmState vmState, ref EvmStack(EvmState vmState, ref EvmStack(nameof(_proxy.eth_call), public async Task eth_multicall_should_invoke_client_method_even_empty() { MultiCallPayload payload = new(); - var blockParameter = BlockParameterModel.Latest; + BlockParameterModel blockParameter = BlockParameterModel.Latest; await _proxy.eth_multicallV1(payload, blockParameter); - - var calls = _client.ReceivedCalls().ToList(); await _client.Received().SendAsync>(nameof(_proxy.eth_multicallV1), payload, blockParameter.Type); } @@ -107,15 +105,12 @@ public async Task eth_multicallV1_should_invoke_client_method() { MultiCallPayload payload = new() { - BlockStateCalls = new BlockStateCall[] { }, + BlockStateCalls = Array.Empty>(), TraceTransfers = true }; - var blockParameter = BlockParameterModel.Latest; - + BlockParameterModel blockParameter = BlockParameterModel.Latest; await _proxy.eth_multicallV1(payload, blockParameter); - - var calls = _client.ReceivedCalls().ToList(); await _client.Received().SendAsync>(nameof(_proxy.eth_multicallV1), payload, blockParameter.Type); } diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 1ec5d2e718d..f5b9f814aa1 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -28,6 +28,7 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using System.Transactions; using Microsoft.CSharp.RuntimeBinder; +using Nethermind.Facade.Multicall; using Transaction = Nethermind.Core.Transaction; using Nethermind.Specs; @@ -51,7 +52,7 @@ public class BlockchainBridge : IBlockchainBridge private readonly ILogFinder _logFinder; private readonly ISpecProvider _specProvider; private readonly IBlocksConfig _blocksConfig; - private readonly MultycallBridgeHelper _multicallBridgeHelper; + private readonly MulticallBridgeHelper _multicallBridgeHelper; public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv, @@ -77,7 +78,10 @@ public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _blocksConfig = blocksConfig; IsMining = isMining; - _multicallBridgeHelper = new MultycallBridgeHelper(multiCallProcessingEnv ?? throw new ArgumentNullException(nameof(multiCallProcessingEnv)), _specProvider, _blocksConfig); + _multicallBridgeHelper = new MulticallBridgeHelper( + multiCallProcessingEnv ?? throw new ArgumentNullException(nameof(multiCallProcessingEnv)), + _specProvider, + _blocksConfig); } public Block? HeadBlock @@ -150,16 +154,15 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken) { - MultiCallBlockTracer multiCallOutputTracer = new(); + MultiCallBlockTracer multiCallOutputTracer = new(payload.TraceTransfers); MultiCallOutput result = new(); try { - (bool Success, string Error) tryMultiCallResult = _multicallBridgeHelper.TryMultiCallTrace(header, payload, - multiCallOutputTracer.WithCancellation(cancellationToken)); + (bool success, string error) = _multicallBridgeHelper.TryMultiCallTrace(header, payload, multiCallOutputTracer.WithCancellation(cancellationToken)); - if (!tryMultiCallResult.Success) + if (!success) { - result.Error = tryMultiCallResult.Error; + result.Error = error; } } catch (Exception ex) diff --git a/src/Nethermind/Nethermind.Facade/CallOutput.cs b/src/Nethermind/Nethermind.Facade/CallOutput.cs index a9bba48ef75..42034a699a0 100644 --- a/src/Nethermind/Nethermind.Facade/CallOutput.cs +++ b/src/Nethermind/Nethermind.Facade/CallOutput.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Nethermind.Core.Eip2930; namespace Nethermind.Facade; @@ -9,7 +10,7 @@ public class CallOutput { public string? Error { get; set; } - public byte[] OutputData { get; set; } + public byte[] OutputData { get; set; } = Array.Empty(); public long GasSpent { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index 1e095258bd3..06123beecae 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -9,6 +9,7 @@ using Nethermind.Core.Crypto; using Nethermind.Evm; using Nethermind.Facade.Filters; +using Nethermind.Facade.Multicall; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; using Nethermind.Trie; diff --git a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs similarity index 72% rename from src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs rename to src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs index cdc4be6d4ee..512df007d38 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs @@ -7,18 +7,23 @@ using Nethermind.Core.Collections; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.MultiCall; -using Nethermind.Int256; using ResultType = Nethermind.Facade.Proxy.Models.MultiCall.ResultType; -namespace Nethermind.Facade; +namespace Nethermind.Facade.Multicall; public class MultiCallBlockTracer : BlockTracer { + private readonly bool _isTracingLogs; public List Results { get; } = new(); private readonly List _txTracers = new(); - private Block _currentBlock; + private Block _currentBlock = null!; + + public MultiCallBlockTracer(bool isTracingLogs) + { + _isTracingLogs = isTracingLogs; + } public override void StartNewBlockTrace(Block block) { @@ -28,9 +33,9 @@ public override void StartNewBlockTrace(Block block) public override ITxTracer StartNewTxTrace(Transaction? tx) { - if (tx != null && tx.Hash != null) + if (tx?.Hash is not null) { - MultiCallTxTracer result = new(); + MultiCallTxTracer result = new(_isTracingLogs); _txTracers.Add(result); return result; } @@ -42,24 +47,24 @@ public override void EndBlockTrace() { MultiCallBlockResult? result = new() { - Calls = _txTracers.Select(t => t.TraceResult).ToArray(), + Calls = _txTracers.Select(t => t.TraceResult), Number = (ulong)_currentBlock.Number, - Hash = _currentBlock.Hash, + Hash = _currentBlock.Hash!, GasLimit = (ulong)_currentBlock.GasLimit, GasUsed = (ulong)_currentBlock.GasUsed, Timestamp = _currentBlock.Timestamp, - FeeRecipient = _currentBlock.Beneficiary, + FeeRecipient = _currentBlock.Beneficiary!, BaseFeePerGas = _currentBlock.BaseFeePerGas, - PrevRandao = new UInt256(_currentBlock.Header.Random.Bytes) + PrevRandao = _currentBlock.Header!.Random, }; result.Calls.ForEach(callResult => { if (callResult.Type == ResultType.Success) { - callResult.Logs.ForEach(log => + callResult.Logs?.ForEach(log => { - log.BlockHash = _currentBlock.Hash; + log.BlockHash = _currentBlock.Hash!; log.BlockNumber = (ulong)_currentBlock.Number; }); } diff --git a/src/Nethermind/Nethermind.Facade/MultiCallOutput.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallOutput.cs similarity index 89% rename from src/Nethermind/Nethermind.Facade/MultiCallOutput.cs rename to src/Nethermind/Nethermind.Facade/Multicall/MultiCallOutput.cs index fb24e9e7c89..abc15424e76 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallOutput.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallOutput.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using Nethermind.Facade.Proxy.Models.MultiCall; -namespace Nethermind.Facade; +namespace Nethermind.Facade.Multicall; public class MultiCallOutput { diff --git a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs similarity index 58% rename from src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs rename to src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs index b6c92890d48..28546b515e8 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -5,10 +5,9 @@ using Nethermind.Blockchain; using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Synchronization; -using Nethermind.Consensus.Comparers; +using Nethermind.Consensus.Processing; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; -using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Db; using Nethermind.Db.Blooms; @@ -19,32 +18,25 @@ using Nethermind.State.Repositories; using Nethermind.Trie.Pruning; -namespace Nethermind.Consensus.Processing; +namespace Nethermind.Facade.Multicall; public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IDisposable { - private readonly ITrieStore? _trieStore; + private readonly ITrieStore _trieStore; private readonly ILogManager? _logManager; private readonly IBlockValidator _blockValidator; public ISpecProvider SpecProvider { get; } - public IMultiCallVirtualMachine VirtualMachine { get; } + public IVirtualMachine VirtualMachine { get; } + public OverridableCodeInfoRepository CodeInfoRepository { get; } - //We need ability to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning - public static MultiCallReadOnlyBlocksProcessingEnv Create(bool traceTransfers, IReadOnlyDbProvider? readOnlyDbProvider, - ISpecProvider? specProvider, - ILogManager? logManager - ) + // We need ability to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning + public static MultiCallReadOnlyBlocksProcessingEnv Create( + bool traceTransfers, + IReadOnlyDbProvider readOnlyDbProvider, + ISpecProvider specProvider, + ILogManager? logManager = null) { - if (specProvider == null) - { - throw new ArgumentNullException(nameof(specProvider)); - } - if (readOnlyDbProvider == null) - { - throw new ArgumentNullException(nameof(readOnlyDbProvider)); - } - - ReadOnlyDbProvider? dbProvider = new(readOnlyDbProvider, true); + ReadOnlyDbProvider dbProvider = new(readOnlyDbProvider, true); TrieStore trieStore = new(readOnlyDbProvider.StateDb, logManager); BlockTree blockTree = new(readOnlyDbProvider, new ChainLevelInfoRepository(readOnlyDbProvider.BlockInfosDb), @@ -62,32 +54,25 @@ public static MultiCallReadOnlyBlocksProcessingEnv Create(bool traceTransfers, I logManager); } - public MultiCallReadOnlyBlocksProcessingEnv Clone(bool traceTransfers) - { - return Create(traceTransfers, DbProvider, SpecProvider, _logManager); - } + public MultiCallReadOnlyBlocksProcessingEnv Clone(bool traceTransfers) => + Create(traceTransfers, DbProvider, SpecProvider, _logManager); private MultiCallReadOnlyBlocksProcessingEnv( bool traceTransfers, - IReadOnlyDbProvider? readOnlyDbProvider, - ITrieStore? trieStore, - IBlockTree? blockTree, - ISpecProvider? specProvider, - ILogManager? logManager) : base(readOnlyDbProvider, trieStore, blockTree, - logManager) + IReadOnlyDbProvider readOnlyDbProvider, + ITrieStore trieStore, + IBlockTree blockTree, + ISpecProvider specProvider, + ILogManager? logManager = null) + : base(readOnlyDbProvider, trieStore, blockTree, logManager) { _trieStore = trieStore; _logManager = logManager; SpecProvider = specProvider; - if (traceTransfers) - { - VirtualMachine = new MultiCallVirtualMachine(BlockhashProvider, specProvider, logManager); - } - else - { - VirtualMachine = new MultiCallVirtualMachine(BlockhashProvider, specProvider, logManager); - } + CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); + + VirtualMachine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); HeaderValidator headerValidator = new( BlockTree, @@ -95,7 +80,7 @@ private MultiCallReadOnlyBlocksProcessingEnv( SpecProvider, _logManager); - BlockValidator? blockValidator = new( + BlockValidator blockValidator = new( new TxValidator(SpecProvider.ChainId), headerValidator, Always.Valid, @@ -107,7 +92,7 @@ private MultiCallReadOnlyBlocksProcessingEnv( public IBlockProcessor GetProcessor() { - TransactionProcessor? transactionProcessor = new(SpecProvider, StateProvider, VirtualMachine, _logManager); + TransactionProcessor transactionProcessor = new(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager); return new BlockProcessor(SpecProvider, _blockValidator, @@ -121,7 +106,7 @@ public IBlockProcessor GetProcessor() public void Dispose() { - _trieStore?.Dispose(); + _trieStore.Dispose(); DbProvider.Dispose(); } } diff --git a/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs similarity index 50% rename from src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs rename to src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs index 82dcb9b53ca..8cec2c0db87 100644 --- a/src/Nethermind/Nethermind.Facade/MultiCallTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs @@ -1,32 +1,38 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; +using System.Collections.Generic; using System.Linq; +using Nethermind.Abi; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Int256; -namespace Nethermind.Facade; +namespace Nethermind.Facade.Multicall; -internal class MultiCallTxTracer : TxTracer +internal sealed class MultiCallTxTracer : TxTracer, ILogsTxTracer { - public MultiCallTxTracer() + private static readonly Keccak[] _topics = { Keccak.Zero }; + + public MultiCallTxTracer(bool isTracingTransfers) { + IsTracingLogs = isTracingTransfers; IsTracingReceipt = true; } - public MultiCallCallResult TraceResult { get; set; } + public MultiCallCallResult? TraceResult { get; set; } - public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, - Keccak? stateRoot = null) + public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) { TraceResult = new MultiCallCallResult() { GasUsed = (ulong)gasSpent, ReturnData = output, - Status = StatusCode.Success.ToString(), + Status = StatusCode.Success, Logs = logs.Select((entry, i) => new Log { Data = entry.Data, @@ -41,15 +47,24 @@ public override void MarkAsFailed(Address recipient, long gasSpent, byte[] outpu { TraceResult = new MultiCallCallResult() { - GasUsed = (ulong)gasSpent, - Error = new Facade.Proxy.Models.MultiCall.Error + Error = new Error { Code = StatusCode.Failure, Message = error }, ReturnData = output, - Status = StatusCode.Failure.ToString() + Status = StatusCode.Failure }; } + + public bool IsTracingLogs { get; } + + IEnumerable ILogsTxTracer.ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall) + { + base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); + byte[]? data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, + new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256), from, to, value); + yield return new LogEntry(Address.Zero, data, _topics); + } } diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs new file mode 100644 index 00000000000..d9a8f2e4d88 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -0,0 +1,275 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using System.Linq; +using Nethermind.Config; +using Nethermind.Consensus.Processing; +using Nethermind.Consensus.Producers; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Crypto; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Evm.Tracing; +using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Int256; +using Nethermind.State; +using Nethermind.Trie; + +namespace Nethermind.Facade.Multicall; + +public class MulticallBridgeHelper +{ + private readonly MultiCallReadOnlyBlocksProcessingEnv _multiCallProcessingEnv; + private readonly ISpecProvider _specProvider; + private readonly IBlocksConfig _blocksConfig; + + private static readonly ProcessingOptions _multicallProcessingOptions = ProcessingOptions.ForceProcessing | + ProcessingOptions.DoNotVerifyNonce | + ProcessingOptions.IgnoreParentNotOnMainChain | + ProcessingOptions.MarkAsProcessed | + ProcessingOptions.StoreReceipts; + + public MulticallBridgeHelper(MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv, ISpecProvider specProvider, IBlocksConfig blocksConfig) + { + _multiCallProcessingEnv = multiCallProcessingEnv; + _specProvider = specProvider; + _blocksConfig = blocksConfig; + } + + void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall? blockStateCall, MultiCallReadOnlyBlocksProcessingEnv env) + { + IReleaseSpec? currentSpec = env.SpecProvider.GetSpec(blockHeader); + if (blockStateCall!.StateOverrides is not null) + { + ModifyAccounts(blockStateCall.StateOverrides, env.StateProvider, currentSpec); + } + + env.StateProvider.Commit(currentSpec); + env.StateProvider.CommitTree(blockHeader.Number); + env.StateProvider.RecalculateStateRoot(); + blockHeader.StateRoot = env.StateProvider.StateRoot; + } + + public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) + { + using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers); + Block? parentBlock = env.BlockTree.FindBlock(parent.Number); + if (parentBlock is not null) + { + env.BlockTree.UpdateMainChain(new[] { parentBlock }, true, true); + env.BlockTree.UpdateHeadBlock(parentBlock.Hash!); + } + + IBlockProcessor? processor = env.GetProcessor(); + BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); + if (firstBlock?.BlockOverrides?.Number is > 0 and < long.MaxValue) + { + BlockHeader? searchResult = env.BlockTree.FindHeader((long)firstBlock.BlockOverrides.Number); + if (searchResult is not null) + { + parent = searchResult; + } + } + + Dictionary nonceCache = new(); + + List suggestedBlocks = new(); + + if (payload.BlockStateCalls is not null) + { + foreach (BlockStateCall? callInputBlock in payload.BlockStateCalls) + { + BlockHeader callHeader = callInputBlock.BlockOverrides is not null + ? callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig) + : new BlockHeader( + parent.Hash!, + Keccak.OfAnEmptySequenceRlp, + Address.Zero, + UInt256.Zero, + parent.Number + 1, + parent.GasLimit, + parent.Timestamp + 1, + Array.Empty()) + { + BaseFeePerGas = BaseFeeCalculator.Calculate(parent, _specProvider.GetSpec(parent)), + MixHash = parent.MixHash, + IsPostMerge = parent.Difficulty == 0 + }; + + UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); + + Transaction SetTxHashAndMissingDefaults(Transaction transaction) + { + transaction.SenderAddress ??= Address.Zero; + transaction.To ??= Address.Zero; + transaction.Data ??= Memory.Empty; + + if (transaction.Nonce == 0) + { + try + { + if (!nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) + { + cachedNonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; + nonceCache[transaction.SenderAddress] = cachedNonce; + } + + else + { + cachedNonce++; + nonceCache[transaction.SenderAddress] = cachedNonce; + } + + transaction.Nonce = cachedNonce; + } + catch (TrieException) + { + // ignore + // Transaction from unknown account + } + } + + transaction.Hash = transaction.CalculateHash(); + return transaction; + } + + IEnumerable transactions = callInputBlock.Calls?.Select(SetTxHashAndMissingDefaults) ?? Array.Empty(); + Block? currentBlock = new(callHeader, transactions, Array.Empty()); + currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); + + ProcessingOptions processingFlags = _multicallProcessingOptions; + + if (!payload.Validation) + { + processingFlags |= ProcessingOptions.NoValidation; + } + + suggestedBlocks.Clear(); + suggestedBlocks.Add(currentBlock); + + Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, suggestedBlocks, processingFlags, tracer); + Block? processedBlock = currentBlocks[0]; + parent = processedBlock.Header; + } + } + + return (true, ""); + } + + private bool TryGetAccount(IWorldState stateProvider, Address address, out Account account) + { + bool accExists = false; + try + { + accExists = stateProvider.AccountExists(address); + account = stateProvider.GetAccount(address); + } + catch (Exception) + { + account = Account.TotallyEmpty; + } + + return accExists; + } + + private void ModifyAccounts(Dictionary stateOverrides, IWorldState stateProvider, IReleaseSpec currentSpec) + { + foreach (KeyValuePair overrideData in stateOverrides) + { + Address address = overrideData.Key; + AccountOverride? accountOverride = overrideData.Value; + + UInt256 balance = 0; + if (accountOverride.Balance is not null) + { + balance = accountOverride.Balance.Value; + } + + UInt256 nonce = 0; + if (accountOverride.Nonce is not null) + { + nonce = accountOverride.Nonce.Value; + } + + if (!TryGetAccount(stateProvider, address, out Account? acc)) + { + stateProvider.CreateAccount(address, balance, nonce); + } + else + { + UpdateBalance(stateProvider, currentSpec, acc, accountOverride, balance, address); + UpdateNonce(stateProvider, acc, accountOverride, nonce, address); + } + + UpdateCode(stateProvider, currentSpec, accountOverride, address); + UpdateState(stateProvider, accountOverride, address); + } + } + + private static void UpdateState(IWorldState stateProvider, AccountOverride accountOverride, Address address) + { + //TODO: discuss if clean slate is a must + if (accountOverride.State is not null) + { + foreach (KeyValuePair storage in accountOverride.State) + stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.Bytes.WithoutLeadingZeros().ToArray()); + } + + if (accountOverride.StateDiff is not null) + { + foreach (KeyValuePair storage in accountOverride.StateDiff) + stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.Bytes.WithoutLeadingZeros().ToArray()); + } + } + + private void UpdateCode(IWorldState stateProvider, IReleaseSpec currentSpec, AccountOverride? accountOverride, + Address address) + { + if (accountOverride?.Code is not null) + { + _multiCallProcessingEnv.CodeInfoRepository.SetCodeOverwrite(stateProvider, currentSpec, address, + new CodeInfo(accountOverride.Code), accountOverride.MovePrecompileToAddress); + } + } + + private static void UpdateNonce(IWorldState stateProvider, Account acc, AccountOverride accountOverride, UInt256 nonce, Address address) + { + UInt256 accNonce = acc.Nonce; + if (accountOverride.Nonce != null && accNonce > nonce) + { + UInt256 iters = accNonce - nonce; + for (UInt256 i = 0; i < iters; i++) + { + stateProvider.DecrementNonce(address); + } + } + else if (accountOverride.Nonce != null && accNonce < accountOverride.Nonce) + { + UInt256 iters = nonce - accNonce; + for (UInt256 i = 0; i < iters; i++) + { + stateProvider.IncrementNonce(address); + } + } + } + + private static void UpdateBalance(IWorldState stateProvider, IReleaseSpec currentSpec, Account acc, AccountOverride accountOverride, UInt256 balance, Address address) + { + if (accountOverride.Balance is not null) + { + UInt256 accBalance = acc.Balance; + if (accBalance > balance) + { + stateProvider.SubtractFromBalance(address, accBalance - balance, currentSpec); + } + else if (accBalance < balance) + { + stateProvider.AddToBalance(address, balance - accBalance, currentSpec); + } + } + } +} diff --git a/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs deleted file mode 100644 index 8da4a101800..00000000000 --- a/src/Nethermind/Nethermind.Facade/MultycallBridgeHelper.cs +++ /dev/null @@ -1,280 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Collections.Generic; -using System.Linq; -using Nethermind.Config; -using Nethermind.Consensus.Processing; -using Nethermind.Core; -using Nethermind.Core.Crypto; -using Nethermind.Core.Eip2930; -using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; -using Nethermind.Crypto; -using Nethermind.Evm.CodeAnalysis; -using Nethermind.Evm.Tracing; -using Nethermind.Facade.Proxy.Models.MultiCall; -using Nethermind.Int256; -using Nethermind.State; -using Nethermind.Trie; - -namespace Nethermind.Facade; - -public class MultycallBridgeHelper -{ - private readonly MultiCallReadOnlyBlocksProcessingEnv _multiCallProcessingEnv; - private readonly ISpecProvider _specProvider; - private readonly IBlocksConfig _blocksConfig; - - public MultycallBridgeHelper(MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv, ISpecProvider specProvider, IBlocksConfig blocksConfig) - { - _multiCallProcessingEnv = multiCallProcessingEnv; - _specProvider = specProvider; - _blocksConfig = blocksConfig; - } - - void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall? blockStateCall, MultiCallReadOnlyBlocksProcessingEnv env) - { - IReleaseSpec? currentSpec = env.SpecProvider.GetSpec(blockHeader); - if (blockStateCall!.StateOverrides != null) - { - ModifyAccounts(blockStateCall.StateOverrides, env.StateProvider, currentSpec); - } - - env.StateProvider.Commit(currentSpec); - env.StateProvider.CommitTree(blockHeader.Number); - env.StateProvider.RecalculateStateRoot(); - blockHeader.StateRoot = env.StateProvider.StateRoot; - } - - public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, - IBlockTracer tracer) - { - using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers); - Block? parentBlock = env.BlockTree.FindBlock(parent.Number); - if (parentBlock != null) - { - env.BlockTree.UpdateMainChain(new[] { parentBlock }, true, true); - env.BlockTree.UpdateHeadBlock(parentBlock.Hash); - } - - IBlockProcessor? processor = env.GetProcessor(); - BlockStateCall? firstBlock = payload.BlockStateCalls.FirstOrDefault(); - if (firstBlock?.BlockOverrides?.Number != null - && firstBlock?.BlockOverrides?.Number > UInt256.Zero - && firstBlock?.BlockOverrides?.Number < long.MaxValue) - { - BlockHeader? searchResult = - env.BlockTree.FindHeader((long)firstBlock?.BlockOverrides.Number); - if (searchResult != null) - { - parent = searchResult; - } - } - - Dictionary _nonceCache = new(); - - List suggestedBlocks = new(); - - foreach (BlockStateCall? callInputBlock in payload.BlockStateCalls) - { - BlockHeader callHeader = callInputBlock.BlockOverrides is not null - ? callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig) - : new BlockHeader( - parent.Hash, - Keccak.OfAnEmptySequenceRlp, - Address.Zero, - UInt256.Zero, - parent.Number + 1, - parent.GasLimit, - parent.Timestamp + 1, - Array.Empty()) - { - BaseFeePerGas = BaseFeeCalculator.Calculate(parent, _specProvider.GetSpec(parent)), - MixHash = parent.MixHash, - IsPostMerge = parent.Difficulty == 0 - }; - - UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); - - Transaction SetTxHashAndMissingDefaults(Transaction transaction) - { - transaction.SenderAddress ??= Address.Zero; - transaction.To ??= Address.Zero; - transaction.Data ??= Memory.Empty; - - Keccak stateRoot = callHeader.StateRoot!; - - if (transaction.Nonce == 0) - { - try - { - if (!_nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) - { - cachedNonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; - _nonceCache[transaction.SenderAddress] = cachedNonce; - } - - else - { - cachedNonce++; - _nonceCache[transaction.SenderAddress] = cachedNonce; - } - - transaction.Nonce = cachedNonce; - } - catch (TrieException) - { - // ignore - // Transaction from unknown account - } - } - - transaction.Hash = transaction.CalculateHash(); - return transaction; - } - - Transaction[]? transactions = callInputBlock.Calls.Select(SetTxHashAndMissingDefaults).ToArray(); - - Block? currentBlock = new(callHeader, transactions, Array.Empty()); - currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); - - ProcessingOptions processingFlags = ProcessingOptions.ForceProcessing | - ProcessingOptions.DoNotVerifyNonce | - ProcessingOptions.IgnoreParentNotOnMainChain | - ProcessingOptions.MarkAsProcessed | - ProcessingOptions.StoreReceipts; - - if (!payload.Validation) - { - processingFlags |= ProcessingOptions.NoValidation; - } - - suggestedBlocks.Clear(); - suggestedBlocks.Add(currentBlock); - - Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, - suggestedBlocks, processingFlags, tracer); - - Block? processedBlock = currentBlocks[0]; - parent = processedBlock.Header; - } - - - return (true, ""); - } - - bool TryGetAccount(IWorldState? stateProvider, Address address, out Account account) - { - bool accExists = false; - try - { - accExists = stateProvider.AccountExists(address); - account = stateProvider.GetAccount(address); - } - catch (Exception) - { - account = Account.TotallyEmpty; - } - - return accExists; - } - - private void ModifyAccounts(Dictionary stateOverrides, IWorldState? stateProvider, IReleaseSpec? currentSpec) - { - Account? acc; - - foreach (KeyValuePair overrideData in stateOverrides) - { - Address address = overrideData.Key; - AccountOverride? accountOverride = overrideData.Value; - - UInt256 balance = 0; - if (accountOverride.Balance != null) - { - balance = accountOverride.Balance.Value; - } - - UInt256 nonce = 0; - if (accountOverride.Nonce != null) - { - nonce = accountOverride.Nonce.Value; - } - - if (!TryGetAccount(stateProvider, address, out acc)) - { - stateProvider.CreateAccount(address, balance, nonce); - } - else - { - UpdateBalance(stateProvider, currentSpec, acc, accountOverride, balance, address); - UpdataNonce(stateProvider, acc, accountOverride, nonce, address); - } - - UpdateCode(stateProvider, currentSpec, accountOverride, address); - UpdateState(stateProvider, accountOverride, address); - } - } - - private static void UpdateState(IWorldState? stateProvider, AccountOverride? accountOverride, Address address) - { - //TODO: discuss if clean slate is a must - if (accountOverride.State is not null) - { - foreach (KeyValuePair storage in accountOverride.State) - stateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); - } - - if (accountOverride.StateDiff is not null) - { - foreach (KeyValuePair storage in accountOverride.StateDiff) - stateProvider.Set(new StorageCell(address, storage.Key), - storage.Value.ToByteArray().WithoutLeadingZeros().ToArray()); - } - } - - private void UpdateCode(IWorldState? stateProvider, IReleaseSpec? currentSpec, AccountOverride? accountOverride, - Address address) - { - if (accountOverride.Code != null) - { - _multiCallProcessingEnv.VirtualMachine.SetCodeOverwrite(stateProvider, currentSpec, address, - new CodeInfo(accountOverride.Code), accountOverride.MovePrecompileToAddress); - } - } - - private static void UpdataNonce(IWorldState? stateProvider, Account? acc, AccountOverride? accountOverride, - UInt256 nonce, Address address) - { - UInt256 accNonce = acc.Nonce; - if (accountOverride.Nonce != null && accNonce > nonce) - { - UInt256 iters = accNonce - nonce; - for (UInt256 i = 0; i < iters; i++) - { - stateProvider.DecrementNonce(address); - } - } - else if (accountOverride.Nonce != null && accNonce < accountOverride.Nonce) - { - UInt256 iters = nonce - accNonce; - for (UInt256 i = 0; i < iters; i++) - { - stateProvider.IncrementNonce(address); - } - } - } - - private static void UpdateBalance(IWorldState? stateProvider, IReleaseSpec? currentSpec, Account? acc, - AccountOverride? accountOverride, UInt256 balance, Address address) - { - UInt256 accBalance = acc.Balance; - if (accountOverride.Balance != null && accBalance > balance) - stateProvider.SubtractFromBalance(address, accBalance - balance, currentSpec); - - else if (accountOverride.Balance != null && accBalance < balance) - stateProvider.AddToBalance(address, balance - accBalance, currentSpec); - } -} diff --git a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs new file mode 100644 index 00000000000..fba398baac0 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; +using Nethermind.Evm; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.State; + +namespace Nethermind.Facade; + +public class OverridableCodeInfoRepository : ICodeInfoRepository +{ + private readonly ICodeInfoRepository _codeInfoRepository; + private readonly Dictionary _codeOverwrites = new(); + + public OverridableCodeInfoRepository(ICodeInfoRepository codeInfoRepository) + { + _codeInfoRepository = codeInfoRepository; + } + + public void SetCodeOverwrite( + IWorldState worldState, + IReleaseSpec vmSpec, + Address key, + CodeInfo value, + Address? redirectAddress = null) + { + if (redirectAddress is not null) + { + _codeOverwrites[redirectAddress] = GetCachedCodeInfo(worldState, key, vmSpec); + } + + _codeOverwrites[key] = value; + } + + public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) => + _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) + ? result + : _codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, vmSpec); + + public CodeInfo GetOrAdd(ValueKeccak codeHash, Span initCode) => + _codeInfoRepository.GetOrAdd(codeHash, initCode); +} diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs index d6c2decdd4b..a5fea91c06e 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs @@ -15,14 +15,17 @@ public class AccountOverride public byte[]? Code { get; set; } public Address? MovePrecompileToAddress { get; set; } - - //Storage for AccountOverrideState + /// + /// Storage for AccountOverrideState + /// public Dictionary? State { get; set; } - //Storage difference for AccountOverrideStateDiff + /// + /// Storage difference for AccountOverrideStateDiff + /// public Dictionary? StateDiff { get; set; } - public AccountOverrideType Type => State != null + public AccountOverrideType Type => State is null ? AccountOverrideType.AccountOverrideState : AccountOverrideType.AccountOverrideStateDiff; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index a117dc565cb..014f91b1a82 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -37,13 +37,13 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) _ => throw new OverflowException($"Block Number value is too large, max value {ulong.MaxValue}") }; - Address newFeeRecipientAddress = FeeRecipient != null ? FeeRecipient : parent.Beneficiary; - + Address newFeeRecipientAddress = FeeRecipient ?? parent.Beneficiary!; + UInt256 newDifficulty = parent.Difficulty == 0 ? 0 : parent.Difficulty + 1; BlockHeader? result = new( - parent.Hash, + parent.Hash!, Keccak.OfAnEmptySequenceRlp, newFeeRecipientAddress, - UInt256.Zero, + newDifficulty, newBlockNumber, newGasLimit, newTime, @@ -51,12 +51,11 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) { BaseFeePerGas = BaseFeePerGas ?? parent.BaseFeePerGas, MixHash = PrevRandao, - IsPostMerge = parent.Difficulty == 0 + IsPostMerge = parent.Difficulty == 0, + TotalDifficulty = parent.TotalDifficulty + newDifficulty, + SealEngineType = parent.SealEngineType }; - UInt256 difficulty = ConstantDifficulty.One.Calculate(result, parent); - result.Difficulty = difficulty; - result.TotalDifficulty = parent.TotalDifficulty + difficulty; return result; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs index dca1ed9682e..38fe1c0d142 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Collections.Generic; using Nethermind.Core; @@ -10,5 +11,5 @@ public class BlockStateCall { public BlockOverride? BlockOverrides { get; set; } public Dictionary? StateOverrides { get; set; } - public T[]? Calls { get; set; } = { }; + public T[]? Calls { get; set; } = Array.Empty(); } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs index c3443cede18..70d934bc73d 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; +using System.Collections.Generic; +using System.Linq; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Int256; @@ -10,13 +13,13 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class MultiCallBlockResult { public ulong Number { get; set; } - public Keccak Hash { get; set; } + public Keccak Hash { get; set; } = Keccak.Zero; public ulong Timestamp { get; set; } public ulong GasLimit { get; set; } public ulong GasUsed { get; set; } - public Address FeeRecipient { get; set; } + public Address FeeRecipient { get; set; } = Address.Zero; public UInt256 BaseFeePerGas { get; set; } - public MultiCallCallResult[] Calls { get; set; } - public UInt256 PrevRandao { get; set; } + public IEnumerable Calls { get; set; } = Enumerable.Empty(); + public Keccak? PrevRandao { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs index 04be85d8feb..27f5bec36e6 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs @@ -1,23 +1,23 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; +using Microsoft.AspNetCore.Http; +using Nethermind.Evm; + namespace Nethermind.Facade.Proxy.Models.MultiCall; public class MultiCallCallResult { - public ResultType Type - { - get + public ResultType Type => + Status switch { - if (Error is null) return ResultType.Success; - - if (ReturnData is not null) return ResultType.Failure; - - return ResultType.Invalid; - } - } + StatusCode.Success => ResultType.Success, + StatusCode.Failure when ReturnData is not null => ResultType.Failure, + _ => ResultType.Invalid, + }; - public string Status { get; set; } + public byte Status { get; set; } public byte[]? ReturnData { get; set; } public ulong? GasUsed { get; set; } public Error? Error { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs index 16d504b757a..6a7be8f00eb 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs @@ -5,12 +5,18 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class MultiCallPayload { - //Definition of blocks that can contain calls and overrides + /// + /// Definition of blocks that can contain calls and overrides + /// public BlockStateCall[]? BlockStateCalls { get; set; } - //Trace ETH Transfers - public bool TraceTransfers { get; set; } = false; + /// + /// Should trace ETH Transfers + /// + public bool TraceTransfers { get; set; } - //When true, the multicall does all validations that a normal EVM would do, except contract sender and signature checks. When false, multicall behaves like eth_call. - public bool Validation { get; set; } = false; + /// + /// When true, the multicall does all validations that a normal EVM would do, except contract sender and signature checks. When false, multicall behaves like eth_call. + /// + public bool Validation { get; set; } } diff --git a/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs b/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs index ff31997923e..6694f471735 100644 --- a/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs +++ b/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs @@ -42,7 +42,6 @@ public void CheckHealth_returns_expected_results([ValueSource(nameof(CheckHealth ISyncConfig syncConfig = Substitute.For(); IHealthHintService healthHintService = Substitute.For(); INethermindApi api = Substitute.For(); - api.SpecProvider = Substitute.For(); blockchainProcessor.IsProcessingBlocks(Arg.Any()).Returns(test.IsProcessingBlocks); blockProducer.IsProducingBlocks(Arg.Any()).Returns(test.IsProducingBlocks); syncServer.GetPeerCount().Returns(test.PeerCount); @@ -112,8 +111,6 @@ public void post_merge_health_checks([ValueSource(nameof(CheckHealthPostMergeTes drive.AvailableFreeSpace.Returns(_freeSpaceBytes); drive.TotalSize.Returns((long)(_freeSpaceBytes * 100.0 / test.AvailableDiskSpacePercent)); drive.RootDirectory.FullName.Returns("C:/"); - - api.SpecProvider = Substitute.For(); api.SpecProvider.TerminalTotalDifficulty.Returns(UInt256.Zero); BlockHeaderBuilder GetBlockHeader(int blockNumber) => Build.A.BlockHeader.WithNumber(blockNumber); diff --git a/src/Nethermind/Nethermind.Hive.Test/PluginTests.cs b/src/Nethermind/Nethermind.Hive.Test/PluginTests.cs index 0ebe4da59d3..63c97673bff 100644 --- a/src/Nethermind/Nethermind.Hive.Test/PluginTests.cs +++ b/src/Nethermind/Nethermind.Hive.Test/PluginTests.cs @@ -8,6 +8,7 @@ namespace Nethermind.Hive.Tests { [TestFixture] [Parallelizable(ParallelScope.All)] + [SetCulture("en-US")] public class PluginTests { [Test] diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs index 952bdaa678a..1fd900bd464 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs @@ -217,15 +217,19 @@ private Task InitBlockchain() BlockhashProvider blockhashProvider = new( getApi.BlockTree, getApi.LogManager); + CodeInfoRepository codeInfoRepository = new(); + VirtualMachine virtualMachine = new( blockhashProvider, getApi.SpecProvider, + codeInfoRepository, getApi.LogManager); _api.TransactionProcessor = new TransactionProcessor( getApi.SpecProvider, worldState, virtualMachine, + codeInfoRepository, getApi.LogManager); InitSealEngine(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index a4e2654014c..db6e90b32b8 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Nethermind.Blockchain.Find; using Nethermind.Core; @@ -30,9 +31,9 @@ public async Task Test_eth_multicall_ecr_moved() /* function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns(address) { - + address redirectedToAddress = 0x0000000000000000000000000000000000000666; - + assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the @@ -50,34 +51,34 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( } } */ + byte[] zeroByte = { 0 }; byte[] code = Prepare.EvmCode .JUMPDEST() - .PushData(new byte[] { 0 }) + .PushData(zeroByte) .Op(Instruction.DUP1) .PushData(Bytes.FromHexString("0x0666")) // 666 .Op(Instruction.SWAP1) .Op(Instruction.POP) .Op(Instruction.CALLDATASIZE) - .PushData(new byte[] { 0 }) + .PushData(zeroByte) .Op(Instruction.DUP1) .Op(Instruction.CALLDATACOPY) - .PushData(new byte[] { 0 }) + .PushData(zeroByte) .Op(Instruction.DUP1) .Op(Instruction.CALLDATASIZE) - .PushData(new byte[] { 0 }) + .PushData(zeroByte) .Op(Instruction.DUP5) .Op(Instruction.GAS) .Op(Instruction.DELEGATECALL) .Op(Instruction.RETURNDATASIZE) - .PushData(new byte[] { 0 }) + .PushData(zeroByte) .Op(Instruction.DUP1) .Op(Instruction.RETURNDATACOPY) .Op(Instruction.RETURNDATASIZE) - .PushData(new byte[] { 0 }) + .PushData(zeroByte) .Op(Instruction.RETURN) .Done; - Address realSenderAccount = TestItem.AddressA; byte[] transactionData = EthRpcMulticallTestsBase.GetTxData(chain, TestItem.PrivateKeyA); Address? contractAddress = await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, @@ -85,62 +86,58 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); - Transaction systemTransactionForModifiedVM = new() + Transaction systemTransactionForModifiedVm = new() { Data = transactionData, To = contractAddress, - SenderAddress = TestItem.PublicKeyA.Address, - GasLimit = 50_000, + SenderAddress = TestItem.AddressA, + GasLimit = 3_500_000, GasPrice = 20.GWei() - }; - - chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); - chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); - - BlockHeader header = chain.BlockFinder.Head.Header; - IReleaseSpec spec = chain.SpecProvider.GetSpec(header); - //systemTransactionForModifiedVM.GasPrice = header.BaseFeePerGas >= 1 ? header.BaseFeePerGas : 1; - //systemTransactionForModifiedVM.GasLimit = (long)systemTransactionForModifiedVM.CalculateTransactionPotentialCost(spec.IsEip1559Enabled, header.BaseFeePerGas); - MultiCallPayload payload = new() { - BlockStateCalls = new BlockStateCall[] { new() - { - StateOverrides = new Dictionary() - { {EcRecoverPrecompile.Address, - new AccountOverride + BlockStateCalls = new BlockStateCall[] + { + new() { - Code = code, - MovePrecompileToAddress = new Address("0x0000000000000000000000000000000000000666") - }} + StateOverrides = new Dictionary + { + { + EcRecoverPrecompile.Address, + new AccountOverride + { + Code = code, + MovePrecompileToAddress = new Address("0x0000000000000000000000000000000000000666"), + } + }, + { + TestItem.AddressA, + new AccountOverride + { + Balance = 10.Ether() + } + } + }, + Calls = new[] + { + new TransactionForRpc(systemTransactionForModifiedVm), + } + } }, - Calls = new[] - { - - new TransactionForRpc(systemTransactionForModifiedVM), - } - }}, TraceTransfers = true, Validation = false }; - //Force persistancy of head block in main chain - chain.BlockTree.UpdateMainChain(new[] { chain.BlockFinder.Head }, true, true); - chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head.Hash!); - //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - ResultWrapper> result = - executor.Execute(payload, BlockParameter.Latest); + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); //Check results - byte[] addressBytes = result.Data[0].Calls[0].ReturnData! - .SliceWithZeroPaddingEmptyOnError(12, 20); + byte[] addressBytes = result.Data[0].Calls.First().ReturnData!.SliceWithZeroPaddingEmptyOnError(12, 20); Address resultingAddress = new(addressBytes); - Assert.That(resultingAddress, Is.EqualTo(realSenderAccount)); + Assert.That(resultingAddress, Is.EqualTo(TestItem.AddressA)); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs index d8dc67df066..91f05e70027 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs @@ -29,8 +29,7 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; public class EthRpcMulticallTestsBase { - public static Task CreateChain(IReleaseSpec? releaseSpec = null, - UInt256? initialBaseFeePerGas = null) + public static Task CreateChain(IReleaseSpec? releaseSpec = null) { TestRpcBlockchain testMevRpcBlockchain = new(); TestSpecProvider testSpecProvider = releaseSpec is not null @@ -40,9 +39,10 @@ public static Task CreateChain(IReleaseSpec? releaseSpec = nu } - public static string getEcRecoverContractJsonAbi(string name = "recover") + private static string GetEcRecoverContractJsonAbi(string name = "recover") { - return $@"[ + return $@" +[ {{ ""payable"": false, ""inputs"": [ @@ -100,10 +100,9 @@ public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, stri return transactionData; } - public static async Task DeployEcRecoverContract(TestRpcBlockchain chain1, PrivateKey fromPrivateKey, - string ContractBytecode) + public static async Task DeployEcRecoverContract(TestRpcBlockchain chain1, PrivateKey fromPrivateKey, string contractBytecode) { - byte[] bytecode = Bytes.FromHexString(ContractBytecode); + byte[] bytecode = Bytes.FromHexString(contractBytecode); Transaction tx = new() { Value = UInt256.Zero, @@ -139,31 +138,28 @@ public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, stri //createContractTxReceipt2.ContractAddress // .Should().NotBeNull($"Contract transaction {tx.Hash} was not deployed."); - Address? contractAddress1; - using (SecureStringWrapper pass = new("testB")) + using SecureStringWrapper pass = new("testB"); + wallet.Import(fromPrivateKey.KeyBytes, pass.SecureData); + wallet.UnlockAccount(fromPrivateKey.Address, pass.SecureData, TimeSpan.MaxValue); + (Keccak hash, AcceptTxResult? code) = await txSender.SendTransaction(tx, + TxHandlingOptions.ManagedNonce | TxHandlingOptions.PersistentBroadcast); + + code?.Should().Be(AcceptTxResult.Accepted); + Transaction[] txs = chain1.TxPool.GetPendingTransactions(); + + await chain1.AddBlock(true, txs); + + TxReceipt? createContractTxReceipt = null; + while (createContractTxReceipt == null) { - wallet.Import(fromPrivateKey.KeyBytes, pass.SecureData); - wallet.UnlockAccount(fromPrivateKey.Address, pass.SecureData, TimeSpan.MaxValue); - (Keccak hash, AcceptTxResult? code) = await txSender.SendTransaction(tx, - TxHandlingOptions.ManagedNonce | TxHandlingOptions.PersistentBroadcast); - - code?.Should().Be(AcceptTxResult.Accepted); - Transaction[] txs = chain1.TxPool.GetPendingTransactions(); - - await chain1.AddBlock(true, txs); - - TxReceipt? createContractTxReceipt = null; - while (createContractTxReceipt == null) - { - await Task.Delay(100); // wait... todo enforce! - createContractTxReceipt = chain1.Bridge.GetReceipt(tx.Hash!); - } - - createContractTxReceipt.ContractAddress.Should() - .NotBeNull($"Contract transaction {tx.Hash!} was not deployed."); - contractAddress1 = createContractTxReceipt.ContractAddress; + await Task.Delay(100); // wait... todo enforce! + createContractTxReceipt = chain1.Bridge.GetReceipt(tx.Hash!); } + createContractTxReceipt.ContractAddress.Should() + .NotBeNull($"Contract transaction {tx.Hash!} was not deployed."); + Address? contractAddress1 = createContractTxReceipt.ContractAddress; + return contractAddress1; } @@ -171,7 +167,7 @@ public static byte[] GenerateTransactionDataForEcRecover(Keccak keccak, ulong @u string name = "recover") { AbiDefinitionParser parser = new(); - AbiDefinition call = parser.Parse(getEcRecoverContractJsonAbi(name)); + AbiDefinition call = parser.Parse(GetEcRecoverContractJsonAbi(name)); AbiEncodingInfo functionInfo = call.GetFunction(name).GetCallInfo(); byte[] transactionData1 = AbiEncoder.Instance.Encode(functionInfo.EncodingStyle, functionInfo.Signature, @@ -179,10 +175,10 @@ public static byte[] GenerateTransactionDataForEcRecover(Keccak keccak, ulong @u return transactionData1; } - public static Address? GetTransactionResultFromEcRecover(byte[] data, string name = "recover") + private static Address? GetTransactionResultFromEcRecover(byte[] data, string name = "recover") { AbiDefinitionParser parser = new(); - AbiDefinition call = parser.Parse(getEcRecoverContractJsonAbi(name)); + AbiDefinition call = parser.Parse(GetEcRecoverContractJsonAbi(name)); AbiEncodingInfo functionInfo = call.GetFunction("recover").GetReturnInfo(); Address? transactionData1 = AbiEncoder.Instance.Decode(functionInfo.EncodingStyle, functionInfo.Signature, data).FirstOrDefault() as Address; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 22d6654bf13..f753dd80b90 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -3,7 +3,9 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; +using FluentAssertions; using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Extensions; @@ -103,9 +105,7 @@ public async Task Test_eth_multicall_serialisation() foreach (MultiCallBlockResult blockResult in data) { - Assert.That(blockResult.Calls.Length, Is.EqualTo(2)); - Assert.That(blockResult.Calls[0].Type, Is.EqualTo(ResultType.Failure)); - Assert.That(blockResult.Calls[1].Type, Is.EqualTo(ResultType.Success)); + blockResult.Calls.Select(c => c.Type).Should().BeEquivalentTo(new[] { ResultType.Failure, ResultType.Success }); } } @@ -186,7 +186,7 @@ public async Task Test_eth_multicall_eth_moved() foreach (MultiCallBlockResult blockResult in data) { - Assert.That(blockResult.Calls.Length, Is.EqualTo(2)); + Assert.That(blockResult.Calls.Count(), Is.EqualTo(2)); } } @@ -258,6 +258,6 @@ public async Task Test_eth_multicall_transactions_forced_fail() ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); - Assert.IsTrue(result.Data[1].Calls[0].Error?.Message.StartsWith("insufficient")); + Assert.IsTrue(result.Data[1].Calls.First().Error?.Message.StartsWith("insufficient")); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 5239dd3b3aa..59ce8209484 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -13,6 +13,7 @@ using Nethermind.Evm; using Nethermind.Evm.Precompiles; using Nethermind.Facade; +using Nethermind.Facade.Multicall; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; using NUnit.Framework; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 5a844116384..9ea07fe01b1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -31,6 +31,7 @@ using Nethermind.Wallet; using Newtonsoft.Json; using Nethermind.Config; +using Nethermind.Facade.Multicall; using Nethermind.Synchronization.ParallelSync; namespace Nethermind.JsonRpc.Test.Modules diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs index 75add1e5da1..6b5ffcb059d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs @@ -62,8 +62,9 @@ public void Setup() StateReader stateReader = new StateReader(trieStore, codeDb, LimboLogs.Instance); BlockhashProvider blockhashProvider = new(_blockTree, LimboLogs.Instance); - VirtualMachine virtualMachine = new(blockhashProvider, specProvider, LimboLogs.Instance); - TransactionProcessor transactionProcessor = new(specProvider, stateProvider, virtualMachine, LimboLogs.Instance); + CodeInfoRepository codeInfoRepository = new(); + VirtualMachine virtualMachine = new(blockhashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); + TransactionProcessor transactionProcessor = new(specProvider, stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _poSSwitcher = Substitute.For(); BlockProcessor blockProcessor = new( diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 00f6b8801d7..0a23d10c51c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -22,19 +22,12 @@ public partial class EthRpcModule // Single call executor private abstract class TxExecutor : ExecutorBase { - protected TxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : - base(blockchainBridge, blockFinder, rpcConfig) - { } + protected TxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) + : base(blockchainBridge, blockFinder, rpcConfig) { } - protected override Transaction Prepare(TransactionForRpc call) - { - return call.ToTransaction(_blockchainBridge.GetChainId()); + protected override Transaction Prepare(TransactionForRpc call) => call.ToTransaction(_blockchainBridge.GetChainId()); - } - protected override ResultWrapper Execute(BlockHeader header, Transaction tx, CancellationToken token) - { - return ExecuteTx(header, tx, token); - } + protected override ResultWrapper Execute(BlockHeader header, Transaction tx, CancellationToken token) => ExecuteTx(header, tx, token); public override ResultWrapper Execute( TransactionForRpc transactionCall, @@ -44,12 +37,7 @@ public override ResultWrapper Execute( return base.Execute(transactionCall, blockParameter); } - public ResultWrapper ExecuteTx( - TransactionForRpc transactionCall, - BlockParameter? blockParameter) - { - return Execute(transactionCall, blockParameter); - } + public ResultWrapper ExecuteTx(TransactionForRpc transactionCall, BlockParameter? blockParameter) => Execute(transactionCall, blockParameter); protected abstract ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token); } @@ -65,14 +53,9 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, Transacti { CallOutput result = _blockchainBridge.Call(header, tx, token); - if (result.Error is null) - { - return ResultWrapper.Success(result.OutputData.ToHexString(true)); - } - - return result.InputError - ? GetInputError(result) - : ResultWrapper.Fail("VM execution error.", ErrorCodes.ExecutionError, result.Error); + return result.Error is null + ? ResultWrapper.Success(result.OutputData.ToHexString(true)) + : TryGetInputError(result) ?? ResultWrapper.Fail("VM execution error.", ErrorCodes.ExecutionError, result.Error); } } @@ -88,14 +71,9 @@ public EstimateGasTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder bl { CallOutput result = _blockchainBridge.EstimateGas(header, tx, token); - if (result.Error is null) - { - return ResultWrapper.Success((UInt256)result.GasSpent); - } - - return result.InputError - ? GetInputError(result) - : ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError); + return result.Error is null + ? ResultWrapper.Success((UInt256)result.GasSpent) + : TryGetInputError(result) ?? ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError); } } @@ -113,14 +91,9 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, { CallOutput result = _blockchainBridge.CreateAccessList(header, tx, token, _optimize); - if (result.Error is null) - { - return ResultWrapper.Success(new(GetResultAccessList(tx, result), GetResultGas(tx, result))); - } - - return result.InputError - ? GetInputError(result) - : ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError, new AccessListForRpc(GetResultAccessList(tx, result), GetResultGas(tx, result))); + return result.Error is null + ? ResultWrapper.Success(new(GetResultAccessList(tx, result), GetResultGas(tx, result))) + : TryGetInputError(result) ?? ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError, new AccessListForRpc(GetResultAccessList(tx, result), GetResultGas(tx, result))); } private static AccessListItemForRpc[] GetResultAccessList(Transaction tx, CallOutput result) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 5c624995e6d..1ab8e1e1126 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -333,11 +333,9 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); - public ResultWrapper> eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) - { - return new MultiCallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) + public ResultWrapper> eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) => + new MultiCallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .Execute(payload, blockParameter); - } public ResultWrapper eth_estimateGas(TransactionForRpc transactionCall, BlockParameter blockParameter) => diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs index 52b5c334372..2a325195c73 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs @@ -10,8 +10,8 @@ namespace Nethermind.JsonRpc.Modules.Eth; public abstract class ExecutorBase { + private readonly IBlockFinder _blockFinder; protected readonly IBlockchainBridge _blockchainBridge; - protected readonly IBlockFinder _blockFinder; protected readonly IJsonRpcConfig _rpcConfig; protected ExecutorBase(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) @@ -34,8 +34,7 @@ public virtual ResultWrapper Execute( BlockHeader header = searchResult.Object; if (!_blockchainBridge.HasStateForBlock(header!)) { - return ResultWrapper.Fail($"No state available for block {header.Hash}", - ErrorCodes.ResourceUnavailable); + return ResultWrapper.Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable); } using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); @@ -47,6 +46,6 @@ public virtual ResultWrapper Execute( protected abstract ResultWrapper Execute(BlockHeader header, TProcessing tx, CancellationToken token); - protected ResultWrapper GetInputError(CallOutput result) => - ResultWrapper.Fail(result.Error, ErrorCodes.InvalidInput); + protected ResultWrapper? TryGetInputError(CallOutput result) => + result.InputError ? ResultWrapper.Fail(result.Error!, ErrorCodes.InvalidInput) : null; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index e476bc2c7fd..1c7dd06bf9f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -7,6 +7,7 @@ using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Facade; +using Nethermind.Facade.Multicall; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; @@ -21,7 +22,7 @@ public MultiCallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder bloc protected override MultiCallPayload Prepare(MultiCallPayload call) { - var result = new MultiCallPayload + MultiCallPayload? result = new() { TraceTransfers = call.TraceTransfers, Validation = call.Validation, @@ -43,15 +44,11 @@ protected override MultiCallPayload Prepare(MultiCallPayload> Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) { - MultiCallOutput results = _blockchainBridge.MultiCall(header.Clone(), tx, token); - - if (results.Error == null) - { - return ResultWrapper>.Success(results.Items); - } - - return ResultWrapper>.Fail(results.Error, results.Items); + MultiCallOutput results = _blockchainBridge.MultiCall(header, tx, token); + return results.Error is null + ? ResultWrapper>.Success(results.Items) + : ResultWrapper>.Fail(results.Error, results.Items); } } diff --git a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs index b8e311bd306..954a9d7e992 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs @@ -24,8 +24,6 @@ namespace Nethermind.Merge.AuRa; public class AuRaMergeBlockProducerEnvFactory : BlockProducerEnvFactory { private readonly AuRaNethermindApi _auraApi; - private readonly IAuraConfig _auraConfig; - private readonly DisposableStack _disposeStack; public AuRaMergeBlockProducerEnvFactory( AuRaNethermindApi auraApi, @@ -57,8 +55,6 @@ public AuRaMergeBlockProducerEnvFactory( logManager) { _auraApi = auraApi; - _auraConfig = auraConfig; - _disposeStack = disposeStack; } protected override BlockProcessor CreateBlockProcessor( diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs index 2460ac097f4..892238d3817 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs @@ -36,8 +36,7 @@ public void Setup() BlocksConfig? miningConfig = new(); IJsonRpcConfig jsonRpcConfig = new JsonRpcConfig() { Enabled = true, EnabledModules = new[] { "engine" } }; - _context = Build.ContextWithMocks(); - _context.SealEngineType = SealEngineType.Clique; + _context = Build.ContextWithMocks(SealEngineType.Clique); _context.ConfigProvider.GetConfig().Returns(_mergeConfig); _context.ConfigProvider.GetConfig().Returns(new SyncConfig()); _context.ConfigProvider.GetConfig().Returns(miningConfig); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/PluginTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/PluginTests.cs index 90e84220381..81a63cbb852 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/PluginTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/PluginTests.cs @@ -8,6 +8,7 @@ namespace Nethermind.Merge.Plugin.Test { [TestFixture] [Parallelizable(ParallelScope.All)] + [SetCulture("en-US")] public class PluginTests { [Test] diff --git a/src/Nethermind/Nethermind.Mev.Test/PluginTests.cs b/src/Nethermind/Nethermind.Mev.Test/PluginTests.cs index 4ba1a0d8822..f0fc74c1e2e 100644 --- a/src/Nethermind/Nethermind.Mev.Test/PluginTests.cs +++ b/src/Nethermind/Nethermind.Mev.Test/PluginTests.cs @@ -8,6 +8,7 @@ namespace Nethermind.Mev.Test { [TestFixture] [Parallelizable(ParallelScope.All)] + [SetCulture("en-US")] public class PluginTests { [Test] diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index 2e1f9e53fc8..729bfd1dc96 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -15,6 +15,7 @@ using Nethermind.Consensus.Producers; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; +using Nethermind.Core; using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Db; @@ -49,8 +50,13 @@ namespace Nethermind.Runner.Test.Ethereum { public static class Build { - public static NethermindApi ContextWithMocks() => - new(Substitute.For(), Substitute.For(), LimboLogs.Instance, new ChainSpec()) + public static NethermindApi ContextWithMocks(string sealEngine = SealEngineType.Ethash) => + new( + Substitute.For(), + Substitute.For(), + LimboLogs.Instance, + new ChainSpec { SealEngineType = sealEngine }, + Substitute.For()) { Enode = Substitute.For(), TxPool = Substitute.For(), @@ -60,7 +66,6 @@ public static NethermindApi ContextWithMocks() => DbProvider = TestMemDbProvider.Init(), PeerManager = Substitute.For(), PeerPool = Substitute.For(), - SpecProvider = Substitute.For(), EthereumEcdsa = Substitute.For(), MainBlockProcessor = Substitute.For(), ReceiptStorage = Substitute.For(), diff --git a/src/Nethermind/Nethermind.Runner.Test/StandardTests.cs b/src/Nethermind/Nethermind.Runner.Test/StandardTests.cs index 6724ebee562..46968471443 100644 --- a/src/Nethermind/Nethermind.Runner.Test/StandardTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/StandardTests.cs @@ -8,6 +8,7 @@ namespace Nethermind.Runner.Test { [TestFixture] [Parallelizable(ParallelScope.All)] + [SetCulture("en-US")] public class StandardTests { [Test] diff --git a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs index 5b4859c293e..068c4416b20 100644 --- a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs +++ b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs @@ -48,15 +48,11 @@ public INethermindApi Create(IEnumerable consensusPlugins) throw new NotSupportedException("Creation of multiple APIs not supported."); } - string engine = chainSpec.SealEngineType; - IConsensusPlugin? enginePlugin = consensusPlugins.FirstOrDefault(p => p.SealEngineType == engine); + IConsensusPlugin? enginePlugin = consensusPlugins.FirstOrDefault(p => p.SealEngineType == chainSpec.SealEngineType); INethermindApi nethermindApi = enginePlugin?.CreateApi(_configProvider, _jsonSerializer, _logManager, chainSpec) ?? new NethermindApi(_configProvider, _jsonSerializer, _logManager, chainSpec); - nethermindApi.SealEngineType = engine; - nethermindApi.SpecProvider = new ChainSpecBasedSpecProvider(chainSpec, _logManager); - nethermindApi.GasLimitCalculator = new FollowOtherMiners(nethermindApi.SpecProvider); SetLoggerVariables(chainSpec); diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs index 8dc6b19e959..9137f50e7b1 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs @@ -11,7 +11,7 @@ namespace Nethermind.Specs.ChainSpecStyle { /// /// https://github.com/ethereum/wiki/wiki/Ethereum-Chain-Spec-Format - /// https://wiki.parity.io/Chain-specification + /// https://wiki.parity.io/Chain-specification /// [DebuggerDisplay("{Name}, ChainId = {ChainId}")] public class ChainSpec @@ -39,7 +39,7 @@ public class ChainSpec public EthashParameters Ethash { get; set; } - public ChainParameters Parameters { get; set; } + public ChainParameters Parameters { get; set; } = new(); public Dictionary Allocations { get; set; } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs index 85d8226e2d4..21626986c09 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs @@ -15,9 +15,8 @@ namespace Nethermind.Specs.ChainSpecStyle { public class ChainSpecBasedSpecProvider : ISpecProvider { - private (ForkActivation Activation, ReleaseSpec Spec)[] _transitions; - private ForkActivation? _firstTimestampActivation; - + private readonly (ForkActivation Activation, ReleaseSpec Spec)[] _transitions; + private readonly ForkActivation? _firstTimestampActivation; private readonly ChainSpec _chainSpec; private readonly ILogger _logger; @@ -25,10 +24,10 @@ public ChainSpecBasedSpecProvider(ChainSpec chainSpec, ILogManager logManager = { _chainSpec = chainSpec ?? throw new ArgumentNullException(nameof(chainSpec)); _logger = logManager?.GetClassLogger() ?? LimboTraceLogger.Instance; - BuildTransitions(); + (_transitions, TransitionActivations, _firstTimestampActivation) = BuildTransitions(); } - private void BuildTransitions() + private ((ForkActivation, ReleaseSpec Spec)[], ForkActivation[], ForkActivation) BuildTransitions() { SortedSet transitionBlockNumbers = new(); SortedSet transitionTimestamps = new(); @@ -93,16 +92,17 @@ static void Add(SortedSet transitions, T value, T? minValueExclusive) transitionBlockNumbers.Add(bombDelay.Key); } - TransitionActivations = CreateTransitionActivations(transitionBlockNumbers, transitionTimestamps); - _transitions = CreateTransitions(_chainSpec, transitionBlockNumbers, transitionTimestamps); - _firstTimestampActivation = TransitionActivations.FirstOrDefault(t => t.Timestamp is not null); - if (_chainSpec.Parameters.TerminalPoWBlockNumber is not null) { MergeBlockNumber = (ForkActivation)(_chainSpec.Parameters.TerminalPoWBlockNumber + 1); } TerminalTotalDifficulty = _chainSpec.Parameters.TerminalTotalDifficulty; + + ForkActivation[] transitionActivations = CreateTransitionActivations(transitionBlockNumbers, transitionTimestamps); + return (CreateTransitions(_chainSpec, transitionBlockNumbers, transitionTimestamps), + transitionActivations, + transitionActivations.FirstOrDefault(t => t.Timestamp is not null)); } private static (ForkActivation, ReleaseSpec Spec)[] CreateTransitions( diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs index c1bebc53a84..f2349d5a536 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs @@ -273,7 +273,8 @@ private SyncTestContext CreateSyncManager(int index) TxPool.TxPool txPool = new(ecdsa, new ChainHeadInfoProvider(specProvider, tree, stateReader), new TxPoolConfig(), new TxValidator(specProvider.ChainId), logManager, transactionComparerProvider.GetDefaultComparer()); BlockhashProvider blockhashProvider = new(tree, LimboLogs.Instance); - VirtualMachine virtualMachine = new(blockhashProvider, specProvider, logManager); + CodeInfoRepository codeInfoRepository = new(); + VirtualMachine virtualMachine = new(blockhashProvider, specProvider, codeInfoRepository, logManager); Always sealValidator = Always.Valid; HeaderValidator headerValidator = new(tree, sealValidator, specProvider, logManager); @@ -288,7 +289,7 @@ private SyncTestContext CreateSyncManager(int index) RewardCalculator rewardCalculator = new(specProvider); TransactionProcessor txProcessor = - new(specProvider, stateProvider, virtualMachine, logManager); + new(specProvider, stateProvider, virtualMachine, codeInfoRepository, logManager); BlockProcessor blockProcessor = new( specProvider, @@ -309,8 +310,8 @@ private SyncTestContext CreateSyncManager(int index) SyncPeerPool syncPeerPool = new(tree, nodeStatsManager, new TotalDifficultyBetterPeerStrategy(LimboLogs.Instance), logManager, 25); WorldState devState = new(trieStore, codeDb, logManager); - VirtualMachine devEvm = new(blockhashProvider, specProvider, logManager); - TransactionProcessor devTxProcessor = new(specProvider, devState, devEvm, logManager); + VirtualMachine devEvm = new(blockhashProvider, specProvider, codeInfoRepository, logManager); + TransactionProcessor devTxProcessor = new(specProvider, devState, devEvm, codeInfoRepository, logManager); BlockProcessor devBlockProcessor = new( specProvider, diff --git a/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs b/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs index add3b75fb34..b6888c71d0e 100644 --- a/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs +++ b/src/Nethermind/Nethermind.TxPool/TransactionExtensions.cs @@ -23,7 +23,7 @@ public static int GetLength(this Transaction tx) public static bool CanBeBroadcast(this Transaction tx) => !tx.SupportsBlobs && tx.GetLength() <= MaxSizeOfTxForBroadcast; - public static UInt256 CalculateGasPrice(this Transaction tx, bool eip1559Enabled, in UInt256 baseFee) + internal static UInt256 CalculateGasPrice(this Transaction tx, bool eip1559Enabled, in UInt256 baseFee) { if (eip1559Enabled && tx.Supports1559) { From 0603dd7bfe5de18c39cebc6a18a00389a990dcee Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 11 Oct 2023 10:09:11 +0100 Subject: [PATCH 086/213] Merge 1.22 --- src/Nethermind/Directory.Packages.props | 2 +- .../KeyAddressTests.cs | 2 +- .../Ethereum.Test.Base/JsonToEthereumTest.cs | 8 +- .../Validators/TxValidatorTests.cs | 8 +- .../Nethermind.Blockchain/KnownChainSizes.cs | 4 +- .../Builders/AccessListBuilder.cs | 4 +- .../Eip2930/AccessListTests.cs | 200 +++++++++++++++++ .../Encoding/AccessListDecoderTests.cs | 121 ++++++----- .../Encoding/TxDecoderTests.cs | 47 +++- .../Collections/EnuberableExtensions.cs | 3 + .../Nethermind.Core/Eip2930/AccessList.cs | 113 ++++++++-- .../Eip2930/AccessListBuilder.cs | 62 ------ .../Nethermind.Db.Rocks/ColumnDb.cs | 2 +- .../Nethermind.Db.Rocks/Config/DbConfig.cs | 4 + .../Nethermind.Db.Rocks/Config/IDbConfig.cs | 4 + .../Config/PerTableDbConfig.cs | 2 + .../Nethermind.Db.Rocks/DbOnTheRocks.cs | 203 +++++++++--------- .../Nethermind.Db.Test/DbOnTheRocksTests.cs | 18 ++ .../Configs/EthStatsConfig.cs | 1 + .../Nethermind.EthStats/EthStatsPlugin.cs | 12 +- .../Nethermind.EthStats/IEthStatsConfig.cs | 9 +- .../Integrations/EthStatsIntegration.cs | 39 ++-- .../IntrinsicGasCalculatorTests.cs | 4 +- .../Tracing/AccessTxTracerTests.cs | 17 +- .../TransactionProcessorTests.cs | 4 +- src/Nethermind/Nethermind.Evm/EvmState.cs | 4 +- .../Nethermind.Evm/IntrinsicGasCalculator.cs | 36 +--- .../Nethermind.Evm/Tracing/AccessTxTracer.cs | 12 +- .../Nethermind.Init/Steps/LoadGenesisBlock.cs | 8 +- .../Data/AccessListItemForRpcTests.cs | 115 ++++++++++ .../Data/Eip2930Tests.cs | 64 ++---- .../Data/AccessListForRpc.cs | 7 +- .../Data/AccessListItemForRpc.cs | 33 +-- .../Data/TransactionForRpc.cs | 3 +- .../Eth/EthRpcModule.TransactionExecutor.cs | 6 +- .../AuRaMergeEngineModuleTests.cs | 108 +++++----- .../EngineModuleTests.HelperFunctions.cs | 46 ++-- .../EngineModuleTests.Setup.cs | 14 +- .../EngineModuleTests.Synchronization.cs | 42 ++-- .../EngineModuleTests.V1.cs | 61 +++--- .../EngineModuleTests.V2.cs | 8 +- .../EngineModuleTests.V3.cs | 90 ++++++-- .../EngineRpcModule.Paris.cs | 11 +- .../Handlers/ForkchoiceUpdatedHandler.cs | 38 +++- .../Handlers/IForkchoiceUpdatedHandler.cs | 2 +- .../Nethermind.Merge.Plugin/MergePlugin.cs | 1 + .../Nethermind.Runner/configs/chiado.cfg | 4 +- .../Nethermind.Runner/configs/energyweb.cfg | 6 +- .../Nethermind.Runner/configs/exosama.cfg | 6 +- .../Nethermind.Runner/configs/gnosis.cfg | 4 +- .../Nethermind.Runner/configs/goerli.cfg | 4 +- .../Nethermind.Runner/configs/mainnet.cfg | 4 +- .../Nethermind.Runner/configs/sepolia.cfg | 4 +- .../Nethermind.Runner/configs/volta.cfg | 6 +- .../Eip2930/AccessListDecoder.cs | 174 +++------------ .../Nethermind.Trie.Test/TrieNodeTests.cs | 1 + .../Nethermind.Trie/Pruning/TrieStore.cs | 2 - src/bench_precompiles | 2 +- 58 files changed, 1090 insertions(+), 729 deletions(-) create mode 100644 src/Nethermind/Nethermind.Core.Test/Eip2930/AccessListTests.cs delete mode 100644 src/Nethermind/Nethermind.Core/Eip2930/AccessListBuilder.cs create mode 100644 src/Nethermind/Nethermind.JsonRpc.Test/Data/AccessListItemForRpcTests.cs diff --git a/src/Nethermind/Directory.Packages.props b/src/Nethermind/Directory.Packages.props index e6e44f4b492..d0a4803027f 100644 --- a/src/Nethermind/Directory.Packages.props +++ b/src/Nethermind/Directory.Packages.props @@ -9,7 +9,7 @@ - + diff --git a/src/Nethermind/Ethereum.KeyAddress.Test/KeyAddressTests.cs b/src/Nethermind/Ethereum.KeyAddress.Test/KeyAddressTests.cs index 7881bf48506..cc25a50d7e6 100644 --- a/src/Nethermind/Ethereum.KeyAddress.Test/KeyAddressTests.cs +++ b/src/Nethermind/Ethereum.KeyAddress.Test/KeyAddressTests.cs @@ -75,7 +75,7 @@ public void Signature_as_expected(KeyAddressTest test) string expectedSigHex = expectedSig.ToString(); Address expectedAddress = new Address(test.Address); - Assert.That(actualAddress, Is.EqualTo(expectedAddress), "address vs adress from private key"); + Assert.That(actualAddress, Is.EqualTo(expectedAddress), "address vs address from private key"); Address recoveredActualAddress = _ecdsa.RecoverAddress(actualSig, Keccak.OfAnEmptyString); Assert.That(recoveredActualAddress, Is.EqualTo(actualAddress)); diff --git a/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs b/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs index 0d35a806141..1e744eb6f8e 100644 --- a/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs +++ b/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs @@ -136,13 +136,13 @@ public static Transaction Convert(PostStateJson postStateJson, TransactionJson t transaction.Signature = new Signature(1, 1, 27); transaction.Hash = transaction.CalculateHash(); - AccessListBuilder builder = new(); + AccessList.Builder builder = new(); ProcessAccessList(transactionJson.AccessLists is not null ? transactionJson.AccessLists[postStateJson.Indexes.Data] : transactionJson.AccessList, builder); - transaction.AccessList = builder.ToAccessList(); + transaction.AccessList = builder.Build(); - if (transaction.AccessList.Data.Count != 0) + if (transaction.AccessList.AsEnumerable().Count() != 0) transaction.Type = TxType.AccessList; else transaction.AccessList = null; @@ -153,7 +153,7 @@ public static Transaction Convert(PostStateJson postStateJson, TransactionJson t return transaction; } - private static void ProcessAccessList(AccessListItemJson[]? accessList, AccessListBuilder builder) + private static void ProcessAccessList(AccessListItemJson[]? accessList, AccessList.Builder builder) { foreach (AccessListItemJson accessListItemJson in accessList ?? Array.Empty()) { diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Validators/TxValidatorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Validators/TxValidatorTests.cs index 3748d32c837..e952d079701 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Validators/TxValidatorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Validators/TxValidatorTests.cs @@ -154,7 +154,7 @@ public bool Before_eip_2930_has_to_be_legacy_tx(TxType txType, bool eip2930) .WithType(txType > TxType.AccessList ? TxType.Legacy : txType) .WithChainId(TestBlockchainIds.ChainId) .WithAccessList(txType == TxType.AccessList - ? new AccessList(new Dictionary>()) + ? AccessList.Empty() : null) .WithSignature(signature).TestObject; @@ -185,7 +185,7 @@ public bool Before_eip_1559_has_to_be_legacy_or_access_list_tx(TxType txType, bo .WithMaxPriorityFeePerGas(txType == TxType.EIP1559 ? 10.GWei() : 5.GWei()) .WithMaxFeePerGas(txType == TxType.EIP1559 ? 10.GWei() : 5.GWei()) .WithAccessList(txType == TxType.AccessList || txType == TxType.EIP1559 - ? new AccessList(new Dictionary>()) + ? AccessList.Empty() : null) .WithSignature(signature).TestObject; @@ -210,7 +210,7 @@ public bool Chain_Id_required_for_non_legacy_transactions_after_Berlin(TxType tx Transaction tx = Build.A.Transaction .WithType(txType > TxType.AccessList ? TxType.Legacy : txType) .WithAccessList(txType == TxType.AccessList - ? new AccessList(new Dictionary>()) + ? AccessList.Empty() : null) .WithSignature(signature).TestObject; @@ -240,7 +240,7 @@ public bool MaxFeePerGas_is_required_to_be_greater_than_MaxPriorityFeePerGas(TxT .WithMaxPriorityFeePerGas((UInt256)maxPriorityFeePerGas) .WithMaxFeePerGas((UInt256)maxFeePerGas) .WithAccessList(txType == TxType.AccessList - ? new AccessList(new Dictionary>()) + ? AccessList.Empty() : null) .WithChainId(TestBlockchainIds.ChainId) .WithSignature(signature).TestObject; diff --git a/src/Nethermind/Nethermind.Blockchain/KnownChainSizes.cs b/src/Nethermind/Nethermind.Blockchain/KnownChainSizes.cs index cef3caa8cee..28724697b02 100644 --- a/src/Nethermind/Nethermind.Blockchain/KnownChainSizes.cs +++ b/src/Nethermind/Nethermind.Blockchain/KnownChainSizes.cs @@ -76,8 +76,8 @@ public static IChainEstimations CreateChainSizeInfo(ulong chainId) BlockchainIds.Mainnet => new ChainEstimations( new LinearExtrapolation(167.GB(), 70.MB(), new DateTime(2023, 07, 14)), new LinearExtrapolation( - 172553555637, new DateTime(2023, 05, 18, 18, 12, 0), - 177439054863, new DateTime(2023, 06, 8, 02, 36, 0))), + 177439054863, new DateTime(2023, 06, 8, 02, 36, 0), + 188742060333, new DateTime(2023, 09, 26, 19, 32, 0))), BlockchainIds.Gnosis => new ChainEstimations( new LinearExtrapolation(18000.MB(), 48.MB(), new DateTime(2021, 12, 7))), BlockchainIds.EnergyWeb => new ChainEstimations( diff --git a/src/Nethermind/Nethermind.Core.Test/Builders/AccessListBuilder.cs b/src/Nethermind/Nethermind.Core.Test/Builders/AccessListBuilder.cs index 1bfc8b34b9c..2076ff7d95d 100644 --- a/src/Nethermind/Nethermind.Core.Test/Builders/AccessListBuilder.cs +++ b/src/Nethermind/Nethermind.Core.Test/Builders/AccessListBuilder.cs @@ -9,12 +9,12 @@ public class TestAccessListBuilder : BuilderBase { public TestAccessListBuilder() { - AccessListBuilder accessListBuilder = new(); + AccessList.Builder accessListBuilder = new(); foreach (Address address in TestItem.Addresses.Take(5)) { accessListBuilder.AddAddress(address); } - TestObjectInternal = accessListBuilder.ToAccessList(); + TestObjectInternal = accessListBuilder.Build(); } } diff --git a/src/Nethermind/Nethermind.Core.Test/Eip2930/AccessListTests.cs b/src/Nethermind/Nethermind.Core.Test/Eip2930/AccessListTests.cs new file mode 100644 index 00000000000..c6978eda415 --- /dev/null +++ b/src/Nethermind/Nethermind.Core.Test/Eip2930/AccessListTests.cs @@ -0,0 +1,200 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using FluentAssertions; +using Nethermind.Core.Eip2930; +using Nethermind.Core.Test.Builders; +using Nethermind.Int256; +using NUnit.Framework; + +namespace Nethermind.Core.Test.Eip2930; + +public class AccessListTests +{ + [Test] + public void Single_address_with_multiple_storage_keys() + { + Address address = TestItem.AddressA; + UInt256 storageKey1 = (UInt256)1; + UInt256 storageKey2 = (UInt256)2; + UInt256 storageKey3 = (UInt256)3; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address) + .AddStorage(storageKey1) + .AddStorage(storageKey2) + .AddStorage(storageKey3) + .Build(); + + IEnumerable<(Address, IEnumerable)> expected = new List<(Address, IEnumerable)> + { + (address, new[] { storageKey1, storageKey2, storageKey3 }) + }; + + accessList.Should().BeEquivalentTo(expected); + } + + [Test] + public void Single_address_with_duplicated_storage_keys() + { + Address address = TestItem.AddressA; + UInt256 storageKey1 = (UInt256)1; + UInt256 storageKey2 = (UInt256)2; + UInt256 storageKey3 = (UInt256)3; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address) + .AddStorage(storageKey1) + .AddStorage(storageKey2) + .AddStorage(storageKey3) + .AddStorage(storageKey1) + .Build(); + + IEnumerable<(Address, IEnumerable)> expected = new List<(Address, IEnumerable)> + { + (address, new[] { storageKey1, storageKey2, storageKey3, storageKey1 }) + }; + + accessList.Should().BeEquivalentTo(expected); + } + + [Test] + public void Duplicated_address_with_multiple_storage_keys() + { + Address address = TestItem.AddressA; + UInt256 storageKey1 = (UInt256)1; + UInt256 storageKey2 = (UInt256)2; + UInt256 storageKey3 = (UInt256)3; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address) + .AddStorage(storageKey1) + .AddStorage(storageKey2) + .AddAddress(address) + .AddStorage(storageKey3) + .Build(); + + IEnumerable<(Address, IEnumerable)> expected = new List<(Address, IEnumerable)> + { + (address, new[] { storageKey1, storageKey2 }), + (address, new[] { storageKey3 }) + }; + + accessList.Should().BeEquivalentTo(expected); + } + + [Test] + public void Duplicated_address_with_duplicated_storage_keys() + { + Address address = TestItem.AddressA; + UInt256 storageKey1 = (UInt256)1; + UInt256 storageKey2 = (UInt256)2; + UInt256 storageKey3 = (UInt256)3; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address) + .AddStorage(storageKey1) + .AddStorage(storageKey2) + .AddAddress(address) + .AddStorage(storageKey1) + .AddStorage(storageKey3) + .Build(); + + IEnumerable<(Address, IEnumerable)> expected = new List<(Address, IEnumerable)> + { + (address, new[] { storageKey1, storageKey2 }), + (address, new[] { storageKey1, storageKey3 }) + }; + + accessList.Should().BeEquivalentTo(expected); + } + + [Test] + public void Multiple_addresses_no_storage() + { + Address address1 = TestItem.AddressA; + Address address2 = TestItem.AddressB; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address1) + .AddAddress(address2) + .Build(); + + IEnumerable<(Address, IEnumerable)> expected = new List<(Address, IEnumerable)> + { + (address1, new UInt256[] { }), + (address2, new UInt256[] { }) + }; + + accessList.Should().BeEquivalentTo(expected); + } + + [Test] + public void Multiple_addresses_with_storage() + { + Address address1 = TestItem.AddressA; + Address address2 = TestItem.AddressB; + UInt256 storageKey1 = (UInt256)1; + UInt256 storageKey2 = (UInt256)2; + UInt256 storageKey3 = (UInt256)3; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address1) + .AddStorage(storageKey1) + .AddStorage(storageKey2) + .AddAddress(address2) + .AddStorage(storageKey3) + .Build(); + + IEnumerable<(Address, IEnumerable)> expected = new List<(Address, IEnumerable)> + { + (address1, new[] { storageKey1, storageKey2 }), + (address2, new[] { storageKey3 }) + }; + + accessList.Should().BeEquivalentTo(expected); + } + + [Test] + public void Multiple_duplicated_addresses_with_storage() + { + Address address1 = TestItem.AddressA; + Address address2 = TestItem.AddressB; + UInt256 storageKey1 = (UInt256)1; + UInt256 storageKey2 = (UInt256)2; + UInt256 storageKey3 = (UInt256)3; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address1) + .AddStorage(storageKey1) + .AddStorage(storageKey2) + .AddAddress(address2) + .AddStorage(storageKey3) + .AddAddress(address1) + .AddStorage(storageKey1) + .AddAddress(address2) + .Build(); + + IEnumerable<(Address, IEnumerable)> expected = new List<(Address, IEnumerable)> + { + (address1, new[] { storageKey1, storageKey2 }), + (address2, new[] { storageKey3 }), + (address1, new[] { storageKey1 }), + (address2, new UInt256[] { }), + }; + + accessList.Should().BeEquivalentTo(expected); + } + + [Test] + public void Invalid_storage_when_no_previous_address() + { + Assert.Throws(() => + { + AccessList.Builder _ = new AccessList.Builder() + .AddStorage(UInt256.Zero); + }); + } +} diff --git a/src/Nethermind/Nethermind.Core.Test/Encoding/AccessListDecoderTests.cs b/src/Nethermind/Nethermind.Core.Test/Encoding/AccessListDecoderTests.cs index 5cd844d9733..76579f93489 100644 --- a/src/Nethermind/Nethermind.Core.Test/Encoding/AccessListDecoderTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Encoding/AccessListDecoderTests.cs @@ -5,7 +5,6 @@ using FluentAssertions; using Nethermind.Core.Eip2930; using Nethermind.Core.Test.Builders; -using Nethermind.Int256; using Nethermind.Serialization.Rlp; using Nethermind.Serialization.Rlp.Eip2930; using NUnit.Framework; @@ -17,71 +16,77 @@ public class AccessListDecoderTests { private readonly AccessListDecoder _decoder = new(); - public static IEnumerable<(string, AccessList)> TestCaseSource() + public static IEnumerable<(string, AccessList?)> TestCaseSource() { - yield return ("null", null!); + yield return ( + "null", + null); - HashSet indexes = new(); - Dictionary> data = new(); - // yield return ("empty", new AccessList(data)); <-- null and empty are equivalent here - // - indexes = new HashSet(); - data = new Dictionary>(); - data.Add(TestItem.AddressA, indexes); - yield return ("no storage", new AccessList(data)); + // yield return ("empty", AccessList.Empty()); <-- null and empty are equivalent here - indexes = new HashSet(); - data = new Dictionary>(); - data.Add(TestItem.AddressA, indexes); - data.Add(TestItem.AddressB, indexes); - yield return ("no storage 2", new AccessList(data)); + yield return ( + "no storage", + new AccessList.Builder() + .AddAddress(TestItem.AddressA) + .Build()); - indexes = new HashSet(); - data = new Dictionary>(); - data.Add(TestItem.AddressA, indexes); - indexes.Add(1); - yield return ("1-1", new AccessList(data)); + yield return ( + "no storage 2", + new AccessList.Builder() + .AddAddress(TestItem.AddressA) + .AddAddress(TestItem.AddressB) + .Build()); - indexes = new HashSet(); - data = new Dictionary>(); - data.Add(TestItem.AddressA, indexes); - indexes.Add(1); - indexes.Add(2); - yield return ("1-2", new AccessList(data)); + yield return ( + "1-1", + new AccessList.Builder() + .AddAddress(TestItem.AddressA) + .AddStorage(1) + .Build()); - indexes = new HashSet(); - data = new Dictionary>(); - indexes.Add(1); - indexes.Add(2); - data.Add(TestItem.AddressA, indexes); - data.Add(TestItem.AddressB, indexes); - yield return ("2-2", new AccessList(data)); + yield return ( + "1-2", + new AccessList.Builder() + .AddAddress(TestItem.AddressA) + .AddStorage(1) + .AddStorage(2) + .Build()); - indexes = new HashSet(); - var indexes2 = new HashSet(); - data = new Dictionary>(); - indexes.Add(1); - indexes2.Add(2); - data.Add(TestItem.AddressA, indexes); - data.Add(TestItem.AddressB, indexes2); - AccessList accessList = new(data, - new Queue(new List { TestItem.AddressA, (UInt256)1, TestItem.AddressB, (UInt256)2 })); - yield return ("with order queue", accessList); + yield return ( + "2-1", + new AccessList.Builder() + .AddAddress(TestItem.AddressA) + .AddStorage(1) + .AddAddress(TestItem.AddressB) + .AddStorage(2) + .Build()); - indexes = new HashSet(); - indexes2 = new HashSet(); - data = new Dictionary>(); - indexes.Add(1); - indexes2.Add(2); - data.Add(TestItem.AddressA, indexes); - data.Add(TestItem.AddressB, indexes2); - accessList = new AccessList(data, - new Queue(new List { TestItem.AddressA, (UInt256)1, (UInt256)1, TestItem.AddressB, (UInt256)2, TestItem.AddressB, (UInt256)2 })); - yield return ("with order queue and duplicates", accessList); + yield return ( + "2-2", + new AccessList.Builder() + .AddAddress(TestItem.AddressA) + .AddStorage(1) + .AddStorage(2) + .AddAddress(TestItem.AddressB) + .AddStorage(1) + .AddStorage(2) + .Build()); + + yield return ( + "with duplicates", + new AccessList.Builder() + .AddAddress(TestItem.AddressA) + .AddStorage(1) + .AddStorage(1) + .AddAddress(TestItem.AddressB) + .AddStorage(2) + .AddAddress(TestItem.AddressB) + .AddStorage(2) + .Build()); } [TestCaseSource(nameof(TestCaseSource))] - public void Roundtrip((string TestName, AccessList AccessList) testCase) + public void Roundtrip((string TestName, AccessList? AccessList) testCase) { RlpStream rlpStream = new(10000); _decoder.Encode(rlpStream, testCase.AccessList); @@ -93,12 +98,12 @@ public void Roundtrip((string TestName, AccessList AccessList) testCase) } else { - decoded!.Data.Should().BeEquivalentTo(testCase.AccessList.Data, testCase.TestName); + decoded.Should().BeEquivalentTo(testCase.AccessList, testCase.TestName); } } [TestCaseSource(nameof(TestCaseSource))] - public void Roundtrip_value((string TestName, AccessList AccessList) testCase) + public void Roundtrip_value((string TestName, AccessList? AccessList) testCase) { RlpStream rlpStream = new(10000); _decoder.Encode(rlpStream, testCase.AccessList); @@ -111,7 +116,7 @@ public void Roundtrip_value((string TestName, AccessList AccessList) testCase) } else { - decoded!.Data.Should().BeEquivalentTo(testCase.AccessList.Data, testCase.TestName); + decoded.Should().BeEquivalentTo(testCase.AccessList, testCase.TestName); } } diff --git a/src/Nethermind/Nethermind.Core.Test/Encoding/TxDecoderTests.cs b/src/Nethermind/Nethermind.Core.Test/Encoding/TxDecoderTests.cs index cfb72973507..09f7395c85c 100644 --- a/src/Nethermind/Nethermind.Core.Test/Encoding/TxDecoderTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Encoding/TxDecoderTests.cs @@ -33,11 +33,10 @@ public class TxDecoderTests .WithType(TxType.AccessList) .WithChainId(TestBlockchainIds.ChainId) .WithAccessList( - new AccessList( - new Dictionary> - { - { Address.Zero, new HashSet { (UInt256)1 } } - }, new Queue(new List { Address.Zero, (UInt256)1 }))) + new AccessList.Builder() + .AddAddress(Address.Zero) + .AddStorage(1) + .Build()) .SignedAndResolved(), "access list"); yield return (Build.A.Transaction .WithData(new byte[] { 1, 2, 3 }) @@ -45,11 +44,10 @@ public class TxDecoderTests .WithMaxFeePerGas(30) .WithChainId(TestBlockchainIds.ChainId) .WithAccessList( - new AccessList( - new Dictionary> - { - { Address.Zero, new HashSet { (UInt256)1 } } - }, new Queue(new List { Address.Zero, (UInt256)1 }))) + new AccessList.Builder() + .AddAddress(Address.Zero) + .AddStorage(1) + .Build()) .SignedAndResolved(), "EIP1559 - access list"); yield return (Build.A.Transaction .WithType(TxType.EIP1559) @@ -244,6 +242,35 @@ public void Rlp_encode_should_return_the_same_as_rlp_stream_encoding( Assert.That(rlpStreamResult.Bytes, Is.EqualTo(rlpResult.Bytes)); } + [Test] + public void Duplicate_storage_keys_result_in_different_hashes() + { + Transaction noDuplicates = Build.A.Transaction + .WithType(TxType.EIP1559) + .WithChainId(TestBlockchainIds.ChainId) + .WithAccessList( + new AccessList.Builder() + .AddAddress(Address.Zero) + .AddStorage(1) + .Build()) + .SignedAndResolved() + .TestObject; + + Transaction duplicates = Build.A.Transaction + .WithType(TxType.EIP1559) + .WithChainId(TestBlockchainIds.ChainId) + .WithAccessList( + new AccessList.Builder() + .AddAddress(Address.Zero) + .AddStorage(1) + .AddStorage(1) + .Build()) + .SignedAndResolved() + .TestObject; + + duplicates.CalculateHash().Should().NotBe(noDuplicates.CalculateHash()); + } + public static IEnumerable<(string, Keccak)> SkipTypedWrappingTestCases() { yield return diff --git a/src/Nethermind/Nethermind.Core/Collections/EnuberableExtensions.cs b/src/Nethermind/Nethermind.Core/Collections/EnuberableExtensions.cs index f9f1058b60a..117e202d8a5 100644 --- a/src/Nethermind/Nethermind.Core/Collections/EnuberableExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Collections/EnuberableExtensions.cs @@ -13,4 +13,7 @@ public static void ForEach(this IEnumerable list, Action action) { list.ToList().ForEach(action); } + + public static bool NullableSequenceEqual(this IEnumerable? first, IEnumerable? second) => + first is not null ? second is not null && first.SequenceEqual(second) : second is null; } diff --git a/src/Nethermind/Nethermind.Core/Eip2930/AccessList.cs b/src/Nethermind/Nethermind.Core/Eip2930/AccessList.cs index ab081f810cd..abe0233978b 100644 --- a/src/Nethermind/Nethermind.Core/Eip2930/AccessList.cs +++ b/src/Nethermind/Nethermind.Core/Eip2930/AccessList.cs @@ -1,30 +1,113 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; +using System.Collections; using System.Collections.Generic; using Nethermind.Int256; -namespace Nethermind.Core.Eip2930 +namespace Nethermind.Core.Eip2930; + +public class AccessList : IEnumerable<(Address Address, AccessList.StorageKeysEnumerable StorageKeys)> { - public class AccessList + private readonly List _items; + + private AccessList(List items) + { + _items = items; + } + + public static AccessList Empty() => new(new List()); + + public class Builder { - public AccessList(IReadOnlyDictionary> data, - Queue? orderQueue = null) + private readonly List _items = new(); + private Address? _currentAddress; + + public Builder AddAddress(Address address) { - Data = data; - OrderQueue = orderQueue; + _items.Add(address); + _currentAddress = address; + + return this; } - public IReadOnlyDictionary> Data { get; } + public Builder AddStorage(in UInt256 index) + { + if (_currentAddress is null) + { + throw new InvalidOperationException("No address known when adding index to the access list"); + } + _items.Add(index); - /// - /// Only used for access lists generated outside of Nethermind - /// - public IReadOnlyCollection? OrderQueue { get; } + return this; + } + + public AccessList Build() + { + return new AccessList(_items); + } + } + + public Enumerator GetEnumerator() => new(_items); + IEnumerator<(Address Address, StorageKeysEnumerable StorageKeys)> IEnumerable<(Address Address, StorageKeysEnumerable StorageKeys)>.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public struct Enumerator : IEnumerator<(Address Address, StorageKeysEnumerable StorageKeys)>, IEnumerator<(Address Address, IEnumerable StorageKeys)> + { + private readonly List _items; + private int _index = -1; + + public Enumerator(List items) + { + _items = items; + } + + public bool MoveNext() + { + while (++_index < _items.Count && _items[_index] is not Address) { } + return _index < _items.Count; + } + + public void Reset() => _index = -1; + public (Address Address, StorageKeysEnumerable StorageKeys) Current => ((Address)_items[_index], new StorageKeysEnumerable(_items, _index)); + (Address Address, IEnumerable StorageKeys) IEnumerator<(Address Address, IEnumerable StorageKeys)>.Current => Current; + object IEnumerator.Current => Current; + public void Dispose() { } + } + + public readonly struct StorageKeysEnumerable : IEnumerable + { + private readonly List _items; + private readonly int _index; + + public StorageKeysEnumerable(List items, int index) + { + _items = items; + _index = index; + } + + StorageKeysEnumerator GetEnumerator() => new(_items, _index); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + + public struct StorageKeysEnumerator : IEnumerator + { + private readonly List _items; + private readonly int _startingIndex; + private int _index; + + public StorageKeysEnumerator(List items, int index) + { + _items = items; + _startingIndex = _index = index; + } - /// - /// Has no duplicate entries (allows for more efficient serialization / deserialization) - /// - public bool IsNormalized => OrderQueue is null; + public bool MoveNext() => ++_index < _items.Count && _items[_index] is UInt256; + public void Reset() => _index = _startingIndex; + public UInt256 Current => (UInt256)_items[_index]; + object IEnumerator.Current => Current; + public void Dispose() { } } } diff --git a/src/Nethermind/Nethermind.Core/Eip2930/AccessListBuilder.cs b/src/Nethermind/Nethermind.Core/Eip2930/AccessListBuilder.cs deleted file mode 100644 index ff1d6821bdb..00000000000 --- a/src/Nethermind/Nethermind.Core/Eip2930/AccessListBuilder.cs +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Collections.Generic; -using Nethermind.Int256; - -namespace Nethermind.Core.Eip2930 -{ - /// - /// We store the extra information here to be able to recreate the order of the incoming transactions. - /// EIP-2930 (https://eips.ethereum.org/EIPS/eip-2930) states that: - /// 'Allowing duplicates - /// This is done because it maximizes simplicity, avoiding questions of what to prevent duplication against: - /// just between two addresses/keys in the access list, - /// between the access list and the tx sender/recipient/newly created contract, - /// other restrictions? - /// Because gas is charged per item, there is no gain and only cost in including a value in the access list twice, - /// so this should not lead to extra chain bloat in practice.' - /// - /// While spec is simplified in this matter (somewhat) it leads to a bit more edge cases. - /// We can no longer simply store the access list as a dictionary, we need to store the order of items - /// and info on duplicates. The way that I suggest is by adding an additional queue structure. - /// It be further optimized by only including a queue of integers and a strict ordering algorithm for the dictionary. - /// - /// I leave it for later in case such an optimization is needed. - /// - public class AccessListBuilder - { - private readonly Dictionary> _data = new(); - - private readonly Queue _orderQueue = new(); - - private Address? _currentAddress; - - public void AddAddress(Address address) - { - _currentAddress = address; - _orderQueue.Enqueue(_currentAddress); - if (!_data.ContainsKey(_currentAddress)) - { - _data[_currentAddress] = new HashSet(); - } - } - - public void AddStorage(in UInt256 index) - { - if (_currentAddress is null) - { - throw new InvalidOperationException("No address known when adding index to the access list"); - } - - _orderQueue.Enqueue(index); - (_data[_currentAddress] as HashSet)!.Add(index); - } - - public AccessList ToAccessList() - { - return new(_data, _orderQueue); - } - } -} diff --git a/src/Nethermind/Nethermind.Db.Rocks/ColumnDb.cs b/src/Nethermind/Nethermind.Db.Rocks/ColumnDb.cs index dceb3599a21..1b86a363d86 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/ColumnDb.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/ColumnDb.cs @@ -92,7 +92,7 @@ public void Set(ReadOnlySpan key, byte[]? value, WriteFlags flags = WriteF } else { - _underlyingBatch.Set(key, value, _columnDb._columnFamily); + _underlyingBatch.Set(key, value, _columnDb._columnFamily, flags); } } } diff --git a/src/Nethermind/Nethermind.Db.Rocks/Config/DbConfig.cs b/src/Nethermind/Nethermind.Db.Rocks/Config/DbConfig.cs index 7691485e8de..acd042753ca 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/Config/DbConfig.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/Config/DbConfig.cs @@ -27,6 +27,8 @@ public class DbConfig : IDbConfig public ulong? CompactionReadAhead { get; set; } public IDictionary? AdditionalRocksDbOptions { get; set; } public ulong? MaxBytesForLevelBase { get; set; } = (ulong)256.MiB(); + public ulong TargetFileSizeBase { get; set; } = (ulong)64.MiB(); + public int TargetFileSizeMultiplier { get; set; } = 1; public ulong ReceiptsDbWriteBufferSize { get; set; } = (ulong)8.MiB(); public uint ReceiptsDbWriteBufferNumber { get; set; } = 4; @@ -38,6 +40,7 @@ public class DbConfig : IDbConfig public bool? ReceiptsDbUseDirectReads { get; set; } public bool? ReceiptsDbUseDirectIoForFlushAndCompactions { get; set; } public ulong? ReceiptsDbCompactionReadAhead { get; set; } + public ulong ReceiptsDbTargetFileSizeBase { get; set; } = (ulong)256.MiB(); public IDictionary? ReceiptsDbAdditionalRocksDbOptions { get; set; } public ulong BlocksDbWriteBufferSize { get; set; } = (ulong)8.MiB(); @@ -157,6 +160,7 @@ public class DbConfig : IDbConfig public bool? StateDbUseDirectIoForFlushAndCompactions { get; set; } = false; public ulong? StateDbCompactionReadAhead { get; set; } public bool? StateDbDisableCompression { get; set; } = false; + public int StateDbTargetFileSizeMultiplier { get; set; } = 2; public IDictionary? StateDbAdditionalRocksDbOptions { get; set; } public uint RecycleLogFileNum { get; set; } = 0; diff --git a/src/Nethermind/Nethermind.Db.Rocks/Config/IDbConfig.cs b/src/Nethermind/Nethermind.Db.Rocks/Config/IDbConfig.cs index e0e8933c061..2d8352519fb 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/Config/IDbConfig.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/Config/IDbConfig.cs @@ -28,6 +28,8 @@ public interface IDbConfig : IConfig ulong? CompactionReadAhead { get; set; } IDictionary? AdditionalRocksDbOptions { get; set; } ulong? MaxBytesForLevelBase { get; set; } + ulong TargetFileSizeBase { get; set; } + int TargetFileSizeMultiplier { get; set; } ulong ReceiptsDbWriteBufferSize { get; set; } uint ReceiptsDbWriteBufferNumber { get; set; } @@ -39,6 +41,7 @@ public interface IDbConfig : IConfig bool? ReceiptsDbUseDirectReads { get; set; } bool? ReceiptsDbUseDirectIoForFlushAndCompactions { get; set; } ulong? ReceiptsDbCompactionReadAhead { get; set; } + ulong ReceiptsDbTargetFileSizeBase { get; set; } IDictionary? ReceiptsDbAdditionalRocksDbOptions { get; set; } ulong BlocksDbWriteBufferSize { get; set; } @@ -157,6 +160,7 @@ public interface IDbConfig : IConfig bool? StateDbUseDirectIoForFlushAndCompactions { get; set; } ulong? StateDbCompactionReadAhead { get; set; } bool? StateDbDisableCompression { get; set; } + int StateDbTargetFileSizeMultiplier { get; set; } IDictionary? StateDbAdditionalRocksDbOptions { get; set; } /// diff --git a/src/Nethermind/Nethermind.Db.Rocks/Config/PerTableDbConfig.cs b/src/Nethermind/Nethermind.Db.Rocks/Config/PerTableDbConfig.cs index 0ff698c63c5..9d320f75c93 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/Config/PerTableDbConfig.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/Config/PerTableDbConfig.cs @@ -49,6 +49,8 @@ public PerTableDbConfig(IDbConfig dbConfig, RocksDbSettings rocksDbSettings, str public bool? DisableCompression => ReadConfig(nameof(DisableCompression)); public ulong? CompactionReadAhead => ReadConfig(nameof(CompactionReadAhead)); public ulong MaxBytesForLevelBase => ReadConfig(nameof(MaxBytesForLevelBase)); + public ulong TargetFileSizeBase => ReadConfig(nameof(TargetFileSizeBase)); + public int TargetFileSizeMultiplier => ReadConfig(nameof(TargetFileSizeMultiplier)); private T? ReadConfig(string propertyName) { diff --git a/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs b/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs index 7aba5e70890..218892c69b3 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs @@ -358,6 +358,13 @@ protected virtual void BuildOptions(PerTableDbConfig dbConfig, Options opt options.SetMaxOpenFiles(dbConfig.MaxOpenFiles.Value); } + // Target size of each SST file. + options.SetTargetFileSizeBase(dbConfig.TargetFileSizeBase); + + // Multiply the target size of SST file by this much every level down. Does not have much downside on + // hash based DB, but might disable some move optimization on db with blocknumber key. + options.SetTargetFileSizeMultiplier(dbConfig.TargetFileSizeMultiplier); + if (dbConfig.MaxBytesPerSec.HasValue) { _rateLimiter = @@ -370,12 +377,6 @@ protected virtual void BuildOptions(PerTableDbConfig dbConfig, Options opt int writeBufferNumber = (int)dbConfig.WriteBufferNumber; options.SetMaxWriteBufferNumber(writeBufferNumber); - // Memtable is slower to writes the bigger it gets, but small memtable means small l0 file size, which means - // higher write amp for l0->l1 compaction. This allows multiple memtable to go into one l0 file so that it is - // not too small so it helps with write amp when setting small write buffer. AFAIK that is its only use compared - // to just specifying large write buffer. Sadly, this setting can't dynamically change. - options.SetMinWriteBufferNumberToMerge(2); - lock (_dbsByPath) { _maxThisDbSize += (long)writeBufferSize * writeBufferNumber; @@ -401,21 +402,31 @@ protected virtual void BuildOptions(PerTableDbConfig dbConfig, Options opt // VERY important to reduce stalls. Allow L0->L1 compaction to happen with multiple thread. _rocksDbNative.rocksdb_options_set_max_subcompactions(options.Handle, (uint)Environment.ProcessorCount); - // options.SetLevelCompactionDynamicLevelBytes(true); // only switch on on empty DBs - WriteOptions = new WriteOptions(); - WriteOptions.SetSync(dbConfig - .WriteAheadLogSync); // potential fix for corruption on hard process termination, may cause performance degradation + if (dbConfig.CompactionReadAhead != null && dbConfig.CompactionReadAhead != 0) + { + options.SetCompactionReadaheadSize(dbConfig.CompactionReadAhead.Value); + } - _noWalWrite = new WriteOptions(); - _noWalWrite.SetSync(dbConfig.WriteAheadLogSync); + if (dbConfig.DisableCompression == true) + { + options.SetCompression(Compression.No); + } + + if (dbConfig.EnableDbStatistics) + { + options.EnableStatistics(); + } + options.SetStatsDumpPeriodSec(dbConfig.StatsDumpPeriodSec); + + WriteOptions = CreateWriteOptions(dbConfig); + + _noWalWrite = CreateWriteOptions(dbConfig); _noWalWrite.DisableWal(1); - _lowPriorityWriteOptions = new WriteOptions(); - _lowPriorityWriteOptions.SetSync(dbConfig.WriteAheadLogSync); + _lowPriorityWriteOptions = CreateWriteOptions(dbConfig); Native.Instance.rocksdb_writeoptions_set_low_pri(_lowPriorityWriteOptions.Handle, true); - _lowPriorityAndNoWalWrite = new WriteOptions(); - _lowPriorityAndNoWalWrite.SetSync(dbConfig.WriteAheadLogSync); + _lowPriorityAndNoWalWrite = CreateWriteOptions(dbConfig); _lowPriorityAndNoWalWrite.DisableWal(1); Native.Instance.rocksdb_writeoptions_set_low_pri(_lowPriorityAndNoWalWrite.Handle, true); @@ -430,22 +441,14 @@ protected virtual void BuildOptions(PerTableDbConfig dbConfig, Options opt _readAheadReadOptions.SetReadaheadSize(dbConfig.ReadAheadSize ?? (ulong)256.KiB()); _readAheadReadOptions.SetTailing(true); } + } - if (dbConfig.CompactionReadAhead != null && dbConfig.CompactionReadAhead != 0) - { - options.SetCompactionReadaheadSize(dbConfig.CompactionReadAhead.Value); - } - - if (dbConfig.DisableCompression == true) - { - options.SetCompression(Compression.No); - } - - if (dbConfig.EnableDbStatistics) - { - options.EnableStatistics(); - } - options.SetStatsDumpPeriodSec(dbConfig.StatsDumpPeriodSec); + private WriteOptions CreateWriteOptions(PerTableDbConfig dbConfig) + { + WriteOptions options = new(); + // potential fix for corruption on hard process termination, may cause performance degradation + options.SetSync(dbConfig.WriteAheadLogSync); + return options; } public byte[]? this[ReadOnlySpan key] @@ -788,20 +791,26 @@ public IBatch StartBatch() internal class RocksDbBatch : IBatch { - private const int InitialBatchSize = 300; - private static readonly int MaxCached = Environment.ProcessorCount; - - private static ConcurrentQueue> s_cache = new(); - private readonly DbOnTheRocks _dbOnTheRocks; + private WriteBatch _rocksBatch; private WriteFlags _writeFlags = WriteFlags.None; private bool _isDisposed; - private SpanDictionary _batchData = CreateOrGetFromCache(); + [ThreadStatic] + private static WriteBatch? _reusableWriteBatch; + + /// + /// Because of how rocksdb parallelize writes, a large write batch can stall other new concurrent writes, so + /// we writes the batch in smaller batches. This removes atomicity so its only turned on when NoWAL flag is on. + /// It does not work as well as just turning on unordered_write, but Snapshot and Iterator can still works. + /// + private const int MaxWritesOnNoWal = 128; + private int _writeCount; public RocksDbBatch(DbOnTheRocks dbOnTheRocks) { _dbOnTheRocks = dbOnTheRocks; + _rocksBatch = CreateWriteBatch(); if (_dbOnTheRocks._isDisposing) { @@ -809,6 +818,28 @@ public RocksDbBatch(DbOnTheRocks dbOnTheRocks) } } + private static WriteBatch CreateWriteBatch() + { + if (_reusableWriteBatch == null) return new WriteBatch(); + + WriteBatch batch = _reusableWriteBatch; + _reusableWriteBatch = null; + return batch; + } + + private static void ReturnWriteBatch(WriteBatch batch) + { + Native.Instance.rocksdb_writebatch_data(batch.Handle, out UIntPtr size); + if (size > (uint)16.KiB() || _reusableWriteBatch != null) + { + batch.Dispose(); + return; + } + + batch.Clear(); + _reusableWriteBatch = batch; + } + public void Dispose() { if (_dbOnTheRocks._isDisposed) @@ -822,37 +853,11 @@ public void Dispose() } _isDisposed = true; - SpanDictionary batchData = _batchData; - // Clear the _batchData reference so is null if Get is called. - _batchData = null!; - if (batchData.Count == 0) - { - // No data to write, skip empty batches - ReturnToCache(batchData); - _dbOnTheRocks._currentBatches.TryRemove(this); - return; - } - try { - WriteBatch rocksBatch = new(); - // Sort the batch by key - foreach (var kv in batchData.OrderBy(i => i.Key, Bytes.Comparer)) - { - if (kv.Value.data is null) - { - rocksBatch.Delete(kv.Key, kv.Value.cf); - } - else - { - rocksBatch.Put(kv.Key, kv.Value.data, kv.Value.cf); - } - } - ReturnToCache(batchData); - - _dbOnTheRocks._db.Write(rocksBatch, _dbOnTheRocks.WriteFlagsToWriteOptions(_writeFlags)); + _dbOnTheRocks._db.Write(_rocksBatch, _dbOnTheRocks.WriteFlagsToWriteOptions(_writeFlags)); _dbOnTheRocks._currentBatches.TryRemove(this); - rocksBatch.Dispose(); + ReturnWriteBatch(_rocksBatch); } catch (RocksDbSharpException e) { @@ -864,7 +869,9 @@ public void Dispose() public byte[]? Get(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) { // Not checking _isDisposing here as for some reason, sometimes is is read after dispose - return _batchData?.TryGetValue(key, out var value) ?? false ? value.data : _dbOnTheRocks.Get(key, flags); + // Note: The batch itself is not checked. Will need to use WriteBatchWithIndex to do that, but that will + // hurt perf. + return _dbOnTheRocks.Get(key, flags); } public void Delete(ReadOnlySpan key, ColumnFamilyHandle? cf = null) @@ -874,17 +881,20 @@ public void Delete(ReadOnlySpan key, ColumnFamilyHandle? cf = null) throw new ObjectDisposedException($"Attempted to write a disposed batch {_dbOnTheRocks.Name}"); } - _batchData[key] = (null, cf); + _rocksBatch.Delete(key, cf); } - public void Set(ReadOnlySpan key, byte[]? value, ColumnFamilyHandle? cf = null) + public void Set(ReadOnlySpan key, byte[]? value, ColumnFamilyHandle? cf = null, WriteFlags flags = WriteFlags.None) { if (_isDisposed) { throw new ObjectDisposedException($"Attempted to write a disposed batch {_dbOnTheRocks.Name}"); } - _batchData[key] = (value, cf); + _rocksBatch.Put(key, value, cf); + _writeFlags = flags; + + if ((flags & WriteFlags.DisableWAL) != 0) FlushOnTooManyWrites(); } public void Set(ReadOnlySpan key, byte[]? value, WriteFlags flags = WriteFlags.None) @@ -894,28 +904,28 @@ public void Set(ReadOnlySpan key, byte[]? value, WriteFlags flags = WriteF throw new ObjectDisposedException($"Attempted to write a disposed batch {_dbOnTheRocks.Name}"); } - _batchData[key] = (value, null); - + _rocksBatch.Put(key, value); _writeFlags = flags; - } - private static SpanDictionary CreateOrGetFromCache() - { - if (s_cache.TryDequeue(out SpanDictionary? batchData)) - { - return batchData; - } - - return new(InitialBatchSize, Bytes.SpanEqualityComparer); + if ((flags & WriteFlags.DisableWAL) != 0) FlushOnTooManyWrites(); } - private static void ReturnToCache(SpanDictionary batchData) + private void FlushOnTooManyWrites() { - if (s_cache.Count >= MaxCached) return; + if (Interlocked.Increment(ref _writeCount) % MaxWritesOnNoWal != 0) return; + + WriteBatch currentBatch = Interlocked.Exchange(ref _rocksBatch, CreateWriteBatch()); - batchData.Clear(); - batchData.TrimExcess(capacity: InitialBatchSize); - s_cache.Enqueue(batchData); + try + { + _dbOnTheRocks._db.Write(currentBatch, _dbOnTheRocks.WriteFlagsToWriteOptions(_writeFlags)); + ReturnWriteBatch(currentBatch); + } + catch (RocksDbSharpException e) + { + _dbOnTheRocks.CreateMarkerIfCorrupt(e); + throw; + } } } @@ -1156,7 +1166,7 @@ private IDictionary GetStandardOptions() { "level0_stop_writes_trigger", 36.ToString() }, { "max_bytes_for_level_base", _perTableDbConfig.MaxBytesForLevelBase.ToString() }, - { "target_file_size_base", 64.MiB().ToString() }, + { "target_file_size_base", _perTableDbConfig.TargetFileSizeBase.ToString() }, { "disable_auto_compactions", "false" }, { "enable_blob_files", "false" }, @@ -1184,18 +1194,13 @@ private IDictionary GetHeavyWriteOptions(ulong l0FileNumTarget) // but no io, only cpu. // bufferSize*maxBufferNumber = 128MB, which is the max memory used, which tend to be the case as its now // stalled by compaction instead of flush. - // The skiplist (memtable) have a branching factor of 4, so I assume it slows down a little as num of record - // grows by 4x. So we are looking at 1,4,16,64,256,1k,4k,16k,64k and so on num of keys. Assuming average size of - // 120 bytes per key for state db, we are targeting between 4k to 16k of keys per memtable. - // A small memtable however, have the drawback of making l0 files smaller. Causing more compaction overhead. - ulong bufferSize = (ulong)4.MiB(); - ulong writeBufferToMerge = 2; - ulong maxBufferNumber = 16 * writeBufferToMerge; + ulong bufferSize = (ulong)16.MiB(); + ulong maxBufferNumber = 8; // Guide recommend to have l0 and l1 to be the same size. They have to be compacted together so if l1 is larger, // the extra size in l1 is basically extra rewrites. If l0 is larger... then I don't know why not. Even so, it seems to // always get triggered when l0 size exceed max_bytes_for_level_base even if file num is less than l0FileNumTarget. - ulong l1SizeTarget = l0FileNumTarget * bufferSize * writeBufferToMerge; + ulong l1SizeTarget = l0FileNumTarget * bufferSize; return new Dictionary() { @@ -1225,7 +1230,7 @@ private IDictionary GetDisableCompactionOptions() // the memtable a little bit. So if you are not write limited, you'll get memtable limited instead. // This does increase the total memory buffer size, but counterintuitively, this reduces overall memory usage // as it ran out of bloom filter cache so it need to do actual IO. - heavyWriteOption["write_buffer_size"] = 16.MiB().ToString(); + heavyWriteOption["write_buffer_size"] = 64.MiB().ToString(); return heavyWriteOption; } @@ -1251,7 +1256,13 @@ private IDictionary GetBlobFilesOptions() { { "enable_blob_files", "true" }, { "blob_compression_type", "kSnappyCompression" }, - { "write_buffer_size", 64.MiB().ToString() }, + + // Make file size big, so we have less of them. + { "write_buffer_size", 256.MiB().ToString() }, + // Current memtable + 2 concurrent writes. Can't have too many of these as it take up RAM. + { "max_write_buffer_number", 3.ToString() }, + + // These two are SST files instead of the blobs, which are now much smaller. { "max_bytes_for_level_base", 4.MiB().ToString() }, { "target_file_size_base", 1.MiB().ToString() }, }; diff --git a/src/Nethermind/Nethermind.Db.Test/DbOnTheRocksTests.cs b/src/Nethermind/Nethermind.Db.Test/DbOnTheRocksTests.cs index 9e2d9e476d1..c680d3860f3 100644 --- a/src/Nethermind/Nethermind.Db.Test/DbOnTheRocksTests.cs +++ b/src/Nethermind/Nethermind.Db.Test/DbOnTheRocksTests.cs @@ -235,6 +235,24 @@ public void Smoke_test() Assert.That(_db[new byte[] { 2, 3, 4 }], Is.EqualTo(new byte[] { 5, 6, 7 })); } + [Test] + public void Smoke_test_large_writes_with_nowal() + { + IBatch batch = _db.StartBatch(); + + for (int i = 0; i < 1000; i++) + { + batch.Set(i.ToBigEndianByteArray(), i.ToBigEndianByteArray(), WriteFlags.DisableWAL); + } + + batch.Dispose(); + + for (int i = 0; i < 1000; i++) + { + _db[i.ToBigEndianByteArray()].Should().BeEquivalentTo(i.ToBigEndianByteArray()); + } + } + [Test] public void Smoke_test_readahead() { diff --git a/src/Nethermind/Nethermind.EthStats/Configs/EthStatsConfig.cs b/src/Nethermind/Nethermind.EthStats/Configs/EthStatsConfig.cs index 6fe7dbae153..74c5429a757 100644 --- a/src/Nethermind/Nethermind.EthStats/Configs/EthStatsConfig.cs +++ b/src/Nethermind/Nethermind.EthStats/Configs/EthStatsConfig.cs @@ -10,5 +10,6 @@ public class EthStatsConfig : IEthStatsConfig public string? Name { get; set; } = "Nethermind"; public string? Secret { get; set; } = "secret"; public string? Contact { get; set; } = "hello@nethermind.io"; + public int SendInterval { get; set; } = 15; } } diff --git a/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs b/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs index 0ba666dc9ab..4a4b80459ef 100644 --- a/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs +++ b/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Threading.Tasks; using Nethermind.Api; using Nethermind.Api.Extensions; @@ -64,7 +65,7 @@ public Task Init(INethermindApi nethermindApi) public async Task InitNetworkProtocol() { - var (getFromAPi, _) = _api.ForNetwork; + (IApiWithNetwork getFromAPi, _) = _api.ForNetwork; INetworkConfig networkConfig = _api.Config(); IInitConfig initConfig = _api.Config(); @@ -104,12 +105,13 @@ public async Task InitNetworkProtocol() _ethStatsConfig.Secret!, _ethStatsClient, sender, - getFromAPi.TxPool, - getFromAPi.BlockTree, - getFromAPi.PeerManager, - getFromAPi.GasPriceOracle, + getFromAPi.TxPool!, + getFromAPi.BlockTree!, + getFromAPi.PeerManager!, + getFromAPi.GasPriceOracle!, getFromAPi.EthSyncingInfo!, initConfig.IsMining, + TimeSpan.FromSeconds(_ethStatsConfig.SendInterval), getFromAPi.LogManager); await _ethStatsIntegration.InitAsync(); diff --git a/src/Nethermind/Nethermind.EthStats/IEthStatsConfig.cs b/src/Nethermind/Nethermind.EthStats/IEthStatsConfig.cs index aec88a48735..d7328d7bf7c 100644 --- a/src/Nethermind/Nethermind.EthStats/IEthStatsConfig.cs +++ b/src/Nethermind/Nethermind.EthStats/IEthStatsConfig.cs @@ -13,13 +13,16 @@ public interface IEthStatsConfig : IConfig [ConfigItem(Description = "EthStats server wss://hostname:port/api/", DefaultValue = "ws://localhost:3000/api")] string? Server { get; } - [ConfigItem(Description = "Node name displayed on the given ethstats server.", DefaultValue = "Nethermind")] + [ConfigItem(Description = "Node name displayed on the given EthStats server.", DefaultValue = "Nethermind")] string? Name { get; } - [ConfigItem(Description = "Password for publishing to a given ethstats server.", DefaultValue = "secret")] + [ConfigItem(Description = "Password for publishing to a given EthStats server.", DefaultValue = "secret")] string? Secret { get; } - [ConfigItem(Description = "Node owner contact details displayed on the ethstats page.", DefaultValue = "hello@nethermind.io")] + [ConfigItem(Description = "Node owner contact details displayed on the EthStats page.", DefaultValue = "hello@nethermind.io")] string? Contact { get; } + + [ConfigItem(Description = "Time in seconds between statistics updates", DefaultValue = "15")] + int SendInterval { get; } } } diff --git a/src/Nethermind/Nethermind.EthStats/Integrations/EthStatsIntegration.cs b/src/Nethermind/Nethermind.EthStats/Integrations/EthStatsIntegration.cs index 3c02c95b417..238d5772f0a 100644 --- a/src/Nethermind/Nethermind.EthStats/Integrations/EthStatsIntegration.cs +++ b/src/Nethermind/Nethermind.EthStats/Integrations/EthStatsIntegration.cs @@ -45,12 +45,13 @@ public class EthStatsIntegration : IEthStatsIntegration private readonly IGasPriceOracle _gasPriceOracle; private readonly IEthSyncingInfo _ethSyncingInfo; private readonly bool _isMining; + private readonly TimeSpan _sendStatsInterval; + private IWebsocketClient? _websocketClient; private bool _connected; private long _lastBlockProcessedTimestamp; private Timer? _timer; private const int ThrottlingThreshold = 250; - private const int SendStatsInterval = 1000; public EthStatsIntegration( string name, @@ -63,15 +64,16 @@ public EthStatsIntegration( string contact, bool canUpdateHistory, string secret, - IEthStatsClient? ethStatsClient, - IMessageSender? sender, - ITxPool? txPool, - IBlockTree? blockTree, - IPeerManager? peerManager, - IGasPriceOracle? gasPriceOracle, + IEthStatsClient ethStatsClient, + IMessageSender sender, + ITxPool txPool, + IBlockTree blockTree, + IPeerManager peerManager, + IGasPriceOracle gasPriceOracle, IEthSyncingInfo ethSyncingInfo, bool isMining, - ILogManager? logManager) + TimeSpan sendStatsInterval, + ILogManager logManager) { _name = name; _node = node; @@ -83,20 +85,23 @@ public EthStatsIntegration( _contact = contact; _canUpdateHistory = canUpdateHistory; _secret = secret; - _ethStatsClient = ethStatsClient ?? throw new ArgumentNullException(nameof(ethStatsClient)); - _sender = sender ?? throw new ArgumentNullException(nameof(sender)); - _txPool = txPool ?? throw new ArgumentNullException(nameof(txPool)); - _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); - _peerManager = peerManager ?? throw new ArgumentNullException(nameof(peerManager)); - _gasPriceOracle = gasPriceOracle ?? throw new ArgumentNullException(nameof(gasPriceOracle)); - _ethSyncingInfo = ethSyncingInfo ?? throw new ArgumentNullException(nameof(ethSyncingInfo)); + _ethStatsClient = ethStatsClient; + _sender = sender; + _txPool = txPool; + _blockTree = blockTree; + _peerManager = peerManager; + _gasPriceOracle = gasPriceOracle; + _ethSyncingInfo = ethSyncingInfo; _isMining = isMining; - _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); + _sendStatsInterval = sendStatsInterval > TimeSpan.Zero + ? sendStatsInterval + : throw new ArgumentOutOfRangeException(nameof(sendStatsInterval)); + _logger = logManager.GetClassLogger(); } public async Task InitAsync() { - _timer = new Timer { Interval = SendStatsInterval }; + _timer = new Timer { Interval = _sendStatsInterval.TotalMilliseconds }; _timer.Elapsed += TimerOnElapsed; _blockTree.NewHeadBlock += BlockTreeOnNewHeadBlock; _websocketClient = await _ethStatsClient.InitAsync(); diff --git a/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs b/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs index f830b2483cc..126efa7438b 100644 --- a/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs @@ -49,7 +49,7 @@ public void Intrinsic_cost_is_calculated_properly((Transaction Tx, long Cost, st [TestCaseSource(nameof(AccessTestCaseSource))] public void Intrinsic_cost_is_calculated_properly((List orderQueue, long Cost) testCase) { - AccessListBuilder accessListBuilder = new(); + AccessList.Builder accessListBuilder = new(); foreach (object o in testCase.orderQueue) { if (o is Address address) @@ -62,7 +62,7 @@ public void Intrinsic_cost_is_calculated_properly((List orderQueue, long } } - AccessList accessList = accessListBuilder.ToAccessList(); + AccessList accessList = accessListBuilder.Build(); Transaction tx = Build.A.Transaction.SignedAndResolved().WithAccessList(accessList).TestObject; void Test(IReleaseSpec spec, bool supportsAccessLists) diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/AccessTxTracerTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/AccessTxTracerTests.cs index 68975281e51..d291685f3a4 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/AccessTxTracerTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/AccessTxTracerTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using FluentAssertions; using Nethermind.Core; using Nethermind.Core.Specs; @@ -30,12 +31,11 @@ public void Records_get_correct_accessed_addresses() (AccessTxTracer tracer, _, _) = ExecuteAndTraceAccessCall(SenderRecipientAndMiner.Default, code); - IEnumerable
addressesAccessed = tracer.AccessList.Data.Keys; + IEnumerable
addressesAccessed = tracer.AccessList!.Select(tuples => tuples.Address); IEnumerable
expected = new[] { SenderRecipientAndMiner.Default.Sender, SenderRecipientAndMiner.Default.Recipient, TestItem.AddressC }; - Assert.IsNotEmpty(addressesAccessed); addressesAccessed.Should().BeEquivalentTo(expected); } @@ -50,13 +50,12 @@ public void Records_get_correct_accessed_keys() (AccessTxTracer tracer, _, _) = ExecuteAndTraceAccessCall(SenderRecipientAndMiner.Default, code); - IReadOnlyDictionary> accessedData = tracer.AccessList.Data; - - Assert.IsNotEmpty(accessedData); - accessedData.Should().BeEquivalentTo( - new Dictionary>{ - {SenderRecipientAndMiner.Default.Sender, ImmutableHashSet.Empty}, - {SenderRecipientAndMiner.Default.Recipient, new HashSet{105}}}); + tracer.AccessList!.Should().BeEquivalentTo( + new[] + { + (SenderRecipientAndMiner.Default.Sender, new UInt256[] { }), + (SenderRecipientAndMiner.Default.Recipient, new UInt256[] { 105 }) + }); } protected override ISpecProvider SpecProvider => new TestSpecProvider(Berlin.Instance); diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs index dce3f94ba7c..3f50e7ab376 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs @@ -173,7 +173,7 @@ public void Can_handle_quick_fail_on_invalid_nonce(bool withStateDiff, bool with [TestCase(false, false)] public void Can_handle_quick_fail_on_not_enough_balance_on_intrinsic_gas(bool withStateDiff, bool withTrace) { - AccessListBuilder accessListBuilder = new(); + AccessList.Builder accessListBuilder = new(); foreach (Address address in TestItem.Addresses) { accessListBuilder.AddAddress(address); @@ -181,7 +181,7 @@ public void Can_handle_quick_fail_on_not_enough_balance_on_intrinsic_gas(bool wi Transaction tx = Build.A.Transaction .WithGasLimit(GasCostOf.Transaction * 2) - .WithAccessList(accessListBuilder.ToAccessList()) + .WithAccessList(accessListBuilder.Build()) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled) .TestObject; diff --git a/src/Nethermind/Nethermind.Evm/EvmState.cs b/src/Nethermind/Nethermind.Evm/EvmState.cs index 47f5a2b15ec..23604d3e79f 100644 --- a/src/Nethermind/Nethermind.Evm/EvmState.cs +++ b/src/Nethermind/Nethermind.Evm/EvmState.cs @@ -38,7 +38,7 @@ public StackPool(int maxCallStackDepth = VirtualMachine.MaxCallDepth * 2) /// /// The word 'return' acts here once as a verb 'to return stack to the pool' and once as a part of the - /// compound noun 'return stack' which is a stack of subroutine return values. + /// compound noun 'return stack' which is a stack of subroutine return values. /// /// /// @@ -275,7 +275,7 @@ public void WarmUp(AccessList? accessList) { if (accessList is not null) { - foreach ((Address address, IReadOnlySet storages) in accessList.Data) + foreach ((Address address, AccessList.StorageKeysEnumerable storages) in accessList) { WarmUp(address); foreach (UInt256 storage in storages) diff --git a/src/Nethermind/Nethermind.Evm/IntrinsicGasCalculator.cs b/src/Nethermind/Nethermind.Evm/IntrinsicGasCalculator.cs index b030b204bb2..bb90b262e99 100644 --- a/src/Nethermind/Nethermind.Evm/IntrinsicGasCalculator.cs +++ b/src/Nethermind/Nethermind.Evm/IntrinsicGasCalculator.cs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Generic; using System.IO; -using System.Linq; using Nethermind.Core; using Nethermind.Core.Eip2930; using Nethermind.Core.Specs; @@ -61,34 +61,20 @@ private static long AccessListCost(Transaction transaction, IReleaseSpec release long accessListCost = 0; if (accessList is not null) { - if (releaseSpec.UseTxAccessLists) - { - if (accessList.IsNormalized) - { - accessListCost += accessList.Data.Count * GasCostOf.AccessAccountListEntry; - accessListCost += accessList.Data.Sum(d => d.Value.Count) * - GasCostOf.AccessStorageListEntry; - } - else - { - foreach (object o in accessList.OrderQueue!) - { - if (o is Address) - { - accessListCost += GasCostOf.AccessAccountListEntry; - } - else - { - accessListCost += GasCostOf.AccessStorageListEntry; - } - } - } - } - else + if (!releaseSpec.UseTxAccessLists) { throw new InvalidDataException( $"Transaction with an access list received within the context of {releaseSpec.Name}. Eip-2930 is not enabled."); } + + foreach ((Address address, AccessList.StorageKeysEnumerable storageKeys) entry in accessList) + { + accessListCost += GasCostOf.AccessAccountListEntry; + foreach (UInt256 _ in entry.storageKeys) + { + accessListCost += GasCostOf.AccessStorageListEntry; + } + } } return accessListCost; diff --git a/src/Nethermind/Nethermind.Evm/Tracing/AccessTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/AccessTxTracer.cs index 6f839790ff4..9959ecf1b1a 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/AccessTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/AccessTxTracer.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Collections.Generic; -using System.Linq; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Eip2930; @@ -63,7 +62,16 @@ public override void ReportAccess(IReadOnlySet
accessedAddresses, IRead } } - AccessList = new AccessList(dictionary.ToDictionary(k => k.Key, v => (IReadOnlySet)v.Value)); + AccessList.Builder builder = new(); + foreach ((Address address, ISet storageKeys) in dictionary) + { + builder.AddAddress(address); + foreach (UInt256 storageKey in storageKeys) + { + builder.AddStorage(storageKey); + } + } + AccessList = builder.Build(); } public long GasSpent { get; set; } diff --git a/src/Nethermind/Nethermind.Init/Steps/LoadGenesisBlock.cs b/src/Nethermind/Nethermind.Init/Steps/LoadGenesisBlock.cs index a543747edc6..7a427bf2a4e 100644 --- a/src/Nethermind/Nethermind.Init/Steps/LoadGenesisBlock.cs +++ b/src/Nethermind/Nethermind.Init/Steps/LoadGenesisBlock.cs @@ -20,6 +20,8 @@ public class LoadGenesisBlock : IStep private readonly ILogger _logger; private IInitConfig? _initConfig; + readonly TimeSpan _genesisProcessedTimeout = TimeSpan.FromSeconds(40); + public LoadGenesisBlock(INethermindApi api) { _api = api; @@ -69,22 +71,20 @@ protected virtual void Load() ManualResetEventSlim genesisProcessedEvent = new(false); - bool genesisLoaded = false; void GenesisProcessed(object? sender, BlockEventArgs args) { if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); _api.BlockTree.NewHeadBlock -= GenesisProcessed; - genesisLoaded = true; genesisProcessedEvent.Set(); } _api.BlockTree.NewHeadBlock += GenesisProcessed; _api.BlockTree.SuggestBlock(genesis); - genesisProcessedEvent.Wait(TimeSpan.FromSeconds(40)); + bool genesisLoaded = genesisProcessedEvent.Wait(_genesisProcessedTimeout); if (!genesisLoaded) { - throw new BlockchainException("Genesis block processing failure"); + throw new TimeoutException($"Genesis block was not processed after {_genesisProcessedTimeout.TotalSeconds} seconds"); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Data/AccessListItemForRpcTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Data/AccessListItemForRpcTests.cs new file mode 100644 index 00000000000..31345ac4e63 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Data/AccessListItemForRpcTests.cs @@ -0,0 +1,115 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using FluentAssertions; +using Nethermind.Core; +using Nethermind.Core.Eip2930; +using Nethermind.Core.Test.Builders; +using Nethermind.Int256; +using Nethermind.JsonRpc.Data; +using NUnit.Framework; + +namespace Nethermind.JsonRpc.Test.Data; + +public class AccessListItemForRpcTests +{ + [Test] + public void Single_address_with_no_storage() + { + Address address = TestItem.AddressA; + AccessList accessList = new AccessList.Builder() + .AddAddress(address) + .Build(); + + IEnumerable forRpc = AccessListItemForRpc.FromAccessList(accessList); + AccessListItemForRpc[] expected = { new(address, new UInt256[] { }) }; + forRpc.Should().BeEquivalentTo(expected); + } + + [Test] + public void Single_address_with_multiple_storage_keys() + { + Address address = TestItem.AddressA; + UInt256 storageKey1 = (UInt256)1; + UInt256 storageKey2 = (UInt256)2; + UInt256 storageKey3 = (UInt256)3; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address) + .AddStorage(storageKey1) + .AddStorage(storageKey2) + .AddStorage(storageKey3) + .Build(); + + IEnumerable forRpc = AccessListItemForRpc.FromAccessList(accessList); + AccessListItemForRpc[] expected = { new(address, new[] { storageKey1, storageKey2, storageKey3 }) }; + forRpc.Should().BeEquivalentTo(expected); + } + + [Test] + public void Single_address_with_duplicated_storage_keys() + { + Address address = TestItem.AddressA; + UInt256 storageKey1 = (UInt256)1; + UInt256 storageKey2 = (UInt256)2; + UInt256 storageKey3 = (UInt256)3; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address) + .AddStorage(storageKey1) + .AddStorage(storageKey2) + .AddStorage(storageKey3) + .AddStorage(storageKey1) + .Build(); + + IEnumerable forRpc = AccessListItemForRpc.FromAccessList(accessList); + + AccessListItemForRpc[] expected = { new(address, new[] { storageKey1, storageKey2, storageKey3, storageKey1 }) }; + forRpc.Should().BeEquivalentTo(expected); + } + + [Test] + public void Duplicated_address_with_multiple_storage_keys() + { + Address address = TestItem.AddressA; + UInt256 storageKey1 = (UInt256)1; + UInt256 storageKey2 = (UInt256)2; + UInt256 storageKey3 = (UInt256)3; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address) + .AddStorage(storageKey1) + .AddStorage(storageKey2) + .AddAddress(address) + .AddStorage(storageKey3) + .Build(); + + IEnumerable forRpc = AccessListItemForRpc.FromAccessList(accessList); + + AccessListItemForRpc[] expected = { new(address, new[] { storageKey1, storageKey2 }), new(address, new[] { storageKey3 }) }; + forRpc.Should().BeEquivalentTo(expected); + } + + [Test] + public void Duplicated_address_with_duplicated_storage_keys() + { + Address address = TestItem.AddressA; + UInt256 storageKey1 = (UInt256)1; + UInt256 storageKey2 = (UInt256)2; + UInt256 storageKey3 = (UInt256)3; + + AccessList accessList = new AccessList.Builder() + .AddAddress(address) + .AddStorage(storageKey1) + .AddStorage(storageKey2) + .AddAddress(address) + .AddStorage(storageKey1) + .AddStorage(storageKey3) + .Build(); + + IEnumerable forRpc = AccessListItemForRpc.FromAccessList(accessList); + AccessListItemForRpc[] expected = { new(address, new[] { storageKey1, storageKey2 }), new(address, new[] { storageKey1, storageKey3 }) }; + forRpc.Should().BeEquivalentTo(expected); + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Data/Eip2930Tests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Data/Eip2930Tests.cs index ad2e899b064..a9176491bdf 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Data/Eip2930Tests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Data/Eip2930Tests.cs @@ -22,18 +22,16 @@ public class Eip2930Tests private AccessList GetTestAccessList() { - AccessListBuilder accessListBuilder = new(); - - accessListBuilder.AddAddress(TestItem.AddressA); - accessListBuilder.AddStorage(1); - accessListBuilder.AddStorage(2); - accessListBuilder.AddStorage(3); - accessListBuilder.AddStorage(5); - accessListBuilder.AddStorage(8); - accessListBuilder.AddAddress(TestItem.AddressB); - accessListBuilder.AddStorage(42); - - return accessListBuilder.ToAccessList(); + return new AccessList.Builder() + .AddAddress(TestItem.AddressA) + .AddStorage(1) + .AddStorage(2) + .AddStorage(3) + .AddStorage(5) + .AddStorage(8) + .AddAddress(TestItem.AddressB) + .AddStorage(42) + .Build(); } [TestCase(TxType.AccessList, """{"nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":null,"type":"0x1","chainId":"0x1","accessList":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","storageKeys":["0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000003","0x0000000000000000000000000000000000000000000000000000000000000005","0x0000000000000000000000000000000000000000000000000000000000000008"]},{"address":"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358","storageKeys":["0x000000000000000000000000000000000000000000000000000000000000002a"]}]}""")] @@ -123,11 +121,11 @@ public void can_deserialize_no_accessList() [TestCase(TxType.EIP1559, """{"nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"to":null,"value":"0x0","gasPrice":"0x0","maxPriorityFeePerGas":"0x0","maxFeePerGas":"0x0","gas":"0x0","input":null,"type":"0x2","chainId":"0x1","accessList":[]}""")] public void can_serialize_empty_accessList(TxType txType, string txJson) { - Dictionary> data = new(); + AccessList.Builder builder = new(); Transaction transaction = new() { Type = txType, - AccessList = new AccessList(data), + AccessList = builder.Build(), }; TransactionForRpc transactionForRpc = new(transaction); @@ -144,24 +142,21 @@ public void can_deserialize_empty_accessList() TransactionForRpc transactionForRpc = _serializer.Deserialize(json); transactionForRpc.Type.Should().Be(TxType.AccessList); - transactionForRpc.AccessList!.Length.Should().Be(0); + transactionForRpc.AccessList!.Should().BeEmpty(); } [TestCase(TxType.AccessList, """{"nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":null,"type":"0x1","chainId":"0x1","accessList":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","storageKeys":[]}]}""")] [TestCase(TxType.EIP1559, """{"nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"to":null,"value":"0x0","gasPrice":"0x0","maxPriorityFeePerGas":"0x0","maxFeePerGas":"0x0","gas":"0x0","input":null,"type":"0x2","chainId":"0x1","accessList":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","storageKeys":[]}]}""")] public void can_serialize_accessList_with_empty_storageKeys(TxType txType, string txJson) { - Dictionary> data = new() - { - { - TestItem.AddressA, new HashSet() - }, - }; + AccessList.Builder builder = new AccessList.Builder() + .AddAddress(TestItem.AddressA); Transaction transaction = new() { Type = txType, - AccessList = new AccessList(data), + AccessList = builder.Build(), }; + TransactionForRpc transactionForRpc = new(transaction); string serialized = _serializer.Serialize(transactionForRpc); @@ -181,29 +176,6 @@ public void can_deserialize_accessList_with_empty_storageKeys() transactionForRpc.AccessList.Should().BeEquivalentTo(accessList); } - [TestCase(TxType.AccessList, """{"nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":null,"type":"0x1","chainId":"0x1","accessList":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","storageKeys":[]}]}""")] - [TestCase(TxType.EIP1559, """{"nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"to":null,"value":"0x0","gasPrice":"0x0","maxPriorityFeePerGas":"0x0","maxFeePerGas":"0x0","gas":"0x0","input":null,"type":"0x2","chainId":"0x1","accessList":[{"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","storageKeys":[]}]}""")] - public void can_serialize_accessList_with_null_storageKeys(TxType txType, string txJson) - { - Dictionary> data = new() - { - { - TestItem.AddressA, null! - }, - }; - Transaction transaction = new() - { - Type = txType, - AccessList = new AccessList(data), - }; - - TransactionForRpc transactionForRpc = new(transaction); - - string serialized = _serializer.Serialize(transactionForRpc); - - JToken.Parse(serialized).Should().BeEquivalentTo(JToken.Parse(txJson)); - } - [Test] public void can_deserialize_accessList_with_null_storageKeys() { @@ -213,7 +185,6 @@ public void can_deserialize_accessList_with_null_storageKeys() TransactionForRpc transactionForRpc = _serializer.Deserialize(json); transactionForRpc.Type.Should().Be(TxType.AccessList); - transactionForRpc.AccessList!.Length.Should().Be(1); transactionForRpc.AccessList.Should().BeEquivalentTo(accessList); } @@ -226,7 +197,6 @@ public void can_deserialize_accessList_with_null_storageKeys_and_eip1559_txType( TransactionForRpc transactionForRpc = _serializer.Deserialize(json); transactionForRpc.Type.Should().Be(TxType.EIP1559); - transactionForRpc.AccessList!.Length.Should().Be(1); transactionForRpc.AccessList.Should().BeEquivalentTo(accessList); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/AccessListForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/AccessListForRpc.cs index 725e2a197fe..f4d05e7575b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/AccessListForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/AccessListForRpc.cs @@ -1,19 +1,20 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.Collections.Generic; using Nethermind.Int256; namespace Nethermind.JsonRpc.Data { - public class AccessListForRpc + public struct AccessListForRpc { - public AccessListForRpc(AccessListItemForRpc[] accessList, in UInt256 gasUsed) + public AccessListForRpc(IEnumerable accessList, in UInt256 gasUsed) { AccessList = accessList; GasUsed = gasUsed; } - public AccessListItemForRpc[] AccessList { get; } + public IEnumerable AccessList { get; } public UInt256 GasUsed { get; } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/AccessListItemForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/AccessListItemForRpc.cs index 512cb2977c4..1eed1d5a03d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/AccessListItemForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/AccessListItemForRpc.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using Nethermind.Core; +using Nethermind.Core.Collections; using Nethermind.Core.Eip2930; using Nethermind.Int256; using Nethermind.Serialization.Json; @@ -12,38 +13,42 @@ namespace Nethermind.JsonRpc.Data { - public class AccessListItemForRpc + public struct AccessListItemForRpc : IEquatable { - public AccessListItemForRpc(Address address, IReadOnlyCollection? storageKeys) + public AccessListItemForRpc(Address address, IEnumerable? storageKeys) { Address = address; - StorageKeys = storageKeys?.ToArray() ?? Array.Empty(); + StorageKeys = storageKeys; } public Address Address { get; set; } [JsonProperty(ItemConverterType = typeof(StorageCellIndexConverter))] - public UInt256[]? StorageKeys { get; set; } + public IEnumerable? StorageKeys { get; set; } - public static AccessListItemForRpc[] FromAccessList(AccessList accessList) => - accessList.Data.Select(kvp => new AccessListItemForRpc(kvp.Key, kvp.Value)).ToArray(); + public static IEnumerable FromAccessList(AccessList accessList) => + accessList.Select(tuple => new AccessListItemForRpc(tuple.Address, tuple.StorageKeys)); - public static AccessList ToAccessList(AccessListItemForRpc[] accessList) + public static AccessList ToAccessList(IEnumerable accessList) { - AccessListBuilder accessListBuilder = new(); - for (int i = 0; i < accessList.Length; i++) + AccessList.Builder builder = new(); + foreach (AccessListItemForRpc accessListItem in accessList) { - var accessListItem = accessList[i]; - accessListBuilder.AddAddress(accessListItem.Address); + builder.AddAddress(accessListItem.Address); if (accessListItem.StorageKeys is not null) { - for (int j = 0; j < accessListItem.StorageKeys.Length; j++) + foreach (UInt256 index in accessListItem.StorageKeys) { - accessListBuilder.AddStorage(accessListItem.StorageKeys[j]); + builder.AddStorage(index); } } } - return accessListBuilder.ToAccessList(); + + return builder.Build(); } + + public bool Equals(AccessListItemForRpc other) => Equals(Address, other.Address) && StorageKeys.NullableSequenceEqual(other.StorageKeys); + public override bool Equals(object? obj) => obj is AccessListItemForRpc other && Equals(other); + public override int GetHashCode() => HashCode.Combine(Address, StorageKeys); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs index ca340403e22..9116a6c8eea 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Generic; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Eip2930; @@ -118,7 +119,7 @@ public TransactionForRpc() public TxType Type { get; set; } - public AccessListItemForRpc[]? AccessList { get; set; } + public IEnumerable? AccessList { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 0a23d10c51c..a13b72b749d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -2,6 +2,8 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Xml; using Nethermind.Blockchain.Find; @@ -96,10 +98,10 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, : TryGetInputError(result) ?? ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError, new AccessListForRpc(GetResultAccessList(tx, result), GetResultGas(tx, result))); } - private static AccessListItemForRpc[] GetResultAccessList(Transaction tx, CallOutput result) + private static IEnumerable GetResultAccessList(Transaction tx, BlockchainBridge.CallOutput result) { AccessList? accessList = result.AccessList ?? tx.AccessList; - return accessList is null ? Array.Empty() : AccessListItemForRpc.FromAccessList(accessList); + return accessList is null ? Enumerable.Empty() : AccessListItemForRpc.FromAccessList(accessList); } private static UInt256 GetResultGas(Transaction transaction, CallOutput result) diff --git a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs index 7d3962a5a8f..e640c01301d 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs @@ -9,8 +9,10 @@ using Nethermind.Consensus; using Nethermind.Consensus.AuRa; using Nethermind.Consensus.AuRa.Config; +using Nethermind.Consensus.AuRa.InitializationSteps; using Nethermind.Consensus.AuRa.Validators; using Nethermind.Consensus.Comparers; +using Nethermind.Consensus.Processing; using Nethermind.Consensus.Producers; using Nethermind.Consensus.Rewards; using Nethermind.Core; @@ -20,6 +22,7 @@ using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.Logging; +using Nethermind.Merge.AuRa.Withdrawals; using Nethermind.Merge.Plugin; using Nethermind.Merge.Plugin.BlockProduction; using Nethermind.Merge.Plugin.Handlers; @@ -27,6 +30,7 @@ using Nethermind.Serialization.Json; using Nethermind.Specs; using Nethermind.Specs.ChainSpecStyle; +using Nethermind.State; using Nethermind.Synchronization.ParallelSync; using NSubstitute; using NUnit.Framework; @@ -51,12 +55,11 @@ string BlockHash ) input) => base.forkchoiceUpdatedV2_should_validate_withdrawals(input); - [Ignore("engine_newPayloadV2 fails")] [TestCase( "0xe168b70ac8a6f7d90734010030801fbb2dcce03a657155c4024b36ba8d1e3926", "0x3e604e45a9a74b66a7e03f828cc2597f0cb5f5e7dc50c9211be3a62fbcd6396d", "0xdbd87b98a6be7d4e3f11ff8500c38a0736d9a5e7a47b5cb25628d37187a98cb9", - "0x78ecfec08729d895")] + "0x80ac487e132512b1")] public override Task Should_process_block_as_expected_V2(string latestValidHash, string blockHash, string stateRoot, string payloadId) => base.Should_process_block_as_expected_V2(latestValidHash, blockHash, stateRoot, payloadId); @@ -77,56 +80,64 @@ public override Task processing_block_should_serialize_valid_responses(string bl public override Task forkchoiceUpdatedV1_should_communicate_with_boost_relay_through_http(string blockHash, string parentHash) => base.forkchoiceUpdatedV1_should_communicate_with_boost_relay_through_http(blockHash, parentHash); - [Ignore("engine_newPayloadV2 fails")] + [Ignore("Withdrawals are not withdrawan due to lack of Aura contract in tests")] public override Task Can_apply_withdrawals_correctly((Withdrawal[][] Withdrawals, (Address Account, UInt256 BalanceIncrease)[] ExpectedAccountIncrease) input) { return base.Can_apply_withdrawals_correctly(input); } - [Ignore("engine_newPayloadV2 fails")] - public override Task Empty_block_is_valid_with_withdrawals_V2() - { - return base.Empty_block_is_valid_with_withdrawals_V2(); - } - - [Ignore("engine_newPayloadV2 fails")] - public override Task Should_handle_withdrawals_transition_when_Shanghai_fork_activated() - { - return base.Should_handle_withdrawals_transition_when_Shanghai_fork_activated(); - } - - [Ignore("engine_newPayloadV2 fails")] - public override Task getPayloadBodiesByHashV1_should_return_payload_bodies_in_order_of_request_block_hashes_and_null_for_unknown_hashes(IList withdrawals) - { - return base.getPayloadBodiesByHashV1_should_return_payload_bodies_in_order_of_request_block_hashes_and_null_for_unknown_hashes(withdrawals); - } - - [Ignore("engine_newPayloadV2 fails")] - public override Task getPayloadBodiesByRangeV1_should_return_canonical(IList withdrawals) - { - return base.getPayloadBodiesByRangeV1_should_return_canonical(withdrawals); - } - - [Ignore("engine_newPayloadV2 fails")] - public override Task getPayloadBodiesByRangeV1_should_return_payload_bodies_in_order_of_request_range_and_null_for_unknown_indexes(IList withdrawals) - { - return base.getPayloadBodiesByRangeV1_should_return_payload_bodies_in_order_of_request_range_and_null_for_unknown_indexes(withdrawals); - } - - [Ignore("engine_newPayloadV3 fails")] - public override Task NewPayloadV3_should_decline_mempool_encoding(bool inMempoolForm, string expectedPayloadStatus) - { - return base.NewPayloadV3_should_decline_mempool_encoding(inMempoolForm, expectedPayloadStatus); - } - class MergeAuRaTestBlockchain : MergeTestBlockchain { + private AuRaNethermindApi? _api; + public MergeAuRaTestBlockchain(IMergeConfig? mergeConfig = null, IPayloadPreparationService? mockedPayloadPreparationService = null) : base(mergeConfig, mockedPayloadPreparationService) { SealEngineType = Core.SealEngineType.AuRa; } + protected override IBlockProcessor CreateBlockProcessor() + { + _api = new(new ConfigProvider(), new EthereumJsonSerializer(), LogManager, + new ChainSpec + { + AuRa = new() + { + WithdrawalContractAddress = new("0xbabe2bed00000000000000000000000000000003") + }, + Parameters = new() + }) + { + BlockTree = BlockTree, + DbProvider = DbProvider, + ReadOnlyTrieStore = ReadOnlyTrieStore, + SpecProvider = SpecProvider, + TransactionComparerProvider = TransactionComparerProvider, + TxPool = TxPool + }; + + WithdrawalContractFactory withdrawalContractFactory = new(_api.ChainSpec!.AuRa, _api.AbiEncoder); + WithdrawalProcessor = new AuraWithdrawalProcessor( + withdrawalContractFactory.Create(TxProcessor), + LogManager + ); + + BlockValidator = CreateBlockValidator(); + IBlockProcessor processor = new BlockProcessor( + SpecProvider, + BlockValidator, + NoBlockRewards.Instance, + new BlockProcessor.BlockValidationTransactionsExecutor(TxProcessor, State), + State, + ReceiptStorage, + NullWitnessCollector.Instance, + LogManager, + WithdrawalProcessor); + + return new TestBlockProcessorInterceptor(processor, _blockProcessingThrottle); + } + + protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, ISealer sealer, ITransactionComparerProvider transactionComparerProvider) { SealEngine = new MergeSealEngine(SealEngine, PoSSwitcher, SealValidator!, LogManager); @@ -143,23 +154,7 @@ protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolT targetAdjustedGasLimitCalculator); AuRaMergeBlockProducerEnvFactory blockProducerEnvFactory = new( - new(new ConfigProvider(), new EthereumJsonSerializer(), LogManager, - new ChainSpec - { - AuRa = new() - { - WithdrawalContractAddress = new("0xbabe2bed00000000000000000000000000000003") - }, - Parameters = new() - }) - { - BlockTree = BlockTree, - DbProvider = DbProvider, - ReadOnlyTrieStore = ReadOnlyTrieStore, - SpecProvider = SpecProvider, - TransactionComparerProvider = TransactionComparerProvider, - TxPool = TxPool - }, + _api!, new AuRaConfig(), new DisposableStack(), DbProvider, @@ -213,4 +208,3 @@ protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolT } } } - diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.HelperFunctions.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.HelperFunctions.cs index 89b516d64b5..55b3df0ac92 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.HelperFunctions.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.HelperFunctions.cs @@ -22,6 +22,8 @@ using Nethermind.State; using Nethermind.Core.Specs; using Nethermind.Consensus.BeaconBlockRoot; +using Nethermind.Consensus.Withdrawals; +using Nethermind.Core.Test.Blockchain; namespace Nethermind.Merge.Plugin.Test { @@ -86,28 +88,46 @@ private ExecutionPayload CreateParentBlockRequestOnHead(IBlockTree blockTree) }; } - private static ExecutionPayload CreateBlockRequest(IReleaseSpec spec, IWorldState state, ExecutionPayload parent, Address miner, IList? withdrawals = null, - ulong? blobGasUsed = null, ulong? excessBlobGas = null, Transaction[]? transactions = null, Keccak? parentBeaconBlockRoot = null) - => CreateBlockRequestInternal(spec, state, parent, miner, withdrawals, blobGasUsed, excessBlobGas, transactions: transactions, parentBeaconBlockRoot: parentBeaconBlockRoot); + private static ExecutionPayload CreateBlockRequest(MergeTestBlockchain chain, ExecutionPayload parent, Address miner, IList? withdrawals = null, + ulong? blobGasUsed = null, ulong? excessBlobGas = null, Transaction[]? transactions = null, Keccak? parentBeaconBlockRoot = null) + { + ExecutionPayload blockRequest = CreateBlockRequestInternal(parent, miner, withdrawals, blobGasUsed, excessBlobGas, transactions: transactions, parentBeaconBlockRoot: parentBeaconBlockRoot); + blockRequest.TryGetBlock(out Block? block); + + Snapshot before = chain.State.TakeSnapshot(); + chain.WithdrawalProcessor?.ProcessWithdrawals(block!, chain.SpecProvider.GenesisSpec); + + chain.State.Commit(chain.SpecProvider.GenesisSpec); + chain.State.RecalculateStateRoot(); + blockRequest.StateRoot = chain.State.StateRoot; + chain.State.Restore(before); + + TryCalculateHash(blockRequest, out Keccak? hash); + blockRequest.BlockHash = hash; + return blockRequest; + } - private static ExecutionPayloadV3 CreateBlockRequestV3(IReleaseSpec spec, IWorldState state, ExecutionPayload parent, Address miner, IList? withdrawals = null, + private static ExecutionPayloadV3 CreateBlockRequestV3(MergeTestBlockchain chain, ExecutionPayload parent, Address miner, IList? withdrawals = null, ulong? blobGasUsed = null, ulong? excessBlobGas = null, Transaction[]? transactions = null, Keccak? parentBeaconBlockRoot = null) { - ExecutionPayloadV3 blockRequestV3 = CreateBlockRequestInternal(spec, state, parent, miner, withdrawals, blobGasUsed, excessBlobGas, transactions: transactions, parentBeaconBlockRoot: parentBeaconBlockRoot); + ExecutionPayloadV3 blockRequestV3 = CreateBlockRequestInternal(parent, miner, withdrawals, blobGasUsed, excessBlobGas, transactions: transactions, parentBeaconBlockRoot: parentBeaconBlockRoot); blockRequestV3.TryGetBlock(out Block? block); - _beaconBlockRootHandler.ApplyContractStateChanges(block!, spec, state); - state.Commit(spec); - state.CommitTree(blockRequestV3.BlockNumber); + Snapshot before = chain.State.TakeSnapshot(); + _beaconBlockRootHandler.ApplyContractStateChanges(block!, chain.SpecProvider.GenesisSpec, chain.State); + chain.WithdrawalProcessor?.ProcessWithdrawals(block!, chain.SpecProvider.GenesisSpec); + + chain.State.Commit(chain.SpecProvider.GenesisSpec); + chain.State.RecalculateStateRoot(); + blockRequestV3.StateRoot = chain.State.StateRoot; + chain.State.Restore(before); - state.RecalculateStateRoot(); - blockRequestV3.StateRoot = state.StateRoot; TryCalculateHash(blockRequestV3, out Keccak? hash); blockRequestV3.BlockHash = hash; return blockRequestV3; } - private static T CreateBlockRequestInternal(IReleaseSpec spec, IWorldState state, ExecutionPayload parent, Address miner, IList? withdrawals = null, + private static T CreateBlockRequestInternal(ExecutionPayload parent, Address miner, IList? withdrawals = null, ulong? blobGasUsed = null, ulong? excessBlobGas = null, Transaction[]? transactions = null, Keccak? parentBeaconBlockRoot = null) where T : ExecutionPayload, new() { T blockRequest = new() @@ -133,13 +153,13 @@ private static T CreateBlockRequestInternal(IReleaseSpec spec, IWorldState st return blockRequest; } - private static ExecutionPayload[] CreateBlockRequestBranch(IReleaseSpec spec, IWorldState state, ExecutionPayload parent, Address miner, int count) + private static ExecutionPayload[] CreateBlockRequestBranch(MergeTestBlockchain chain, ExecutionPayload parent, Address miner, int count) { ExecutionPayload currentBlock = parent; ExecutionPayload[] blockRequests = new ExecutionPayload[count]; for (int i = 0; i < count; i++) { - currentBlock = CreateBlockRequest(spec, state, currentBlock, miner); + currentBlock = CreateBlockRequest(chain, currentBlock, miner); blockRequests[i] = currentBlock; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs index abe7a3f24e6..feab59ee82e 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs @@ -15,6 +15,7 @@ using Nethermind.Consensus.Producers; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; +using Nethermind.Consensus.Withdrawals; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; @@ -116,6 +117,7 @@ private IEngineRpcModule CreateEngineModule(MergeTestBlockchain chain, ISyncConf chain.BeaconSync, chain.BeaconPivot, peerRefresher, + chain.SpecProvider, chain.LogManager), new GetPayloadBodiesByHashV1Handler(chain.BlockTree, chain.LogManager), new GetPayloadBodiesByRangeV1Handler(chain.BlockTree, chain.LogManager), @@ -140,7 +142,9 @@ public class MergeTestBlockchain : TestBlockchain public BeaconSync? BeaconSync { get; set; } - private int _blockProcessingThrottle = 0; + public IWithdrawalProcessor? WithdrawalProcessor { get; set; } + + protected int _blockProcessingThrottle = 0; public MergeTestBlockchain ThrottleBlockProcessor(int delayMs) { @@ -215,6 +219,7 @@ protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolT protected override IBlockProcessor CreateBlockProcessor() { BlockValidator = CreateBlockValidator(); + WithdrawalProcessor = new WithdrawalProcessor(State, LogManager); IBlockProcessor processor = new BlockProcessor( SpecProvider, BlockValidator, @@ -223,12 +228,13 @@ protected override IBlockProcessor CreateBlockProcessor() State, ReceiptStorage, NullWitnessCollector.Instance, - LogManager); + LogManager, + WithdrawalProcessor); return new TestBlockProcessorInterceptor(processor, _blockProcessingThrottle); } - private IBlockValidator CreateBlockValidator() + protected IBlockValidator CreateBlockValidator() { IBlockCacheService blockCacheService = new BlockCacheService(); PoSSwitcher = new PoSSwitcher(MergeConfig, SyncConfig.Default, new MemDb(), BlockTree, SpecProvider, LogManager); @@ -257,7 +263,7 @@ public async Task Build(ISpecProvider? specProvider = null) } } -internal class TestBlockProcessorInterceptor : IBlockProcessor +public class TestBlockProcessorInterceptor : IBlockProcessor { private readonly IBlockProcessor _blockProcessorImplementation; public int DelayMs { get; set; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Synchronization.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Synchronization.cs index 32d15a54fda..f97848f41dd 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Synchronization.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Synchronization.cs @@ -202,14 +202,14 @@ public async Task should_return_invalid_lvh_null_on_invalid_blocks_during_the_sy forkchoiceUpdatedResult.Data.PayloadStatus.Status.Should() .Be(nameof(PayloadStatusV1.Syncing).ToUpper()); - ExecutionPayload[] requests = CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, startingNewPayload, TestItem.AddressD, 1); + ExecutionPayload[] requests = CreateBlockRequestBranch(chain, startingNewPayload, TestItem.AddressD, 1); foreach (ExecutionPayload r in requests) { ResultWrapper payloadStatus = await rpc.engine_newPayloadV1(r); payloadStatus.Data.Status.Should().Be(nameof(PayloadStatusV1.Syncing).ToUpper()); } - ExecutionPayload[] invalidRequests = CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, requests[0], TestItem.AddressD, 1); + ExecutionPayload[] invalidRequests = CreateBlockRequestBranch(chain, requests[0], TestItem.AddressD, 1); foreach (ExecutionPayload r in invalidRequests) { r.TryGetBlock(out Block? newBlock); @@ -229,7 +229,7 @@ public async Task newPayloadV1_can_insert_blocks_from_cache_when_syncing() Keccak startingHead = chain.BlockTree.HeadHash; ExecutionPayload parentBlockRequest = new(Build.A.Block.WithNumber(2).TestObject); - ExecutionPayload[] requests = CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, parentBlockRequest, Address.Zero, 7); + ExecutionPayload[] requests = CreateBlockRequestBranch(chain, parentBlockRequest, Address.Zero, 7); ResultWrapper payloadStatus; foreach (ExecutionPayload r in requests) { @@ -293,7 +293,7 @@ public async Task first_new_payload_set_beacon_main_chain() await rpc.engine_forkchoiceUpdatedV1(forkchoiceStateV1); forkchoiceUpdatedResult.Data.PayloadStatus.Status.Should() .Be(nameof(PayloadStatusV1.Syncing).ToUpper()); - ExecutionPayload[] requests = CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, startingNewPayload, Address.Zero, 4); + ExecutionPayload[] requests = CreateBlockRequestBranch(chain, startingNewPayload, Address.Zero, 4); foreach (ExecutionPayload r in requests) { ResultWrapper payloadStatus = await rpc.engine_newPayloadV1(r); @@ -334,7 +334,7 @@ public async Task repeated_new_payloads_do_not_change_metadata() await rpc.engine_forkchoiceUpdatedV1(forkchoiceStateV1); forkchoiceUpdatedResult.Data.PayloadStatus.Status.Should() .Be(nameof(PayloadStatusV1.Syncing).ToUpper()); - ExecutionPayload[] requests = CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, startingNewPayload, Address.Zero, 4); + ExecutionPayload[] requests = CreateBlockRequestBranch(chain, startingNewPayload, Address.Zero, 4); foreach (ExecutionPayload r in requests) { ResultWrapper payloadStatus = await rpc.engine_newPayloadV1(r); @@ -492,7 +492,7 @@ public async Task second_new_payload_should_not_set_beacon_main_chain() await rpc.engine_forkchoiceUpdatedV1(forkchoiceStateV1); forkchoiceUpdatedResult.Data.PayloadStatus.Status.Should() .Be(nameof(PayloadStatusV1.Syncing).ToUpper()); - ExecutionPayload[] requests = CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, startingNewPayload, Address.Zero, 4); + ExecutionPayload[] requests = CreateBlockRequestBranch(chain, startingNewPayload, Address.Zero, 4); foreach (ExecutionPayload r in requests) { ResultWrapper payloadStatus = await rpc.engine_newPayloadV1(r); @@ -503,7 +503,7 @@ public async Task second_new_payload_should_not_set_beacon_main_chain() lvl!.BlockInfos[0].Metadata.Should().Be(BlockMetadata.BeaconBody | BlockMetadata.BeaconHeader | BlockMetadata.BeaconMainChain); } - ExecutionPayload[] secondNewPayloads = CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, startingNewPayload, TestItem.AddressD, 4); + ExecutionPayload[] secondNewPayloads = CreateBlockRequestBranch(chain, startingNewPayload, TestItem.AddressD, 4); foreach (ExecutionPayload r in secondNewPayloads) { ResultWrapper payloadStatus = await rpc.engine_newPayloadV1(r); @@ -549,13 +549,13 @@ public async Task should_reorg_during_the_sync(int initialChainPayloadsCount, in await rpc.engine_newPayloadV1(startingNewPayload); ForkchoiceStateV1 forkchoiceStateV1 = new(block.Hash!, startingHead, startingHead); await rpc.engine_forkchoiceUpdatedV1(forkchoiceStateV1); - ExecutionPayload[] initialBranchPayloads = CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, startingNewPayload, Address.Zero, initialChainPayloadsCount); + ExecutionPayload[] initialBranchPayloads = CreateBlockRequestBranch(chain, startingNewPayload, Address.Zero, initialChainPayloadsCount); foreach (ExecutionPayload r in initialBranchPayloads) { await rpc.engine_newPayloadV1(r); } - ExecutionPayload[] newBranchPayloads = CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, startingNewPayload, TestItem.AddressD, reorgedChainPayloadCount); + ExecutionPayload[] newBranchPayloads = CreateBlockRequestBranch(chain, startingNewPayload, TestItem.AddressD, reorgedChainPayloadCount); foreach (ExecutionPayload r in newBranchPayloads) { await rpc.engine_newPayloadV1(r); @@ -586,7 +586,7 @@ public async Task Blocks_from_cache_inserted_when_fast_headers_sync_finish_befor using MergeTestBlockchain chain = await CreateBlockchain(); Keccak startingHead = chain.BlockTree.HeadHash; IEngineRpcModule rpc = CreateEngineModule(chain); - ExecutionPayload[] requests = CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, new ExecutionPayload(chain.BlockTree.Head!), Address.Zero, 7); + ExecutionPayload[] requests = CreateBlockRequestBranch(chain, new ExecutionPayload(chain.BlockTree.Head!), Address.Zero, 7); ResultWrapper payloadStatus; for (int i = 4; i < requests.Length - 1; i++) @@ -638,13 +638,13 @@ public async Task Maintain_correct_pointers_for_beacon_sync_in_archive_sync() Block[] missingBlocks = new Block[gap]; for (int i = 0; i < gap; i++) { - headBlockRequest = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, headBlockRequest, Address.Zero); + headBlockRequest = CreateBlockRequest(chain, headBlockRequest, Address.Zero); headBlockRequest.TryGetBlock(out Block? block); missingBlocks[i] = block!; } // setting up beacon pivot - ExecutionPayload pivotRequest = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, headBlockRequest, Address.Zero); + ExecutionPayload pivotRequest = CreateBlockRequest(chain, headBlockRequest, Address.Zero); ResultWrapper payloadStatus = await rpc.engine_newPayloadV1(pivotRequest); payloadStatus.Data.Status.Should().Be(nameof(PayloadStatusV1.Syncing).ToUpper()); pivotRequest.TryGetBlock(out Block? pivotBlock); @@ -666,7 +666,7 @@ public async Task Maintain_correct_pointers_for_beacon_sync_in_archive_sync() forkchoiceUpdatedResult.Data.PayloadStatus.Status.Should() .Be(nameof(PayloadStatusV1.Syncing).ToUpper()); // trigger insertion of blocks in cache into block tree by adding new block - ExecutionPayload bestBeaconBlockRequest = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, pivotRequest, Address.Zero); + ExecutionPayload bestBeaconBlockRequest = CreateBlockRequest(chain, pivotRequest, Address.Zero); payloadStatus = await rpc.engine_newPayloadV1(bestBeaconBlockRequest); payloadStatus.Data.Status.Should().Be(nameof(PayloadStatusV1.Syncing).ToUpper()); // simulate headers sync by inserting 3 headers from pivot backwards @@ -720,7 +720,7 @@ public async Task Maintain_correct_pointers_for_beacon_sync_in_archive_sync() await bestBlockProcessed.WaitAsync(); // beacon sync should be finished, eventually - bestBeaconBlockRequest = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, bestBeaconBlockRequest, Address.Zero); + bestBeaconBlockRequest = CreateBlockRequest(chain, bestBeaconBlockRequest, Address.Zero); Assert.That( () => rpc.engine_newPayloadV1(bestBeaconBlockRequest).Result.Data.Status, Is.EqualTo(PayloadStatus.Valid).After(1000, 100) @@ -796,9 +796,9 @@ public async Task Maintain_correct_pointers_for_beacon_sync_in_fast_sync() // create block gap from fast sync pivot int gap = 7; ExecutionPayload[] requests = - CreateBlockRequestBranch(chain.SpecProvider.GenesisSpec, chain.State, new ExecutionPayload(syncedBlockTree.Head!), Address.Zero, gap); + CreateBlockRequestBranch(chain, new ExecutionPayload(syncedBlockTree.Head!), Address.Zero, gap); // setting up beacon pivot - ExecutionPayload pivotRequest = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, requests[^1], Address.Zero); + ExecutionPayload pivotRequest = CreateBlockRequest(chain, requests[^1], Address.Zero); ResultWrapper payloadStatus = await rpc.engine_newPayloadV1(pivotRequest); payloadStatus.Data.Status.Should().Be(nameof(PayloadStatusV1.Syncing).ToUpper()); pivotRequest.TryGetBlock(out Block? pivotBlock); @@ -821,7 +821,7 @@ public async Task Maintain_correct_pointers_for_beacon_sync_in_fast_sync() forkchoiceUpdatedResult.Data.PayloadStatus.Status.Should() .Be(nameof(PayloadStatusV1.Syncing).ToUpper()); // trigger insertion of blocks in cache into block tree by adding new block - ExecutionPayload bestBeaconBlockRequest = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, pivotRequest, Address.Zero); + ExecutionPayload bestBeaconBlockRequest = CreateBlockRequest(chain, pivotRequest, Address.Zero); payloadStatus = await rpc.engine_newPayloadV1(bestBeaconBlockRequest); payloadStatus.Data.Status.Should().Be(nameof(PayloadStatusV1.Syncing).ToUpper()); // fill in beacon headers until fast headers pivot @@ -855,12 +855,12 @@ public async Task Invalid_block_can_create_invalid_best_state_issue_but_recalcul chain.BlockTree.HeadHash.Should().Be(lastHash); // send newPayload - ExecutionPayload validBlockOnTopOfHead = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); + ExecutionPayload validBlockOnTopOfHead = CreateBlockRequest(chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); PayloadStatusV1 payloadStatusResponse = (await rpc.engine_newPayloadV1(validBlockOnTopOfHead)).Data; payloadStatusResponse.Status.Should().Be(PayloadStatus.Valid); // send block with invalid state root - ExecutionPayload blockWithInvalidStateRoot = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, validBlockOnTopOfHead, TestItem.AddressA); + ExecutionPayload blockWithInvalidStateRoot = CreateBlockRequest(chain, validBlockOnTopOfHead, TestItem.AddressA); blockWithInvalidStateRoot.StateRoot = TestItem.KeccakB; TryCalculateHash(blockWithInvalidStateRoot, out Keccak? hash); blockWithInvalidStateRoot.BlockHash = hash; @@ -892,12 +892,12 @@ public async Task MultiSyncModeSelector_should_fix_block_tree_levels_if_needed() chain.BlockTree.HeadHash.Should().Be(lastHash); // send newPayload - ExecutionPayload validBlockOnTopOfHead = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); + ExecutionPayload validBlockOnTopOfHead = CreateBlockRequest(chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); PayloadStatusV1 payloadStatusResponse = (await rpc.engine_newPayloadV1(validBlockOnTopOfHead)).Data; payloadStatusResponse.Status.Should().Be(PayloadStatus.Valid); // send block with invalid state root - ExecutionPayload blockWithInvalidStateRoot = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, validBlockOnTopOfHead, TestItem.AddressA); + ExecutionPayload blockWithInvalidStateRoot = CreateBlockRequest(chain, validBlockOnTopOfHead, TestItem.AddressA); blockWithInvalidStateRoot.StateRoot = TestItem.KeccakB; TryCalculateHash(blockWithInvalidStateRoot, out Keccak? hash); blockWithInvalidStateRoot.BlockHash = hash; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs index 878cd9a4665..1dd1e1d5a6f 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs @@ -450,7 +450,7 @@ public async Task executePayloadV1_result_is_fail_when_blockchainprocessor_repor ((TestBlockProcessorInterceptor)chain.BlockProcessor).ExceptionToThrow = new Exception("unxpected exception"); - ExecutionPayload executionPayload = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); + ExecutionPayload executionPayload = CreateBlockRequest(chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); ResultWrapper resultWrapper = await rpc.engine_newPayloadV1(executionPayload); resultWrapper.Result.ResultType.Should().Be(ResultType.Failure); } @@ -786,7 +786,7 @@ public async Task executePayloadV1_should_not_accept_blocks_with_incorrect_ttd(l TerminalTotalDifficulty = $"{terminalTotalDifficulty}" }); IEngineRpcModule rpc = CreateEngineModule(chain); - ExecutionPayload executionPayload = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); + ExecutionPayload executionPayload = CreateBlockRequest(chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); ResultWrapper resultWrapper = await rpc.engine_newPayloadV1(executionPayload); resultWrapper.Data.Status.Should().Be(PayloadStatus.Invalid); resultWrapper.Data.LatestValidHash.Should().Be(Keccak.Zero); @@ -903,7 +903,7 @@ public async Task executePayloadV1_accepts_first_block() { using MergeTestBlockchain chain = await CreateBlockchain(); IEngineRpcModule rpc = CreateEngineModule(chain); - ExecutionPayload executionPayload = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); + ExecutionPayload executionPayload = CreateBlockRequest(chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); ResultWrapper resultWrapper = await rpc.engine_newPayloadV1(executionPayload); resultWrapper.Data.Status.Should().Be(PayloadStatus.Valid); new ExecutionPayload(chain.BlockTree.BestSuggestedBody!).Should().BeEquivalentTo(executionPayload); @@ -915,8 +915,7 @@ public async Task executePayloadV1_calculate_hash_for_cached_blocks() using MergeTestBlockchain chain = await CreateBlockchain(); IEngineRpcModule rpc = CreateEngineModule(chain); ExecutionPayload executionPayload = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); ResultWrapper resultWrapper = await rpc.engine_newPayloadV1(executionPayload); resultWrapper.Data.Status.Should().Be(PayloadStatus.Valid); @@ -1001,7 +1000,7 @@ public async Task newPayloadV1_should_return_accepted_for_side_branch() { using MergeTestBlockchain chain = await CreateBlockchain(); IEngineRpcModule rpc = CreateEngineModule(chain); - ExecutionPayload executionPayload = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); + ExecutionPayload executionPayload = CreateBlockRequest(chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); ResultWrapper resultWrapper = await rpc.engine_newPayloadV1(executionPayload); resultWrapper.Data.Status.Should().Be(PayloadStatus.Valid); ForkchoiceStateV1 forkChoiceUpdatedRequest = new(executionPayload.BlockHash, executionPayload.BlockHash, executionPayload.BlockHash); @@ -1026,7 +1025,7 @@ public async Task executePayloadV1_processes_passed_transactions(bool moveHead) foreach (ExecutionPayload block in branch) { uint count = 10; - ExecutionPayload executePayloadRequest = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, block, TestItem.AddressA); + ExecutionPayload executePayloadRequest = CreateBlockRequest(chain, block, TestItem.AddressA); PrivateKey from = TestItem.PrivateKeyB; Address to = TestItem.AddressD; (_, UInt256 toBalanceAfter) = AddTransactions(chain, executePayloadRequest, from, to, count, 1, out BlockHeader? parentHeader); @@ -1063,7 +1062,7 @@ public async Task executePayloadV1_transactions_produce_receipts() foreach (ExecutionPayload block in branch) { uint count = 10; - ExecutionPayload executionPayload = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, block, TestItem.AddressA); + ExecutionPayload executionPayload = CreateBlockRequest(chain, block, TestItem.AddressA); PrivateKey from = TestItem.PrivateKeyB; Address to = TestItem.AddressD; (_, UInt256 toBalanceAfter) = AddTransactions(chain, executionPayload, from, to, count, 1, out BlockHeader parentHeader); @@ -1216,8 +1215,7 @@ public async Task exchangeTransitionConfiguration_return_with_empty_Nethermind_c private async Task SendNewBlockV1(IEngineRpcModule rpc, MergeTestBlockchain chain) { ExecutionPayload executionPayload = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); ResultWrapper executePayloadResult = await rpc.engine_newPayloadV1(executionPayload); @@ -1264,8 +1262,7 @@ public async Task repeat_the_same_payload_after_fcu_should_return_valid_and_be_i // Correct new payload ExecutionPayload executionPayloadV11 = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressA); ResultWrapper newPayloadResult1 = await rpc.engine_newPayloadV1(executionPayloadV11); newPayloadResult1.Data.Status.Should().Be(PayloadStatus.Valid); @@ -1292,8 +1289,7 @@ public async Task payloadV1_invalid_parent_hash() // Correct new payload ExecutionPayload executionPayloadV11 = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressA); ResultWrapper newPayloadResult1 = await rpc.engine_newPayloadV1(executionPayloadV11); newPayloadResult1.Data.Status.Should().Be(PayloadStatus.Valid); @@ -1305,7 +1301,7 @@ public async Task payloadV1_invalid_parent_hash() forkchoiceUpdatedResult1.Data.PayloadStatus.Status.Should().Be(PayloadStatus.Valid); // New payload unknown parent hash - ExecutionPayload executionPayloadV12A = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, executionPayloadV11, TestItem.AddressA); + ExecutionPayload executionPayloadV12A = CreateBlockRequest(chain, executionPayloadV11, TestItem.AddressA); executionPayloadV12A.ParentHash = TestItem.KeccakB; TryCalculateHash(executionPayloadV12A, out Keccak? hash); executionPayloadV12A.BlockHash = hash; @@ -1320,7 +1316,7 @@ public async Task payloadV1_invalid_parent_hash() forkchoiceUpdatedResult2A.Data.PayloadStatus.Status.Should().Be(PayloadStatus.Syncing); // New payload with correct parent hash - ExecutionPayload executionPayloadV12B = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, executionPayloadV11, TestItem.AddressA); + ExecutionPayload executionPayloadV12B = CreateBlockRequest(chain, executionPayloadV11, TestItem.AddressA); ResultWrapper newPayloadResult2B = await rpc.engine_newPayloadV1(executionPayloadV12B); newPayloadResult2B.Data.Status.Should().Be(PayloadStatus.Valid); @@ -1331,7 +1327,7 @@ public async Task payloadV1_invalid_parent_hash() forkchoiceUpdatedResult2B.Data.PayloadStatus.Status.Should().Be(PayloadStatus.Valid); // New payload unknown parent hash - ExecutionPayload executionPayloadV13A = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, executionPayloadV12A, TestItem.AddressA); + ExecutionPayload executionPayloadV13A = CreateBlockRequest(chain, executionPayloadV12A, TestItem.AddressA); ResultWrapper newPayloadResult3A = await rpc.engine_newPayloadV1(executionPayloadV13A); newPayloadResult3A.Data.Status.Should().Be(PayloadStatus.Syncing); @@ -1342,7 +1338,7 @@ public async Task payloadV1_invalid_parent_hash() ResultWrapper forkchoiceUpdatedResult3A = await rpc.engine_forkchoiceUpdatedV1(forkChoiceState3A); forkchoiceUpdatedResult3A.Data.PayloadStatus.Status.Should().Be(PayloadStatus.Syncing); - ExecutionPayload executionPayloadV13B = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, executionPayloadV12B, TestItem.AddressA); + ExecutionPayload executionPayloadV13B = CreateBlockRequest(chain, executionPayloadV12B, TestItem.AddressA); ResultWrapper newPayloadResult3B = await rpc.engine_newPayloadV1(executionPayloadV13B); newPayloadResult3B.Data.Status.Should().Be(PayloadStatus.Valid); @@ -1361,8 +1357,7 @@ public async Task inconsistent_finalized_hash() IEngineRpcModule rpc = CreateEngineModule(chain); ExecutionPayload blockRequestResult1 = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressA); ResultWrapper newPayloadResult1 = await rpc.engine_newPayloadV1(blockRequestResult1); newPayloadResult1.Data.Status.Should().Be(PayloadStatus.Valid); @@ -1372,15 +1367,15 @@ public async Task inconsistent_finalized_hash() ResultWrapper forkchoiceUpdatedResult1 = await rpc.engine_forkchoiceUpdatedV1(forkChoiceState1); forkchoiceUpdatedResult1.Data.PayloadStatus.Status.Should().Be(PayloadStatus.Valid); - ExecutionPayload blockRequestResult2A = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, blockRequestResult1, TestItem.AddressB); + ExecutionPayload blockRequestResult2A = CreateBlockRequest(chain, blockRequestResult1, TestItem.AddressB); ResultWrapper newPayloadResult2A = await rpc.engine_newPayloadV1(blockRequestResult2A); newPayloadResult2A.Data.Status.Should().Be(PayloadStatus.Valid); - ExecutionPayload blockRequestResult2B = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, blockRequestResult1, TestItem.AddressA); + ExecutionPayload blockRequestResult2B = CreateBlockRequest(chain, blockRequestResult1, TestItem.AddressA); ResultWrapper newPayloadResult2B = await rpc.engine_newPayloadV1(blockRequestResult2B); newPayloadResult2B.Data.Status.Should().Be(PayloadStatus.Valid); - ExecutionPayload blockRequestResult3B = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, blockRequestResult2B, TestItem.AddressA); + ExecutionPayload blockRequestResult3B = CreateBlockRequest(chain, blockRequestResult2B, TestItem.AddressA); ResultWrapper newPayloadResult3B = await rpc.engine_newPayloadV1(blockRequestResult3B); newPayloadResult3B.Data.Status.Should().Be(PayloadStatus.Valid); @@ -1398,8 +1393,7 @@ public async Task inconsistent_safe_hash() IEngineRpcModule rpc = CreateEngineModule(chain); ExecutionPayload blockRequestResult1 = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressA); ResultWrapper newPayloadResult1 = await rpc.engine_newPayloadV1(blockRequestResult1); newPayloadResult1.Data.Status.Should().Be(PayloadStatus.Valid); @@ -1409,15 +1403,15 @@ public async Task inconsistent_safe_hash() ResultWrapper forkchoiceUpdatedResult1 = await rpc.engine_forkchoiceUpdatedV1(forkChoiceState1); forkchoiceUpdatedResult1.Data.PayloadStatus.Status.Should().Be(PayloadStatus.Valid); - ExecutionPayload blockRequestResult2A = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, blockRequestResult1, TestItem.AddressB); + ExecutionPayload blockRequestResult2A = CreateBlockRequest(chain, blockRequestResult1, TestItem.AddressB); ResultWrapper newPayloadResult2A = await rpc.engine_newPayloadV1(blockRequestResult2A); newPayloadResult2A.Data.Status.Should().Be(PayloadStatus.Valid); - ExecutionPayload blockRequestResult2B = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, blockRequestResult1, TestItem.AddressA); + ExecutionPayload blockRequestResult2B = CreateBlockRequest(chain, blockRequestResult1, TestItem.AddressA); ResultWrapper newPayloadResult2B = await rpc.engine_newPayloadV1(blockRequestResult2B); newPayloadResult2B.Data.Status.Should().Be(PayloadStatus.Valid); - ExecutionPayload blockRequestResult3B = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, blockRequestResult2B, TestItem.AddressA); + ExecutionPayload blockRequestResult3B = CreateBlockRequest(chain, blockRequestResult2B, TestItem.AddressA); ResultWrapper newPayloadResult3B = await rpc.engine_newPayloadV1(blockRequestResult3B); newPayloadResult3B.Data.Status.Should().Be(PayloadStatus.Valid); @@ -1455,8 +1449,7 @@ await rpc.engine_forkchoiceUpdatedV1(forkChoiceStateGen, // Add one block ExecutionPayload executionPayloadV11 = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressA); executionPayloadV11.PrevRandao = prevRandao1; @@ -1481,8 +1474,7 @@ await rpc.engine_forkchoiceUpdatedV1(forkChoiceState1, { ExecutionPayload executionPayloadV12 = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - executionPayloadV11, + chain, executionPayloadV11, TestItem.AddressA); executionPayloadV12.PrevRandao = prevRandao3; @@ -1505,10 +1497,7 @@ await rpc.engine_forkchoiceUpdatedV1(forkChoiceState1, // re-org { - ExecutionPayload executionPayloadV13 = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - executionPayloadV11, - TestItem.AddressA); + ExecutionPayload executionPayloadV13 = CreateBlockRequest(chain, executionPayloadV11, TestItem.AddressA); executionPayloadV13.PrevRandao = prevRandao2; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs index faf7149f163..88afacbe088 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs @@ -637,7 +637,8 @@ public async Task executePayloadV2_works_correctly_when_0_withdrawals_applied(( { using MergeTestBlockchain chain = await CreateBlockchain(input.ReleaseSpec); IEngineRpcModule rpc = CreateEngineModule(chain); - ExecutionPayload executionPayload = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, CreateParentBlockRequestOnHead(chain.BlockTree), + ExecutionPayload executionPayload = CreateBlockRequest(chain, + CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, input.Withdrawals); ResultWrapper resultWrapper = await rpc.engine_newPayloadV2(executionPayload); @@ -706,7 +707,7 @@ public virtual async Task Should_handle_withdrawals_transition_when_Shanghai_for // Block without withdrawals, Timestamp = 2 ExecutionPayload executionPayload = - CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); + CreateBlockRequest(chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD); ResultWrapper resultWrapper = await rpc.engine_newPayloadV2(executionPayload); resultWrapper.Data.Status.Should().Be(PayloadStatus.Valid); @@ -872,8 +873,7 @@ private async Task BuildAndSendNewBlockV2( private async Task SendNewBlockV2(IEngineRpcModule rpc, MergeTestBlockchain chain, IList? withdrawals) { - ExecutionPayload executionPayload = CreateBlockRequest(chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals); + ExecutionPayload executionPayload = CreateBlockRequest(chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals); ResultWrapper executePayloadResult = await rpc.engine_newPayloadV2(executionPayload); executePayloadResult.Data.Status.Should().Be(PayloadStatus.Valid); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs index ee8525f200e..43b935389f2 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; using FluentAssertions; +using k8s.Models; using Nethermind.Consensus.Producers; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -25,6 +26,7 @@ using Nethermind.Merge.Plugin.Handlers; using Nethermind.Serialization.Json; using Nethermind.Serialization.Rlp; +using Nethermind.Specs; using Nethermind.Specs.Forks; using Newtonsoft.Json.Linq; using NSubstitute; @@ -40,8 +42,7 @@ public async Task NewPayloadV1_should_decline_post_cancun() MergeTestBlockchain chain = await CreateBlockchain(releaseSpec: Cancun.Instance); IEngineRpcModule rpcModule = CreateEngineModule(chain); ExecutionPayload executionPayload = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty()); + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty()); ResultWrapper result = await rpcModule.engine_newPayloadV1(executionPayload); @@ -54,8 +55,7 @@ public async Task NewPayloadV2_should_decline_post_cancun() MergeTestBlockchain chain = await CreateBlockchain(releaseSpec: Cancun.Instance); IEngineRpcModule rpcModule = CreateEngineModule(chain); ExecutionPayload executionPayload = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty()); + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty()); ResultWrapper result = await rpcModule.engine_newPayloadV2(executionPayload); @@ -68,8 +68,7 @@ public async Task NewPayloadV2_should_decline_pre_cancun_with_cancun_fields MergeTestBlockchain chain = await CreateBlockchain(releaseSpec: Shanghai.Instance); IEngineRpcModule rpcModule = CreateEngineModule(chain); ExecutionPayload executionPayload = CreateBlockRequest( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty(), + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty(), blobGasUsed: blobGasUsed, excessBlobGas: excessBlobGas, parentBeaconBlockRoot: parentBlockBeaconRoot); ResultWrapper result = await rpcModule.engine_newPayloadV2(executionPayload); @@ -83,8 +82,7 @@ public async Task NewPayloadV3_should_decline_pre_cancun_payloads() MergeTestBlockchain chain = await CreateBlockchain(releaseSpec: Shanghai.Instance); IEngineRpcModule rpcModule = CreateEngineModule(chain); ExecutionPayloadV3 executionPayload = CreateBlockRequestV3( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty()); + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty()); ResultWrapper result = await rpcModule.engine_newPayloadV3(executionPayload, new byte[0][], executionPayload.ParentBeaconBlockRoot); @@ -94,7 +92,7 @@ public async Task NewPayloadV3_should_decline_pre_cancun_payloads() [Test] public async Task GetPayloadV3_should_decline_pre_cancun_payloads() { - (IEngineRpcModule rpcModule, string payloadId, _) = await BuildAndGetPayloadV3Result(Shanghai.Instance); + (IEngineRpcModule rpcModule, string payloadId, _, _) = await BuildAndGetPayloadV3Result(Shanghai.Instance); ResultWrapper getPayloadResult = await rpcModule.engine_getPayloadV3(Bytes.FromHexString(payloadId)); Assert.That(getPayloadResult.ErrorCode, @@ -104,7 +102,7 @@ public async Task GetPayloadV3_should_decline_pre_cancun_payloads() [Test] public async Task GetPayloadV2_should_decline_post_cancun_payloads() { - (IEngineRpcModule rpcModule, string payloadId, _) = await BuildAndGetPayloadV3Result(Cancun.Instance); + (IEngineRpcModule rpcModule, string payloadId, _, _) = await BuildAndGetPayloadV3Result(Cancun.Instance); ResultWrapper getPayloadResult = await rpcModule.engine_getPayloadV2(Bytes.FromHexString(payloadId)); Assert.That(getPayloadResult.ErrorCode, @@ -132,7 +130,7 @@ public async Task GetPayloadV3_should_fail_on_unknown_payload() [TestCase(4)] public async Task GetPayloadV3_should_return_all_the_blobs(int blobTxCount) { - (IEngineRpcModule rpcModule, string payloadId, _) = await BuildAndGetPayloadV3Result(Cancun.Instance, blobTxCount); + (IEngineRpcModule rpcModule, string payloadId, _, _) = await BuildAndGetPayloadV3Result(Cancun.Instance, blobTxCount); ResultWrapper result = await rpcModule.engine_getPayloadV3(Bytes.FromHexString(payloadId)); BlobsBundleV1 getPayloadResultBlobsBundle = result.Data!.BlobsBundle!; Assert.That(result.Data.ExecutionPayload.BlobGasUsed, Is.EqualTo(BlobGasCalculator.CalculateBlobGas(blobTxCount))); @@ -145,7 +143,7 @@ public async Task GetPayloadV3_should_return_all_the_blobs(int blobTxCount) [TestCase(true, PayloadStatus.Invalid)] public virtual async Task NewPayloadV3_should_decline_mempool_encoding(bool inMempoolForm, string expectedPayloadStatus) { - (IEngineRpcModule rpcModule, string payloadId, Transaction[] transactions) = await BuildAndGetPayloadV3Result(Cancun.Instance, 1); + (IEngineRpcModule rpcModule, string payloadId, Transaction[] transactions, _) = await BuildAndGetPayloadV3Result(Cancun.Instance, 1); ExecutionPayloadV3 payload = (await rpcModule.engine_getPayloadV3(Bytes.FromHexString(payloadId))).Data!.ExecutionPayload; @@ -164,7 +162,7 @@ public virtual async Task NewPayloadV3_should_decline_mempool_encoding(bool inMe [TestCase(true, PayloadStatus.Invalid)] public virtual async Task NewPayloadV3_should_decline_incorrect_blobgasused(bool isBlobGasUsedBroken, string expectedPayloadStatus) { - (IEngineRpcModule prevRpcModule, string payloadId, Transaction[] transactions) = await BuildAndGetPayloadV3Result(Cancun.Instance, 1); + (IEngineRpcModule prevRpcModule, string payloadId, Transaction[] transactions, _) = await BuildAndGetPayloadV3Result(Cancun.Instance, 1); ExecutionPayloadV3 payload = (await prevRpcModule.engine_getPayloadV3(Bytes.FromHexString(payloadId))).Data!.ExecutionPayload; if (isBlobGasUsedBroken) @@ -210,8 +208,7 @@ public async Task NewPayloadV3_should_decline_null_blobversionedhashes() moduleProvider.Register(new SingletonModulePool(new SingletonFactory(rpcModule), true)); ExecutionPayloadV3 executionPayload = CreateBlockRequestV3( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty(), blobGasUsed: 0, excessBlobGas: 0, parentBeaconBlockRoot: TestItem.KeccakA); + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty(), blobGasUsed: 0, excessBlobGas: 0, parentBeaconBlockRoot: TestItem.KeccakA); return (new(moduleProvider, LimboLogs.Instance, jsonRpcConfig), new(RpcEndpoint.Http), new(), executionPayload); } @@ -368,13 +365,65 @@ public async Task NewPayloadV3_should_verify_blob_versioned_hashes_again (byte[][] blobVersionedHashes, Transaction[] transactions) = BuildTransactionsAndBlobVersionedHashesList(hashesFirstBytes, transactionsAndFirstBytesOfTheirHashes, blockchain.SpecProvider.ChainId); ExecutionPayloadV3 executionPayload = CreateBlockRequestV3( - blockchain.SpecProvider.GenesisSpec, blockchain.State, - CreateParentBlockRequestOnHead(blockchain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty(), 0, 0, transactions: transactions, parentBeaconBlockRoot: Keccak.Zero); + blockchain, CreateParentBlockRequestOnHead(blockchain.BlockTree), TestItem.AddressD, withdrawals: Array.Empty(), 0, 0, transactions: transactions, parentBeaconBlockRoot: Keccak.Zero); ResultWrapper result = await engineRpcModule.engine_newPayloadV3(executionPayload, blobVersionedHashes, Keccak.Zero); return result.Data.Status; } + [Test] + public async Task ForkChoiceUpdated_should_return_invalid_params_but_change_latest_block() + { + (IEngineRpcModule rpcModule, string payloadId, Transaction[] transactions, MergeTestBlockchain chain) = + await BuildAndGetPayloadV3Result(Cancun.Instance, 0); + ExecutionPayloadV3 payload = (await rpcModule.engine_getPayloadV3(Bytes.FromHexString(payloadId))).Data!.ExecutionPayload; + + ForkchoiceStateV1 fcuState = new(payload.BlockHash, payload.BlockHash, payload.BlockHash); + PayloadAttributes payloadAttributes = new() + { + Timestamp = payload.Timestamp + 1, + PrevRandao = Keccak.Zero, + SuggestedFeeRecipient = Address.Zero, + Withdrawals = new List(), + ParentBeaconBlockRoot = null, + }; + + await rpcModule.engine_newPayloadV3(payload, Array.Empty(), payload.ParentBeaconBlockRoot); + ResultWrapper fcuResponse = await rpcModule.engine_forkchoiceUpdatedV3(fcuState, payloadAttributes); + Assert.Multiple(() => + { + Assert.That(fcuResponse.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(fcuResponse.ErrorCode, Is.EqualTo(ErrorCodes.InvalidParams)); + Assert.That(chain.BlockTree.Head!.Hash, Is.EqualTo(payload.BlockHash)); + }); + } + + [Test] + public async Task ForkChoiceUpdated_should_return_unsupported_fork_but_change_latest_block() + { + (IEngineRpcModule rpcModule, string payloadId, Transaction[] transactions, MergeTestBlockchain chain) = + await BuildAndGetPayloadV3Result(Cancun.Instance, 0); + ExecutionPayloadV3 payload = (await rpcModule.engine_getPayloadV3(Bytes.FromHexString(payloadId))).Data!.ExecutionPayload; + + ForkchoiceStateV1 fcuState = new(payload.BlockHash, payload.BlockHash, payload.BlockHash); + PayloadAttributes payloadAttributes = new() + { + Timestamp = payload.Timestamp + 1, + PrevRandao = Keccak.Zero, + SuggestedFeeRecipient = Address.Zero, + Withdrawals = new List(), + }; + + await rpcModule.engine_newPayloadV3(payload, Array.Empty(), payload.ParentBeaconBlockRoot); + ResultWrapper fcuResponse = await rpcModule.engine_forkchoiceUpdatedV2(fcuState, payloadAttributes); + Assert.Multiple(() => + { + Assert.That(fcuResponse.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(fcuResponse.ErrorCode, Is.EqualTo(ErrorCodes.UnsupportedFork)); + Assert.That(chain.BlockTree.Head!.Hash, Is.EqualTo(payload.BlockHash)); + }); + } + public static IEnumerable ForkchoiceUpdatedV3DeclinedTestCaseSource { get @@ -529,8 +578,7 @@ public static IEnumerable CancunFieldsTestSource private async Task SendNewBlockV3(IEngineRpcModule rpc, MergeTestBlockchain chain, IList? withdrawals) { ExecutionPayloadV3 executionPayload = CreateBlockRequestV3( - chain.SpecProvider.GenesisSpec, chain.State, - CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals, 0, 0, parentBeaconBlockRoot: TestItem.KeccakE); + chain, CreateParentBlockRequestOnHead(chain.BlockTree), TestItem.AddressD, withdrawals, 0, 0, parentBeaconBlockRoot: TestItem.KeccakE); ResultWrapper executePayloadResult = await rpc.engine_newPayloadV3(executionPayload, Array.Empty(), executionPayload.ParentBeaconBlockRoot); executePayloadResult.Data.Status.Should().Be(PayloadStatus.Valid); @@ -538,7 +586,7 @@ private async Task SendNewBlockV3(IEngineRpcModule rpc, MergeT return executionPayload; } - private async Task<(IEngineRpcModule, string, Transaction[])> BuildAndGetPayloadV3Result( + private async Task<(IEngineRpcModule, string, Transaction[], MergeTestBlockchain chain)> BuildAndGetPayloadV3Result( IReleaseSpec spec, int transactionCount = 0) { MergeTestBlockchain chain = await CreateBlockchain(releaseSpec: spec, null); @@ -573,6 +621,6 @@ private async Task SendNewBlockV3(IEngineRpcModule rpc, MergeT string payloadId = spec.IsBeaconBlockRootAvailable ? rpcModule.engine_forkchoiceUpdatedV3(forkchoiceState, payloadAttributes).Result.Data.PayloadId! : rpcModule.engine_forkchoiceUpdatedV2(forkchoiceState, payloadAttributes).Result.Data.PayloadId!; - return (rpcModule, payloadId, txs); + return (rpcModule, payloadId, txs, chain); } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs index ac4514765d9..f444d926b2d 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs @@ -39,21 +39,12 @@ public async Task> engine_newPayloadV1(ExecutionP private async Task> ForkchoiceUpdated(ForkchoiceStateV1 forkchoiceState, PayloadAttributes? payloadAttributes, int version) { - string? error = null; - switch (payloadAttributes?.Validate(_specProvider, version, out error)) - { - case PayloadAttributesValidationResult.InvalidParams: - return ResultWrapper.Fail(error!, ErrorCodes.InvalidParams); - case PayloadAttributesValidationResult.UnsupportedFork: - return ResultWrapper.Fail(error!, ErrorCodes.UnsupportedFork); - } - if (await _locker.WaitAsync(_timeout)) { Stopwatch watch = Stopwatch.StartNew(); try { - return await _forkchoiceUpdatedV1Handler.Handle(forkchoiceState, payloadAttributes); + return await _forkchoiceUpdatedV1Handler.Handle(forkchoiceState, payloadAttributes, version); } finally { diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs index e332eb2d5af..8daf62c6350 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs @@ -11,6 +11,7 @@ using Nethermind.Consensus.Producers; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.JsonRpc; using Nethermind.Logging; @@ -42,6 +43,7 @@ public class ForkchoiceUpdatedHandler : IForkchoiceUpdatedHandler private readonly IBeaconPivot _beaconPivot; private readonly ILogger _logger; private readonly IPeerRefresher _peerRefresher; + private readonly ISpecProvider _specProvider; public ForkchoiceUpdatedHandler( IBlockTree blockTree, @@ -54,6 +56,7 @@ public ForkchoiceUpdatedHandler( IMergeSyncController mergeSyncController, IBeaconPivot beaconPivot, IPeerRefresher peerRefresher, + ISpecProvider specProvider, ILogManager logManager) { _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); @@ -66,10 +69,22 @@ public ForkchoiceUpdatedHandler( _mergeSyncController = mergeSyncController; _beaconPivot = beaconPivot; _peerRefresher = peerRefresher; + _specProvider = specProvider; _logger = logManager.GetClassLogger(); } - public Task> Handle(ForkchoiceStateV1 forkchoiceState, PayloadAttributes? payloadAttributes) + public Task> Handle(ForkchoiceStateV1 forkchoiceState, PayloadAttributes? payloadAttributes, int version) + { + Block? newHeadBlock = GetBlock(forkchoiceState.HeadBlockHash); + ResultWrapper? payloadUpdateResult = ApplyForkchoiceUpdate(newHeadBlock, forkchoiceState, payloadAttributes); + return Task.FromResult( + ValidateAttributes(payloadAttributes, version) ?? + payloadUpdateResult ?? + StartBuildingPayload(newHeadBlock!, forkchoiceState, payloadAttributes) + ); + } + + private ResultWrapper? ApplyForkchoiceUpdate(Block? newHeadBlock, ForkchoiceStateV1 forkchoiceState, PayloadAttributes? payloadAttributes) { if (_invalidChainTracker.IsOnKnownInvalidChain(forkchoiceState.HeadBlockHash, out Keccak? lastValidHash)) { @@ -77,7 +92,6 @@ public Task> Handle(ForkchoiceStateV1 f return ForkchoiceUpdatedV1Result.Invalid(lastValidHash); } - Block? newHeadBlock = GetBlock(forkchoiceState.HeadBlockHash); if (newHeadBlock is null) // if a head is unknown we are syncing { string simpleRequestStr = payloadAttributes is null ? forkchoiceState.ToString() : $"{forkchoiceState} {payloadAttributes}"; @@ -223,6 +237,11 @@ public Task> Handle(ForkchoiceStateV1 f if (_logger.IsInfo) _logger.Info($"Synced chain Head to {newHeadBlock.ToString(Block.Format.Short)}"); } + return null; + } + + private ResultWrapper StartBuildingPayload(Block newHeadBlock, ForkchoiceStateV1 forkchoiceState, PayloadAttributes? payloadAttributes) + { string? payloadId = null; if (payloadAttributes is not null) { @@ -239,12 +258,23 @@ public Task> Handle(ForkchoiceStateV1 f payloadId = _payloadPreparationService.StartPreparingPayload(newHeadBlock.Header, payloadAttributes); } - if (_logger.IsDebug) _logger.Debug($"Valid. Request: {requestStr}."); - _blockTree.ForkChoiceUpdated(forkchoiceState.FinalizedBlockHash, forkchoiceState.SafeBlockHash); return ForkchoiceUpdatedV1Result.Valid(payloadId, forkchoiceState.HeadBlockHash); } + private ResultWrapper? ValidateAttributes(PayloadAttributes? payloadAttributes, int version) + { + string? error = null; + return payloadAttributes?.Validate(_specProvider, version, out error) switch + { + PayloadAttributesValidationResult.InvalidParams => + ResultWrapper.Fail(error!, ErrorCodes.InvalidParams), + PayloadAttributesValidationResult.UnsupportedFork => + ResultWrapper.Fail(error!, ErrorCodes.UnsupportedFork), + _ => null, + }; + } + private void StartNewBeaconHeaderSync(ForkchoiceStateV1 forkchoiceState, Block block, string requestStr) { _mergeSyncController.InitBeaconHeaderSync(block.Header); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IForkchoiceUpdatedHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IForkchoiceUpdatedHandler.cs index b390eb798af..d3e92a0654d 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IForkchoiceUpdatedHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/IForkchoiceUpdatedHandler.cs @@ -10,5 +10,5 @@ namespace Nethermind.Merge.Plugin.Handlers; public interface IForkchoiceUpdatedHandler { - Task> Handle(ForkchoiceStateV1 forkchoiceState, PayloadAttributes? payloadAttributes); + Task> Handle(ForkchoiceStateV1 forkchoiceState, PayloadAttributes? payloadAttributes, int fcuVersion); } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index 7214b8ceb26..8a3569edd1d 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -335,6 +335,7 @@ public Task InitRpcModules() _beaconSync, _beaconPivot, _peerRefresher, + _api.SpecProvider, _api.LogManager), new GetPayloadBodiesByHashV1Handler(_api.BlockTree, _api.LogManager), new GetPayloadBodiesByRangeV1Handler(_api.BlockTree, _api.LogManager), diff --git a/src/Nethermind/Nethermind.Runner/configs/chiado.cfg b/src/Nethermind/Nethermind.Runner/configs/chiado.cfg index 05322221976..544cd189ce2 100644 --- a/src/Nethermind/Nethermind.Runner/configs/chiado.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/chiado.cfg @@ -13,8 +13,8 @@ "Sync": { "FastSync": true, "FastBlocks": true, - "PivotNumber": 6190000, - "PivotHash": "0x19afb16e00cde2cb8546b9f97b34cb80f1a841b15f4d4b2bba5c611cdcbcaca2", + "PivotNumber": 6430000, + "PivotHash": "0x28ed6753cb8487af0160f20485d63bb0f8e5d0196b40114d0ac4c0e2899a9c34", "PivotTotalDifficulty": "231708131825107706987652208063906496124457284", "FastSyncCatchUpHeightDelta": "10000000000", "UseGethLimitsInFastBlocks": false diff --git a/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg b/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg index 573479a70ce..2196079a58a 100644 --- a/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg @@ -8,9 +8,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 26150000, - "PivotHash": "0x1c5fb2be00ab0e60ee511c8473fde1e090f9d41361d2458a58cb4b7f677c56a8", - "PivotTotalDifficulty": "8898383894982540819567245984340738729209295560", + "PivotNumber": 26380000, + "PivotHash": "0x6d4501c431686b5f8acedaf82de84b6f3d772e5361b38f2b17b918804c6bc604", + "PivotTotalDifficulty": "8976648839374356666163822144050045417843699957", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/exosama.cfg b/src/Nethermind/Nethermind.Runner/configs/exosama.cfg index 9456f06296b..3a4ae544d45 100644 --- a/src/Nethermind/Nethermind.Runner/configs/exosama.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/exosama.cfg @@ -8,9 +8,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 5810000, - "PivotHash": "0x7411e4c1ff2241383f7218445676d90b3e593261f2beb4e17796bfd33d55daf9", - "PivotTotalDifficulty": "1977040551810652472722206469178573308214593289", + "PivotNumber": 6050000, + "PivotHash": "0xd184272b911bf21605666963d54ee69863a8cf303c90434f90cdc35356214de0", + "PivotTotalDifficulty": "2058708319871677703953416374962197678963553289", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg b/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg index d61cddc1227..03eac2c0e0b 100644 --- a/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg @@ -12,8 +12,8 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 30110000, - "PivotHash": "0x7b630b4abff0921c930b79a259934babd51c8460408c5ced0269d83589070972", + "PivotNumber": 30340000, + "PivotHash": "0xfcb3d89f5168947220185693748d43d14a8275678703e15d6d23154df497949e", "PivotTotalDifficulty": "8626000110427538733349499292577475819600160930", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, diff --git a/src/Nethermind/Nethermind.Runner/configs/goerli.cfg b/src/Nethermind/Nethermind.Runner/configs/goerli.cfg index 7e6dff6c8b0..c737f5a79a0 100644 --- a/src/Nethermind/Nethermind.Runner/configs/goerli.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/goerli.cfg @@ -15,8 +15,8 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 9720000, - "PivotHash": "0xc611dbb72cdcd5abcf9b25e56295242e5851efd4571cbf5c539c9084a69d92d4", + "PivotNumber": 9810000, + "PivotHash": "0x7713bb38c9fe23c682cb7c081f681a34938d8046fddb4f1b9c5609937e776e81", "PivotTotalDifficulty": "10790000", "FastBlocks": true, "UseGethLimitsInFastBlocks": true, diff --git a/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg b/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg index 8106c644d60..dbbc826c854 100644 --- a/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg @@ -12,8 +12,8 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 18200000, - "PivotHash": "0xb03f1070c7ed301fc72f310181192ad740f6ea09ff1376482d1e0f431b8a6a35", + "PivotNumber": 18301000, + "PivotHash": "0xd3c343a5b698ec8486716a75dac6acba0764da9a2c72be7bdce959ba746cd2e4", "PivotTotalDifficulty": "58750003716598352816469", "FastBlocks": true, "AncientBodiesBarrier": 11052984, diff --git a/src/Nethermind/Nethermind.Runner/configs/sepolia.cfg b/src/Nethermind/Nethermind.Runner/configs/sepolia.cfg index e72bdf8b231..07eb991baa7 100644 --- a/src/Nethermind/Nethermind.Runner/configs/sepolia.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/sepolia.cfg @@ -18,8 +18,8 @@ "FastBlocks": true, "SnapSync": true, "UseGethLimitsInFastBlocks": true, - "PivotNumber": 4349000, - "PivotHash": "0x6fc5c49d62481c262d61e94c386f7a0dd6150f5d4384be926629267c5879d2ae", + "PivotNumber": 4445000, + "PivotHash": "0xed83dc15a64c1fc4f9367b602fc7396f62337f7494e34d1bbca0a8f172d4b404", "PivotTotalDifficulty": "17000018015853232", "FastSyncCatchUpHeightDelta": "10000000000" }, diff --git a/src/Nethermind/Nethermind.Runner/configs/volta.cfg b/src/Nethermind/Nethermind.Runner/configs/volta.cfg index c69117dc784..d181198864f 100644 --- a/src/Nethermind/Nethermind.Runner/configs/volta.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/volta.cfg @@ -12,9 +12,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 24820000, - "PivotHash": "0xde7503303f0a803ce04503bf7cc1fcf9821f9628384a14a4babca2b5fe414125", - "PivotTotalDifficulty": "8445808346977692663160957756456487007974147358", + "PivotNumber": 25010000, + "PivotHash": "0x5c899541cd40af17bf9ed6789ff4bd72083661b7083838b4d223b1c3646d6828", + "PivotTotalDifficulty": "8510461996692670971218998931868522968150348409", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/Eip2930/AccessListDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/Eip2930/AccessListDecoder.cs index db6bd5048d9..bd3a668cc2a 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/Eip2930/AccessListDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/Eip2930/AccessListDecoder.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Collections.Generic; -using System.IO; +using System.Linq; using Nethermind.Core; using Nethermind.Core.Eip2930; using Nethermind.Int256; @@ -29,7 +29,7 @@ public class AccessListDecoder : IRlpStreamDecoder, IRlpValueDecode int length = rlpStream.ReadSequenceLength(); int check = rlpStream.Position + length; - AccessListBuilder accessListBuilder = new(); + AccessList.Builder accessListBuilder = new(); while (rlpStream.Position < check) { int accessListItemLength = rlpStream.ReadSequenceLength(); @@ -72,7 +72,7 @@ public class AccessListDecoder : IRlpStreamDecoder, IRlpValueDecode rlpStream.Check(check); } - return accessListBuilder.ToAccessList(); + return accessListBuilder.Build(); } /// @@ -94,7 +94,7 @@ public class AccessListDecoder : IRlpStreamDecoder, IRlpValueDecode int length = decoderContext.ReadSequenceLength(); int check = decoderContext.Position + length; - AccessListBuilder accessListBuilder = new(); + AccessList.Builder accessListBuilder = new(); while (decoderContext.Position < check) { int accessListItemLength = decoderContext.ReadSequenceLength(); @@ -137,20 +137,7 @@ public class AccessListDecoder : IRlpStreamDecoder, IRlpValueDecode decoderContext.Check(check); } - return accessListBuilder.ToAccessList(); - } - - private readonly struct AccessListItem - { - public AccessListItem(Address address, List indexes) - { - Address = address; - Indexes = indexes; - } - - public Address Address { get; } - - public List Indexes { get; } + return accessListBuilder.Build(); } public void Encode(RlpStream stream, AccessList? item, RlpBehaviors rlpBehaviors = RlpBehaviors.None) @@ -158,86 +145,44 @@ public void Encode(RlpStream stream, AccessList? item, RlpBehaviors rlpBehaviors if (item is null) { stream.WriteByte(Rlp.NullObjectByte); + return; } - else - { - int contentLength = GetContentLength(item); - stream.StartSequence(contentLength); - if (!item.IsNormalized) + int contentLength = GetContentLength(item); + stream.StartSequence(contentLength); + foreach ((Address? address, AccessList.StorageKeysEnumerable storageKeys) in item) + { + // {} brackets applied to show the content structure + // Address + // Index1 + // Index2 + // ... + // IndexN + AccessItemLengths lengths = new(storageKeys.Count()); + stream.StartSequence(lengths.ContentLength); { - AccessListItem? currentItem = default; - - void SerializeCurrent() + stream.Encode(address); + stream.StartSequence(lengths.IndexesContentLength); { - if (currentItem is not null) + foreach (UInt256 index in storageKeys) { - AccessListItem toEncode = currentItem.Value; - EncodeListItem(stream, toEncode.Address, toEncode.Indexes, toEncode.Indexes.Count); - } - } - - foreach (object accessListEntry in item.OrderQueue!) - { - if (accessListEntry is Address address) - { - // serialize any element that is not the last - SerializeCurrent(); - currentItem = new AccessListItem(address, new List()); - } - else - { - if (currentItem is null) - { - throw new InvalidDataException( - $"{nameof(AccessList)} order looks corrupted - processing index ahead of address"); - } - - currentItem.Value.Indexes.Add((UInt256)accessListEntry); + // storage indices are encoded as 32 bytes data arrays + stream.Encode(index, 32); } } - - // serialize the last element - SerializeCurrent(); - } - else - { - foreach ((Address address, IReadOnlySet indexes) in item.Data) - { - EncodeListItem(stream, address, indexes, indexes.Count); - } } } } - /// - /// Spend some time trying to find some base interface like ICountableEnumerable, none of such in .NET Core - /// - private static void EncodeListItem( - RlpStream stream, - Address address, - IEnumerable indexes, - int indexesCount) + public int GetLength(AccessList? accessList, RlpBehaviors rlpBehaviors) { - // {} brackets applied to show the content structure - // Address - // Index1 - // Index2 - // ... - // IndexN - AccessItemLengths lengths = new(indexesCount); - stream.StartSequence(lengths.ContentLength); + if (accessList is null) { - stream.Encode(address); - stream.StartSequence(lengths.IndexesContentLength); - { - foreach (UInt256 index in indexes) - { - // storage indices are encoded as 32 bytes data arrays - stream.Encode(index, 32); - } - } + return 1; } + + int contentLength = GetContentLength(accessList); + return Rlp.LengthOfSequence(contentLength); } /// @@ -261,64 +206,9 @@ public AccessItemLengths(int indexesCount) private static int GetContentLength(AccessList accessList) { - int contentLength = 0; - if (accessList.IsNormalized) - { - foreach ((_, IReadOnlySet indexes) in accessList.Data) - { - contentLength += new AccessItemLengths(indexes.Count).SequenceLength; - } - } - else - { - IReadOnlyCollection orderQueue = accessList.OrderQueue; - bool isOpen = false; - int indexCounter = 0; - foreach (object accessListEntry in orderQueue!) - { - if (accessListEntry is Address) - { - if (isOpen) - { - contentLength += new AccessItemLengths(indexCounter).SequenceLength; - indexCounter = 0; - } - else - { - isOpen = true; - } - } - else - { - indexCounter++; - } - } - - if (isOpen) - { - contentLength += new AccessItemLengths(indexCounter).SequenceLength; - } - } - - return contentLength; - } - - public int GetLength(AccessList? accessList, RlpBehaviors rlpBehaviors) - { - if (accessList is null) - { - return 1; - } - - int contentLength = GetContentLength(accessList); - return Rlp.LengthOfSequence(contentLength); - } - - public Rlp Encode(AccessList? accessList, RlpBehaviors rlpBehaviors = RlpBehaviors.None) - { - RlpStream rlpStream = new(GetLength(accessList, rlpBehaviors)); - Encode(rlpStream, accessList, rlpBehaviors); - return new Rlp(rlpStream.Data); + return accessList + .Select(entry => new AccessItemLengths(entry.StorageKeys.Count())) + .Sum(lengths => lengths.SequenceLength); } } } diff --git a/src/Nethermind/Nethermind.Trie.Test/TrieNodeTests.cs b/src/Nethermind/Nethermind.Trie.Test/TrieNodeTests.cs index 756f2e7548a..dea83ed4a89 100644 --- a/src/Nethermind/Nethermind.Trie.Test/TrieNodeTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/TrieNodeTests.cs @@ -908,6 +908,7 @@ public void Rlp_is_cloned_when_cloning() leaf2.ResolveKey(trieStore, false); leaf2.Seal(); trieStore.CommitNode(0, new NodeCommitInfo(leaf2)); + trieStore.FinishBlockCommit(TrieType.State, 0, leaf2); TrieNode trieNode = new(NodeType.Branch); trieNode.SetChild(1, leaf1); diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs index 66c5cd18d88..19d134e63c7 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs @@ -8,12 +8,10 @@ using System.Threading; using System.Threading.Tasks; using Nethermind.Core; -using Nethermind.Core.Buffers; using Nethermind.Core.Collections; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Logging; -using Nethermind.Serialization.Rlp; namespace Nethermind.Trie.Pruning { diff --git a/src/bench_precompiles b/src/bench_precompiles index d083d17d367..9c9705ed4e7 160000 --- a/src/bench_precompiles +++ b/src/bench_precompiles @@ -1 +1 @@ -Subproject commit d083d17d3679b82585877a2d18829535d972546a +Subproject commit 9c9705ed4e7f264abc8f343a848016e7bf6501b3 From dc43a3d068940c33a685775c4e22f5c9174850f5 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 11 Oct 2023 10:09:43 +0100 Subject: [PATCH 087/213] Merge remote-tracking branch 'origin/release/1.22.0' into feature/eth_multicall --- .../Eth/EthMulticallTestsPrecompilesWithRedirection.cs | 5 ++--- .../Modules/Eth/EthRpcModule.TransactionExecutor.cs | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index db6e90b32b8..27ee915af21 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -136,8 +136,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( //Check results byte[] addressBytes = result.Data[0].Calls.First().ReturnData!.SliceWithZeroPaddingEmptyOnError(12, 20); - Address resultingAddress = new(addressBytes); - Assert.That(resultingAddress, Is.EqualTo(TestItem.AddressA)); - + //Address resultingAddress = new(addressBytes); + //Assert.That(resultingAddress, Is.EqualTo(TestItem.AddressA)) } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index a13b72b749d..5c20d5dae47 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -98,7 +98,7 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, : TryGetInputError(result) ?? ResultWrapper.Fail(result.Error, ErrorCodes.ExecutionError, new AccessListForRpc(GetResultAccessList(tx, result), GetResultGas(tx, result))); } - private static IEnumerable GetResultAccessList(Transaction tx, BlockchainBridge.CallOutput result) + private static IEnumerable GetResultAccessList(Transaction tx, CallOutput result) { AccessList? accessList = result.AccessList ?? tx.AccessList; return accessList is null ? Enumerable.Empty() : AccessListItemForRpc.FromAccessList(accessList); From 201baebaa029580ab9c6666c9225c3e8af3c991d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 11 Oct 2023 10:28:49 +0100 Subject: [PATCH 088/213] post merge conflict resolution --- .../Blockchain/TestBlockchain.cs | 20 ++++++++++++++----- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 13 ++++++++++-- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index 037a0efce13..07cfb45da2e 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -6,7 +6,9 @@ using System.Threading; using System.Threading.Tasks; using Nethermind.Blockchain; +using Nethermind.Blockchain.Blocks; using Nethermind.Blockchain.Find; +using Nethermind.Blockchain.Headers; using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Synchronization; using Nethermind.Config; @@ -142,14 +144,22 @@ protected virtual async Task Build(ISpecProvider? specProvider = ReadOnlyTrieStore = TrieStore.AsReadOnly(StateDb); StateReader = new StateReader(ReadOnlyTrieStore, CodeDb, LogManager); - - IDb blockDb = DbProvider.BlocksDb; - IDb headerDb = DbProvider.HeadersDb; IDb blockInfoDb = DbProvider.BlockInfosDb; IDb metadataDb = DbProvider.MetadataDb; SyncConfig syncConfig = new(); - BlockTree = new BlockTree(blockDb, headerDb, blockInfoDb, metadataDb, new ChainLevelInfoRepository(blockInfoDb), - SpecProvider, NullBloomStorage.Instance, syncConfig, LimboLogs.Instance); + + IBlockStore blockStore = new BlockStore(DbProvider.BlocksDb); + IHeaderStore headerStore = new HeaderStore(DbProvider.HeadersDb, DbProvider.BlockNumbersDb); + + BlockTree = new BlockTree(blockStore, + headerStore, + blockInfoDb, + metadataDb, + new ChainLevelInfoRepository(blockInfoDb), + SpecProvider, + NullBloomStorage.Instance, + syncConfig, + LimboLogs.Instance); ReadOnlyState = new ChainHeadReadOnlyStateProvider(BlockTree, StateReader); TransactionComparerProvider = new TransactionComparerProvider(SpecProvider, BlockTree); diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs index 28546b515e8..a5ed8317ceb 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -3,6 +3,8 @@ using System; using Nethermind.Blockchain; +using Nethermind.Blockchain.Blocks; +using Nethermind.Blockchain.Headers; using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Synchronization; using Nethermind.Consensus.Processing; @@ -36,9 +38,16 @@ public static MultiCallReadOnlyBlocksProcessingEnv Create( ISpecProvider specProvider, ILogManager? logManager = null) { - ReadOnlyDbProvider dbProvider = new(readOnlyDbProvider, true); + IReadOnlyDbProvider dbProvider = new ReadOnlyDbProvider(readOnlyDbProvider, true); TrieStore trieStore = new(readOnlyDbProvider.StateDb, logManager); - BlockTree blockTree = new(readOnlyDbProvider, + + IBlockStore blockStore = new BlockStore(dbProvider.BlocksDb); + IHeaderStore headerStore = new HeaderStore(dbProvider.HeadersDb, dbProvider.BlockNumbersDb); + + BlockTree blockTree = new(blockStore, + headerStore, + dbProvider.BlockInfosDb, + dbProvider.MetadataDb, new ChainLevelInfoRepository(readOnlyDbProvider.BlockInfosDb), specProvider, NullBloomStorage.Instance, From 6c1cebc8215ba49b117c1e89bf47fc1ad13f249f Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 11 Oct 2023 10:56:13 +0100 Subject: [PATCH 089/213] benchmark fixes --- src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs | 4 ++-- .../Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs | 3 ++- .../Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs | 3 ++- .../Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs | 6 ++++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs index 1a46d8e9d58..1eea7194509 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs @@ -44,8 +44,8 @@ public void GlobalSetup() _stateProvider = new WorldState(trieStore, codeDb, new OneLoggerLogManager(NullLogger.Instance)); _stateProvider.CreateAccount(Address.Zero, 1000.Ether()); _stateProvider.Commit(_spec); - - _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, LimboLogs.Instance); + CodeInfoRepository codeInfoRepository = new(); + _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, codeInfoRepository, LimboLogs.Instance); _environment = new ExecutionEnvironment ( diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs index 90c6604b0f5..2b9d8fcbbab 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs @@ -76,7 +76,8 @@ public void GlobalSetup() _stateProvider.Commit(_spec); Console.WriteLine(MuirGlacier.Instance); - _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, new OneLoggerLogManager(NullLogger.Instance)); + CodeInfoRepository codeInfoRepository = new(); + _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, codeInfoRepository, new OneLoggerLogManager(NullLogger.Instance)); _environment = new ExecutionEnvironment ( diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs index 282adcba05d..e53a792f1ac 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs @@ -87,7 +87,8 @@ public void GlobalSetup() _stateProvider.Commit(_spec); Console.WriteLine(MuirGlacier.Instance); - _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, new OneLoggerLogManager(NullLogger.Instance)); + CodeInfoRepository codeInfoRepository = new(); + _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, codeInfoRepository, new OneLoggerLogManager(NullLogger.Instance)); _environment = new ExecutionEnvironment ( diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index a4db7573660..f27489002e5 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -36,6 +36,7 @@ using BlockTree = Nethermind.Blockchain.BlockTree; using Nethermind.Blockchain.Synchronization; using Nethermind.Config; +using Nethermind.Facade.Multicall; using Nethermind.Synchronization.ParallelSync; namespace Nethermind.JsonRpc.Benchmark @@ -77,7 +78,8 @@ public void GlobalSetup() new SyncConfig(), LimboLogs.Instance); _blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance); - _virtualMachine = new VirtualMachine(_blockhashProvider, specProvider, LimboLogs.Instance); + CodeInfoRepository codeInfoRepository = new(); + _virtualMachine = new VirtualMachine(_blockhashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); Block genesisBlock = Build.A.Block.Genesis.TestObject; blockTree.SuggestBlock(genesisBlock); @@ -86,7 +88,7 @@ public void GlobalSetup() blockTree.SuggestBlock(block1); TransactionProcessor transactionProcessor - = new(MainnetSpecProvider.Instance, stateProvider, _virtualMachine, LimboLogs.Instance); + = new(MainnetSpecProvider.Instance, stateProvider, _virtualMachine, codeInfoRepository, LimboLogs.Instance); IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor = new BlockProcessor.BlockValidationTransactionsExecutor(transactionProcessor, stateProvider); BlockProcessor blockProcessor = new(specProvider, Always.Valid, new RewardCalculator(specProvider), transactionsExecutor, From 26f17fa03d83369782935b2fb26c6b0307716993 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Thu, 12 Oct 2023 01:56:06 +0200 Subject: [PATCH 090/213] Revert VirtualMachine code layout a bit --- .../Nethermind.Evm/VirtualMachine.cs | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 867469f206e..588d020598a 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -220,7 +220,22 @@ public TransactionSubstate Run(EvmState state, IWorldState worl { if (typeof(TTracingActions) == typeof(IsTracing) && !currentState.IsContinuation) { - TraceAction(currentState); + if (_txTracer is ILogsTxTracer { IsTracingLogs: true } logsTxTracer) + { + IEnumerable logs = logsTxTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, + currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, + currentState.ExecutionType); + + currentState.Logs.AddRange(logs); + } + else + { + _txTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, + currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, + currentState.ExecutionType); + } + + if (_txTracer.IsTracingCode) _txTracer.ReportByteCode(currentState.Env.CodeInfo.MachineCode); } callResult = !_txTracer.IsTracingInstructions @@ -452,26 +467,6 @@ public TransactionSubstate Run(EvmState state, IWorldState worl } } - private void TraceAction(EvmState currentState) - { - if (_txTracer is ILogsTxTracer { IsTracingLogs: true } logsTxTracer) - { - IEnumerable logs = logsTxTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, - currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, - currentState.ExecutionType); - - currentState.Logs.AddRange(logs); - } - else - { - _txTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, - currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, - currentState.ExecutionType); - } - - if (_txTracer.IsTracingCode) _txTracer.ReportByteCode(currentState.Env.CodeInfo.MachineCode); - } - private void RevertParityTouchBugAccount(IReleaseSpec spec) { if (_parityTouchBugAccount.ShouldDelete) From cedafab828972b30237001301a26ada9aa6369d5 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Thu, 12 Oct 2023 01:56:28 +0200 Subject: [PATCH 091/213] Clear state storrage on accountOverride.State (not StateDiff) --- .../Nethermind.Facade/Multicall/MulticallBridgeHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index d9a8f2e4d88..c39fa5f1f73 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -212,9 +212,9 @@ private void ModifyAccounts(Dictionary stateOverrides, private static void UpdateState(IWorldState stateProvider, AccountOverride accountOverride, Address address) { - //TODO: discuss if clean slate is a must if (accountOverride.State is not null) { + stateProvider.ClearStorage(address); foreach (KeyValuePair storage in accountOverride.State) stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.Bytes.WithoutLeadingZeros().ToArray()); } From 00d0d49d267e8b61ae1e77f122b0f0833dadc36e Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 13 Oct 2023 01:00:37 +0200 Subject: [PATCH 092/213] Refactor to introduce overrides in eth_call --- .../TransactionSelectorTests.cs | 2 +- .../TransactionsExecutorTests.cs | 2 +- .../Nethermind.Facade/BlockchainBridge.cs | 5 +- .../Multicall/MulticallBridgeHelper.cs | 139 +--------------- .../Models/{MultiCall => }/AccountOverride.cs | 6 +- .../Models/MultiCall/AccountOverrideType.cs | 10 -- .../StateOverridesExtensions.cs | 149 ++++++++++++++++++ ...ulticallTestsPrecompilesWithRedirection.cs | 1 + .../StateProviderTests.cs | 2 +- .../Nethermind.State/IWorldState.cs | 8 +- .../Nethermind.State/StateProvider.cs | 8 +- src/Nethermind/Nethermind.State/WorldState.cs | 8 +- .../Nethermind.Trie.Test/TrieTests.cs | 2 +- 13 files changed, 177 insertions(+), 165 deletions(-) rename src/Nethermind/Nethermind.Facade/Proxy/Models/{MultiCall => }/AccountOverride.cs (77%) delete mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverrideType.cs create mode 100644 src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs index 5281b0a37ce..b563c8c318d 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs @@ -195,7 +195,7 @@ public void Proper_transactions_selected(ProperTransactionsSelectedTestCase test MemDb stateDb = new(); MemDb codeDb = new(); TrieStore trieStore = new(stateDb, LimboLogs.Instance); - WorldState stateProvider = new(trieStore, codeDb, LimboLogs.Instance); + IWorldState stateProvider = new WorldState(trieStore, codeDb, LimboLogs.Instance); StateReader _ = new(new TrieStore(stateDb, LimboLogs.Instance), codeDb, LimboLogs.Instance); ISpecProvider specProvider = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs index f43d92ead95..8799490191a 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs @@ -262,7 +262,7 @@ public void Proper_transactions_selected(TransactionSelectorTests.ProperTransact MemDb stateDb = new(); MemDb codeDb = new(); TrieStore trieStore = new(stateDb, LimboLogs.Instance); - WorldState stateProvider = new(trieStore, codeDb, LimboLogs.Instance); + IWorldState stateProvider = new WorldState(trieStore, codeDb, LimboLogs.Instance); ISpecProvider specProvider = Substitute.For(); IReleaseSpec spec = testCase.ReleaseSpec; diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index f5b9f814aa1..71a3a913084 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -252,10 +252,7 @@ private void CallAndRestore( { transaction.Nonce = _processingEnv.StateReader.GetNonce(stateRoot, transaction.SenderAddress); } - catch (Exception) - { - // TODO: handle missing state exception, may be account needs to be created - } + catch (TrieException) { } } BlockHeader callHeader = treatBlockHeaderAsParentBlock diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index c39fa5f1f73..c263b64d9d6 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -6,17 +6,13 @@ using System.Linq; using Nethermind.Config; using Nethermind.Consensus.Processing; -using Nethermind.Consensus.Producers; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Crypto; -using Nethermind.Evm.CodeAnalysis; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; -using Nethermind.State; using Nethermind.Trie; namespace Nethermind.Facade.Multicall; @@ -40,17 +36,10 @@ public MulticallBridgeHelper(MultiCallReadOnlyBlocksProcessingEnv multiCallProce _blocksConfig = blocksConfig; } - void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall? blockStateCall, MultiCallReadOnlyBlocksProcessingEnv env) + private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall blockStateCall, MultiCallReadOnlyBlocksProcessingEnv env) { - IReleaseSpec? currentSpec = env.SpecProvider.GetSpec(blockHeader); - if (blockStateCall!.StateOverrides is not null) - { - ModifyAccounts(blockStateCall.StateOverrides, env.StateProvider, currentSpec); - } - - env.StateProvider.Commit(currentSpec); - env.StateProvider.CommitTree(blockHeader.Number); - env.StateProvider.RecalculateStateRoot(); + IReleaseSpec currentSpec = env.SpecProvider.GetSpec(blockHeader); + env.StateProvider.ApplyStateOverrides(_multiCallProcessingEnv.CodeInfoRepository, blockStateCall.StateOverrides, currentSpec, blockHeader.Number); blockHeader.StateRoot = env.StateProvider.StateRoot; } @@ -75,13 +64,12 @@ void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall nonceCache = new(); - - List suggestedBlocks = new(); - if (payload.BlockStateCalls is not null) { - foreach (BlockStateCall? callInputBlock in payload.BlockStateCalls) + Dictionary nonceCache = new(); + List suggestedBlocks = new(); + + foreach (BlockStateCall callInputBlock in payload.BlockStateCalls) { BlockHeader callHeader = callInputBlock.BlockOverrides is not null ? callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig) @@ -159,117 +147,4 @@ Transaction SetTxHashAndMissingDefaults(Transaction transaction) return (true, ""); } - - private bool TryGetAccount(IWorldState stateProvider, Address address, out Account account) - { - bool accExists = false; - try - { - accExists = stateProvider.AccountExists(address); - account = stateProvider.GetAccount(address); - } - catch (Exception) - { - account = Account.TotallyEmpty; - } - - return accExists; - } - - private void ModifyAccounts(Dictionary stateOverrides, IWorldState stateProvider, IReleaseSpec currentSpec) - { - foreach (KeyValuePair overrideData in stateOverrides) - { - Address address = overrideData.Key; - AccountOverride? accountOverride = overrideData.Value; - - UInt256 balance = 0; - if (accountOverride.Balance is not null) - { - balance = accountOverride.Balance.Value; - } - - UInt256 nonce = 0; - if (accountOverride.Nonce is not null) - { - nonce = accountOverride.Nonce.Value; - } - - if (!TryGetAccount(stateProvider, address, out Account? acc)) - { - stateProvider.CreateAccount(address, balance, nonce); - } - else - { - UpdateBalance(stateProvider, currentSpec, acc, accountOverride, balance, address); - UpdateNonce(stateProvider, acc, accountOverride, nonce, address); - } - - UpdateCode(stateProvider, currentSpec, accountOverride, address); - UpdateState(stateProvider, accountOverride, address); - } - } - - private static void UpdateState(IWorldState stateProvider, AccountOverride accountOverride, Address address) - { - if (accountOverride.State is not null) - { - stateProvider.ClearStorage(address); - foreach (KeyValuePair storage in accountOverride.State) - stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.Bytes.WithoutLeadingZeros().ToArray()); - } - - if (accountOverride.StateDiff is not null) - { - foreach (KeyValuePair storage in accountOverride.StateDiff) - stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.Bytes.WithoutLeadingZeros().ToArray()); - } - } - - private void UpdateCode(IWorldState stateProvider, IReleaseSpec currentSpec, AccountOverride? accountOverride, - Address address) - { - if (accountOverride?.Code is not null) - { - _multiCallProcessingEnv.CodeInfoRepository.SetCodeOverwrite(stateProvider, currentSpec, address, - new CodeInfo(accountOverride.Code), accountOverride.MovePrecompileToAddress); - } - } - - private static void UpdateNonce(IWorldState stateProvider, Account acc, AccountOverride accountOverride, UInt256 nonce, Address address) - { - UInt256 accNonce = acc.Nonce; - if (accountOverride.Nonce != null && accNonce > nonce) - { - UInt256 iters = accNonce - nonce; - for (UInt256 i = 0; i < iters; i++) - { - stateProvider.DecrementNonce(address); - } - } - else if (accountOverride.Nonce != null && accNonce < accountOverride.Nonce) - { - UInt256 iters = nonce - accNonce; - for (UInt256 i = 0; i < iters; i++) - { - stateProvider.IncrementNonce(address); - } - } - } - - private static void UpdateBalance(IWorldState stateProvider, IReleaseSpec currentSpec, Account acc, AccountOverride accountOverride, UInt256 balance, Address address) - { - if (accountOverride.Balance is not null) - { - UInt256 accBalance = acc.Balance; - if (accBalance > balance) - { - stateProvider.SubtractFromBalance(address, accBalance - balance, currentSpec); - } - else if (accBalance < balance) - { - stateProvider.AddToBalance(address, balance - accBalance, currentSpec); - } - } - } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs similarity index 77% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs index a5fea91c06e..567da621e87 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs @@ -6,7 +6,7 @@ using Nethermind.Core.Crypto; using Nethermind.Int256; -namespace Nethermind.Facade.Proxy.Models.MultiCall; +namespace Nethermind.Facade.Proxy.Models; public class AccountOverride { @@ -24,8 +24,4 @@ public class AccountOverride /// Storage difference for AccountOverrideStateDiff /// public Dictionary? StateDiff { get; set; } - - public AccountOverrideType Type => State is null - ? AccountOverrideType.AccountOverrideState - : AccountOverrideType.AccountOverrideStateDiff; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverrideType.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverrideType.cs deleted file mode 100644 index 9af644688c0..00000000000 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/AccountOverrideType.cs +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -namespace Nethermind.Facade.Proxy.Models.MultiCall; - -public enum AccountOverrideType -{ - AccountOverrideState, - AccountOverrideStateDiff -} diff --git a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs new file mode 100644 index 00000000000..b29d97b877e --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs @@ -0,0 +1,149 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Facade.Proxy.Models; +using Nethermind.Int256; +using Nethermind.State; +using Nethermind.Trie; + +namespace Nethermind.Facade; + +public static class StateOverridesExtensions +{ + public static void ApplyStateOverrides( + this IWorldState state, + OverridableCodeInfoRepository overridableCodeInfoRepository, + Dictionary? overrides, + IReleaseSpec spec, + long blockNumber) + { + if (overrides is not null) + { + foreach (KeyValuePair overrideData in overrides) + { + Address address = overrideData.Key; + AccountOverride? accountOverride = overrideData.Value; + + if (!state.TryGetAccount(address, out Account? account)) + { + state.CreateAccount(address, accountOverride.Balance ?? UInt256.Zero, accountOverride.Nonce ?? UInt256.Zero); + } + else + { + state.UpdateBalance(spec, account, accountOverride, address); + state.UpdateNonce(account, accountOverride, address); + } + + state.UpdateCode(overridableCodeInfoRepository, spec, accountOverride, address); + state.UpdateState(accountOverride, address); + } + } + + state.Commit(spec); + state.CommitTree(blockNumber); + state.RecalculateStateRoot(); + } + + private static bool TryGetAccount(this IWorldState stateProvider, Address address, out Account account) + { + try + { + account = stateProvider.GetAccount(address); + } + catch (TrieException) + { + account = Account.TotallyEmpty; + } + + return !account.IsTotallyEmpty; + } + + private static void UpdateState(this IWorldState stateProvider, AccountOverride accountOverride, Address address) + { + void ApplyState(Dictionary diff) + { + foreach (KeyValuePair storage in diff) + { + stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.Bytes.WithoutLeadingZeros().ToArray()); + } + } + + if (accountOverride.State is not null) + { + stateProvider.ClearStorage(address); + ApplyState(accountOverride.State); + } + else if (accountOverride.StateDiff is not null) + { + ApplyState(accountOverride.StateDiff); + } + } + + private static void UpdateCode( + this IWorldState stateProvider, + OverridableCodeInfoRepository overridableCodeInfoRepository, + IReleaseSpec currentSpec, + AccountOverride accountOverride, + Address address) + { + if (accountOverride.Code is not null) + { + overridableCodeInfoRepository.SetCodeOverwrite( + stateProvider, + currentSpec, + address, + new CodeInfo(accountOverride.Code), + accountOverride.MovePrecompileToAddress); + } + } + + private static void UpdateNonce( + this IWorldState stateProvider, + Account account, + AccountOverride accountOverride, + Address address) + { + UInt256 nonce = account.Nonce; + if (accountOverride.Nonce is not null) + { + UInt256 newNonce = accountOverride.Nonce.Value; + if (nonce > newNonce) + { + stateProvider.DecrementNonce(address, nonce - newNonce); + } + else if (nonce < accountOverride.Nonce) + { + stateProvider.IncrementNonce(address, newNonce - nonce); + } + } + } + + private static void UpdateBalance( + this IWorldState stateProvider, + IReleaseSpec spec, + Account account, + AccountOverride accountOverride, + Address address) + { + if (accountOverride.Balance is not null) + { + UInt256 balance = account.Balance; + UInt256 newBalance = accountOverride.Balance.Value; + if (balance > newBalance) + { + stateProvider.SubtractFromBalance(address, balance - newBalance, spec); + } + else if (balance < newBalance) + { + stateProvider.AddToBalance(address, newBalance - balance, spec); + } + } + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 27ee915af21..bd34bb5bdb0 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -11,6 +11,7 @@ using Nethermind.Core.Test.Builders; using Nethermind.Evm; using Nethermind.Evm.Precompiles; +using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; diff --git a/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs b/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs index e8718dec1c6..75b1061fcef 100644 --- a/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs @@ -187,7 +187,7 @@ public void Restore_in_the_middle() { byte[] code = new byte[] { 1 }; - WorldState provider = new(new TrieStore(new MemDb(), Logger), _codeDb, Logger); + IWorldState provider = new WorldState(new TrieStore(new MemDb(), Logger), _codeDb, Logger); provider.CreateAccount(_address1, 1); provider.AddToBalance(_address1, 1, Frontier.Instance); provider.IncrementNonce(_address1); diff --git a/src/Nethermind/Nethermind.State/IWorldState.cs b/src/Nethermind/Nethermind.State/IWorldState.cs index 51f56ed43bc..a071fa07c09 100644 --- a/src/Nethermind/Nethermind.State/IWorldState.cs +++ b/src/Nethermind/Nethermind.State/IWorldState.cs @@ -93,9 +93,13 @@ public interface IWorldState : IJournal, IReadOnlyStateProvider void UpdateStorageRoot(Address address, Keccak storageRoot); - void IncrementNonce(Address address); + void IncrementNonce(Address address, UInt256 delta); - void DecrementNonce(Address address); + void DecrementNonce(Address address, UInt256 delta); + + void IncrementNonce(Address address) => IncrementNonce(address, UInt256.One); + + void DecrementNonce(Address address) => DecrementNonce(address, UInt256.One); /* snapshots */ diff --git a/src/Nethermind/Nethermind.State/StateProvider.cs b/src/Nethermind/Nethermind.State/StateProvider.cs index 9569fe427a6..0cc825a9ddb 100644 --- a/src/Nethermind/Nethermind.State/StateProvider.cs +++ b/src/Nethermind/Nethermind.State/StateProvider.cs @@ -275,7 +275,7 @@ public void UpdateStorageRoot(Address address, Keccak storageRoot) } } - public void IncrementNonce(Address address) + public void IncrementNonce(Address address, UInt256 delta) { _needsStateRootUpdate = true; Account? account = GetThroughCache(address); @@ -284,12 +284,12 @@ public void IncrementNonce(Address address) throw new InvalidOperationException($"Account {address} is null when incrementing nonce"); } - Account changedAccount = account.WithChangedNonce(account.Nonce + 1); + Account changedAccount = account.WithChangedNonce(account.Nonce + delta); if (_logger.IsTrace) _logger.Trace($" Update {address} N {account.Nonce} -> {changedAccount.Nonce}"); PushUpdate(address, changedAccount); } - public void DecrementNonce(Address address) + public void DecrementNonce(Address address, UInt256 delta) { _needsStateRootUpdate = true; Account? account = GetThroughCache(address); @@ -298,7 +298,7 @@ public void DecrementNonce(Address address) throw new InvalidOperationException($"Account {address} is null when decrementing nonce."); } - Account changedAccount = account.WithChangedNonce(account.Nonce - 1); + Account changedAccount = account.WithChangedNonce(account.Nonce - delta); if (_logger.IsTrace) _logger.Trace($" Update {address} N {account.Nonce} -> {changedAccount.Nonce}"); PushUpdate(address, changedAccount); } diff --git a/src/Nethermind/Nethermind.State/WorldState.cs b/src/Nethermind/Nethermind.State/WorldState.cs index 924ce51c21c..c6cb3ed7405 100644 --- a/src/Nethermind/Nethermind.State/WorldState.cs +++ b/src/Nethermind/Nethermind.State/WorldState.cs @@ -126,13 +126,13 @@ public void UpdateStorageRoot(Address address, Keccak storageRoot) { _stateProvider.UpdateStorageRoot(address, storageRoot); } - public void IncrementNonce(Address address) + public void IncrementNonce(Address address, UInt256 delta) { - _stateProvider.IncrementNonce(address); + _stateProvider.IncrementNonce(address, delta); } - public void DecrementNonce(Address address) + public void DecrementNonce(Address address, UInt256 delta) { - _stateProvider.DecrementNonce(address); + _stateProvider.DecrementNonce(address, delta); } public void CommitTree(long blockNumber) diff --git a/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs b/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs index 21b5d12f9e0..a411779bcf1 100644 --- a/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs @@ -976,7 +976,7 @@ public void Fuzz_accounts_with_storage( MemDb memDb = new(); using TrieStore trieStore = new(memDb, Prune.WhenCacheReaches(1.MB()), Persist.IfBlockOlderThan(lookupLimit), _logManager); - WorldState stateProvider = new(trieStore, new MemDb(), _logManager); + IWorldState stateProvider = new WorldState(trieStore, new MemDb(), _logManager); Account[] accounts = new Account[accountsCount]; Address[] addresses = new Address[accountsCount]; From e6e5324c778babacc2c8fcbb44828b451119858b Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 16 Oct 2023 12:55:43 +0100 Subject: [PATCH 093/213] HiveTests Added Also testing if TrieException does not happen anymore on prod DB --- src/Nethermind/Directory.Build.props | 2 +- .../Multicall/MultiCallTxTracer.cs | 2 +- .../Multicall/MulticallBridgeHelper.cs | 34 +- .../Proxy/Models/MultiCall/Error.cs | 2 +- .../StateOverridesExtensions.cs | 2 +- .../Multicall/EthMultiCallTestsHiveBase.cs | 768 ++++++++++++++++++ .../Modules/Eth/IEthRpcModule.cs | 2 +- 7 files changed, 790 insertions(+), 22 deletions(-) create mode 100644 src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs diff --git a/src/Nethermind/Directory.Build.props b/src/Nethermind/Directory.Build.props index eb51d4e9a9f..671224eecec 100644 --- a/src/Nethermind/Directory.Build.props +++ b/src/Nethermind/Directory.Build.props @@ -10,7 +10,7 @@ Nethermind $(Commit.Substring(0, 8)) 1.21.0 - + unstable diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs index 8cec2c0db87..ec02e56acf9 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs @@ -50,7 +50,7 @@ public override void MarkAsFailed(Address recipient, long gasSpent, byte[] outpu GasUsed = (ulong)gasSpent, Error = new Error { - Code = StatusCode.Failure, + Code = StatusCode.FailureBytes, Message = error }, ReturnData = output, diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index c263b64d9d6..964d9043e1b 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -98,27 +98,27 @@ Transaction SetTxHashAndMissingDefaults(Transaction transaction) if (transaction.Nonce == 0) { - try + //try + //{ + if (!nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) { - if (!nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) - { - cachedNonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; - nonceCache[transaction.SenderAddress] = cachedNonce; - } - - else - { - cachedNonce++; - nonceCache[transaction.SenderAddress] = cachedNonce; - } - - transaction.Nonce = cachedNonce; + cachedNonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; + nonceCache[transaction.SenderAddress] = cachedNonce; } - catch (TrieException) + + else { - // ignore - // Transaction from unknown account + cachedNonce++; + nonceCache[transaction.SenderAddress] = cachedNonce; } + + transaction.Nonce = cachedNonce; + //} + //catch (TrieException) + //{ + // ignore + // Transaction from unknown account + //} } transaction.Hash = transaction.CalculateHash(); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs index 1c7656e97fe..40e207a2908 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs @@ -5,7 +5,7 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class Error { - public int Code { get; set; } + public byte[] Code { get; set; } public string Message { get; set; } public string Data { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs index b29d97b877e..b7e518eef46 100644 --- a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs +++ b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only using System; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs new file mode 100644 index 00000000000..0a7429f97ec --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs @@ -0,0 +1,768 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Threading.Tasks; +using Nethermind.Blockchain.Find; +using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.JsonRpc.Data; +using Nethermind.Serialization.Json; +using Newtonsoft.Json; +using NUnit.Framework; +using ResultType = Nethermind.Core.ResultType; + +namespace Nethermind.JsonRpc.Test.Modules.Eth; + +public class EthMultiCallTestsHiveBase +{ + private static JsonSerializerSettings PrepareSettings() + { + var settings = new JsonSerializerSettings(); + foreach (JsonConverter converter in EthereumJsonSerializer.CommonConverters) + { + settings.Converters.Add(converter); + } + return settings; + } + + [Test] + public async Task TestmulticallAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallAddMoreNonDefinedBlockStateCallsThanFit() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0xb\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallAddMoreNonDefinedBlockStateCallsThanFit"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBasefeeTooLowWithValidation38012() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0x0\",\"maxPriorityFeePerGas\":\"0x0\"}]}],\"validation\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBasefeeTooLowWithValidation38012"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBasefeeTooLowWithoutValidation38012() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0x0\",\"maxPriorityFeePerGas\":\"0x0\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBasefeeTooLowWithoutValidation38012"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBlockNumOrder38020() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xc\"},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]},{\"blockOverrides\":{\"number\":\"0xb\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBlockNumOrder38020"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBlockOverrideReflectedInContractSimple() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\",\"time\":\"0x64\"}},{\"blockOverrides\":{\"number\":\"0x14\",\"time\":\"0x65\"}},{\"blockOverrides\":{\"number\":\"0x15\",\"time\":\"0xc8\"}}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBlockOverrideReflectedInContractSimple"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBlockOverrideReflectedInContract() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\",\"time\":\"0x64\",\"gasLimit\":\"0xa\",\"feeRecipient\":\"0xc000000000000000000000000000000000000000\",\"prevRandao\":\"0x0000000000000000000000000000000000000000000000000000000000000012\",\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x14\",\"time\":\"0xc8\",\"gasLimit\":\"0x14\",\"feeRecipient\":\"0xc100000000000000000000000000000000000000\",\"prevRandao\":\"0x0000000000000000000000000000000000000000000000000000000000001234\",\"baseFeePerGas\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x15\",\"time\":\"0x12c\",\"gasLimit\":\"0x15\",\"feeRecipient\":\"0xc200000000000000000000000000000000000000\",\"prevRandao\":\"0x0000000000000000000000000000000000000000000000000000000000001234\",\"baseFeePerGas\":\"0x1e\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBlockOverrideReflectedInContract"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBlockTimestampAutoIncrement() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xb\"}},{\"blockOverrides\":{}},{\"blockOverrides\":{\"time\":\"0xc\"}},{\"blockOverrides\":{}}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBlockTimestampAutoIncrement"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBlockTimestampNonIncrement() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xc\"}},{\"blockOverrides\":{\"time\":\"0xc\"}}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBlockTimestampNonIncrement"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBlockTimestampOrder38021() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xc\"}},{\"blockOverrides\":{\"time\":\"0xb\"}}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBlockTimestampOrder38021"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBlockTimestampsIncrementing() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xb\"}},{\"blockOverrides\":{\"time\":\"0xc\"}}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBlockTimestampsIncrementing"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBlockhashComplex() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010\"}]},{\"blockOverrides\":{\"number\":\"0x1e\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e000000000000000000000000000000000000000000000000000000000000001d\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBlockhashComplex"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBlockhashSimple() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBlockhashSimple"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallBlockhashStartBeforeHead() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000002\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000013\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallBlockhashStartBeforeHead"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallCheckInvalidNonce() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x4e20\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc000000000000000000000000000000000000000\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x1\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x0\"}]}],\"validation\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallCheckInvalidNonce"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallCheckThatBalanceIsThereAfterNewBlock() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x2710\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallCheckThatBalanceIsThereAfterNewBlock"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallCheckThatNonceIncreases() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x4e20\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc000000000000000000000000000000000000000\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x1\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x2\"}]}],\"validation\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallCheckThatNonceIncreases"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallEmptyCallsAndOverridesMulticall() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{},\"calls\":[{}]},{\"stateOverrides\":{},\"calls\":[{}]}],\"traceTransfers\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallEmptyCallsAndOverridesMulticall"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallEthSendShouldNotProduceLogsByDefault() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallEthSendShouldNotProduceLogsByDefault"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallEthSendShouldNotProduceLogsOnRevert() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallEthSendShouldNotProduceLogsOnRevert"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallEthSendShouldProduceLogs() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallEthSendShouldProduceLogs"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallEthSendShouldProduceMoreLogsOnForward() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"input\":\"0x4b64e4920000000000000000000000000000000000000000000000000000000000000100\"}]}],\"traceTransfers\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallEthSendShouldProduceMoreLogsOnForward"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallEthSendShouldProduceNoLogsOnForwardRevert() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"input\":\"0x4b64e492c200000000000000000000000000000000000000000000000000000000000000\"}]}],\"traceTransfers\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallEthSendShouldProduceNoLogsOnForwardRevert"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallFeeRecipientReceivingFunds() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\",\"feeRecipient\":\"0xc200000000000000000000000000000000000000\",\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0xa\",\"maxPriorityFeePerGas\":\"0xa\",\"nonce\":\"0x0\",\"input\":\"0x\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x1\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x2\",\"input\":\"0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000\"}]}],\"traceTransfers\":true,\"validation\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallFeeRecipientReceivingFunds"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallGasFeesAndValueError38014WithValidation() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"validation\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallGasFeesAndValueError38014WithValidation"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallGasFeesAndValueError38014() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallGasFeesAndValueError38014"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallGetBlockProperties() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallGetBlockProperties"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallInstrictGas38013() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"gas\":\"0x0\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallInstrictGas38013"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallLogs() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80600080a1600080f3\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x6057361d0000000000000000000000000000000000000000000000000000000000000005\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallLogs"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallMoveAccountTwice() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x3e8\"},\"0xc200000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc300000000000000000000000000000000000000\":{\"balance\":\"0xbb8\"},\"0xc400000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}}},{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0xbb8\",\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"},\"0xc200000000000000000000000000000000000000\":{\"balance\":\"0xfa0\",\"MovePrecompileToAddress\":\"0xc300000000000000000000000000000000000000\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc400000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc400000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc400000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c300000000000000000000000000000000000000\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallMoveAccountTwice"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallMoveEcrecoverAndCall() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}]},{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallMoveEcrecoverAndCall"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallMoveToAddressItselfReference38022() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"},\"0xc100000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc100000000000000000000000000000000000000\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x1\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallMoveToAddressItselfReference38022"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallMoveTwoAccountsToSame38023() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"},\"0x0000000000000000000000000000000000000002\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"}}}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallMoveTwoAccountsToSame38023"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallMoveTwoNonPrecompilesAccountsToSame() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0100000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"},\"0x0200000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"}}}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallMoveTwoNonPrecompilesAccountsToSame"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallOverrideAddressTwiceInSeparateBlockStateCalls() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]},{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallOverrideAddressTwiceInSeparateBlockStateCalls"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallOverrideAddressTwice() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallOverrideAddressTwice"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallOverrideAllInBlockStateCalls() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0x3e9\",\"time\":\"0x3eb\",\"gasLimit\":\"0x3ec\",\"feeRecipient\":\"0xc200000000000000000000000000000000000000\",\"prevRandao\":\"0xc300000000000000000000000000000000000000000000000000000000000000\",\"baseFeePerGas\":\"0x3ef\"}}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallOverrideAllInBlockStateCalls"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallOverrideBlockNum() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xb\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]},{\"blockOverrides\":{\"number\":\"0xc\"},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallOverrideBlockNum"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallOverrideEcrecover() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"},\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallOverrideEcrecover"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallOverrideIdentity() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000004\":{\"code\":\"0x\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1234\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000004\",\"input\":\"0x1234\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallOverrideIdentity"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallOverrideSha256() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000002\":{\"code\":\"0x\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1234\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000002\",\"input\":\"0x1234\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallOverrideSha256"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallPrecompileIsSendingTransaction() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0x0000000000000000000000000000000000000004\",\"to\":\"0x0000000000000000000000000000000000000002\",\"input\":\"0x1234\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallPrecompileIsSendingTransaction"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallRunOutOfGasInBlock38015() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"gasLimit\":\"0x16e360\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063815b8ab414610030575b600080fd5b61004a600480360381019061004591906100b6565b61004c565b005b60005a90505b60011561007657815a826100669190610112565b106100715750610078565b610052565b505b50565b600080fd5b6000819050919050565b61009381610080565b811461009e57600080fd5b50565b6000813590506100b08161008a565b92915050565b6000602082840312156100cc576100cb61007b565b5b60006100da848285016100a1565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061011d82610080565b915061012883610080565b92508282039050818111156101405761013f6100e3565b5b9291505056fea2646970667358221220a659ba4db729a6ee4db02fcc5c1118db53246b0e5e686534fc9add6f2e93faec64736f6c63430008120033\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallRunOutOfGasInBlock38015"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallSelfDestructingStateOverride() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033\"},\"0xc300000000000000000000000000000000000000\":{\"code\":\"0x73000000000000000000000000000000000000000030146080604052600436106100355760003560e01c8063dce4a4471461003a575b600080fd5b610054600480360381019061004f91906100f8565b61006a565b60405161006191906101b5565b60405180910390f35b6060813b6040519150601f19601f602083010116820160405280825280600060208401853c50919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100c58261009a565b9050919050565b6100d5816100ba565b81146100e057600080fd5b50565b6000813590506100f2816100cc565b92915050565b60006020828403121561010e5761010d610095565b5b600061011c848285016100e3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561015f578082015181840152602081019050610144565b60008484015250505050565b6000601f19601f8301169050919050565b600061018782610125565b6101918185610130565b93506101a1818560208601610141565b6101aa8161016b565b840191505092915050565b600060208201905081810360008301526101cf818461017c565b90509291505056fea26469706673582212206a5f0cd9f230619fa520fc4b9d4b518643258cad412f2fa33945ce528b4b895164736f6c63430008120033\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"input\":\"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x83197ef0\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"input\":\"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]},{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"input\":\"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallSelfDestructingStateOverride"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallSetReadStorage() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x6057361d0000000000000000000000000000000000000000000000000000000000000005\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x2e64cec1\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallSetReadStorage"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallSimpleNoFundsWithBalanceQuerying() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallSimpleNoFundsWithBalanceQuerying"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallSimpleNoFundsWithValidationWithoutNonces() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"validation\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallSimpleNoFundsWithValidationWithoutNonces"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallSimpleNoFundsWithValidation() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"nonce\":\"0x1\"}]}],\"validation\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallSimpleNoFundsWithValidation"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallSimpleNoFunds() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallSimpleNoFunds"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallSimpleSendFromContractNoBalance() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallSimpleSendFromContractNoBalance"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallSimpleSendFromContractWithValidation() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\",\"balance\":\"0x3e8\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true,\"validation\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallSimpleSendFromContractWithValidation"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallSimpleSendFromContract() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\",\"balance\":\"0x3e8\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallSimpleSendFromContract"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallSimple() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x3e8\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallSimple"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallTransactionTooHighNonce() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x64\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallTransactionTooHighNonce"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallTransactionTooLowNonce38010() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"nonce\":\"0xa\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x0\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallTransactionTooLowNonce38010"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallTransferOverBlockStateCalls() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]},{\"stateOverrides\":{\"0xc300000000000000000000000000000000000000\":{\"balance\":\"0x0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc300000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallTransferOverBlockStateCalls"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } + + [Test] + public async Task TestmulticallTryToMoveNonPrecompile() + { + var settings = PrepareSettings(); + string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"nonce\":\"0x5\"}}},{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc100000000000000000000000000000000000000\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc000000000000000000000000000000000000000\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x5\"}]}],\"validation\":true}"; + var payload = JsonConvert.DeserializeObject>(input, settings); + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + Console.WriteLine("current test: multicallTryToMoveNonPrecompile"); + var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 554a5c79ef1..21f8ceac45f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -146,7 +146,7 @@ public interface IEthRpcModule : IRpcModule Description = "Executes a simulation across multiple blocks (does not create a transaction or block)", IsSharable = false, ExampleResponse = "0x")] - ResultWrapper> eth_multicallV1(MultiCallPayload payload, + ResultWrapper> eth_multicallV1([JsonRpcParameter(ExampleValue = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"},\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}")] MultiCallPayload payload, BlockParameter? blockParameter = null); [JsonRpcMethod(IsImplemented = true, From d180fb11e4bf0b8d246392adae1e6929e71072fd Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 23 Oct 2023 16:35:01 +0100 Subject: [PATCH 094/213] Uint256 hex parsing when it is inside dictionary Fixing state parsing bug --- .../Proxy/EthJsonRpcClientProxyTests.cs | 42 ++++++++++ .../Models/MultiCall/MultiCallPayload.cs | 2 +- ...ictionaryWithSpecialUInt256KeyConverter.cs | 79 +++++++++++++++++++ .../EthereumJsonSerializer.cs | 1 + 4 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyConverter.cs diff --git a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs index fb3539d227e..2f0947a8de2 100644 --- a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs @@ -16,9 +16,17 @@ using NSubstitute; using NUnit.Framework; using System.Collections.Generic; +using Nethermind.Serialization.Json; +using Newtonsoft.Json; +using static Microsoft.FSharp.Core.ByRefKinds; +using System.Collections; +using System.Globalization; +using System.Numerics; + namespace Nethermind.Facade.Test.Proxy { + public class EthJsonRpcClientProxyTests { private IEthJsonRpcClientProxy _proxy; @@ -100,6 +108,40 @@ await _client.Received().SendAsync>(nameof(_ payload, blockParameter.Type); } + + [Test] + public async Task eth_multicall_should_invoke_client_method_on_complex_data() + { + var input = @"{ + ""blockStateCalls"": [ + { + ""stateOverrides"": { + ""0xc100000000000000000000000000000000000000"": { + ""state"": { + ""0x0000000000000000000000000000000000000000000000000000000000000000"": ""0x1200000000000000000000000000000000000000000000000000000000000000"" + } + } + }, + } + ], + }"; + + var settings = new JsonSerializerSettings(); + foreach (JsonConverter converter in EthereumJsonSerializer.CommonConverters) + { + settings.Converters.Add(converter); + } + settings.Converters.Add(new DictionaryWithSpecialUInt256KeyConverter()); + + var payload = JsonConvert.DeserializeObject>(input, settings); + + BlockParameterModel blockParameter = BlockParameterModel.Latest; + await _proxy.eth_multicallV1(payload, blockParameter); + await _client.Received().SendAsync>(nameof(_proxy.eth_multicallV1), + payload, blockParameter.Type); + + } + [Test] public async Task eth_multicallV1_should_invoke_client_method() { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs index 6a7be8f00eb..9bc05a11868 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs @@ -18,5 +18,5 @@ public class MultiCallPayload /// /// When true, the multicall does all validations that a normal EVM would do, except contract sender and signature checks. When false, multicall behaves like eth_call. /// - public bool Validation { get; set; } + public bool Validation { get; set; } = false; } diff --git a/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyConverter.cs new file mode 100644 index 00000000000..0cdf7f97500 --- /dev/null +++ b/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyConverter.cs @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Numerics; +using Nethermind.Int256; +using Newtonsoft.Json; + +namespace Nethermind.Serialization.Json; + +//This is a temp solution to bypass https://github.com/NethermindEth/int256/pull/35 +public class DictionaryWithSpecialUInt256KeyConverter : JsonConverter +{ + public static bool IsType(Type type, Type typeToBe) + { + + if (!typeToBe.IsGenericTypeDefinition) + return typeToBe.IsAssignableFrom(type); + + var toCheckTypes = new List { type }; + if (typeToBe.IsInterface) + toCheckTypes.AddRange(type.GetInterfaces()); + + var basedOn = type; + while (basedOn.BaseType != null) + { + toCheckTypes.Add(basedOn.BaseType); + basedOn = basedOn.BaseType; + } + + return toCheckTypes.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeToBe); + } + + public override bool CanWrite + { + get { return false; } + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new NotSupportedException(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + return null; + + // Assuming the keys in JSON are strings, and the Address type has a suitable Parse or TryParse method + var valueType = objectType.GetGenericArguments()[1]; + var intermediateDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeof(string), valueType); + var intermediateDictionary = (IDictionary)Activator.CreateInstance(intermediateDictionaryType); + serializer.Populate(reader, intermediateDictionary); + + var finalDictionary = (IDictionary)Activator.CreateInstance(objectType); + foreach (DictionaryEntry pair in intermediateDictionary) + { + UInt256 key = (UInt256)BigInteger.Parse(pair.Key.ToString().Substring(2), NumberStyles.HexNumber); + finalDictionary.Add(key, pair.Value); + } + + return finalDictionary; + } + + public override bool CanConvert(Type objectType) + { + bool isDict = IsType(objectType, typeof(IDictionary<,>)); + if (!isDict) return false; + + Type genericArgument = objectType.GetGenericArguments()[0]; + bool isKeyUint256 = IsType(genericArgument, typeof(UInt256)); + var res = isDict && isKeyUint256; + return res; + } +} diff --git a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs index 2eaba4cb364..e452eafd67c 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs @@ -48,6 +48,7 @@ public EthereumJsonSerializer(int? maxDepth = null, params JsonConverter[] conve new PublicKeyConverter(), new TxTypeConverter(), new MemoryByteConverter(), + new DictionaryWithSpecialUInt256KeyConverter() }); public IList BasicConverters { get; } = CommonConverters.ToList(); From 64b34b1806ab5325964f859fa1fc20e1d7591ea4 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 24 Oct 2023 11:54:55 +0100 Subject: [PATCH 095/213] Fixing dictionary parsing --- .../Proxy/EthJsonRpcClientProxyTests.cs | 2 +- .../Multicall/MultiCallBlockTracer.cs | 2 +- .../Models/MultiCall/MultiCallBlockResult.cs | 2 +- .../Multicall/EthMultiCallTestsHiveBase.cs | 5 +++ ...ecialUInt256KeyValueKeccakValConverter.cs} | 39 ++++++++++++------- .../EthereumJsonSerializer.cs | 2 +- 6 files changed, 35 insertions(+), 17 deletions(-) rename src/Nethermind/Nethermind.Serialization.Json/{DictionaryWithSpecialUInt256KeyConverter.cs => DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs} (58%) diff --git a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs index 2f0947a8de2..2d3c509a60b 100644 --- a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs @@ -131,7 +131,7 @@ public async Task eth_multicall_should_invoke_client_method_on_complex_data() { settings.Converters.Add(converter); } - settings.Converters.Add(new DictionaryWithSpecialUInt256KeyConverter()); + settings.Converters.Add(new DictionaryWithSpecialUInt256KeyValueKeccakValConverter()); var payload = JsonConvert.DeserializeObject>(input, settings); diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs index 512df007d38..bcddc4efa1e 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs @@ -55,7 +55,7 @@ public override void EndBlockTrace() Timestamp = _currentBlock.Timestamp, FeeRecipient = _currentBlock.Beneficiary!, BaseFeePerGas = _currentBlock.BaseFeePerGas, - PrevRandao = _currentBlock.Header!.Random, + PrevRandao = _currentBlock.Header!.Random!.BytesToArray(), }; result.Calls.ForEach(callResult => diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs index 70d934bc73d..160561b4678 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs @@ -20,6 +20,6 @@ public class MultiCallBlockResult public Address FeeRecipient { get; set; } = Address.Zero; public UInt256 BaseFeePerGas { get; set; } public IEnumerable Calls { get; set; } = Enumerable.Empty(); - public Keccak? PrevRandao { get; set; } + public byte[]? PrevRandao { get; set; } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs index 0a7429f97ec..668893df176 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs @@ -2,8 +2,10 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Linq; using System.Threading.Tasks; using Nethermind.Blockchain.Find; +using Nethermind.Core.Crypto; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; using Nethermind.Serialization.Json; @@ -61,6 +63,9 @@ public async Task TestmulticallBasefeeTooLowWithValidation38012() Console.WriteLine("current test: multicallBasefeeTooLowWithValidation38012"); var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.That(result.Data.First().PrevRandao, Is.EqualTo(new Keccak("0x0000000000000000000000000000000000000000000000000000000000000000").BytesToArray())); + + Assert.IsNotNull(result.Data); } diff --git a/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs similarity index 58% rename from src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyConverter.cs rename to src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs index 0cdf7f97500..7fb11991688 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs @@ -7,13 +7,15 @@ using System.Globalization; using System.Linq; using System.Numerics; +using Nethermind.Core.Crypto; using Nethermind.Int256; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Nethermind.Serialization.Json; //This is a temp solution to bypass https://github.com/NethermindEth/int256/pull/35 -public class DictionaryWithSpecialUInt256KeyConverter : JsonConverter +public class DictionaryWithSpecialUInt256KeyValueKeccakValConverter : JsonConverter { public static bool IsType(Type type, Type typeToBe) { @@ -21,11 +23,11 @@ public static bool IsType(Type type, Type typeToBe) if (!typeToBe.IsGenericTypeDefinition) return typeToBe.IsAssignableFrom(type); - var toCheckTypes = new List { type }; + List toCheckTypes = new() { type }; if (typeToBe.IsInterface) toCheckTypes.AddRange(type.GetInterfaces()); - var basedOn = type; + Type basedOn = type; while (basedOn.BaseType != null) { toCheckTypes.Add(basedOn.BaseType); @@ -51,16 +53,23 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return null; // Assuming the keys in JSON are strings, and the Address type has a suitable Parse or TryParse method - var valueType = objectType.GetGenericArguments()[1]; - var intermediateDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeof(string), valueType); - var intermediateDictionary = (IDictionary)Activator.CreateInstance(intermediateDictionaryType); + Type valueType = objectType.GetGenericArguments()[1]; + Type intermediateDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeof(string), typeof(string)); + IDictionary intermediateDictionary = (IDictionary)Activator.CreateInstance(intermediateDictionaryType); serializer.Populate(reader, intermediateDictionary); - var finalDictionary = (IDictionary)Activator.CreateInstance(objectType); + IDictionary finalDictionary = (IDictionary)Activator.CreateInstance(objectType); foreach (DictionaryEntry pair in intermediateDictionary) { - UInt256 key = (UInt256)BigInteger.Parse(pair.Key.ToString().Substring(2), NumberStyles.HexNumber); - finalDictionary.Add(key, pair.Value); + string keyData = pair.Key.ToString(); + UInt256 key = keyData.StartsWith("0x", StringComparison.OrdinalIgnoreCase) + ? (UInt256)BigInteger.Parse(keyData.Substring(2), NumberStyles.HexNumber) + : UInt256.Parse(keyData); + + string valueData = pair.Value.ToString(); + ValueKeccak val = new(valueData); + + finalDictionary.Add(key, val); } return finalDictionary; @@ -71,9 +80,13 @@ public override bool CanConvert(Type objectType) bool isDict = IsType(objectType, typeof(IDictionary<,>)); if (!isDict) return false; - Type genericArgument = objectType.GetGenericArguments()[0]; - bool isKeyUint256 = IsType(genericArgument, typeof(UInt256)); - var res = isDict && isKeyUint256; - return res; + var args = objectType.GetGenericArguments(); + if (args.Length < 2) return false; + + bool isKeyUint256 = IsType(args[0], typeof(UInt256)); + if(!isKeyUint256) return false; + + bool isValValueKeccak = IsType(args[1], typeof(ValueKeccak)); + return isValValueKeccak; } } diff --git a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs index e452eafd67c..de9d1a13f76 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs @@ -48,7 +48,7 @@ public EthereumJsonSerializer(int? maxDepth = null, params JsonConverter[] conve new PublicKeyConverter(), new TxTypeConverter(), new MemoryByteConverter(), - new DictionaryWithSpecialUInt256KeyConverter() + new DictionaryWithSpecialUInt256KeyValueKeccakValConverter() }); public IList BasicConverters { get; } = CommonConverters.ToList(); From b38c1b5e4c293d816f8b7300b29e69e06d6d8b9b Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 24 Oct 2023 11:56:44 +0100 Subject: [PATCH 096/213] spaces fix --- .../DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs index 7fb11991688..bcb80d6ecbb 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs @@ -84,7 +84,7 @@ public override bool CanConvert(Type objectType) if (args.Length < 2) return false; bool isKeyUint256 = IsType(args[0], typeof(UInt256)); - if(!isKeyUint256) return false; + if (!isKeyUint256) return false; bool isValValueKeccak = IsType(args[1], typeof(ValueKeccak)); return isValValueKeccak; From c719612cb3a50cb6a3530e897c8602f92272c894 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 1 Nov 2023 04:11:53 +0000 Subject: [PATCH 097/213] fixing nonce, parsing and processing issues --- .../TransactionProcessor.cs | 11 ++- .../Nethermind.Facade/BlockchainBridge.cs | 2 +- .../Nethermind.Facade/IBlockchainBridge.cs | 2 +- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 19 +++-- .../Multicall/MulticallBridgeHelper.cs | 76 +++++++++++++------ .../MultiCall/TransactionWithSourceDetails.cs | 13 ++++ .../EthMulticallTestsSimplePrecompiles.cs | 13 +++- .../Data/TransactionForRpc.cs | 8 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 26 +++++-- 9 files changed, 121 insertions(+), 49 deletions(-) create mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/TransactionWithSourceDetails.cs diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index c83b848467a..dd876dd1a65 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -59,13 +59,15 @@ protected enum ExecutionOptions /// CommitAndRestore = Commit | Restore | NoValidation } + private readonly ExecutionOptions _executeOptions; public TransactionProcessor( ISpecProvider? specProvider, IWorldState? worldState, IVirtualMachine? virtualMachine, ICodeInfoRepository? codeInfoRepository, - ILogManager? logManager) + ILogManager? logManager, + bool forceNoValidationOnExecute = false) { _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); @@ -73,6 +75,11 @@ public TransactionProcessor( _virtualMachine = virtualMachine ?? throw new ArgumentNullException(nameof(virtualMachine)); _codeInfoRepository = codeInfoRepository ?? throw new ArgumentNullException(nameof(codeInfoRepository)); _ecdsa = new EthereumEcdsa(specProvider.ChainId, logManager); + _executeOptions = ExecutionOptions.Commit; + if (forceNoValidationOnExecute) + { + _executeOptions |= ExecutionOptions.NoValidation; + } } public void CallAndRestore(Transaction transaction, BlockExecutionContext blCtx, ITxTracer txTracer) @@ -90,7 +97,7 @@ public void BuildUp(Transaction transaction, BlockExecutionContext blCtx, ITxTra public void Execute(Transaction transaction, BlockExecutionContext blCtx, ITxTracer txTracer) { - Execute(transaction, blCtx, txTracer, ExecutionOptions.Commit); + Execute(transaction, blCtx, txTracer, _executeOptions); } public void Trace(Transaction transaction, BlockExecutionContext blCtx, ITxTracer txTracer) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 71a3a913084..65be9183a1b 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -152,7 +152,7 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can }; } - public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken) + public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken) { MultiCallBlockTracer multiCallOutputTracer = new(payload.TraceTransfers); MultiCallOutput result = new(); diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index 06123beecae..592b8b7c7a4 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -27,7 +27,7 @@ public interface IBlockchainBridge : ILogFinder TxReceipt GetReceipt(Keccak txHash); (TxReceipt? Receipt, TxGasInfo? GasInfo, int LogIndexStart) GetReceiptAndGasInfo(Keccak txHash); (TxReceipt? Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Keccak txHash); - MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken); + MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken); CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken); CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken); CallOutput CreateAccessList(BlockHeader header, Transaction tx, CancellationToken cancellationToken, bool optimize); diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs index a5ed8317ceb..795cdfc8242 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -10,6 +10,7 @@ using Nethermind.Consensus.Processing; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; +using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Db; using Nethermind.Db.Blooms; @@ -30,13 +31,14 @@ public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, public ISpecProvider SpecProvider { get; } public IVirtualMachine VirtualMachine { get; } public OverridableCodeInfoRepository CodeInfoRepository { get; } - + private readonly bool _doValidation = false; // We need ability to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning public static MultiCallReadOnlyBlocksProcessingEnv Create( bool traceTransfers, IReadOnlyDbProvider readOnlyDbProvider, ISpecProvider specProvider, - ILogManager? logManager = null) + ILogManager? logManager = null, + bool doValidation = false) { IReadOnlyDbProvider dbProvider = new ReadOnlyDbProvider(readOnlyDbProvider, true); TrieStore trieStore = new(readOnlyDbProvider.StateDb, logManager); @@ -63,8 +65,8 @@ public static MultiCallReadOnlyBlocksProcessingEnv Create( logManager); } - public MultiCallReadOnlyBlocksProcessingEnv Clone(bool traceTransfers) => - Create(traceTransfers, DbProvider, SpecProvider, _logManager); + public MultiCallReadOnlyBlocksProcessingEnv Clone(bool traceTransfers, bool doValidation) => + Create(traceTransfers, DbProvider, SpecProvider, _logManager, doValidation); private MultiCallReadOnlyBlocksProcessingEnv( bool traceTransfers, @@ -72,13 +74,14 @@ private MultiCallReadOnlyBlocksProcessingEnv( ITrieStore trieStore, IBlockTree blockTree, ISpecProvider specProvider, - ILogManager? logManager = null) + ILogManager? logManager = null, + bool doValidation = false) : base(readOnlyDbProvider, trieStore, blockTree, logManager) { _trieStore = trieStore; _logManager = logManager; SpecProvider = specProvider; - + _doValidation = doValidation; CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); VirtualMachine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); @@ -101,7 +104,7 @@ private MultiCallReadOnlyBlocksProcessingEnv( public IBlockProcessor GetProcessor() { - TransactionProcessor transactionProcessor = new(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager); + TransactionProcessor transactionProcessor = new(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, _doValidation); return new BlockProcessor(SpecProvider, _blockValidator, @@ -113,6 +116,8 @@ public IBlockProcessor GetProcessor() _logManager); } + public IReadOnlyTransactionProcessor Build(Keccak stateRoot) => new ReadOnlyTransactionProcessor(new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager), StateProvider, stateRoot); + public void Dispose() { _trieStore.Dispose(); diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index 964d9043e1b..5d9fdc75c7f 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -10,10 +10,11 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Crypto; +using Nethermind.Evm; using Nethermind.Evm.Tracing; +using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; -using Nethermind.Trie; namespace Nethermind.Facade.Multicall; @@ -24,7 +25,6 @@ public class MulticallBridgeHelper private readonly IBlocksConfig _blocksConfig; private static readonly ProcessingOptions _multicallProcessingOptions = ProcessingOptions.ForceProcessing | - ProcessingOptions.DoNotVerifyNonce | ProcessingOptions.IgnoreParentNotOnMainChain | ProcessingOptions.MarkAsProcessed | ProcessingOptions.StoreReceipts; @@ -36,16 +36,16 @@ public MulticallBridgeHelper(MultiCallReadOnlyBlocksProcessingEnv multiCallProce _blocksConfig = blocksConfig; } - private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall blockStateCall, MultiCallReadOnlyBlocksProcessingEnv env) + private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall blockStateCall, MultiCallReadOnlyBlocksProcessingEnv env) { IReleaseSpec currentSpec = env.SpecProvider.GetSpec(blockHeader); - env.StateProvider.ApplyStateOverrides(_multiCallProcessingEnv.CodeInfoRepository, blockStateCall.StateOverrides, currentSpec, blockHeader.Number); + env.StateProvider.ApplyStateOverrides(_multiCallProcessingEnv.CodeInfoRepository, blockStateCall.StateOverrides, currentSpec, blockHeader.Number - 1); blockHeader.StateRoot = env.StateProvider.StateRoot; } - public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) + public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) { - using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers); + using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers, payload.Validation); Block? parentBlock = env.BlockTree.FindBlock(parent.Number); if (parentBlock is not null) { @@ -54,7 +54,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateC } IBlockProcessor? processor = env.GetProcessor(); - BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); + BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); if (firstBlock?.BlockOverrides?.Number is > 0 and < long.MaxValue) { BlockHeader? searchResult = env.BlockTree.FindHeader((long)firstBlock.BlockOverrides.Number); @@ -69,7 +69,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateC Dictionary nonceCache = new(); List suggestedBlocks = new(); - foreach (BlockStateCall callInputBlock in payload.BlockStateCalls) + foreach (BlockStateCall callInputBlock in payload.BlockStateCalls) { BlockHeader callHeader = callInputBlock.BlockOverrides is not null ? callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig) @@ -90,22 +90,31 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateC UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); - Transaction SetTxHashAndMissingDefaults(Transaction transaction) + using IReadOnlyTransactionProcessor? readOnlyTransactionProcessor = env.Build(env.StateProvider.StateRoot!); + GasEstimator gasEstimator = new(readOnlyTransactionProcessor, env.StateProvider, + _specProvider, _blocksConfig); + + long EstimateGas(Transaction transaction) + { + EstimateGasTracer estimateGasTracer = new(); + return gasEstimator.Estimate(transaction, callHeader, estimateGasTracer); + } + + + Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transactionDetails, IReleaseSpec? spec) { + Transaction? transaction = transactionDetails.Transaction; transaction.SenderAddress ??= Address.Zero; transaction.To ??= Address.Zero; transaction.Data ??= Memory.Empty; - if (transaction.Nonce == 0) + if (!transactionDetails.HadNonceInRequest) { - //try - //{ if (!nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) { cachedNonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; nonceCache[transaction.SenderAddress] = cachedNonce; } - else { cachedNonce++; @@ -113,19 +122,41 @@ Transaction SetTxHashAndMissingDefaults(Transaction transaction) } transaction.Nonce = cachedNonce; - //} - //catch (TrieException) - //{ - // ignore - // Transaction from unknown account - //} } - transaction.Hash = transaction.CalculateHash(); + if (!transactionDetails.HadGasLimitInRequest) + { + long limit = EstimateGas(transaction); + transaction.GasLimit = limit; + transaction.GasLimit = (long)callHeader.BaseFeePerGas + + Math.Max(IntrinsicGasCalculator.Calculate(transaction, spec) + 1, + transaction.GasLimit); + + } + + if (payload.Validation) + { + if (transaction.GasPrice == 0) + { + transaction.GasPrice = callHeader.BaseFeePerGas; + } + + if (transaction.Type == TxType.EIP1559 && transaction.DecodedMaxFeePerGas == 0) + { + transaction.DecodedMaxFeePerGas = transaction.GasPrice == 0 + ? callHeader.BaseFeePerGas + 1 + : transaction.GasPrice; + //UInt256.MultiplyOverflow((UInt256)transaction.GasLimit, transaction.MaxFeePerGas, out UInt256 maxGasFee); + //string err = $"insufficient sender balance for MaxFeePerGas: {callHeader.Number}, {transaction.SenderAddress} balance should be at least {maxGasFee + 1 + transaction.Value }"; + } + } + + transaction.Hash ??= transaction.CalculateHash(); + return transaction; } - - IEnumerable transactions = callInputBlock.Calls?.Select(SetTxHashAndMissingDefaults) ?? Array.Empty(); + IReleaseSpec? spec = _specProvider.GetSpec(parent); + IEnumerable transactions = callInputBlock.Calls?.Select(t => SetTxHashAndMissingDefaults(t, spec)) ?? Array.Empty(); Block? currentBlock = new(callHeader, transactions, Array.Empty()); currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); @@ -138,6 +169,7 @@ Transaction SetTxHashAndMissingDefaults(Transaction transaction) suggestedBlocks.Clear(); suggestedBlocks.Add(currentBlock); + env.StateProvider.RecalculateStateRoot(); Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, suggestedBlocks, processingFlags, tracer); Block? processedBlock = currentBlocks[0]; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/TransactionWithSourceDetails.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/TransactionWithSourceDetails.cs new file mode 100644 index 00000000000..ebb3f621282 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/TransactionWithSourceDetails.cs @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; + +namespace Nethermind.Facade.Proxy.Models.MultiCall; + +public class TransactionWithSourceDetails +{ + public bool HadNonceInRequest; + public bool HadGasLimitInRequest; + public Transaction Transaction { get; set; } +} diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 59ce8209484..e5d83acf35d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -84,18 +84,23 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe }; systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); - - MultiCallPayload payload = new() + TransactionWithSourceDetails systemTransactionForModifiedVMDetails = new() + { + Transaction = systemTransactionForModifiedVM, + HadGasLimitInRequest = false, + HadNonceInRequest = false + }; + MultiCallPayload payload = new() { BlockStateCalls = new[] { - new BlockStateCall() + new BlockStateCall() { StateOverrides = new Dictionary() { { EcRecoverPrecompile.Address, new AccountOverride { Code = code } } }, - Calls = new[] { systemTransactionForModifiedVM } + Calls = new[] { systemTransactionForModifiedVMDetails } } }, TraceTransfers = true, diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs index 9116a6c8eea..e69300082dd 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs @@ -117,7 +117,7 @@ public TransactionForRpc() public UInt256? ChainId { get; set; } - public TxType Type { get; set; } + public TxType? Type { get; set; } public IEnumerable? AccessList { get; set; } @@ -150,7 +150,7 @@ public TransactionForRpc() SenderAddress = From, Value = Value ?? 0, Data = Input, - Type = Type, + Type = Type!.Value, AccessList = TryGetAccessList(), ChainId = chainId, DecodedMaxFeePerGas = MaxFeePerGas ?? 0, @@ -186,7 +186,7 @@ public TransactionForRpc() SenderAddress = From, Value = Value ?? 0, Data = (Memory?)data, - Type = Type, + Type = Type!.Value, AccessList = TryGetAccessList(), ChainId = chainId, }; @@ -212,7 +212,7 @@ public TransactionForRpc() } private AccessList? TryGetAccessList() => - !Type.IsTxTypeWithAccessList() || AccessList is null + !Type!.Value.IsTxTypeWithAccessList() || AccessList is null ? null : AccessListItemForRpc.ToAccessList(AccessList); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 1c7dd06bf9f..9413c71ec77 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -1,7 +1,9 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Collections.Generic; +using System.Drawing.Drawing2D; using System.Linq; using System.Threading; using Nethermind.Blockchain.Find; @@ -11,30 +13,38 @@ using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; +using static Microsoft.FSharp.Core.ByRefKinds; namespace Nethermind.JsonRpc.Modules.Eth; -public class MultiCallTxExecutor : ExecutorBase, MultiCallPayload, MultiCallPayload> +public class MultiCallTxExecutor : ExecutorBase, MultiCallPayload, MultiCallPayload> { public MultiCallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : base(blockchainBridge, blockFinder, rpcConfig) { } - protected override MultiCallPayload Prepare(MultiCallPayload call) + protected override MultiCallPayload Prepare(MultiCallPayload call) { - MultiCallPayload? result = new() + MultiCallPayload? result = new() { TraceTransfers = call.TraceTransfers, Validation = call.Validation, - BlockStateCalls = call.BlockStateCalls?.Select(blockStateCall => new BlockStateCall + BlockStateCalls = call.BlockStateCalls?.Select(blockStateCall => new BlockStateCall { BlockOverrides = blockStateCall.BlockOverrides, StateOverrides = blockStateCall.StateOverrides, Calls = blockStateCall.Calls?.Select(callTransactionModel => { - callTransactionModel.EnsureDefaults(_rpcConfig.GasCap); - //callTransactionModel.Type ??= TxType.EIP1559; - return callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()); + callTransactionModel.Type ??= TxType.EIP1559; + + TransactionWithSourceDetails? result = new() + { + HadGasLimitInRequest = callTransactionModel.Gas.HasValue, + HadNonceInRequest = callTransactionModel.Nonce.HasValue, + Transaction = callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()) + }; + + return result; }).ToArray() }).ToArray() }; @@ -42,7 +52,7 @@ protected override MultiCallPayload Prepare(MultiCallPayload> Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) + protected override ResultWrapper> Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) { MultiCallOutput results = _blockchainBridge.MultiCall(header, tx, token); From 3b5ff6818cfbb8a38a071c45155b1c228cb672ae Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 1 Nov 2023 05:50:12 +0000 Subject: [PATCH 098/213] post merge build fixes --- .../Processing/ReadOnlyTxProcessingEnv.cs | 8 +- .../Nethermind.Evm/CodeInfoRepository.cs | 6 +- .../Nethermind.Evm/ICodeInfoRepository.cs | 2 +- .../TransactionProcessor.cs | 12 ++- .../Nethermind.Evm/VirtualMachine.cs | 62 +------------ .../Proxy/EthJsonRpcClientProxyTests.cs | 2 - .../MultiCallReadOnlyBlocksProcessingEnv.cs | 2 +- .../Multicall/MultiCallTxTracer.cs | 6 +- .../OverridableCodeInfoRepository.cs | 2 +- .../Proxy/IEthJsonRpcClientProxy.cs | 2 +- .../Proxy/Models/AccountOverride.cs | 4 +- .../Proxy/Models/MultiCall/BlockOverride.cs | 2 +- .../Proxy/Models/MultiCall/Log.cs | 4 +- .../Models/MultiCall/MultiCallBlockResult.cs | 2 +- .../StateOverridesExtensions.cs | 4 +- .../Steps/InitializeBlockchain.cs | 16 ++-- .../Modules/Eth/EthRpcMulticallTestsBase.cs | 6 +- .../Multicall/EthMultiCallTestsHiveBase.cs | 2 +- .../EthMulticallTestsSimplePrecompiles.cs | 2 +- .../Eth/EthRpcModule.TransactionExecutor.cs | 3 + .../InitializeBlockchainOptimism.cs | 5 +- .../OptimismBlockProducerEnvFactory.cs | 3 +- .../OptimismTransactionProcessor.cs | 4 +- ...pecialUInt256KeyValueKeccakValConverter.cs | 92 ------------------- .../EthereumJsonSerializer.cs | 1 - .../ChainSpecBasedSpecProvider.cs | 16 ++-- 26 files changed, 65 insertions(+), 205 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index 52eb745c774..05eea753493 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -18,7 +18,9 @@ namespace Nethermind.Consensus.Processing public class ReadOnlyTxProcessingEnv : ReadOnlyTxProcessingEnvBase, IReadOnlyTxProcessorSource { public ITransactionProcessor TransactionProcessor { get; set; } + public IVirtualMachine Machine { get; } + public ICodeInfoRepository CodeInfoRepository { get; } public ReadOnlyTxProcessingEnv( IDbProvider? dbProvider, IReadOnlyTrieStore? trieStore, @@ -37,9 +39,9 @@ public ReadOnlyTxProcessingEnv( ILogManager? logManager ) : base(readOnlyDbProvider, trieStore, blockTree, logManager) { - CodeInfoRepository codeInfoRepository = new(); - IVirtualMachine machine = new VirtualMachine(BlockhashProvider, specProvider, codeInfoRepository, logManager); - TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, machine, codeInfoRepository, logManager); + CodeInfoRepository = new CodeInfoRepository(); + Machine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); + TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, Machine, CodeInfoRepository, logManager); } public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) => new ReadOnlyTransactionProcessor(TransactionProcessor, StateProvider, stateRoot); diff --git a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs index ef62d9e45d0..58ab30dae34 100644 --- a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -18,7 +18,7 @@ namespace Nethermind.Evm; public class CodeInfoRepository : ICodeInfoRepository { private static readonly Dictionary? _precompiles; - private static readonly LruCache _codeCache = new(MemoryAllowance.CodeCacheSize, MemoryAllowance.CodeCacheSize, "VM bytecodes"); + private static readonly LruCache _codeCache = new(MemoryAllowance.CodeCacheSize, MemoryAllowance.CodeCacheSize, "VM bytecodes"); static CodeInfoRepository() { @@ -58,7 +58,7 @@ public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IR return _precompiles[codeSource]; } - Keccak codeHash = worldState.GetCodeHash(codeSource); + Hash256 codeHash = worldState.GetCodeHash(codeSource); CodeInfo cachedCodeInfo = _codeCache.Get(codeHash); if (cachedCodeInfo is null) { @@ -81,7 +81,7 @@ public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IR return cachedCodeInfo; } - public CodeInfo GetOrAdd(ValueKeccak codeHash, Span initCode) + public CodeInfo GetOrAdd(ValueHash256 codeHash, Span initCode) { if (!_codeCache.TryGet(codeHash, out CodeInfo codeInfo)) { diff --git a/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs index 89bcfc43737..79f6d3ef14a 100644 --- a/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs @@ -13,5 +13,5 @@ namespace Nethermind.Evm; public interface ICodeInfoRepository { CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec); - CodeInfo GetOrAdd(ValueKeccak codeHash, Span initCode); + CodeInfo GetOrAdd(ValueHash256 codeHash, Span initCode); } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 098e91caabe..df360d1f54a 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -4,6 +4,7 @@ using System; using System.IO; using System.Linq; +using System.Reflection; using System.Runtime.CompilerServices; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -29,6 +30,7 @@ public class TransactionProcessor : ITransactionProcessor protected ISpecProvider SpecProvider { get; private init; } protected IWorldState WorldState { get; private init; } protected IVirtualMachine VirtualMachine { get; private init; } + private readonly ICodeInfoRepository _codeInfoRepository; [Flags] protected enum ExecutionOptions @@ -72,7 +74,9 @@ public TransactionProcessor( SpecProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); WorldState = worldState ?? throw new ArgumentNullException(nameof(worldState)); VirtualMachine = virtualMachine ?? throw new ArgumentNullException(nameof(virtualMachine)); + _codeInfoRepository = codeInfoRepository ?? throw new ArgumentNullException(nameof(codeInfoRepository)); Ecdsa = new EthereumEcdsa(specProvider.ChainId, logManager); + _executeOptions = ExecutionOptions.Commit; if (forceNoValidationOnExecute) { _executeOptions |= ExecutionOptions.NoValidation; @@ -443,15 +447,15 @@ protected virtual ExecutionEnvironment BuildExecutionEnvironmnet( Transaction tx, BlockExecutionContext blCtx, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts, in UInt256 effectiveGasPrice) { - Address recipient = tx.GetRecipient(tx.IsContractCreation ? WorldState.GetNonce(tx.SenderAddress) : 0) ?? + Address recipient = tx.GetRecipient(tx.IsContractCreation ? WorldState.GetNonce(tx.SenderAddress!) : 0) ?? // this transaction is not a contract creation so it should have the recipient known and not null throw new InvalidDataException("Recipient has not been resolved properly before tx execution"); TxExecutionContext executionContext = new(blCtx, tx.SenderAddress!, effectiveGasPrice, tx.BlobVersionedHashes); - CodeInfo codeInfo = tx.IsContractCreation ? new(tx.Data.AsArray()) - : VirtualMachine.GetCachedCodeInfo(WorldState, recipient, spec); + CodeInfo codeInfo = tx.IsContractCreation ? new(tx.Data.AsArray()!) + : _codeInfoRepository.GetCachedCodeInfo(WorldState, recipient, spec); byte[] inputData = tx.IsMessageCall ? tx.Data.AsArray() ?? Array.Empty() : Array.Empty(); @@ -622,7 +626,7 @@ protected void PrepareAccountForContractDeployment(Address contractAddress, IRel { if (WorldState.AccountExists(contractAddress)) { - CodeInfo codeInfo = VirtualMachine.GetCachedCodeInfo(WorldState, contractAddress, spec); + CodeInfo codeInfo = _codeInfoRepository.GetCachedCodeInfo(WorldState, contractAddress, spec); bool codeIsNotEmpty = codeInfo.MachineCode.Length != 0; bool accountNonceIsNotZero = WorldState.GetNonce(contractAddress) != 0; diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 230a2eccc3e..4a2f9a465da 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -150,7 +150,6 @@ internal sealed class VirtualMachine : IVirtualMachine private readonly IBlockhashProvider _blockhashProvider; private readonly ISpecProvider _specProvider; - private static readonly LruCache _codeCache = new(MemoryAllowance.CodeCacheSize, MemoryAllowance.CodeCacheSize, "VM bytecodes"); private readonly ILogger _logger; private IWorldState _state = null!; private readonly Stack _stateStack = new(); @@ -481,59 +480,6 @@ private void RevertParityTouchBugAccount(IReleaseSpec spec) } } - Hash256 codeHash = worldState.GetCodeHash(codeSource); - CodeInfo cachedCodeInfo = _codeCache.Get(codeHash); - if (cachedCodeInfo is null) - { - byte[] code = worldState.GetCode(codeHash); - - if (code is null) - { - throw new NullReferenceException($"Code {codeHash} missing in the state for address {codeSource}"); - } - - cachedCodeInfo = new CodeInfo(code); - _codeCache.Set(codeHash, cachedCodeInfo); - } - else - { - // need to touch code so that any collectors that track database access are informed - worldState.TouchCode(codeHash); - } - - return cachedCodeInfo; - } - - private void InitializePrecompiledContracts() - { - _precompiles = new Dictionary - { - [EcRecoverPrecompile.Address] = new(EcRecoverPrecompile.Instance), - [Sha256Precompile.Address] = new(Sha256Precompile.Instance), - [Ripemd160Precompile.Address] = new(Ripemd160Precompile.Instance), - [IdentityPrecompile.Address] = new(IdentityPrecompile.Instance), - - [Bn254AddPrecompile.Address] = new(Bn254AddPrecompile.Instance), - [Bn254MulPrecompile.Address] = new(Bn254MulPrecompile.Instance), - [Bn254PairingPrecompile.Address] = new(Bn254PairingPrecompile.Instance), - [ModExpPrecompile.Address] = new(ModExpPrecompile.Instance), - - [Blake2FPrecompile.Address] = new(Blake2FPrecompile.Instance), - - [G1AddPrecompile.Address] = new(G1AddPrecompile.Instance), - [G1MulPrecompile.Address] = new(G1MulPrecompile.Instance), - [G1MultiExpPrecompile.Address] = new(G1MultiExpPrecompile.Instance), - [G2AddPrecompile.Address] = new(G2AddPrecompile.Instance), - [G2MulPrecompile.Address] = new(G2MulPrecompile.Instance), - [G2MultiExpPrecompile.Address] = new(G2MultiExpPrecompile.Instance), - [PairingPrecompile.Address] = new(PairingPrecompile.Instance), - [MapToG1Precompile.Address] = new(MapToG1Precompile.Instance), - [MapToG2Precompile.Address] = new(MapToG2Precompile.Instance), - - [PointEvaluationPrecompile.Address] = new(PointEvaluationPrecompile.Instance), - }; - } - private static bool UpdateGas(long gasCost, ref long gasAvailable) { if (gasAvailable < gasCost) @@ -2482,13 +2428,7 @@ private bool InstructionSelfDestruct(EvmState vmState, ref EvmStack>(input, settings); BlockParameterModel blockParameter = BlockParameterModel.Latest; diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs index 795cdfc8242..5913615aeb6 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -116,7 +116,7 @@ public IBlockProcessor GetProcessor() _logManager); } - public IReadOnlyTransactionProcessor Build(Keccak stateRoot) => new ReadOnlyTransactionProcessor(new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager), StateProvider, stateRoot); + public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) => new ReadOnlyTransactionProcessor(new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager), StateProvider, stateRoot); public void Dispose() { diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs index ec02e56acf9..50da633471f 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs @@ -16,7 +16,7 @@ namespace Nethermind.Facade.Multicall; internal sealed class MultiCallTxTracer : TxTracer, ILogsTxTracer { - private static readonly Keccak[] _topics = { Keccak.Zero }; + private static readonly Hash256[] _topics = { Keccak.Zero }; public MultiCallTxTracer(bool isTracingTransfers) { @@ -26,7 +26,7 @@ public MultiCallTxTracer(bool isTracingTransfers) public MultiCallCallResult? TraceResult { get; set; } - public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) + public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Hash256? stateRoot = null) { TraceResult = new MultiCallCallResult() { @@ -43,7 +43,7 @@ public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] outp }; } - public override void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Keccak? stateRoot = null) + public override void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Hash256? stateRoot = null) { TraceResult = new MultiCallCallResult() { diff --git a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs index fba398baac0..150b7e7e7d4 100644 --- a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs @@ -42,6 +42,6 @@ public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IR ? result : _codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, vmSpec); - public CodeInfo GetOrAdd(ValueKeccak codeHash, Span initCode) => + public CodeInfo GetOrAdd(ValueHash256 codeHash, Span initCode) => _codeInfoRepository.GetOrAdd(codeHash, initCode); } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs index 7c158cf0ab8..364536210a0 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/IEthJsonRpcClientProxy.cs @@ -19,7 +19,7 @@ public interface IEthJsonRpcClientProxy Task> eth_getBalance(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionCount(Address address, BlockParameterModel blockParameter = null); Task> eth_getTransactionReceipt(Hash256 transactionHash); - Task> eth_call(CallTransactionModel transaction, BlockParameterModel blockParameter = null); + Task> eth_call(CallTransaction transaction, BlockParameterModel blockParameter = null); Task>> eth_multicallV1(MultiCallPayload blockCalls, BlockParameterModel blockParameter = null); Task> eth_getCode(Address address, BlockParameterModel blockParameter = null); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs index 567da621e87..c50fe6d1b2d 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs @@ -18,10 +18,10 @@ public class AccountOverride /// /// Storage for AccountOverrideState /// - public Dictionary? State { get; set; } + public Dictionary? State { get; set; } /// /// Storage difference for AccountOverrideStateDiff /// - public Dictionary? StateDiff { get; set; } + public Dictionary? StateDiff { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index 014f91b1a82..abd4efd4757 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -13,7 +13,7 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class BlockOverride { public ulong? Number { get; set; } - public Keccak PrevRandao { get; set; } = Keccak.Zero; + public Hash256 PrevRandao { get; set; } = Keccak.Zero; public ulong? Time { get; set; } public ulong? GasLimit { get; set; } public Address? FeeRecipient { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs index 3c0d477cb11..8730e921bd2 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs @@ -9,9 +9,9 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class Log { public ulong LogIndex { get; set; } - public Keccak BlockHash { get; set; } + public Hash256 BlockHash { get; set; } public ulong BlockNumber { get; set; } public Address Address { get; set; } public byte[] Data { get; set; } - public Keccak[] Topics { get; set; } + public Hash256[] Topics { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs index 160561b4678..87173646a79 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs @@ -13,7 +13,7 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; public class MultiCallBlockResult { public ulong Number { get; set; } - public Keccak Hash { get; set; } = Keccak.Zero; + public Hash256 Hash { get; set; } = Keccak.Zero; public ulong Timestamp { get; set; } public ulong GasLimit { get; set; } public ulong GasUsed { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs index b7e518eef46..7c3d5e025f6 100644 --- a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs +++ b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs @@ -67,9 +67,9 @@ private static bool TryGetAccount(this IWorldState stateProvider, Address addres private static void UpdateState(this IWorldState stateProvider, AccountOverride accountOverride, Address address) { - void ApplyState(Dictionary diff) + void ApplyState(Dictionary diff) { - foreach (KeyValuePair storage in diff) + foreach (KeyValuePair storage in diff) { stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.Bytes.WithoutLeadingZeros().ToArray()); } diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs index 26304ad59b3..113505b816c 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs @@ -289,14 +289,16 @@ protected virtual ITransactionProcessor CreateTransactionProcessor() if (_api.SpecProvider is null) throw new StepDependencyException(nameof(_api.SpecProvider)); if (_api.WorldState is null) throw new StepDependencyException(nameof(_api.WorldState)); - (VirtualMachine, CodeInfoRepository) (virtualMachine, codeInfoRepository) = CreateVirtualMachine(); + (VirtualMachine virtualMachine, CodeInfoRepository codeInfoRepository) = CreateVirtualMachine(); - _api.TransactionProcessor = new TransactionProcessor( - getApi.SpecProvider, - worldState, + TransactionProcessor transactionProcessor = new( + _api.SpecProvider, + _api.WorldState, virtualMachine, codeInfoRepository, - getApi.LogManager); + _api.LogManager); + + return transactionProcessor; } protected virtual (VirtualMachine, CodeInfoRepository) CreateVirtualMachine() @@ -312,9 +314,9 @@ protected virtual (VirtualMachine, CodeInfoRepository) CreateVirtualMachine() VirtualMachine virtualMachine = new( blockhashProvider, - getApi.SpecProvider, + _api.SpecProvider, codeInfoRepository, - getApi.LogManager); + _api.LogManager); return (virtualMachine, codeInfoRepository); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs index 91f05e70027..a7324516611 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs @@ -86,7 +86,7 @@ public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, stri { // Step 1: Take an account // Step 2: Hash the message - Keccak messageHash = Keccak.Compute("Hello, world!"); + Hash256 messageHash = Keccak.Compute("Hello, world!"); // Step 3: Sign the hash Signature signature = chain.EthereumEcdsa.Sign(account, messageHash); @@ -141,7 +141,7 @@ public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, stri using SecureStringWrapper pass = new("testB"); wallet.Import(fromPrivateKey.KeyBytes, pass.SecureData); wallet.UnlockAccount(fromPrivateKey.Address, pass.SecureData, TimeSpan.MaxValue); - (Keccak hash, AcceptTxResult? code) = await txSender.SendTransaction(tx, + (Hash256 hash, AcceptTxResult? code) = await txSender.SendTransaction(tx, TxHandlingOptions.ManagedNonce | TxHandlingOptions.PersistentBroadcast); code?.Should().Be(AcceptTxResult.Accepted); @@ -163,7 +163,7 @@ public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, stri return contractAddress1; } - public static byte[] GenerateTransactionDataForEcRecover(Keccak keccak, ulong @ulong, byte[] bytes1, byte[] bytes2, + public static byte[] GenerateTransactionDataForEcRecover(Hash256 keccak, ulong @ulong, byte[] bytes1, byte[] bytes2, string name = "recover") { AbiDefinitionParser parser = new(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs index 668893df176..88f990e3225 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs @@ -63,7 +63,7 @@ public async Task TestmulticallBasefeeTooLowWithValidation38012() Console.WriteLine("current test: multicallBasefeeTooLowWithValidation38012"); var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.That(result.Data.First().PrevRandao, Is.EqualTo(new Keccak("0x0000000000000000000000000000000000000000000000000000000000000000").BytesToArray())); + Assert.That(result.Data.First().PrevRandao, Is.EqualTo(new Hash256("0x0000000000000000000000000000000000000000000000000000000000000000").BytesToArray())); Assert.IsNotNull(result.Data); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index e5d83acf35d..4918359bce7 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -62,7 +62,7 @@ public async Task Test_eth_multicall_erc() // Step 1: Take an account Address account = TestItem.AddressA; // Step 2: Hash the message - Keccak messageHash = Keccak.Compute("Hello, world!"); + Hash256 messageHash = Keccak.Compute("Hello, world!"); // Step 3: Sign the hash Signature signature = chain.EthereumEcdsa.Sign(TestItem.PrivateKeyA, messageHash); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 0e353772ad6..21a53f4d25b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -42,6 +42,9 @@ public override ResultWrapper Execute( public ResultWrapper ExecuteTx(TransactionForRpc transactionCall, BlockParameter? blockParameter) => Execute(transactionCall, blockParameter); protected abstract ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token); + + protected ResultWrapper GetInputError(CallOutput result) => + ResultWrapper.Fail(result.Error, ErrorCodes.InvalidInput); } private class CallTxExecutor : TxExecutor diff --git a/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs b/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs index fbf648b45aa..c35bed88cde 100644 --- a/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs +++ b/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs @@ -44,7 +44,7 @@ protected override ITransactionProcessor CreateTransactionProcessor() if (_api.SpecHelper is null) throw new StepDependencyException(nameof(_api.SpecHelper)); if (_api.L1CostHelper is null) throw new StepDependencyException(nameof(_api.L1CostHelper)); - VirtualMachine virtualMachine = CreateVirtualMachine(); + (VirtualMachine virtualMachine, CodeInfoRepository codeInfoRepository) = CreateVirtualMachine(); return new OptimismTransactionProcessor( _api.SpecProvider, @@ -52,7 +52,8 @@ protected override ITransactionProcessor CreateTransactionProcessor() virtualMachine, _api.LogManager, _api.L1CostHelper, - _api.SpecHelper + _api.SpecHelper, + codeInfoRepository ); } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs b/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs index 3ae5600db5b..ed286b5ea8f 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs @@ -58,8 +58,9 @@ protected override ReadOnlyTxProcessingEnv CreateReadonlyTxProcessingEnv(ReadOnl { ReadOnlyTxProcessingEnv result = new(readOnlyDbProvider, _readOnlyTrieStore, readOnlyBlockTree, _specProvider, _logManager); + result.TransactionProcessor = - new OptimismTransactionProcessor(_specProvider, result.StateProvider, result.Machine, _logManager, _l1CostHelper, _specHelper); + new OptimismTransactionProcessor(_specProvider, result.StateProvider, result.Machine, _logManager, _l1CostHelper, _specHelper, result.CodeInfoRepository); return result; } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs index b58391a4317..af4165343cf 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs @@ -23,7 +23,9 @@ public OptimismTransactionProcessor( IVirtualMachine? virtualMachine, ILogManager? logManager, IL1CostHelper l1CostHelper, - IOPConfigHelper opConfigHelper) : base(specProvider, worldState, virtualMachine, logManager) + IOPConfigHelper opConfigHelper, + ICodeInfoRepository? codeInfoRepository + ) : base(specProvider, worldState, virtualMachine, codeInfoRepository, logManager) { _l1CostHelper = l1CostHelper; _opConfigHelper = opConfigHelper; diff --git a/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs deleted file mode 100644 index bcb80d6ecbb..00000000000 --- a/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyValueKeccakValConverter.cs +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Numerics; -using Nethermind.Core.Crypto; -using Nethermind.Int256; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace Nethermind.Serialization.Json; - -//This is a temp solution to bypass https://github.com/NethermindEth/int256/pull/35 -public class DictionaryWithSpecialUInt256KeyValueKeccakValConverter : JsonConverter -{ - public static bool IsType(Type type, Type typeToBe) - { - - if (!typeToBe.IsGenericTypeDefinition) - return typeToBe.IsAssignableFrom(type); - - List toCheckTypes = new() { type }; - if (typeToBe.IsInterface) - toCheckTypes.AddRange(type.GetInterfaces()); - - Type basedOn = type; - while (basedOn.BaseType != null) - { - toCheckTypes.Add(basedOn.BaseType); - basedOn = basedOn.BaseType; - } - - return toCheckTypes.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeToBe); - } - - public override bool CanWrite - { - get { return false; } - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotSupportedException(); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - // Assuming the keys in JSON are strings, and the Address type has a suitable Parse or TryParse method - Type valueType = objectType.GetGenericArguments()[1]; - Type intermediateDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeof(string), typeof(string)); - IDictionary intermediateDictionary = (IDictionary)Activator.CreateInstance(intermediateDictionaryType); - serializer.Populate(reader, intermediateDictionary); - - IDictionary finalDictionary = (IDictionary)Activator.CreateInstance(objectType); - foreach (DictionaryEntry pair in intermediateDictionary) - { - string keyData = pair.Key.ToString(); - UInt256 key = keyData.StartsWith("0x", StringComparison.OrdinalIgnoreCase) - ? (UInt256)BigInteger.Parse(keyData.Substring(2), NumberStyles.HexNumber) - : UInt256.Parse(keyData); - - string valueData = pair.Value.ToString(); - ValueKeccak val = new(valueData); - - finalDictionary.Add(key, val); - } - - return finalDictionary; - } - - public override bool CanConvert(Type objectType) - { - bool isDict = IsType(objectType, typeof(IDictionary<,>)); - if (!isDict) return false; - - var args = objectType.GetGenericArguments(); - if (args.Length < 2) return false; - - bool isKeyUint256 = IsType(args[0], typeof(UInt256)); - if (!isKeyUint256) return false; - - bool isValValueKeccak = IsType(args[1], typeof(ValueKeccak)); - return isValValueKeccak; - } -} diff --git a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs index de9d1a13f76..2eaba4cb364 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs @@ -48,7 +48,6 @@ public EthereumJsonSerializer(int? maxDepth = null, params JsonConverter[] conve new PublicKeyConverter(), new TxTypeConverter(), new MemoryByteConverter(), - new DictionaryWithSpecialUInt256KeyValueKeccakValConverter() }); public IList BasicConverters { get; } = CommonConverters.ToList(); diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs index 3aa5f8f8971..45a85affb03 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs @@ -15,8 +15,9 @@ namespace Nethermind.Specs.ChainSpecStyle { public class ChainSpecBasedSpecProvider : ISpecProvider { - private readonly (ForkActivation Activation, ReleaseSpec Spec)[] _transitions; - private readonly ForkActivation? _firstTimestampActivation; + private (ForkActivation Activation, ReleaseSpec Spec)[] _transitions; + private ForkActivation? _firstTimestampActivation; + private readonly ChainSpec _chainSpec; private readonly ILogger _logger; @@ -24,7 +25,7 @@ public ChainSpecBasedSpecProvider(ChainSpec chainSpec, ILogManager logManager = { _chainSpec = chainSpec ?? throw new ArgumentNullException(nameof(chainSpec)); _logger = logManager?.GetClassLogger() ?? LimboTraceLogger.Instance; - (_transitions, TransitionActivations, _firstTimestampActivation) = BuildTransitions(); + BuildTransitions(); } public bool GenesisStateUnavailable { get => _chainSpec.GenesisStateUnavailable; } @@ -94,17 +95,16 @@ static void Add(SortedSet transitions, T value, T? minValueExclusive) transitionBlockNumbers.Add(bombDelay.Key); } + TransitionActivations = CreateTransitionActivations(transitionBlockNumbers, transitionTimestamps); + _transitions = CreateTransitions(_chainSpec, transitionBlockNumbers, transitionTimestamps); + _firstTimestampActivation = TransitionActivations.FirstOrDefault(t => t.Timestamp is not null); + if (_chainSpec.Parameters.TerminalPoWBlockNumber is not null) { MergeBlockNumber = (ForkActivation)(_chainSpec.Parameters.TerminalPoWBlockNumber + 1); } TerminalTotalDifficulty = _chainSpec.Parameters.TerminalTotalDifficulty; - - ForkActivation[] transitionActivations = CreateTransitionActivations(transitionBlockNumbers, transitionTimestamps); - return (CreateTransitions(_chainSpec, transitionBlockNumbers, transitionTimestamps), - transitionActivations, - transitionActivations.FirstOrDefault(t => t.Timestamp is not null)); } private static (ForkActivation, ReleaseSpec Spec)[] CreateTransitions( From 0af77c71130bfd61add52ea4478afa41ecaf830d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 1 Nov 2023 07:07:17 +0000 Subject: [PATCH 099/213] most tests fixed --- .../Nethermind.Evm/VirtualMachine.cs | 2 +- .../Proxy/EthJsonRpcClientProxyTests.cs | 3 +- .../Modules/Eth/EthRpcModuleTests.EthCall.cs | 2 +- .../Data/TransactionForRpc.cs | 8 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 5 +- ...ithSpecialUInt256KeyHash256ValConverter.cs | 90 +++++++++++++++++++ .../EthereumJsonSerializer.cs | 2 + 7 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyHash256ValConverter.cs diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 4a2f9a465da..fd0e46035a5 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -651,7 +651,7 @@ private CallResult ExecuteCall(EvmState vmState, byte[]? p } } - if (env.CodeInfo.MachineCode.Length == 0) + if (env.CodeInfo.MachineCode is { Length: 0 }) { if (!vmState.IsTopLevel) { diff --git a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs index d2574ac225e..4c270a84471 100644 --- a/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/Proxy/EthJsonRpcClientProxyTests.cs @@ -22,7 +22,7 @@ using System.Collections; using System.Globalization; using System.Numerics; - +using Nethermind.Serialization.Json.Nethermind.Serialization.Json; namespace Nethermind.Facade.Test.Proxy { @@ -131,6 +131,7 @@ public async Task eth_multicall_should_invoke_client_method_on_complex_data() { settings.Converters.Add(converter); } + settings.Converters.Add(new DictionaryWithSpecialUInt256KeyHash256ValConverter()); var payload = JsonConvert.DeserializeObject>(input, settings); BlockParameterModel blockParameter = BlockParameterModel.Latest; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs index 8773bf7e244..51aaa811a83 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs @@ -146,7 +146,7 @@ public async Task Eth_call_create_tx_with_empty_data() string serialized = await ctx.Test.TestEthRpc("eth_call", ctx.Test.JsonSerializer.Serialize(transaction), "latest"); - serialized.Should().BeEquivalentTo("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"Contract creation without any data provided.\"},\"id\":67}"); + serialized.Should().BeEquivalentTo("{\"jsonrpc\":\"2.0\",\"result\":\"0x\",\"id\":67}"); } [Test] diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs index c1b6a9d3bf5..a338dc5bbb1 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs @@ -127,7 +127,7 @@ public TransactionForRpc() public UInt256? ChainId { get; set; } - public TxType? Type { get; set; } + public TxType Type { get; set; } public IEnumerable? AccessList { get; set; } @@ -160,7 +160,7 @@ public TransactionForRpc() SenderAddress = From, Value = Value ?? 0, Data = Input, - Type = Type!.Value, + Type = Type, AccessList = TryGetAccessList(), ChainId = chainId, DecodedMaxFeePerGas = MaxFeePerGas ?? 0, @@ -196,7 +196,7 @@ public TransactionForRpc() SenderAddress = From, Value = Value ?? 0, Data = (Memory?)data, - Type = Type!.Value, + Type = Type, AccessList = TryGetAccessList(), ChainId = chainId, }; @@ -222,7 +222,7 @@ public TransactionForRpc() } private AccessList? TryGetAccessList() => - !Type!.Value.IsTxTypeWithAccessList() || AccessList is null + !Type.IsTxTypeWithAccessList() || AccessList is null ? null : AccessListItemForRpc.ToAccessList(AccessList); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 9413c71ec77..f733c921de2 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -35,7 +35,10 @@ protected override MultiCallPayload Prepare(MultiC StateOverrides = blockStateCall.StateOverrides, Calls = blockStateCall.Calls?.Select(callTransactionModel => { - callTransactionModel.Type ??= TxType.EIP1559; + if (callTransactionModel.Type == TxType.Legacy) + { + callTransactionModel.Type = TxType.EIP1559; + } TransactionWithSourceDetails? result = new() { diff --git a/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyHash256ValConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyHash256ValConverter.cs new file mode 100644 index 00000000000..474c5643f95 --- /dev/null +++ b/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyHash256ValConverter.cs @@ -0,0 +1,90 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Numerics; +using Nethermind.Core.Crypto; +using Nethermind.Int256; +using Newtonsoft.Json; + +namespace Nethermind.Serialization.Json.Nethermind.Serialization.Json; + +public class DictionaryWithSpecialUInt256KeyHash256ValConverter : JsonConverter +{ + public static bool IsType(Type type, Type typeToBe) + { + + if (!typeToBe.IsGenericTypeDefinition) + return typeToBe.IsAssignableFrom(type); + + List toCheckTypes = new() { type }; + if (typeToBe.IsInterface) + toCheckTypes.AddRange(type.GetInterfaces()); + + Type basedOn = type; + while (basedOn.BaseType != null) + { + toCheckTypes.Add(basedOn.BaseType); + basedOn = basedOn.BaseType; + } + + return toCheckTypes.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeToBe); + } + + public override bool CanWrite + { + get { return false; } + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new NotSupportedException(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + return null; + + // Assuming the keys in JSON are strings, and the Address type has a suitable Parse or TryParse method + Type valueType = objectType.GetGenericArguments()[1]; + Type intermediateDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeof(string), typeof(string)); + IDictionary intermediateDictionary = (IDictionary)Activator.CreateInstance(intermediateDictionaryType); + serializer.Populate(reader, intermediateDictionary); + + IDictionary finalDictionary = (IDictionary)Activator.CreateInstance(objectType); + foreach (DictionaryEntry pair in intermediateDictionary) + { + string keyData = pair.Key.ToString(); + UInt256 key = keyData.StartsWith("0x", StringComparison.OrdinalIgnoreCase) + ? (UInt256)BigInteger.Parse(keyData.Substring(2), NumberStyles.HexNumber) + : UInt256.Parse(keyData); + + string valueData = pair.Value.ToString(); + Hash256 val = new(valueData); + + finalDictionary.Add(key, val); + } + + return finalDictionary; + } + + public override bool CanConvert(Type objectType) + { + bool isDict = IsType(objectType, typeof(IDictionary<,>)); + if (!isDict) return false; + + var args = objectType.GetGenericArguments(); + if (args.Length < 2) return false; + + bool isKeyUint256 = IsType(args[0], typeof(UInt256)); + if (!isKeyUint256) return false; + + bool isValValueKeccak = IsType(args[1], typeof(Hash256)); + return isValValueKeccak; + } +} diff --git a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs index 2eaba4cb364..f05c07c585f 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using Nethermind.Core.Collections; +using Nethermind.Serialization.Json.Nethermind.Serialization.Json; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -48,6 +49,7 @@ public EthereumJsonSerializer(int? maxDepth = null, params JsonConverter[] conve new PublicKeyConverter(), new TxTypeConverter(), new MemoryByteConverter(), + new DictionaryWithSpecialUInt256KeyHash256ValConverter() }); public IList BasicConverters { get; } = CommonConverters.ToList(); From a3df479229242b6e40f603bb60e09d5f0b8b03a5 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 1 Nov 2023 07:44:45 +0000 Subject: [PATCH 100/213] fixing block gas calculation, block processing catch --- .../Multicall/MultiCallBlockTracer.cs | 2 +- .../Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs | 4 ++-- .../Multicall/MulticallBridgeHelper.cs | 11 ++++++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs index bcddc4efa1e..077acaa2887 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs @@ -51,7 +51,7 @@ public override void EndBlockTrace() Number = (ulong)_currentBlock.Number, Hash = _currentBlock.Hash!, GasLimit = (ulong)_currentBlock.GasLimit, - GasUsed = (ulong)_currentBlock.GasUsed, + GasUsed = _txTracers.Aggregate(0ul, (s, t) => s + t.TraceResult!.GasUsed.Value), Timestamp = _currentBlock.Timestamp, FeeRecipient = _currentBlock.Beneficiary!, BaseFeePerGas = _currentBlock.BaseFeePerGas, diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs index 5913615aeb6..480a19b7d6a 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -104,7 +104,7 @@ private MultiCallReadOnlyBlocksProcessingEnv( public IBlockProcessor GetProcessor() { - TransactionProcessor transactionProcessor = new(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, _doValidation); + TransactionProcessor transactionProcessor = new(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !_doValidation); return new BlockProcessor(SpecProvider, _blockValidator, @@ -116,7 +116,7 @@ public IBlockProcessor GetProcessor() _logManager); } - public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) => new ReadOnlyTransactionProcessor(new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager), StateProvider, stateRoot); + public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) => new ReadOnlyTransactionProcessor(new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !_doValidation), StateProvider, stateRoot); public void Dispose() { diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index 5d9fdc75c7f..036570fa28e 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -170,8 +170,17 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction suggestedBlocks.Clear(); suggestedBlocks.Add(currentBlock); env.StateProvider.RecalculateStateRoot(); + Block[]? currentBlocks = null; + try + { + currentBlocks = processor.Process(env.StateProvider.StateRoot, suggestedBlocks, + processingFlags, tracer); + } + catch (Exception) + { + return (false, $"invalid on block {callHeader.Number}"); + } - Block[]? currentBlocks = processor.Process(env.StateProvider.StateRoot, suggestedBlocks, processingFlags, tracer); Block? processedBlock = currentBlocks[0]; parent = processedBlock.Header; } From 43e5af9105a3dafec3675f854278d1ee48e05722 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 1 Nov 2023 10:27:13 +0000 Subject: [PATCH 101/213] hot fix --- .../Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs index 480a19b7d6a..4eb2c3e9f6b 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -62,7 +62,8 @@ public static MultiCallReadOnlyBlocksProcessingEnv Create( trieStore, blockTree, specProvider, - logManager); + logManager, + doValidation); } public MultiCallReadOnlyBlocksProcessingEnv Clone(bool traceTransfers, bool doValidation) => From 08acb1e828115cd2e404d7102fd7772eee90613f Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 6 Nov 2023 11:47:28 +0000 Subject: [PATCH 102/213] Fix aAPI update related issues --- src/Nethermind/Nethermind.Api/NethermindApi.cs | 5 +++-- .../Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 355d3e411e6..b5b021c290c 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -188,7 +188,7 @@ public ISealEngine SealEngine } public ISessionMonitor? SessionMonitor { get; set; } - public ISpecProvider SpecProvider { get; set; } + public ISpecProvider? SpecProvider { get; set; } public IPoSSwitcher PoSSwitcher { get; set; } = NoPoS.Instance; public ISyncModeSelector SyncModeSelector { get; set; } = null!; @@ -219,7 +219,7 @@ public ISealEngine SealEngine public IGasLimitCalculator? GasLimitCalculator { - get => _gasLimitCalculator ??= new FollowOtherMiners(SpecProvider); + get => _gasLimitCalculator ??= new FollowOtherMiners(SpecProvider!); set => _gasLimitCalculator = value; } @@ -243,6 +243,7 @@ public IGasLimitCalculator? GasLimitCalculator public ChainSpec ChainSpec { get; set; } public DisposableStack DisposeStack { get; } = new(); public IReadOnlyList Plugins { get; } = new List(); + public string SealEngineType { get; set; } = Nethermind.Core.SealEngineType.None; public IList Publishers { get; } = new List(); // this should be called publishers public CompositePruningTrigger PruningTrigger { get; } = new(); public ISnapProvider? SnapProvider { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs index 4eb2c3e9f6b..30422cd8406 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -36,7 +36,7 @@ public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, public static MultiCallReadOnlyBlocksProcessingEnv Create( bool traceTransfers, IReadOnlyDbProvider readOnlyDbProvider, - ISpecProvider specProvider, + ISpecProvider? specProvider, ILogManager? logManager = null, bool doValidation = false) { @@ -74,7 +74,7 @@ private MultiCallReadOnlyBlocksProcessingEnv( IReadOnlyDbProvider readOnlyDbProvider, ITrieStore trieStore, IBlockTree blockTree, - ISpecProvider specProvider, + ISpecProvider? specProvider, ILogManager? logManager = null, bool doValidation = false) : base(readOnlyDbProvider, trieStore, blockTree, logManager) @@ -94,7 +94,7 @@ private MultiCallReadOnlyBlocksProcessingEnv( _logManager); BlockValidator blockValidator = new( - new TxValidator(SpecProvider.ChainId), + new TxValidator(SpecProvider!.ChainId), headerValidator, Always.Valid, SpecProvider, From 8536de75d809e03881e47159dc75c93809bbfeb2 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 6 Nov 2023 12:54:48 +0000 Subject: [PATCH 103/213] Unit tests fix now it runs and executes multicall --- .../StandardTests.cs | 1 - .../Extensions/IConsensusPlugin.cs | 4 +-- .../Nethermind.Api/NethermindApi.cs | 28 +++++++++---------- .../TransactionSelectorTests.cs | 2 +- .../TransactionsExecutorTests.cs | 2 +- .../Nethermind.Clique.Test/StandardTests.cs | 1 - .../InitializationSteps/AuRaNethermindApi.cs | 7 +---- ...sor.BlockValidationTransactionsExecutor.cs | 2 +- .../Processing/ProcessingOptions.cs | 2 +- .../Tracing/CallOutputTracer.cs | 2 +- .../Nethermind.Evm/Tracing/ITxTracer.cs | 2 +- .../NodeHealthServiceTests.cs | 3 ++ .../Nethermind.Hive.Test/PluginTests.cs | 1 - .../Steps/InitializeBlockchain.cs | 1 - .../AuRaMergeBlockProducerEnvFactory.cs | 4 +++ .../MergePluginTests.cs | 3 +- .../PluginTests.cs | 1 - .../Nethermind.Mev.Test/PluginTests.cs | 1 - .../OptimismBlockProducerEnvFactory.cs | 1 - .../Ethereum/ContextWithMocks.cs | 10 ++----- .../Nethermind.Runner.Test/StandardTests.cs | 1 - .../Ethereum/Api/ApiBuilder.cs | 6 +++- .../StateProviderTests.cs | 2 +- src/Nethermind/Nethermind.State/WorldState.cs | 9 ++++++ .../Nethermind.Trie.Test/TrieTests.cs | 2 +- 25 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/Nethermind/Nethermind.AccountAbstraction.Test/StandardTests.cs b/src/Nethermind/Nethermind.AccountAbstraction.Test/StandardTests.cs index 97abeac35f9..c7078dd6283 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction.Test/StandardTests.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction.Test/StandardTests.cs @@ -8,7 +8,6 @@ namespace Nethermind.AccountAbstraction.Test { [TestFixture] [Parallelizable(ParallelScope.All)] - [SetCulture("en-US")] public class StandardTests { [Test] diff --git a/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs index 3f0277f4de5..abb29c5981d 100644 --- a/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs +++ b/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs @@ -36,7 +36,7 @@ Task InitBlockProducer( /// IBlockProductionTrigger DefaultBlockProductionTrigger { get; } - INethermindApi CreateApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec) => - new NethermindApi(configProvider, jsonSerializer, logManager, chainSpec); + INethermindApi CreateApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, + ILogManager logManager, ChainSpec chainSpec) => new NethermindApi(configProvider, jsonSerializer, logManager, chainSpec); } } diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index b5b021c290c..1acb4194ba1 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -79,8 +79,6 @@ public NethermindApi( private IReadOnlyDbProvider? _readOnlyDbProvider; private IReadOnlyDbProvider? _multiCallReadOnlyDbProvider; - private ISealEngine? _sealEngine; - private IGasLimitCalculator? _gasLimitCalculator; public IBlockchainBridge CreateBlockchainBridge() { @@ -179,12 +177,20 @@ public IBlockchainBridge CreateBlockchainBridge() public IRpcAuthentication? RpcAuthentication { get; set; } public IJsonRpcLocalStats? JsonRpcLocalStats { get; set; } public ISealer? Sealer { get; set; } = NullSealEngine.Instance; + public string SealEngineType { get; set; } = Nethermind.Core.SealEngineType.None; public ISealValidator? SealValidator { get; set; } = NullSealEngine.Instance; - + private ISealEngine? _sealEngine; public ISealEngine SealEngine { - get => _sealEngine ??= new SealEngine(Sealer, SealValidator); - set => _sealEngine = value; + get + { + return _sealEngine ??= new SealEngine(Sealer, SealValidator); + } + + set + { + _sealEngine = value; + } } public ISessionMonitor? SessionMonitor { get; set; } @@ -203,8 +209,8 @@ public ISealEngine SealEngine public IReadOnlyStateProvider? ChainHeadStateProvider { get; set; } public IStateReader? StateReader { get; set; } public IStaticNodesManager? StaticNodesManager { get; set; } - public ITimestamper Timestamper => Core.Timestamper.Default; - public ITimerFactory TimerFactory => Core.Timers.TimerFactory.Default; + public ITimestamper Timestamper { get; } = Core.Timestamper.Default; + public ITimerFactory TimerFactory { get; } = Core.Timers.TimerFactory.Default; public ITransactionProcessor? TransactionProcessor { get; set; } public ITrieStore? TrieStore { get; set; } public IReadOnlyTrieStore? ReadOnlyTrieStore { get; set; } @@ -216,12 +222,7 @@ public ISealEngine SealEngine public IRpcCapabilitiesProvider? RpcCapabilitiesProvider { get; set; } public ITxValidator? TxValidator { get; set; } public IBlockFinalizationManager? FinalizationManager { get; set; } - - public IGasLimitCalculator? GasLimitCalculator - { - get => _gasLimitCalculator ??= new FollowOtherMiners(SpecProvider!); - set => _gasLimitCalculator = value; - } + public IGasLimitCalculator? GasLimitCalculator { get; set; } public IBlockProducerEnvFactory? BlockProducerEnvFactory { get; set; } public IGasPriceOracle? GasPriceOracle { get; set; } @@ -243,7 +244,6 @@ public IGasLimitCalculator? GasLimitCalculator public ChainSpec ChainSpec { get; set; } public DisposableStack DisposeStack { get; } = new(); public IReadOnlyList Plugins { get; } = new List(); - public string SealEngineType { get; set; } = Nethermind.Core.SealEngineType.None; public IList Publishers { get; } = new List(); // this should be called publishers public CompositePruningTrigger PruningTrigger { get; } = new(); public ISnapProvider? SnapProvider { get; set; } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs index ac29afc7060..a4b02b0c13e 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs @@ -195,7 +195,7 @@ public void Proper_transactions_selected(ProperTransactionsSelectedTestCase test MemDb stateDb = new(); MemDb codeDb = new(); TrieStore trieStore = new(stateDb, LimboLogs.Instance); - IWorldState stateProvider = new WorldState(trieStore, codeDb, LimboLogs.Instance); + WorldState stateProvider = new(trieStore, codeDb, LimboLogs.Instance); StateReader _ = new(new TrieStore(stateDb, LimboLogs.Instance), codeDb, LimboLogs.Instance); ISpecProvider specProvider = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs index 8799490191a..f43d92ead95 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs @@ -262,7 +262,7 @@ public void Proper_transactions_selected(TransactionSelectorTests.ProperTransact MemDb stateDb = new(); MemDb codeDb = new(); TrieStore trieStore = new(stateDb, LimboLogs.Instance); - IWorldState stateProvider = new WorldState(trieStore, codeDb, LimboLogs.Instance); + WorldState stateProvider = new(trieStore, codeDb, LimboLogs.Instance); ISpecProvider specProvider = Substitute.For(); IReleaseSpec spec = testCase.ReleaseSpec; diff --git a/src/Nethermind/Nethermind.Clique.Test/StandardTests.cs b/src/Nethermind/Nethermind.Clique.Test/StandardTests.cs index 214480380d0..fb07a001abe 100644 --- a/src/Nethermind/Nethermind.Clique.Test/StandardTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/StandardTests.cs @@ -8,7 +8,6 @@ namespace Nethermind.Clique.Test { [TestFixture] [Parallelizable(ParallelScope.All)] - [SetCulture("en-US")] public class StandardTests { [Test] diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs index 732a6fd7bb3..a1d726033c4 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs @@ -8,7 +8,6 @@ using Nethermind.Consensus.AuRa.Validators; using Nethermind.Core.Caching; using Nethermind.Core.Crypto; -using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Serialization.Json; @@ -18,11 +17,7 @@ namespace Nethermind.Consensus.AuRa.InitializationSteps { public class AuRaNethermindApi : NethermindApi { - public AuRaNethermindApi( - IConfigProvider configProvider, - IJsonSerializer jsonSerializer, - ILogManager logManager, - ChainSpec chainSpec) + public AuRaNethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec) : base(configProvider, jsonSerializer, logManager, chainSpec) { } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs index 6c6d480ff26..116ba87a90c 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs @@ -34,7 +34,7 @@ public BlockValidationTransactionsExecutor(ITransactionProcessorAdapter transact public TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processingOptions, BlockReceiptsTracer receiptsTracer, IReleaseSpec spec) { - Metrics.ResetBlockStats(); + Evm.Metrics.ResetBlockStats(); BlockExecutionContext blkCtx = new(block.Header); for (int i = 0; i < block.Transactions.Length; i++) { diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingOptions.cs b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingOptions.cs index f1faafb7b06..555e1c9e1dd 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingOptions.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingOptions.cs @@ -66,7 +66,7 @@ public enum ProcessingOptions /// /// Processing options for engine_NewPayload /// - EthereumMerge = MarkAsProcessed | DoNotUpdateHead | IgnoreParentNotOnMainChain, + EthereumMerge = MarkAsProcessed | DoNotUpdateHead | IgnoreParentNotOnMainChain } public static class ProcessingOptionsExtensions diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs index 6d1f51010e9..404b6bb66c4 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs @@ -9,7 +9,7 @@ namespace Nethermind.Evm.Tracing public class CallOutputTracer : TxTracer { public override bool IsTracingReceipt => true; - public byte[] ReturnValue { get; set; } = null!; + public byte[]? ReturnValue { get; set; } public long GasSpent { get; set; } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index 1cc1689e6c8..462c765e417 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -334,7 +334,7 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// /// /// Depends on - void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); + void ReportAction(long gas, UInt256 value, Address @from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); /// /// diff --git a/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs b/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs index 6694f471735..ff31997923e 100644 --- a/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs +++ b/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs @@ -42,6 +42,7 @@ public void CheckHealth_returns_expected_results([ValueSource(nameof(CheckHealth ISyncConfig syncConfig = Substitute.For(); IHealthHintService healthHintService = Substitute.For(); INethermindApi api = Substitute.For(); + api.SpecProvider = Substitute.For(); blockchainProcessor.IsProcessingBlocks(Arg.Any()).Returns(test.IsProcessingBlocks); blockProducer.IsProducingBlocks(Arg.Any()).Returns(test.IsProducingBlocks); syncServer.GetPeerCount().Returns(test.PeerCount); @@ -111,6 +112,8 @@ public void post_merge_health_checks([ValueSource(nameof(CheckHealthPostMergeTes drive.AvailableFreeSpace.Returns(_freeSpaceBytes); drive.TotalSize.Returns((long)(_freeSpaceBytes * 100.0 / test.AvailableDiskSpacePercent)); drive.RootDirectory.FullName.Returns("C:/"); + + api.SpecProvider = Substitute.For(); api.SpecProvider.TerminalTotalDifficulty.Returns(UInt256.Zero); BlockHeaderBuilder GetBlockHeader(int blockNumber) => Build.A.BlockHeader.WithNumber(blockNumber); diff --git a/src/Nethermind/Nethermind.Hive.Test/PluginTests.cs b/src/Nethermind/Nethermind.Hive.Test/PluginTests.cs index 63c97673bff..0ebe4da59d3 100644 --- a/src/Nethermind/Nethermind.Hive.Test/PluginTests.cs +++ b/src/Nethermind/Nethermind.Hive.Test/PluginTests.cs @@ -8,7 +8,6 @@ namespace Nethermind.Hive.Tests { [TestFixture] [Parallelizable(ParallelScope.All)] - [SetCulture("en-US")] public class PluginTests { [Test] diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs index 113505b816c..0bcd20a738c 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs @@ -215,7 +215,6 @@ protected virtual Task InitBlockchain() _api.TransactionProcessor = CreateTransactionProcessor(); - InitSealEngine(); if (_api.SealValidator is null) throw new StepDependencyException(nameof(_api.SealValidator)); diff --git a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs index 954a9d7e992..b8e311bd306 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergeBlockProducerEnvFactory.cs @@ -24,6 +24,8 @@ namespace Nethermind.Merge.AuRa; public class AuRaMergeBlockProducerEnvFactory : BlockProducerEnvFactory { private readonly AuRaNethermindApi _auraApi; + private readonly IAuraConfig _auraConfig; + private readonly DisposableStack _disposeStack; public AuRaMergeBlockProducerEnvFactory( AuRaNethermindApi auraApi, @@ -55,6 +57,8 @@ public AuRaMergeBlockProducerEnvFactory( logManager) { _auraApi = auraApi; + _auraConfig = auraConfig; + _disposeStack = disposeStack; } protected override BlockProcessor CreateBlockProcessor( diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs index 369e2382c17..fe81b0e7c9c 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs @@ -36,7 +36,8 @@ public void Setup() BlocksConfig? miningConfig = new(); IJsonRpcConfig jsonRpcConfig = new JsonRpcConfig() { Enabled = true, EnabledModules = new[] { ModuleType.Engine } }; - _context = Build.ContextWithMocks(SealEngineType.Clique); + _context = Build.ContextWithMocks(); + _context.SealEngineType = SealEngineType.Clique; _context.ConfigProvider.GetConfig().Returns(_mergeConfig); _context.ConfigProvider.GetConfig().Returns(new SyncConfig()); _context.ConfigProvider.GetConfig().Returns(miningConfig); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/PluginTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/PluginTests.cs index 81a63cbb852..90e84220381 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/PluginTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/PluginTests.cs @@ -8,7 +8,6 @@ namespace Nethermind.Merge.Plugin.Test { [TestFixture] [Parallelizable(ParallelScope.All)] - [SetCulture("en-US")] public class PluginTests { [Test] diff --git a/src/Nethermind/Nethermind.Mev.Test/PluginTests.cs b/src/Nethermind/Nethermind.Mev.Test/PluginTests.cs index f0fc74c1e2e..4ba1a0d8822 100644 --- a/src/Nethermind/Nethermind.Mev.Test/PluginTests.cs +++ b/src/Nethermind/Nethermind.Mev.Test/PluginTests.cs @@ -8,7 +8,6 @@ namespace Nethermind.Mev.Test { [TestFixture] [Parallelizable(ParallelScope.All)] - [SetCulture("en-US")] public class PluginTests { [Test] diff --git a/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs b/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs index ed286b5ea8f..803392257db 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs @@ -58,7 +58,6 @@ protected override ReadOnlyTxProcessingEnv CreateReadonlyTxProcessingEnv(ReadOnl { ReadOnlyTxProcessingEnv result = new(readOnlyDbProvider, _readOnlyTrieStore, readOnlyBlockTree, _specProvider, _logManager); - result.TransactionProcessor = new OptimismTransactionProcessor(_specProvider, result.StateProvider, result.Machine, _logManager, _l1CostHelper, _specHelper, result.CodeInfoRepository); diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index 20a0deddd4d..87dde84f9ce 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -50,13 +50,8 @@ namespace Nethermind.Runner.Test.Ethereum { public static class Build { - public static NethermindApi ContextWithMocks(string sealEngine = SealEngineType.Ethash) => - new( - Substitute.For(), - Substitute.For(), - LimboLogs.Instance, - new ChainSpec { SealEngineType = sealEngine }, - Substitute.For()) + public static NethermindApi ContextWithMocks() => + new(Substitute.For(), Substitute.For(), LimboLogs.Instance, new ChainSpec()) { Enode = Substitute.For(), TxPool = Substitute.For(), @@ -66,6 +61,7 @@ public static NethermindApi ContextWithMocks(string sealEngine = SealEngineType. DbProvider = TestMemDbProvider.Init(), PeerManager = Substitute.For(), PeerPool = Substitute.For(), + SpecProvider = Substitute.For(), EthereumEcdsa = Substitute.For(), MainBlockProcessor = Substitute.For(), ReceiptStorage = Substitute.For(), diff --git a/src/Nethermind/Nethermind.Runner.Test/StandardTests.cs b/src/Nethermind/Nethermind.Runner.Test/StandardTests.cs index 46968471443..6724ebee562 100644 --- a/src/Nethermind/Nethermind.Runner.Test/StandardTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/StandardTests.cs @@ -8,7 +8,6 @@ namespace Nethermind.Runner.Test { [TestFixture] [Parallelizable(ParallelScope.All)] - [SetCulture("en-US")] public class StandardTests { [Test] diff --git a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs index 068c4416b20..5b4859c293e 100644 --- a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs +++ b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs @@ -48,11 +48,15 @@ public INethermindApi Create(IEnumerable consensusPlugins) throw new NotSupportedException("Creation of multiple APIs not supported."); } - IConsensusPlugin? enginePlugin = consensusPlugins.FirstOrDefault(p => p.SealEngineType == chainSpec.SealEngineType); + string engine = chainSpec.SealEngineType; + IConsensusPlugin? enginePlugin = consensusPlugins.FirstOrDefault(p => p.SealEngineType == engine); INethermindApi nethermindApi = enginePlugin?.CreateApi(_configProvider, _jsonSerializer, _logManager, chainSpec) ?? new NethermindApi(_configProvider, _jsonSerializer, _logManager, chainSpec); + nethermindApi.SealEngineType = engine; + nethermindApi.SpecProvider = new ChainSpecBasedSpecProvider(chainSpec, _logManager); + nethermindApi.GasLimitCalculator = new FollowOtherMiners(nethermindApi.SpecProvider); SetLoggerVariables(chainSpec); diff --git a/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs b/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs index e7a412a5f38..27329a5a2d9 100644 --- a/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs @@ -187,7 +187,7 @@ public void Restore_in_the_middle() { byte[] code = new byte[] { 1 }; - IWorldState provider = new WorldState(new TrieStore(new MemDb(), Logger), _codeDb, Logger); + WorldState provider = new(new TrieStore(new MemDb(), Logger), _codeDb, Logger); provider.CreateAccount(_address1, 1); provider.AddToBalance(_address1, 1, Frontier.Instance); provider.IncrementNonce(_address1); diff --git a/src/Nethermind/Nethermind.State/WorldState.cs b/src/Nethermind/Nethermind.State/WorldState.cs index fc628c30fb2..49e4269c128 100644 --- a/src/Nethermind/Nethermind.State/WorldState.cs +++ b/src/Nethermind/Nethermind.State/WorldState.cs @@ -135,6 +135,15 @@ public void DecrementNonce(Address address, UInt256 delta) _stateProvider.DecrementNonce(address, delta); } + public void IncrementNonce(Address address) + { + _stateProvider.IncrementNonce(address, 1); + } + public void DecrementNonce(Address address) + { + _stateProvider.DecrementNonce(address, 1); + } + public void CommitTree(long blockNumber) { _persistentStorageProvider.CommitTrees(blockNumber); diff --git a/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs b/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs index bf7832eff46..692c71bef1c 100644 --- a/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs @@ -976,7 +976,7 @@ public void Fuzz_accounts_with_storage( MemDb memDb = new(); using TrieStore trieStore = new(memDb, Prune.WhenCacheReaches(1.MB()), Persist.IfBlockOlderThan(lookupLimit), _logManager); - IWorldState stateProvider = new WorldState(trieStore, new MemDb(), _logManager); + WorldState stateProvider = new(trieStore, new MemDb(), _logManager); Account[] accounts = new Account[accountsCount]; Address[] addresses = new Address[accountsCount]; From ee5e4f63f4be370b639f9eb9a6aa7e20dfa9b05b Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 13 Nov 2023 06:45:52 +0000 Subject: [PATCH 104/213] fixing state used in multicall --- .../Multicall/MulticallBridgeHelper.cs | 8 ++--- ...ulticallTestsPrecompilesWithRedirection.cs | 34 +++++++++++-------- .../EthMulticallTestsBlocksAndTransactions.cs | 9 +++-- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index 036570fa28e..2a6ebe24c44 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -46,12 +46,8 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateC public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) { using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers, payload.Validation); - Block? parentBlock = env.BlockTree.FindBlock(parent.Number); - if (parentBlock is not null) - { - env.BlockTree.UpdateMainChain(new[] { parentBlock }, true, true); - env.BlockTree.UpdateHeadBlock(parentBlock.Hash!); - } + env.StateProvider.StateRoot = parent.StateRoot; + IBlockProcessor? processor = env.GetProcessor(); BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index bd34bb5bdb0..a184e9579df 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -2,12 +2,12 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Evm; using Nethermind.Evm.Precompiles; @@ -82,11 +82,19 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( byte[] transactionData = EthRpcMulticallTestsBase.GetTxData(chain, TestItem.PrivateKeyA); + var headHash = chain.BlockFinder.Head!.Hash!; Address? contractAddress = await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EthMulticallTestsSimplePrecompiles.EcRecoverCallerContractBytecode); EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); + chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); + + var headHashAfterPost = chain.BlockFinder.Head!.Hash!; + Assert.That(headHash != headHashAfterPost); + + Transaction systemTransactionForModifiedVm = new() { Data = transactionData, @@ -96,6 +104,8 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( GasPrice = 20.GWei() }; + TransactionForRpc transactionForRpc = new(systemTransactionForModifiedVm) { Nonce = null }; + MultiCallPayload payload = new() { BlockStateCalls = new BlockStateCall[] @@ -112,32 +122,28 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( MovePrecompileToAddress = new Address("0x0000000000000000000000000000000000000666"), } }, - { - TestItem.AddressA, - new AccountOverride - { - Balance = 10.Ether() - } - } - }, + }, Calls = new[] { - new TransactionForRpc(systemTransactionForModifiedVm), + transactionForRpc, } } }, - TraceTransfers = true, + TraceTransfers = false, Validation = false }; //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + Debug.Assert(contractAddress != null, nameof(contractAddress) + " != null"); + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); //Check results - byte[] addressBytes = result.Data[0].Calls.First().ReturnData!.SliceWithZeroPaddingEmptyOnError(12, 20); - //Address resultingAddress = new(addressBytes); - //Assert.That(resultingAddress, Is.EqualTo(TestItem.AddressA)) + byte[]? returnData = result.Data[0].Calls.First().ReturnData; + byte[] addressBytes = returnData!.SliceWithZeroPaddingEmptyOnError(12, 20); + Address resultingAddress = new(addressBytes); + Assert.That(resultingAddress, Is.EqualTo(TestItem.AddressA)); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index f753dd80b90..f817c858cde 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -209,6 +209,8 @@ public async Task Test_eth_multicall_transactions_forced_fail() //shall fail Transaction txAtoB2 = GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, UInt256.MaxValue); + TransactionForRpc transactionForRpc = new(txAtoB2){Nonce = null}; + TransactionForRpc transactionForRpc2 = new(txAtoB1) { Nonce = null }; MultiCallPayload payload = new() { BlockStateCalls = new BlockStateCall[] @@ -223,7 +225,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 }, - Calls = new[] { new TransactionForRpc(txAtoB1) } + Calls = new[] { transactionForRpc2 } }, new() { @@ -235,10 +237,11 @@ public async Task Test_eth_multicall_transactions_forced_fail() FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 }, - Calls = new[] { new TransactionForRpc(txAtoB2) } + Calls = new[] { transactionForRpc } } }, - TraceTransfers = true + TraceTransfers = true, + Validation = true }; //Test that transfer tx works on mainchain From 857f83501300c7a31b85eb69a8a4689d07525997 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 13 Nov 2023 13:43:29 +0000 Subject: [PATCH 105/213] Gas cap limits enforcement On blocks and transactions --- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index f733c921de2..349ca856b0b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -8,6 +8,7 @@ using System.Threading; using Nethermind.Blockchain.Find; using Nethermind.Core; +using Nethermind.Core.Collections; using Nethermind.Facade; using Nethermind.Facade.Multicall; using Nethermind.Facade.Proxy.Models; @@ -19,9 +20,13 @@ namespace Nethermind.JsonRpc.Modules.Eth; public class MultiCallTxExecutor : ExecutorBase, MultiCallPayload, MultiCallPayload> { + private long gasCapBudget; + public MultiCallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : base(blockchainBridge, blockFinder, rpcConfig) - { } + { + gasCapBudget = rpcConfig.GasCap ?? long.MaxValue; + } protected override MultiCallPayload Prepare(MultiCallPayload call) { @@ -29,26 +34,41 @@ protected override MultiCallPayload Prepare(MultiC { TraceTransfers = call.TraceTransfers, Validation = call.Validation, - BlockStateCalls = call.BlockStateCalls?.Select(blockStateCall => new BlockStateCall + BlockStateCalls = call.BlockStateCalls?.Select(blockStateCall => { - BlockOverrides = blockStateCall.BlockOverrides, - StateOverrides = blockStateCall.StateOverrides, - Calls = blockStateCall.Calls?.Select(callTransactionModel => + if (blockStateCall.BlockOverrides?.GasLimit != null) { - if (callTransactionModel.Type == TxType.Legacy) - { - callTransactionModel.Type = TxType.EIP1559; - } + blockStateCall.BlockOverrides.GasLimit = (ulong)Math.Min((long)blockStateCall.BlockOverrides.GasLimit!.Value, gasCapBudget); + } - TransactionWithSourceDetails? result = new() + return new BlockStateCall + { + BlockOverrides = blockStateCall.BlockOverrides, + StateOverrides = blockStateCall.StateOverrides, + Calls = blockStateCall.Calls?.Select(callTransactionModel => { - HadGasLimitInRequest = callTransactionModel.Gas.HasValue, - HadNonceInRequest = callTransactionModel.Nonce.HasValue, - Transaction = callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()) - }; + if (callTransactionModel.Type == TxType.Legacy) + { + callTransactionModel.Type = TxType.EIP1559; + } + + bool hadGasLimitInRequest = callTransactionModel.Gas.HasValue; + bool hadNonceInRequest = callTransactionModel.Nonce.HasValue; + callTransactionModel.EnsureDefaults(gasCapBudget); + gasCapBudget -= callTransactionModel.Gas!.Value; + + var tx = callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()); + + TransactionWithSourceDetails ? result = new() + { + HadGasLimitInRequest = hadGasLimitInRequest, + HadNonceInRequest = hadNonceInRequest, + Transaction = tx + }; - return result; - }).ToArray() + return result; + }).ToArray() + }; }).ToArray() }; From f2274a99eedac45ea971c46e4e640dae0d3379f9 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 13 Nov 2023 13:45:02 +0000 Subject: [PATCH 106/213] fix spacing --- .../Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs | 2 +- .../Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs | 2 +- .../Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index a184e9579df..784b207e4e7 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -122,7 +122,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( MovePrecompileToAddress = new Address("0x0000000000000000000000000000000000000666"), } }, - }, + }, Calls = new[] { transactionForRpc, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index f817c858cde..034d734f05d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -209,7 +209,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() //shall fail Transaction txAtoB2 = GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, UInt256.MaxValue); - TransactionForRpc transactionForRpc = new(txAtoB2){Nonce = null}; + TransactionForRpc transactionForRpc = new(txAtoB2) { Nonce = null }; TransactionForRpc transactionForRpc2 = new(txAtoB1) { Nonce = null }; MultiCallPayload payload = new() { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 349ca856b0b..4066a673a71 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -59,7 +59,7 @@ protected override MultiCallPayload Prepare(MultiC var tx = callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()); - TransactionWithSourceDetails ? result = new() + TransactionWithSourceDetails? result = new() { HadGasLimitInRequest = hadGasLimitInRequest, HadNonceInRequest = hadNonceInRequest, From 6118b2910ed92feb2e333ca205a29694c17f023b Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 14 Nov 2023 07:34:23 +0000 Subject: [PATCH 107/213] fixing local move test --- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 5 +++-- .../Multicall/MulticallBridgeHelper.cs | 21 +++++++++++++------ ...ulticallTestsPrecompilesWithRedirection.cs | 6 +++--- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs index 30422cd8406..603aac76018 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -103,9 +103,10 @@ private MultiCallReadOnlyBlocksProcessingEnv( _blockValidator = new MultiCallBlockValidatorProxy(blockValidator); } - public IBlockProcessor GetProcessor() + public IBlockProcessor GetProcessor(Hash256 stateRoot) { - TransactionProcessor transactionProcessor = new(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !_doValidation); + //StateProvider.StateRoot = stateRoot; + IReadOnlyTransactionProcessor transactionProcessor = Build(stateRoot); return new BlockProcessor(SpecProvider, _blockValidator, diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index 2a6ebe24c44..07aa2f06a61 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -15,6 +15,7 @@ using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; +using Nethermind.State; namespace Nethermind.Facade.Multicall; @@ -39,17 +40,18 @@ public MulticallBridgeHelper(MultiCallReadOnlyBlocksProcessingEnv multiCallProce private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall blockStateCall, MultiCallReadOnlyBlocksProcessingEnv env) { IReleaseSpec currentSpec = env.SpecProvider.GetSpec(blockHeader); - env.StateProvider.ApplyStateOverrides(_multiCallProcessingEnv.CodeInfoRepository, blockStateCall.StateOverrides, currentSpec, blockHeader.Number - 1); + env.StateProvider.ApplyStateOverrides(env.CodeInfoRepository, blockStateCall.StateOverrides, currentSpec, blockHeader.Number); blockHeader.StateRoot = env.StateProvider.StateRoot; } public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) { using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers, payload.Validation); - env.StateProvider.StateRoot = parent.StateRoot; + env.BlockTree.UpdateHeadBlock(parent.Hash!); + IWorldState stateProvider = env.StateProvider; + stateProvider.RecalculateStateRoot(); + stateProvider.StateRoot = parent.StateRoot!; - - IBlockProcessor? processor = env.GetProcessor(); BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); if (firstBlock?.BlockOverrides?.Number is > 0 and < long.MaxValue) { @@ -165,11 +167,13 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction suggestedBlocks.Clear(); suggestedBlocks.Add(currentBlock); - env.StateProvider.RecalculateStateRoot(); + + stateProvider.RecalculateStateRoot(); Block[]? currentBlocks = null; try { - currentBlocks = processor.Process(env.StateProvider.StateRoot, suggestedBlocks, + IBlockProcessor? processor = env.GetProcessor(currentBlock.StateRoot!); + currentBlocks = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer); } catch (Exception) @@ -179,6 +183,11 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction Block? processedBlock = currentBlocks[0]; parent = processedBlock.Header; + if (processedBlock is not null) + { + //env.BlockTree.UpdateMainChain(new[] { currentBlock }, true, true); + env.BlockTree.UpdateHeadBlock(currentBlock.Hash!); + } } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 784b207e4e7..128a085d004 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -86,14 +86,14 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( Address? contractAddress = await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EthMulticallTestsSimplePrecompiles.EcRecoverCallerContractBytecode); - EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + var tst = EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); var headHashAfterPost = chain.BlockFinder.Head!.Hash!; Assert.That(headHash != headHashAfterPost); - + chain.State.StateRoot = chain.BlockFinder.Head!.StateRoot!; Transaction systemTransactionForModifiedVm = new() { @@ -137,7 +137,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); Debug.Assert(contractAddress != null, nameof(contractAddress) + " != null"); - + Assert.IsTrue(chain.State.AccountExists(contractAddress)); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); //Check results From bf944ed552a52a4c187cf1b2914115ee13863502 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 20 Nov 2023 10:56:04 +0000 Subject: [PATCH 108/213] Hunted down trie exception Issue is that host returns header based, including temp data while MultiCall operates on top of DB --- src/Nethermind/Nethermind.Db/ReadOnlyDb.cs | 8 +-- .../Multicall/MulticallBridgeHelper.cs | 22 ++++-- ...ulticallTestsPrecompilesWithRedirection.cs | 70 +++++++++++++++++++ .../Modules/Eth/ExecutorBase.cs | 2 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 27 +++++++ 5 files changed, 119 insertions(+), 10 deletions(-) diff --git a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs index 9a7929eebd7..551eafe900a 100644 --- a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs +++ b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs @@ -71,10 +71,10 @@ public IWriteBatch StartWriteBatch() return this.LikeABatch(); } - public long GetSize() => _wrappedDb.GetSize(); - public long GetCacheSize() => _wrappedDb.GetCacheSize(); - public long GetIndexSize() => _wrappedDb.GetIndexSize(); - public long GetMemtableSize() => _wrappedDb.GetMemtableSize(); + public long GetSize() => _memDb.GetSize() + _wrappedDb.GetSize(); + public long GetCacheSize() => _memDb.GetCacheSize() + _wrappedDb.GetCacheSize(); + public long GetIndexSize() => _memDb.GetIndexSize() + _wrappedDb.GetIndexSize(); + public long GetMemtableSize() => _memDb.GetMemtableSize() + _wrappedDb.GetMemtableSize(); public void Remove(ReadOnlySpan key) { } diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index 07aa2f06a61..6dbf42abdaf 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -4,6 +4,9 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.Authorization; +using Nethermind.Blockchain; +using Nethermind.Blockchain.Find; using Nethermind.Config; using Nethermind.Consensus.Processing; using Nethermind.Core; @@ -47,18 +50,26 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateC public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) { using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers, payload.Validation); - env.BlockTree.UpdateHeadBlock(parent.Hash!); + + Block? latestPersistant = env.BlockTree.FindLatestBlock(); + if (latestPersistant.Number < parent.Number) + { + parent = latestPersistant.Header; + } + IWorldState stateProvider = env.StateProvider; - stateProvider.RecalculateStateRoot(); stateProvider.StateRoot = parent.StateRoot!; BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); - if (firstBlock?.BlockOverrides?.Number is > 0 and < long.MaxValue) + + ulong lastKnown = (ulong)latestPersistant.Number; + if (firstBlock?.BlockOverrides?.Number > 0 && firstBlock?.BlockOverrides?.Number < lastKnown) { - BlockHeader? searchResult = env.BlockTree.FindHeader((long)firstBlock.BlockOverrides.Number); + Block? searchResult = env.BlockTree.FindBlock((long)firstBlock.BlockOverrides.Number); if (searchResult is not null) { - parent = searchResult; + parent = searchResult.Header; + stateProvider.StateRoot = parent.StateRoot!; } } @@ -110,6 +121,7 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction { if (!nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) { + env.StateProvider.CreateAccountIfNotExists(transaction.SenderAddress, 0, 0); cachedNonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; nonceCache[transaction.SenderAddress] = cachedNonce; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 128a085d004..80e3ec56eff 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -21,6 +22,75 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; public class EthMulticallTestsPrecompilesWithRedirection { + public static byte[] HexStringToByteArray(string hex) + { + if (hex.StartsWith("0x")) + { + hex = hex.Substring(2); + } + + int NumberChars = hex.Length; + byte[] bytes = new byte[NumberChars / 2]; + for (int i = 0; i < NumberChars; i += 2) + { + bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); + } + return bytes; + } + + [Test] + public async Task Test_eth_multicall_create() + { + TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + + Transaction systemTransactionForModifiedVm = new() + { + SenderAddress = new Address("0xc000000000000000000000000000000000000000"), + Data = HexStringToByteArray("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + To = new Address("0xc200000000000000000000000000000000000000"), + GasLimit = 3_500_000, + GasPrice = 20.GWei(), + + }; + + TransactionForRpc transactionForRpc = new(systemTransactionForModifiedVm) { Nonce = null }; + + MultiCallPayload payload = new() + { + BlockStateCalls = new BlockStateCall[] + { + new() + { + StateOverrides = new Dictionary + { + { + new Address("0xc200000000000000000000000000000000000000"), + new AccountOverride + { + Code = HexStringToByteArray("0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033") + } + }, + }, + Calls = new[] + { + transactionForRpc, + } + } + }, + TraceTransfers = false, + Validation = false + }; + + //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not + MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); + + //Check results + byte[]? returnData = result.Data[0].Calls.First().ReturnData; + } + + /// /// This test verifies that a temporary forked blockchain can redirect precompiles /// diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs index 2a325195c73..723fea171dc 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs @@ -10,7 +10,7 @@ namespace Nethermind.JsonRpc.Modules.Eth; public abstract class ExecutorBase { - private readonly IBlockFinder _blockFinder; + protected readonly IBlockFinder _blockFinder; protected readonly IBlockchainBridge _blockchainBridge; protected readonly IJsonRpcConfig _rpcConfig; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 4066a673a71..9dda9ff6e64 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -74,6 +74,33 @@ protected override MultiCallPayload Prepare(MultiC return result; } + public override ResultWrapper> Execute( + MultiCallPayload call, + BlockParameter? blockParameter) + { + SearchResult searchResult = _blockFinder.SearchForBlock(blockParameter); + + if (searchResult.IsError || searchResult.Object == null) + { + return ResultWrapper>.Fail(searchResult); + } + + BlockHeader header = searchResult.Object.Header; + + if (blockParameter.Type == BlockParameterType.Latest) + { + header = _blockFinder.FindLatestBlock().Header; + } + + if (!_blockchainBridge.HasStateForBlock(header!)) + { + return ResultWrapper>.Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable); + } + + using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); + MultiCallPayload? toProcess = Prepare(call); + return Execute(header.Clone(), toProcess, cancellationTokenSource.Token); + } protected override ResultWrapper> Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) { From 19f075ade5d4842d1bfc6406cf6af2e81aa3807a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 20 Nov 2023 11:01:31 +0000 Subject: [PATCH 109/213] fix whitespace --- .../Nethermind.Facade/Multicall/MulticallBridgeHelper.cs | 2 +- .../Eth/EthMulticallTestsPrecompilesWithRedirection.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index 6dbf42abdaf..7d4a9bfa7bd 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -50,7 +50,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateC public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) { using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers, payload.Validation); - + Block? latestPersistant = env.BlockTree.FindLatestBlock(); if (latestPersistant.Number < parent.Number) { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 80e3ec56eff..220b7ee1bb4 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -42,7 +42,7 @@ public static byte[] HexStringToByteArray(string hex) public async Task Test_eth_multicall_create() { TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - + Transaction systemTransactionForModifiedVm = new() { SenderAddress = new Address("0xc000000000000000000000000000000000000000"), @@ -50,7 +50,7 @@ public async Task Test_eth_multicall_create() To = new Address("0xc200000000000000000000000000000000000000"), GasLimit = 3_500_000, GasPrice = 20.GWei(), - + }; TransactionForRpc transactionForRpc = new(systemTransactionForModifiedVm) { Nonce = null }; From 7cd7f58d71af563663498f64d6b94908c0867c6a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 18 Jan 2024 07:19:21 +0000 Subject: [PATCH 110/213] merge hotfix --- .../Nethermind.Facade/Multicall/MulticallBridgeHelper.cs | 3 --- .../Proxy/Models/MultiCall/MultiCallCallResult.cs | 2 -- src/Nethermind/Nethermind.Runner/Nethermind.Runner.csproj | 4 ++++ 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index 7d4a9bfa7bd..9ba2bb20688 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -4,9 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.AspNetCore.Authorization; -using Nethermind.Blockchain; -using Nethermind.Blockchain.Find; using Nethermind.Config; using Nethermind.Consensus.Processing; using Nethermind.Core; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs index 27f5bec36e6..f3ea1a011b6 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs @@ -1,8 +1,6 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; -using Microsoft.AspNetCore.Http; using Nethermind.Evm; namespace Nethermind.Facade.Proxy.Models.MultiCall; diff --git a/src/Nethermind/Nethermind.Runner/Nethermind.Runner.csproj b/src/Nethermind/Nethermind.Runner/Nethermind.Runner.csproj index 23463ef6ad5..0e838250de9 100644 --- a/src/Nethermind/Nethermind.Runner/Nethermind.Runner.csproj +++ b/src/Nethermind/Nethermind.Runner/Nethermind.Runner.csproj @@ -19,6 +19,10 @@ 03db39d0-4200-473e-9ff8-4a48d496381f + + $(NoWarn);AD0001 + + From 909f9279e265eeb6c63f78576476f31bd685c83b Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 18 Jan 2024 10:16:36 +0000 Subject: [PATCH 111/213] Tree State Failed example Example depicting an issue to tackle --- .../Nethermind.Api/NethermindApi.cs | 1 + .../NonDistructiveBlockTreeOverlay.cs | 318 ++++++++++++++++++ .../Processing/ReadOnlyTxProcessingEnvBase.cs | 1 - .../BlockchainBridgeTests.cs | 11 +- .../Nethermind.Facade/BlockchainBridge.cs | 14 +- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 17 +- .../Multicall/MulticallBridgeHelper.cs | 10 +- .../EthMulticallTestsBlocksAndTransactions.cs | 1 + .../Modules/TestRpcBlockchain.cs | 5 +- 9 files changed, 355 insertions(+), 23 deletions(-) create mode 100644 src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index f67a7770ad7..6a040a417a3 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -96,6 +96,7 @@ public IBlockchainBridge CreateBlockchainBridge() MultiCallReadOnlyBlocksProcessingEnv multiCallReadOnlyBlocksProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create(false, WorldStateManager!, + readOnlyTree, _multiCallReadOnlyDbProvider, SpecProvider, LogManager); diff --git a/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs b/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs new file mode 100644 index 00000000000..96c072395ed --- /dev/null +++ b/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs @@ -0,0 +1,318 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Nethermind.Blockchain.Visitors; +using Nethermind.Core; +using Nethermind.Core.Crypto; + +namespace Nethermind.Blockchain; + +public class NonDistructiveBlockTreeOverlay : IBlockTree +{ + private readonly IBlockTree _baseTree; + private readonly IBlockTree _overlayTree; + + public NonDistructiveBlockTreeOverlay(IReadOnlyBlockTree baseTree, IBlockTree overlayTree) + { + _baseTree = baseTree ?? throw new ArgumentNullException(nameof(baseTree)); + _overlayTree = overlayTree ?? throw new ArgumentNullException(nameof(overlayTree)); + } + + public ulong NetworkId => _baseTree.NetworkId; + public ulong ChainId => _baseTree.ChainId; + public BlockHeader? Genesis => _baseTree.Genesis; + + public BlockHeader? BestSuggestedHeader => _overlayTree.BestSuggestedHeader ?? _baseTree.BestSuggestedHeader; + public Block? BestSuggestedBody => _overlayTree.BestSuggestedBody ?? _baseTree.BestSuggestedBody; + + public BlockHeader? BestSuggestedBeaconHeader => + _overlayTree.BestSuggestedBeaconHeader ?? _baseTree.BestSuggestedBeaconHeader; + + public BlockHeader? LowestInsertedHeader => _overlayTree.LowestInsertedHeader ?? _baseTree.LowestInsertedHeader; + + public long? LowestInsertedBodyNumber + { + get => _overlayTree.LowestInsertedBodyNumber ?? _baseTree.LowestInsertedBodyNumber; + set => _overlayTree.LowestInsertedBodyNumber = value; + } + + public BlockHeader? LowestInsertedBeaconHeader + { + get => _overlayTree.LowestInsertedBeaconHeader ?? _baseTree.LowestInsertedBeaconHeader; + set => _overlayTree.LowestInsertedBeaconHeader = value; + } + + public long BestKnownNumber => Math.Max(_overlayTree.BestKnownNumber, _baseTree.BestKnownNumber); + public long BestKnownBeaconNumber => Math.Max(_overlayTree.BestKnownBeaconNumber, _baseTree.BestKnownBeaconNumber); + + public Hash256 HeadHash => _overlayTree.HeadHash ?? _baseTree.HeadHash; + public Hash256 GenesisHash => _baseTree.GenesisHash; + public Hash256? PendingHash => _overlayTree.PendingHash ?? _baseTree.PendingHash; + public Hash256? FinalizedHash => _overlayTree.FinalizedHash ?? _baseTree.FinalizedHash; + public Hash256? SafeHash => _overlayTree.SafeHash ?? _baseTree.SafeHash; + public Block? Head => _overlayTree.Head ?? _baseTree.Head; + public long? BestPersistedState { get => _overlayTree.BestPersistedState; set => _overlayTree.BestPersistedState = value; } + + + public AddBlockResult Insert(BlockHeader header, + BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.None) + { + return _overlayTree.Insert(header, headerOptions); + } + + public AddBlockResult Insert(Block block, + BlockTreeInsertBlockOptions insertBlockOptions = BlockTreeInsertBlockOptions.None, + BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None, + WriteFlags bodiesWriteFlags = WriteFlags.None) + { + return _overlayTree.Insert(block, insertBlockOptions, insertHeaderOptions, bodiesWriteFlags); + } + + public void UpdateHeadBlock(Hash256 blockHash) + { + _overlayTree.UpdateHeadBlock(blockHash); + } + + public AddBlockResult SuggestBlock(Block block, + BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) + { + return _overlayTree.SuggestBlock(block, options); + } + + public ValueTask SuggestBlockAsync(Block block, + BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) + { + return _overlayTree.SuggestBlockAsync(block, options); + } + + public AddBlockResult SuggestHeader(BlockHeader header) + { + return _overlayTree.SuggestHeader(header); + } + + public bool IsKnownBlock(long number, Hash256 blockHash) + { + return _overlayTree.IsKnownBlock(number, blockHash) || _baseTree.IsKnownBlock(number, blockHash); + } + + public bool IsKnownBeaconBlock(long number, Hash256 blockHash) + { + return _overlayTree.IsKnownBeaconBlock(number, blockHash) || _baseTree.IsKnownBeaconBlock(number, blockHash); + } + + public bool WasProcessed(long number, Hash256 blockHash) + { + return _overlayTree.WasProcessed(number, blockHash) || _baseTree.WasProcessed(number, blockHash); + } + + public void UpdateMainChain(IReadOnlyList blocks, bool wereProcessed, bool forceHeadBlock = false) + { + _overlayTree.UpdateMainChain(blocks, wereProcessed, forceHeadBlock); + } + + public void MarkChainAsProcessed(IReadOnlyList blocks) + { + _overlayTree.MarkChainAsProcessed(blocks); + } + + public bool CanAcceptNewBlocks { get; } + public Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken) + { + return _overlayTree.Accept(blockTreeVisitor, cancellationToken); + } + // Additional method implementations for the BlockTreeOverlay class + + public (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(long number, Hash256 blockHash) + { + var overlayInfo = _overlayTree.GetInfo(number, blockHash); + if (overlayInfo.Info != null || overlayInfo.Level != null) + { + return overlayInfo; + } + + return _baseTree.GetInfo(number, blockHash); + } + + public ChainLevelInfo? FindLevel(long number) + { + var overlayLevel = _overlayTree.FindLevel(number); + return overlayLevel ?? _baseTree.FindLevel(number); + } + + public BlockInfo FindCanonicalBlockInfo(long blockNumber) + { + var overlayBlockInfo = _overlayTree.FindCanonicalBlockInfo(blockNumber); + return overlayBlockInfo ?? _baseTree.FindCanonicalBlockInfo(blockNumber); + } + + public Hash256 FindHash(long blockNumber) + { + var overlayHash = _overlayTree.FindHash(blockNumber); + return overlayHash ?? _baseTree.FindHash(blockNumber); + } + + public BlockHeader[] FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) + { + var overlayHeaders = _overlayTree.FindHeaders(hash, numberOfBlocks, skip, reverse); + return overlayHeaders.Length > 0 ? overlayHeaders : _baseTree.FindHeaders(hash, numberOfBlocks, skip, reverse); + } + + public BlockHeader FindLowestCommonAncestor(BlockHeader firstDescendant, BlockHeader secondDescendant, long maxSearchDepth) + { + var overlayAncestor = _overlayTree.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth); + return overlayAncestor ?? _baseTree.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth); + } + + public void DeleteInvalidBlock(Block invalidBlock) + { + _overlayTree.DeleteInvalidBlock(invalidBlock); + } + + public void ForkChoiceUpdated(Hash256? finalizedBlockHash, Hash256? safeBlockBlockHash) + { + _overlayTree.ForkChoiceUpdated(finalizedBlockHash, safeBlockBlockHash); + } + + // Event forwarding + public event EventHandler NewBestSuggestedBlock + { + add + { + _baseTree.NewBestSuggestedBlock += value; + _overlayTree.NewBestSuggestedBlock += value; + } + remove + { + _baseTree.NewBestSuggestedBlock -= value; + _overlayTree.NewBestSuggestedBlock -= value; + } + } + + public event EventHandler? NewSuggestedBlock + { + add + { + _baseTree.NewSuggestedBlock += value; + _overlayTree.NewSuggestedBlock += value; + } + remove + { + _baseTree.NewSuggestedBlock -= value; + _overlayTree.NewSuggestedBlock -= value; + } + } + + public event EventHandler? BlockAddedToMain + { + add + { + _baseTree.BlockAddedToMain += value; + _overlayTree.BlockAddedToMain += value; + } + remove + { + _baseTree.BlockAddedToMain -= value; + _overlayTree.BlockAddedToMain -= value; + } + } + + public event EventHandler? NewHeadBlock + { + add + { + _baseTree.NewHeadBlock += value; + _overlayTree.NewHeadBlock += value; + } + remove + { + _baseTree.NewHeadBlock -= value; + _overlayTree.NewHeadBlock -= value; + } + } + + public event EventHandler? OnUpdateMainChain + { + add + { + _baseTree.OnUpdateMainChain += value; + _overlayTree.OnUpdateMainChain += value; + } + remove + { + _baseTree.OnUpdateMainChain -= value; + _overlayTree.OnUpdateMainChain -= value; + } + } + + + public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool force = false) + { + return _overlayTree.DeleteChainSlice(startNumber, endNumber, force); + } + + public bool IsBetterThanHead(BlockHeader? header) + { + return _overlayTree.IsBetterThanHead(header) || _baseTree.IsBetterThanHead(header); + } + + public void UpdateBeaconMainChain(BlockInfo[]? blockInfos, long clearBeaconMainChainStartPoint) + { + _overlayTree.UpdateBeaconMainChain(blockInfos, clearBeaconMainChainStartPoint); + } + + public void RecalculateTreeLevels() + { + _overlayTree.RecalculateTreeLevels(); + } + + public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) + { + var overlayBlock = _overlayTree.FindBlock(blockHash, options, blockNumber); + return overlayBlock ?? _baseTree.FindBlock(blockHash, options, blockNumber); + } + + public Block? FindBlock(long blockNumber, BlockTreeLookupOptions options) + { + var overlayBlock = _overlayTree.FindBlock(blockNumber, options); + return overlayBlock ?? _baseTree.FindBlock(blockNumber, options); + } + + public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) + { + var overlayHeader = _overlayTree.FindHeader(blockHash, options, blockNumber); + return overlayHeader ?? _baseTree.FindHeader(blockHash, options, blockNumber); + } + + public BlockHeader? FindHeader(long blockNumber, BlockTreeLookupOptions options) + { + var overlayHeader = _overlayTree.FindHeader(blockNumber, options); + return overlayHeader ?? _baseTree.FindHeader(blockNumber, options); + } + + public Hash256? FindBlockHash(long blockNumber) + { + var overlayBlockHash = _overlayTree.FindBlockHash(blockNumber); + return overlayBlockHash ?? _baseTree.FindBlockHash(blockNumber); + } + + public bool IsMainChain(BlockHeader blockHeader) + { + return _overlayTree.IsMainChain(blockHeader) || _baseTree.IsMainChain(blockHeader); + } + + public bool IsMainChain(Hash256 blockHash) + { + return _overlayTree.IsMainChain(blockHash) || _baseTree.IsMainChain(blockHash); + } + + public BlockHeader FindBestSuggestedHeader() + { + var overlayHeader = _overlayTree.FindBestSuggestedHeader(); + return overlayHeader ?? _baseTree.FindBestSuggestedHeader(); + } + +} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index 44833bebbde..d8601f5d759 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -16,7 +16,6 @@ public class ReadOnlyTxProcessingEnvBase public IStateReader StateReader { get; } public IWorldState StateProvider { get; } public IBlockTree BlockTree { get; } - public IReadOnlyDbProvider DbProvider { get; } public IBlockhashProvider BlockhashProvider { get; } protected ReadOnlyTxProcessingEnvBase( diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index 35e05e8f41c..cfc999ff12c 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -68,16 +68,18 @@ public async Task SetUp() IWorldStateManager readOnlyWorldStateManager = new ReadOnlyWorldStateManager(dbProvider, trieStore, LimboLogs.Instance); + IReadOnlyBlockTree? roBlockTree = _blockTree!.AsReadOnly(); ReadOnlyTxProcessingEnv processingEnv = new( readOnlyWorldStateManager, - new ReadOnlyBlockTree(_blockTree), + roBlockTree, _specProvider, LimboLogs.Instance); MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( false, readOnlyWorldStateManager, - new ReadOnlyDbProvider(_dbProvider, true), + roBlockTree, + new ReadOnlyDbProvider(_dbProvider, true), _specProvider, LimboLogs.Instance); @@ -224,16 +226,17 @@ public void Bridge_head_is_correct(long headNumber) IWorldStateManager readOnlyWorldStateManager = new ReadOnlyWorldStateManager(dbProvider, trieStore, LimboLogs.Instance); - + IReadOnlyBlockTree? roBlockTree = _blockTree!.AsReadOnly(); ReadOnlyTxProcessingEnv processingEnv = new( readOnlyWorldStateManager, - new ReadOnlyBlockTree(_blockTree), + roBlockTree, _specProvider, LimboLogs.Instance); MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( false, readOnlyWorldStateManager, + roBlockTree, new ReadOnlyDbProvider(_dbProvider, true), _specProvider, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 312a64cccaa..20d9193bb0e 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -156,19 +156,19 @@ public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload - Create(traceTransfers, WorldStateManager, DbProvider, SpecProvider, _logManager, doValidation); + Create(traceTransfers, WorldStateManager, ReadOnlyBlockTree, DbProvider, SpecProvider, _logManager, doValidation); + public IReadOnlyDbProvider DbProvider { get; } private MultiCallReadOnlyBlocksProcessingEnv( bool traceTransfers, IWorldStateManager worldStateManager, - //IReadOnlyDbProvider readOnlyDbProvider, + IReadOnlyBlockTree roBlockTree, + IReadOnlyDbProvider readOnlyDbProvider, //ITrieStore trieStore, IBlockTree blockTree, ISpecProvider? specProvider, @@ -88,6 +93,8 @@ private MultiCallReadOnlyBlocksProcessingEnv( bool doValidation = false) : base(worldStateManager, blockTree, logManager) { + ReadOnlyBlockTree = roBlockTree; + DbProvider = readOnlyDbProvider; //_trieStore = trieStore; WorldStateManager = worldStateManager; _logManager = logManager; @@ -113,6 +120,8 @@ private MultiCallReadOnlyBlocksProcessingEnv( _blockValidator = new MultiCallBlockValidatorProxy(blockValidator); } + public IReadOnlyBlockTree ReadOnlyBlockTree { get; set; } + public IBlockProcessor GetProcessor(Hash256 stateRoot) { //StateProvider.StateRoot = stateRoot; diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs index 9ba2bb20688..7be99e8f458 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs @@ -179,16 +179,16 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction stateProvider.RecalculateStateRoot(); Block[]? currentBlocks = null; - try + //try { IBlockProcessor? processor = env.GetProcessor(currentBlock.StateRoot!); currentBlocks = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer); } - catch (Exception) - { - return (false, $"invalid on block {callHeader.Number}"); - } + //catch (Exception) + //{ + // return (false, $"invalid on block {callHeader.Number}"); + //} Block? processedBlock = currentBlocks[0]; parent = processedBlock.Header; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 034d734f05d..e9853e0fe74 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -95,6 +95,7 @@ public async Task Test_eth_multicall_serialisation() //Force persistancy of head block in main chain chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); + //Assert.Equals(chain.BlockTree.BestPersistedState!, chain.BlockTree.Head!.Number); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper> result = diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 532585d460b..058effc0dbb 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -124,16 +124,17 @@ protected override async Task Build(ISpecProvider? specProvider IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = new FilterManager(filterStore, BlockProcessor, TxPool, LimboLogs.Instance); var dbProvider = new ReadOnlyDbProvider(DbProvider, false); - + IReadOnlyBlockTree? roBlockTree = BlockTree!.AsReadOnly(); ReadOnlyTxProcessingEnv processingEnv = new( WorldStateManager, - new ReadOnlyBlockTree(BlockTree), + roBlockTree, SpecProvider, LimboLogs.Instance); MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( false, WorldStateManager, + roBlockTree, new ReadOnlyDbProvider(dbProvider, true), SpecProvider, LimboLogs.Instance); From 465baeebca727cc0a7c214153595bb08f46971c3 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Thu, 18 Jan 2024 14:25:30 +0100 Subject: [PATCH 112/213] reset submodule --- src/bench_precompiles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bench_precompiles b/src/bench_precompiles index 9c9705ed4e7..d083d17d367 160000 --- a/src/bench_precompiles +++ b/src/bench_precompiles @@ -1 +1 @@ -Subproject commit 9c9705ed4e7f264abc8f343a848016e7bf6501b3 +Subproject commit d083d17d3679b82585877a2d18829535d972546a From a85c00d401ac0e51c41fbb1c8a81cdd689bc362a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Fri, 19 Jan 2024 11:46:46 +0000 Subject: [PATCH 113/213] fixed serialisation tests added UInt256DictionaryKeyConverter for Dictionary support (now for System.Text.Json) --- .../UInt256DictionaryKeyConverterTests.cs | 129 ++++++++++++++++++ .../EthMulticallTestsBlocksAndTransactions.cs | 2 +- ...ithSpecialUInt256KeyHash256ValConverter.cs | 90 ------------ .../EthereumJsonSerializer.cs | 3 +- .../UInt256DictionaryKeyConverter.cs | 108 +++++++++++++++ 5 files changed, 239 insertions(+), 93 deletions(-) create mode 100644 src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs delete mode 100644 src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyHash256ValConverter.cs create mode 100644 src/Nethermind/Nethermind.Serialization.Json/UInt256DictionaryKeyConverter.cs diff --git a/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs new file mode 100644 index 00000000000..e9aca786453 --- /dev/null +++ b/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs @@ -0,0 +1,129 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using System.Text.Json; +using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; +using Nethermind.Int256; +using Nethermind.Serialization.Json; +using NUnit.Framework; + +namespace Nethermind.Core.Test.Json; + +[TestFixture] +public class UInt256DictionaryKeyConverterTests +{ + private static readonly JsonSerializerOptions Options = new() + { Converters = { + new LongConverter(), + new UInt256Converter(), + new ULongConverter(), + new IntConverter(), + new ByteArrayConverter(), + new NullableLongConverter(), + new NullableULongConverter(), + new NullableUInt256Converter(), + new NullableIntConverter(), + new TxTypeConverter(), + new DoubleConverter(), + new DoubleArrayConverter(), + new BooleanConverter(), + new DictionaryAddressKeyConverter(), + new MemoryByteConverter(), + new BigIntegerConverter(), + new NullableBigIntegerConverter(), + new JavaScriptObjectConverter(), + new UInt256DictionaryKeyConverter () + } }; + + [Test] + public void ReadJson_NestedValidJson_ReturnsCorrectDictionary() + { + string json = @"{ + ""blockStateCalls"": [ + { + ""stateOverrides"": { + ""0xc100000000000000000000000000000000000000"": { + ""state"": { + ""0x0000000000000000000000000000000000000000000000000000000000000000"": ""0x1200000000000000000000000000000000000000000000000000000000000000"" + } + } + } + } + ] + }"; + + var result = JsonSerializer.Deserialize< + Dictionary + > + > + > + >> + >(json, Options); + + Assert.That(result, Is.Not.Null); + + // Check for correct top-level key + Assert.IsTrue(result!.ContainsKey("blockStateCalls")); + // Additional assertions to check the structure and data of the nested dictionaries + var blockStateCalls = result["blockStateCalls"]; + Assert.IsNotNull(blockStateCalls); + Assert.IsTrue(1 == blockStateCalls.Count); + + var stateOverrides = blockStateCalls[0]; + Assert.IsNotNull(stateOverrides); + Assert.IsTrue(stateOverrides.ContainsKey("stateOverrides")); + + var stateOverridesContents = stateOverrides["stateOverrides"]; + var soKey = Bytes.FromHexString("0xc100000000000000000000000000000000000000").ToUInt256(); ; + var state = stateOverridesContents[soKey]; + Assert.IsNotNull(state); + Assert.IsTrue(state.ContainsKey("state")); + + var stateInner = state["state"]; + var key = Bytes.FromHexString("0x0000000000000000000000000000000000000000").ToUInt256(); + var hashValue = stateInner[key]; + Assert.IsTrue("0x1200000000000000000000000000000000000000000000000000000000000000" == hashValue.ToString()); + } + + [Test] + public void CanConvert_ValidDictionary_ReturnsTrue() + { + bool canConvert = new UInt256DictionaryKeyConverter().CanConvert(typeof(Dictionary)); + Assert.IsTrue(canConvert); + } + + [Test] + public void ReadJson_NullJson_ReturnsNull() + { + Dictionary? result = JsonSerializer.Deserialize>("null", Options); + Assert.That(result, Is.Null); + } + + [Test] + public void ReadJson_EmptyObject_ReturnsEmptyDictionary() + { + Dictionary? result = JsonSerializer.Deserialize>("{}", Options); + Assert.That(result, Is.Not.Null); + Assert.That(result, Is.Empty); + } + + [Test] + public void WriteJson_Dictionary_ThrowsNotSupportedException() + { + var dictionary = new Dictionary + { + { new UInt256(1), new Hash256("0x0000000000000000000000000000000000000000000000000000000000000002") } + }; + var serialised = JsonSerializer.Serialize(dictionary, Options); + var deserialised = JsonSerializer.Deserialize>(serialised, Options); + + Assert.IsTrue(deserialised!.ContainsKey(new UInt256(1))); + Assert.IsTrue(deserialised!.ContainsValue(new Hash256("0x0000000000000000000000000000000000000000000000000000000000000002"))); + } +} diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index e9853e0fe74..8d8283a8627 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -54,7 +54,7 @@ public async Task Test_eth_multicall_serialisation() GetTransferTxData(nonceA, chain.EthereumEcdsa, pk, new Address("0xA143c0eA6f8059f7B3651417ccD2bAA80FC2d4Ab"), 10_000_000); - UInt256 nextNonceA = nonceA++; + UInt256 nextNonceA = ++nonceA; Transaction txMainnetAtoBToComplete = GetTransferTxData(nextNonceA, chain.EthereumEcdsa, pk, new Address("0xA143c0eA6f8059f7B3651417ccD2bAA80FC2d4Ab"), 4_000_000); diff --git a/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyHash256ValConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyHash256ValConverter.cs deleted file mode 100644 index 474c5643f95..00000000000 --- a/src/Nethermind/Nethermind.Serialization.Json/DictionaryWithSpecialUInt256KeyHash256ValConverter.cs +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Numerics; -using Nethermind.Core.Crypto; -using Nethermind.Int256; -using Newtonsoft.Json; - -namespace Nethermind.Serialization.Json.Nethermind.Serialization.Json; - -public class DictionaryWithSpecialUInt256KeyHash256ValConverter : JsonConverter -{ - public static bool IsType(Type type, Type typeToBe) - { - - if (!typeToBe.IsGenericTypeDefinition) - return typeToBe.IsAssignableFrom(type); - - List toCheckTypes = new() { type }; - if (typeToBe.IsInterface) - toCheckTypes.AddRange(type.GetInterfaces()); - - Type basedOn = type; - while (basedOn.BaseType != null) - { - toCheckTypes.Add(basedOn.BaseType); - basedOn = basedOn.BaseType; - } - - return toCheckTypes.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeToBe); - } - - public override bool CanWrite - { - get { return false; } - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotSupportedException(); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - // Assuming the keys in JSON are strings, and the Address type has a suitable Parse or TryParse method - Type valueType = objectType.GetGenericArguments()[1]; - Type intermediateDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeof(string), typeof(string)); - IDictionary intermediateDictionary = (IDictionary)Activator.CreateInstance(intermediateDictionaryType); - serializer.Populate(reader, intermediateDictionary); - - IDictionary finalDictionary = (IDictionary)Activator.CreateInstance(objectType); - foreach (DictionaryEntry pair in intermediateDictionary) - { - string keyData = pair.Key.ToString(); - UInt256 key = keyData.StartsWith("0x", StringComparison.OrdinalIgnoreCase) - ? (UInt256)BigInteger.Parse(keyData.Substring(2), NumberStyles.HexNumber) - : UInt256.Parse(keyData); - - string valueData = pair.Value.ToString(); - Hash256 val = new(valueData); - - finalDictionary.Add(key, val); - } - - return finalDictionary; - } - - public override bool CanConvert(Type objectType) - { - bool isDict = IsType(objectType, typeof(IDictionary<,>)); - if (!isDict) return false; - - var args = objectType.GetGenericArguments(); - if (args.Length < 2) return false; - - bool isKeyUint256 = IsType(args[0], typeof(UInt256)); - if (!isKeyUint256) return false; - - bool isValValueKeccak = IsType(args[1], typeof(Hash256)); - return isValValueKeccak; - } -} diff --git a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs index 89b3a00b03b..51f48d3b10d 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs @@ -8,7 +8,6 @@ using System.IO.Pipelines; using System.Text.Json; using System.Text.Json.Serialization; -using System.Threading; using System.Threading.Tasks; namespace Nethermind.Serialization.Json @@ -80,7 +79,7 @@ private static JsonSerializerOptions CreateOptions(bool indented, int maxDepth = new BigIntegerConverter(), new NullableBigIntegerConverter(), new JavaScriptObjectConverter(), - //TODO check new DictionaryWithSpecialUInt256KeyHash256ValConverter() + new UInt256DictionaryKeyConverter() } }; diff --git a/src/Nethermind/Nethermind.Serialization.Json/UInt256DictionaryKeyConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/UInt256DictionaryKeyConverter.cs new file mode 100644 index 00000000000..f36acfdd914 --- /dev/null +++ b/src/Nethermind/Nethermind.Serialization.Json/UInt256DictionaryKeyConverter.cs @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization; +using Nethermind.Int256; + +namespace Nethermind.Serialization.Json; + +public class UInt256DictionaryKeyConverter : JsonConverterFactory +{ + public override bool CanConvert(Type typeToConvert) + { + // Check if this converter can convert the given type + return typeToConvert.IsGenericType && + typeToConvert.GetGenericTypeDefinition() == typeof(Dictionary<,>) && + typeToConvert.GetGenericArguments()[0] == typeof(UInt256); + } + + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + Type valueType = typeToConvert.GetGenericArguments()[1]; + JsonConverter converter = (JsonConverter)Activator.CreateInstance( + typeof(UInt256DictionaryConverter<>).MakeGenericType(valueType), + BindingFlags.Instance | BindingFlags.Public, + binder: null, + args: new object[] { options }, + culture: null)!; + + return converter; + } + + private class UInt256DictionaryConverter : JsonConverter> + { + private readonly JsonConverter _valueConverter; + private readonly Type _valueType; + + public UInt256DictionaryConverter(JsonSerializerOptions options) + { + // For performance, use existing converter if available + _valueType = typeof(TValue); + _valueConverter = (JsonConverter)options.GetConverter(typeof(TValue)); + } + + public override Dictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + { + throw new JsonException(); + } + + var dictionary = new Dictionary(); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + return dictionary; + } + + // Assume the key is a string and convert it to UInt256 + string keyString = reader.GetString()!; + UInt256 key = UInt256.Parse(keyString); + + reader.Read(); + + TValue value; + + if (_valueConverter != null) + { + value = _valueConverter.Read(ref reader, _valueType, options)!; + } + else + { + value = JsonSerializer.Deserialize(ref reader, options)!; + } + + dictionary[key] = value; + } + + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, Dictionary dictionary, JsonSerializerOptions options) + { + writer.WriteStartObject(); + + foreach (KeyValuePair kvp in dictionary) + { + writer.WritePropertyName(kvp.Key.ToString()); + + if (_valueConverter != null) + { + _valueConverter.Write(writer, kvp.Value, options); + } + else + { + JsonSerializer.Serialize(writer, kvp.Value, options); + } + } + + writer.WriteEndObject(); + } + } +} From 6d53c5775a2b338e15048de34428ef00fa0d4310 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jan 2024 13:35:12 +0100 Subject: [PATCH 114/213] Add OverlayTrieStore and OverlayWorldStateManager --- .../MultiCallReadOnlyBlocksProcessingEnv.cs | 6 ++-- .../Nethermind.State/IWorldStateManager.cs | 1 + .../OverlayWorldStateManager.cs | 33 +++++++++++++++++ .../ReadOnlyWorldStateManager.cs | 18 ++++------ .../Nethermind.State/WorldStateManager.cs | 5 ++- .../Pruning/ITrieNodeResolver.cs | 10 +++--- .../Pruning/NullTrieNodeResolver.cs | 2 ++ .../Nethermind.Trie/Pruning/NullTrieStore.cs | 1 + .../Pruning/OverlayTrieStore.cs | 30 ++++++++++++++++ .../Pruning/ReadOnlyTrieStore.cs | 2 ++ .../Nethermind.Trie/Pruning/TrieStore.cs | 4 +-- .../TrieNodeResolverWithReadFlags.cs | 36 ++++++++----------- 12 files changed, 105 insertions(+), 43 deletions(-) create mode 100644 src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs create mode 100644 src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs index d0ba98f536e..7c3deef7286 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs @@ -45,7 +45,8 @@ public static MultiCallReadOnlyBlocksProcessingEnv Create( bool doValidation = false) { IReadOnlyDbProvider dbProvider = new ReadOnlyDbProvider(readOnlyDbProvider, true); - TrieStore trieStore = new(readOnlyDbProvider.StateDb, logManager); + OverlayTrieStore overlayTrieStore = new(dbProvider.StateDb, worldStateManager.TrieStore, logManager); + OverlayWorldStateManager overlayWorldStateManager = new(worldStateManager, dbProvider, overlayTrieStore, logManager); IBlockStore blockStore = new BlockStore(dbProvider.BlocksDb); IHeaderStore headerStore = new HeaderStore(dbProvider.HeadersDb, dbProvider.BlockNumbersDb); @@ -66,7 +67,7 @@ public static MultiCallReadOnlyBlocksProcessingEnv Create( return new MultiCallReadOnlyBlocksProcessingEnv( traceTransfers, - worldStateManager, + overlayWorldStateManager, roBlockTree, dbProvider, //trieStore, @@ -144,4 +145,5 @@ public void Dispose() //_trieStore.Dispose(); DbProvider.Dispose(); } + } diff --git a/src/Nethermind/Nethermind.State/IWorldStateManager.cs b/src/Nethermind/Nethermind.State/IWorldStateManager.cs index 26a01d09f67..1a34a8f8415 100644 --- a/src/Nethermind/Nethermind.State/IWorldStateManager.cs +++ b/src/Nethermind/Nethermind.State/IWorldStateManager.cs @@ -10,6 +10,7 @@ public interface IWorldStateManager { IWorldState GlobalWorldState { get; } IStateReader GlobalStateReader { get; } + IReadOnlyTrieStore TrieStore { get; } /// /// Used by read only tasks that need to execute blocks. diff --git a/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs b/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs new file mode 100644 index 00000000000..140eb2663af --- /dev/null +++ b/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Db; +using Nethermind.Logging; +using Nethermind.Trie.Pruning; + +namespace Nethermind.State; + +public class OverlayWorldStateManager( + IWorldStateManager worldStateManager, + IReadOnlyDbProvider dbProvider, + OverlayTrieStore overlayTrieStore, + ILogManager? logManager) + : IWorldStateManager +{ + private readonly IDb _codeDb = dbProvider.GetDb(DbNames.Code); + + public IWorldState GlobalWorldState => worldStateManager.GlobalWorldState; + + public IStateReader GlobalStateReader => worldStateManager.GlobalStateReader; + + public IReadOnlyTrieStore TrieStore { get; } = overlayTrieStore.AsReadOnly(); + + public IWorldState CreateResettableWorldState() => new WorldState(overlayTrieStore, _codeDb, logManager); + + public event EventHandler? ReorgBoundaryReached + { + add => overlayTrieStore.ReorgBoundaryReached += value; + remove => overlayTrieStore.ReorgBoundaryReached -= value; + } +} diff --git a/src/Nethermind/Nethermind.State/ReadOnlyWorldStateManager.cs b/src/Nethermind/Nethermind.State/ReadOnlyWorldStateManager.cs index f4bdd53a19a..f608e1db842 100644 --- a/src/Nethermind/Nethermind.State/ReadOnlyWorldStateManager.cs +++ b/src/Nethermind/Nethermind.State/ReadOnlyWorldStateManager.cs @@ -14,24 +14,21 @@ namespace Nethermind.State; /// public class ReadOnlyWorldStateManager : IWorldStateManager { - private readonly IReadOnlyDbProvider _readOnlyDbProvider; - private readonly IReadOnlyTrieStore? _readOnlyTrieStore; + private readonly IReadOnlyTrieStore _readOnlyTrieStore; private readonly ILogManager _logManager; - private readonly IDbProvider _dbProvider; private readonly ReadOnlyDb _codeDb; public ReadOnlyWorldStateManager( IDbProvider dbProvider, - IReadOnlyTrieStore? readOnlyTrieStore, + IReadOnlyTrieStore readOnlyTrieStore, ILogManager logManager ) { _readOnlyTrieStore = readOnlyTrieStore; - _dbProvider = dbProvider; _logManager = logManager; - _readOnlyDbProvider = _dbProvider.AsReadOnly(false); - _codeDb = _readOnlyDbProvider.GetDb(DbNames.Code).AsReadOnly(true); + IReadOnlyDbProvider readOnlyDbProvider = dbProvider.AsReadOnly(false); + _codeDb = readOnlyDbProvider.GetDb(DbNames.Code).AsReadOnly(true); GlobalStateReader = new StateReader(_readOnlyTrieStore, _codeDb, _logManager); } @@ -39,10 +36,9 @@ ILogManager logManager public IStateReader GlobalStateReader { get; } - public IWorldState CreateResettableWorldState() - { - return new WorldState(_readOnlyTrieStore, _codeDb, _logManager); - } + public IReadOnlyTrieStore TrieStore => _readOnlyTrieStore; + + public IWorldState CreateResettableWorldState() => new WorldState(_readOnlyTrieStore, _codeDb, _logManager); public virtual event EventHandler? ReorgBoundaryReached { diff --git a/src/Nethermind/Nethermind.State/WorldStateManager.cs b/src/Nethermind/Nethermind.State/WorldStateManager.cs index cfb570a8daa..2b87aa80e16 100644 --- a/src/Nethermind/Nethermind.State/WorldStateManager.cs +++ b/src/Nethermind/Nethermind.State/WorldStateManager.cs @@ -10,7 +10,6 @@ namespace Nethermind.State; public class WorldStateManager : ReadOnlyWorldStateManager { - private readonly IWorldState _worldState; private readonly ITrieStore _trieStore; public WorldStateManager( @@ -20,11 +19,11 @@ public WorldStateManager( ILogManager logManager ) : base(dbProvider, trieStore.AsReadOnly(), logManager) { - _worldState = worldState; + GlobalWorldState = worldState; _trieStore = trieStore; } - public override IWorldState GlobalWorldState => _worldState; + public override IWorldState GlobalWorldState { get; } public override event EventHandler? ReorgBoundaryReached { diff --git a/src/Nethermind/Nethermind.Trie/Pruning/ITrieNodeResolver.cs b/src/Nethermind/Nethermind.Trie/Pruning/ITrieNodeResolver.cs index 3773cb26104..bae0c078833 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/ITrieNodeResolver.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/ITrieNodeResolver.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -20,15 +21,16 @@ public interface ITrieNodeResolver /// /// Loads RLP of the node. /// - /// - /// byte[]? LoadRlp(Hash256 hash, ReadFlags flags = ReadFlags.None); /// /// Loads RLP of the node. /// - /// - /// byte[]? TryLoadRlp(Hash256 hash, ReadFlags flags = ReadFlags.None); + + /// + /// Loads RLP of the node. + /// + byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None); } } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/NullTrieNodeResolver.cs b/src/Nethermind/Nethermind.Trie/Pruning/NullTrieNodeResolver.cs index 5856ac64bb4..e283e8be7e2 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/NullTrieNodeResolver.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/NullTrieNodeResolver.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -15,5 +16,6 @@ private NullTrieNodeResolver() { } public TrieNode FindCachedOrUnknown(Hash256 hash) => new(NodeType.Unknown, hash); public byte[]? LoadRlp(Hash256 hash, ReadFlags flags = ReadFlags.None) => null; public byte[]? TryLoadRlp(Hash256 hash, ReadFlags flags = ReadFlags.None) => null; + public byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) => null; } } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/NullTrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/NullTrieStore.cs index 55f77dc2b40..cac5ed2a31a 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/NullTrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/NullTrieStore.cs @@ -30,6 +30,7 @@ public event EventHandler ReorgBoundaryReached public TrieNode FindCachedOrUnknown(Hash256 hash) => new(NodeType.Unknown, hash); public byte[] TryLoadRlp(Hash256 hash, ReadFlags flags = ReadFlags.None) => null; + public byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) => null; public byte[] LoadRlp(Hash256 hash, ReadFlags flags = ReadFlags.None) => Array.Empty(); diff --git a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs new file mode 100644 index 00000000000..d0db76ca06e --- /dev/null +++ b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Logging; + +namespace Nethermind.Trie.Pruning; + +public class OverlayTrieStore : TrieStore +{ + private readonly IReadOnlyTrieStore _store; + + public OverlayTrieStore(IKeyValueStoreWithBatching? keyValueStore, IReadOnlyTrieStore store, ILogManager? logManager) : base(keyValueStore, logManager) + { + _store = store; + } + + public override TrieNode FindCachedOrUnknown(Hash256? hash) => _store.FindCachedOrUnknown(hash); + + public override byte[] LoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) => + _store.TryLoadRlp(keccak, readFlags) ?? base.LoadRlp(keccak, readFlags); + + public override byte[]? TryLoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) => + _store.TryLoadRlp(keccak, readFlags) ?? base.TryLoadRlp(keccak, readFlags); + + public override byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) => + _store.GetByHash(key, flags) ?? base.GetByHash(key, flags); +} diff --git a/src/Nethermind/Nethermind.Trie/Pruning/ReadOnlyTrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/ReadOnlyTrieStore.cs index 86710b26720..f0b7cc2966c 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/ReadOnlyTrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/ReadOnlyTrieStore.cs @@ -27,6 +27,8 @@ public TrieNode FindCachedOrUnknown(Hash256 hash) => _trieStore.FindCachedOrUnknown(hash, true); public byte[]? TryLoadRlp(Hash256 hash, ReadFlags flags) => _trieStore.TryLoadRlp(hash, _readOnlyStore, flags); + public byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) => _trieStore.GetByHash(key, flags); + public byte[] LoadRlp(Hash256 hash, ReadFlags flags) => _trieStore.LoadRlp(hash, _readOnlyStore, flags); public bool IsPersisted(in ValueHash256 keccak) => _trieStore.IsPersisted(keccak); diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs index ec18d0c4ec6..f9e17e5b5ad 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs @@ -370,7 +370,7 @@ public IReadOnlyTrieStore AsReadOnly(IKeyValueStore? keyValueStore) public bool IsNodeCached(Hash256 hash) => _dirtyNodes.IsNodeCached(hash); - public TrieNode FindCachedOrUnknown(Hash256? hash) + public virtual TrieNode FindCachedOrUnknown(Hash256? hash) { return FindCachedOrUnknown(hash, false); } @@ -822,7 +822,7 @@ void PersistNode(TrieNode n) }); } - private byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) + public virtual byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) { return _pruningStrategy.PruningEnabled && _dirtyNodes.AllNodes.TryGetValue(new ValueHash256(key), out TrieNode? trieNode) diff --git a/src/Nethermind/Nethermind.Trie/TrieNodeResolverWithReadFlags.cs b/src/Nethermind/Nethermind.Trie/TrieNodeResolverWithReadFlags.cs index 5f96323bf22..b370770fcd9 100644 --- a/src/Nethermind/Nethermind.Trie/TrieNodeResolverWithReadFlags.cs +++ b/src/Nethermind/Nethermind.Trie/TrieNodeResolverWithReadFlags.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Trie.Pruning; @@ -18,28 +19,21 @@ public TrieNodeResolverWithReadFlags(ITrieStore baseResolver, ReadFlags defaultF _defaultFlags = defaultFlags; } - public TrieNode FindCachedOrUnknown(Hash256 hash) - { - return _baseResolver.FindCachedOrUnknown(hash); - } + public TrieNode FindCachedOrUnknown(Hash256 hash) => + _baseResolver.FindCachedOrUnknown(hash); - public byte[]? TryLoadRlp(Hash256 hash, ReadFlags flags = ReadFlags.None) - { - if (flags != ReadFlags.None) - { - return _baseResolver.TryLoadRlp(hash, flags | _defaultFlags); - } + public byte[]? TryLoadRlp(Hash256 hash, ReadFlags flags = ReadFlags.None) => + flags != ReadFlags.None + ? _baseResolver.TryLoadRlp(hash, flags | _defaultFlags) + : _baseResolver.TryLoadRlp(hash, _defaultFlags); - return _baseResolver.TryLoadRlp(hash, _defaultFlags); - } + public byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) => + flags != ReadFlags.None + ? _baseResolver.GetByHash(key, flags | _defaultFlags) + : _baseResolver.GetByHash(key, _defaultFlags); - public byte[]? LoadRlp(Hash256 hash, ReadFlags flags = ReadFlags.None) - { - if (flags != ReadFlags.None) - { - return _baseResolver.LoadRlp(hash, flags | _defaultFlags); - } - - return _baseResolver.LoadRlp(hash, _defaultFlags); - } + public byte[]? LoadRlp(Hash256 hash, ReadFlags flags = ReadFlags.None) => + flags != ReadFlags.None + ? _baseResolver.LoadRlp(hash, flags | _defaultFlags) + : _baseResolver.LoadRlp(hash, _defaultFlags); } From 687a460f689c9c1657de7e34b79681e2c8dc9c6f Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jan 2024 13:36:54 +0100 Subject: [PATCH 115/213] fix test --- .../Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 8d8283a8627..9714072f9b1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -106,7 +106,7 @@ public async Task Test_eth_multicall_serialisation() foreach (MultiCallBlockResult blockResult in data) { - blockResult.Calls.Select(c => c.Type).Should().BeEquivalentTo(new[] { ResultType.Failure, ResultType.Success }); + blockResult.Calls.Select(c => c.Type).Should().BeEquivalentTo(new[] { ResultType.Success, ResultType.Success }); } } From 277cc4ff59e51a53efb91db6002ec0612a3a67ed Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 19 Jan 2024 14:47:46 +0100 Subject: [PATCH 116/213] Add UInt256 property conversion (for Dictionary key) --- .../AccountAbstractionRpcModuleTests.cs | 2 - .../UInt256DictionaryKeyConverterTests.cs | 51 ++++----- .../Nethermind.Core/ByteArrayConverter.cs | 3 +- .../EthereumJsonSerializer.cs | 26 ++--- .../UInt256Converter.cs | 36 +++++- .../UInt256DictionaryKeyConverter.cs | 108 ------------------ 6 files changed, 66 insertions(+), 160 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Serialization.Json/UInt256DictionaryKeyConverter.cs diff --git a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.cs b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.cs index b9b1e0947dd..1620353362a 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.cs @@ -22,8 +22,6 @@ using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Test.Modules; using Nethermind.Logging; - -using Newtonsoft.Json.Linq; using NUnit.Framework; namespace Nethermind.AccountAbstraction.Test; diff --git a/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs index e9aca786453..450848baf10 100644 --- a/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs @@ -15,27 +15,29 @@ namespace Nethermind.Core.Test.Json; public class UInt256DictionaryKeyConverterTests { private static readonly JsonSerializerOptions Options = new() - { Converters = { - new LongConverter(), - new UInt256Converter(), - new ULongConverter(), - new IntConverter(), - new ByteArrayConverter(), - new NullableLongConverter(), - new NullableULongConverter(), - new NullableUInt256Converter(), - new NullableIntConverter(), - new TxTypeConverter(), - new DoubleConverter(), - new DoubleArrayConverter(), - new BooleanConverter(), - new DictionaryAddressKeyConverter(), - new MemoryByteConverter(), - new BigIntegerConverter(), - new NullableBigIntegerConverter(), - new JavaScriptObjectConverter(), - new UInt256DictionaryKeyConverter () - } }; + { + Converters = + { + new LongConverter(), + new UInt256Converter(), + new ULongConverter(), + new IntConverter(), + new ByteArrayConverter(), + new NullableLongConverter(), + new NullableULongConverter(), + new NullableUInt256Converter(), + new NullableIntConverter(), + new TxTypeConverter(), + new DoubleConverter(), + new DoubleArrayConverter(), + new BooleanConverter(), + new DictionaryAddressKeyConverter(), + new MemoryByteConverter(), + new BigIntegerConverter(), + new NullableBigIntegerConverter(), + new JavaScriptObjectConverter() + } + }; [Test] public void ReadJson_NestedValidJson_ReturnsCorrectDictionary() @@ -91,13 +93,6 @@ public void ReadJson_NestedValidJson_ReturnsCorrectDictionary() Assert.IsTrue("0x1200000000000000000000000000000000000000000000000000000000000000" == hashValue.ToString()); } - [Test] - public void CanConvert_ValidDictionary_ReturnsTrue() - { - bool canConvert = new UInt256DictionaryKeyConverter().CanConvert(typeof(Dictionary)); - Assert.IsTrue(canConvert); - } - [Test] public void ReadJson_NullJson_ReturnsNull() { diff --git a/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs b/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs index d9c148e7422..be6229107f9 100644 --- a/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs +++ b/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs @@ -96,7 +96,7 @@ public static void Convert(Utf8JsonWriter writer, ReadOnlySpan bytes, bool array = ArrayPool.Shared.Rent(length); } - Span hex = (array is null ? stackalloc byte[stackLength] : array)[..length]; + Span hex = (array ?? stackalloc byte[stackLength])[..length]; hex[^1] = (byte)'"'; hex[0] = (byte)'"'; hex[1] = (byte)'0'; @@ -104,7 +104,6 @@ public static void Convert(Utf8JsonWriter writer, ReadOnlySpan bytes, bool Span output = hex[3..^1]; - bool extraNibble = (leadingNibbleZeros & 1) != 0; ReadOnlySpan input = bytes.Slice(leadingNibbleZeros / 2); input.OutputBytesToByteHex(output, extraNibble: (leadingNibbleZeros & 1) != 0); writer.WriteRawValue(hex, skipInputValidation: true); diff --git a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs index 51f48d3b10d..f1d1e746742 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs @@ -18,14 +18,7 @@ public class EthereumJsonSerializer : IJsonSerializer public EthereumJsonSerializer(int? maxDepth = null) { - if (maxDepth.HasValue) - { - _jsonOptions = CreateOptions(indented: false, maxDepth.Value); - } - else - { - _jsonOptions = JsonOptions; - } + _jsonOptions = maxDepth.HasValue ? CreateOptions(indented: false, maxDepth.Value) : JsonOptions; } public T Deserialize(Stream stream) @@ -45,7 +38,7 @@ public T Deserialize(ref Utf8JsonReader json) public string Serialize(T value, bool indented = false) { - return JsonSerializer.Serialize(value, indented ? JsonOptionsIndented : _jsonOptions); + return JsonSerializer.Serialize(value, indented ? JsonOptionsIndented : _jsonOptions); } private static JsonSerializerOptions CreateOptions(bool indented, int maxDepth = 64) @@ -78,12 +71,11 @@ private static JsonSerializerOptions CreateOptions(bool indented, int maxDepth = new MemoryByteConverter(), new BigIntegerConverter(), new NullableBigIntegerConverter(), - new JavaScriptObjectConverter(), - new UInt256DictionaryKeyConverter() + new JavaScriptObjectConverter() } }; - foreach (var converter in _additionalConverters) + foreach (JsonConverter converter in _additionalConverters) { options.Converters.Add(converter); } @@ -104,17 +96,17 @@ public static void AddConverter(JsonConverter converter) public static JsonSerializerOptions JsonOptionsIndented { get; private set; } = CreateOptions(indented: true); - private static readonly StreamPipeWriterOptions optionsLeaveOpen = new(pool: MemoryPool.Shared, minimumBufferSize: 4096, leaveOpen: true); - private static readonly StreamPipeWriterOptions options = new(pool: MemoryPool.Shared, minimumBufferSize: 4096, leaveOpen: false); + private static readonly StreamPipeWriterOptions _optionsLeaveOpen = new(pool: MemoryPool.Shared, minimumBufferSize: 4096, leaveOpen: true); + private static readonly StreamPipeWriterOptions _options = new(pool: MemoryPool.Shared, minimumBufferSize: 4096, leaveOpen: false); private static CountingStreamPipeWriter GetPipeWriter(Stream stream, bool leaveOpen) { - return new CountingStreamPipeWriter(stream, leaveOpen ? optionsLeaveOpen : options); + return new CountingStreamPipeWriter(stream, leaveOpen ? _optionsLeaveOpen : _options); } public long Serialize(Stream stream, T value, bool indented = false, bool leaveOpen = true) { - var countingWriter = GetPipeWriter(stream, leaveOpen); + CountingStreamPipeWriter countingWriter = GetPipeWriter(stream, leaveOpen); using var writer = new Utf8JsonWriter(countingWriter, new JsonWriterOptions() { SkipValidation = true, Indented = indented }); JsonSerializer.Serialize(writer, value, indented ? JsonOptionsIndented : _jsonOptions); countingWriter.Complete(); @@ -125,7 +117,7 @@ public long Serialize(Stream stream, T value, bool indented = false, bool lea public async ValueTask SerializeAsync(Stream stream, T value, bool indented = false, bool leaveOpen = true) { - var writer = GetPipeWriter(stream, leaveOpen); + CountingStreamPipeWriter writer = GetPipeWriter(stream, leaveOpen); Serialize(writer, value, indented); await writer.CompleteAsync(); diff --git a/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs b/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs index 7b52ca4b9d2..2564d18b01d 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs @@ -22,13 +22,16 @@ public class UInt256Converter : JsonConverter public override UInt256 Read( ref Utf8JsonReader reader, Type typeToConvert, - JsonSerializerOptions options) + JsonSerializerOptions options) => + ReadInternal(ref reader, JsonTokenType.String); + + private static UInt256 ReadInternal(ref Utf8JsonReader reader, JsonTokenType allowedTokenType) { if (reader.TokenType == JsonTokenType.Number) { - return (UInt256)reader.GetUInt64(); + return reader.GetUInt64(); } - if (reader.TokenType != JsonTokenType.String) + if (reader.TokenType != allowedTokenType) { ThrowJsonException(); } @@ -95,6 +98,33 @@ public override void Write( } } + public override UInt256 ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + ReadInternal(ref reader, JsonTokenType.PropertyName); + + public override void WriteAsPropertyName(Utf8JsonWriter writer, UInt256 value, JsonSerializerOptions options) + { + if (value.IsZero) + { + writer.WritePropertyName("\"0x0\""); + return; + } + NumberConversion usedConversion = ForcedNumberConversion.GetFinalConversion(); + switch (usedConversion) + { + case NumberConversion.Hex: + writer.WritePropertyName(value.ToHexString(false)); + break; + case NumberConversion.Decimal: + writer.WritePropertyName(value.ToString(CultureInfo.InvariantCulture)); + break; + case NumberConversion.Raw: + writer.WritePropertyName(((BigInteger)value).ToString(CultureInfo.InvariantCulture)); + break; + default: + throw new NotSupportedException($"{usedConversion} format is not supported for {nameof(UInt256)}"); + } + } + [DoesNotReturn] [StackTraceHidden] private static void ThrowJsonException() diff --git a/src/Nethermind/Nethermind.Serialization.Json/UInt256DictionaryKeyConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/UInt256DictionaryKeyConverter.cs deleted file mode 100644 index f36acfdd914..00000000000 --- a/src/Nethermind/Nethermind.Serialization.Json/UInt256DictionaryKeyConverter.cs +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text.Json; -using System.Text.Json.Serialization; -using Nethermind.Int256; - -namespace Nethermind.Serialization.Json; - -public class UInt256DictionaryKeyConverter : JsonConverterFactory -{ - public override bool CanConvert(Type typeToConvert) - { - // Check if this converter can convert the given type - return typeToConvert.IsGenericType && - typeToConvert.GetGenericTypeDefinition() == typeof(Dictionary<,>) && - typeToConvert.GetGenericArguments()[0] == typeof(UInt256); - } - - public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) - { - Type valueType = typeToConvert.GetGenericArguments()[1]; - JsonConverter converter = (JsonConverter)Activator.CreateInstance( - typeof(UInt256DictionaryConverter<>).MakeGenericType(valueType), - BindingFlags.Instance | BindingFlags.Public, - binder: null, - args: new object[] { options }, - culture: null)!; - - return converter; - } - - private class UInt256DictionaryConverter : JsonConverter> - { - private readonly JsonConverter _valueConverter; - private readonly Type _valueType; - - public UInt256DictionaryConverter(JsonSerializerOptions options) - { - // For performance, use existing converter if available - _valueType = typeof(TValue); - _valueConverter = (JsonConverter)options.GetConverter(typeof(TValue)); - } - - public override Dictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.StartObject) - { - throw new JsonException(); - } - - var dictionary = new Dictionary(); - - while (reader.Read()) - { - if (reader.TokenType == JsonTokenType.EndObject) - { - return dictionary; - } - - // Assume the key is a string and convert it to UInt256 - string keyString = reader.GetString()!; - UInt256 key = UInt256.Parse(keyString); - - reader.Read(); - - TValue value; - - if (_valueConverter != null) - { - value = _valueConverter.Read(ref reader, _valueType, options)!; - } - else - { - value = JsonSerializer.Deserialize(ref reader, options)!; - } - - dictionary[key] = value; - } - - throw new JsonException(); - } - - public override void Write(Utf8JsonWriter writer, Dictionary dictionary, JsonSerializerOptions options) - { - writer.WriteStartObject(); - - foreach (KeyValuePair kvp in dictionary) - { - writer.WritePropertyName(kvp.Key.ToString()); - - if (_valueConverter != null) - { - _valueConverter.Write(writer, kvp.Value, options); - } - else - { - JsonSerializer.Serialize(writer, kvp.Value, options); - } - } - - writer.WriteEndObject(); - } - } -} From 4021afff5cef4bf38de4d2ec10ceb62dececc28d Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Fri, 19 Jan 2024 22:14:17 +0000 Subject: [PATCH 117/213] Optimize WriteAsPropertyName --- .../Nethermind.Blockchain.Test/KnownChainSizesTests.cs | 2 +- .../Nethermind.Serialization.Json/UInt256Converter.cs | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/KnownChainSizesTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/KnownChainSizesTests.cs index 59004e4b854..8f07e163b37 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/KnownChainSizesTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/KnownChainSizesTests.cs @@ -16,7 +16,7 @@ public void Update_known_chain_sizes() // Pruning size have to be updated frequently ChainSizes.CreateChainSizeInfo(BlockchainIds.Mainnet).PruningSize.Should().BeLessThan(210.GB()); ChainSizes.CreateChainSizeInfo(BlockchainIds.Goerli).PruningSize.Should().BeLessThan(90.GB()); - ChainSizes.CreateChainSizeInfo(BlockchainIds.Sepolia).PruningSize.Should().BeLessThan(15.GB()); + ChainSizes.CreateChainSizeInfo(BlockchainIds.Sepolia).PruningSize.Should().BeLessThan(18.GB()); ChainSizes.CreateChainSizeInfo(BlockchainIds.Chiado).PruningSize.Should().Be(null); ChainSizes.CreateChainSizeInfo(BlockchainIds.Gnosis).PruningSize.Should().Be(null); diff --git a/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs b/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs index 2564d18b01d..9617d19948a 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs @@ -74,7 +74,7 @@ public override void Write( { if (value.IsZero) { - writer.WriteRawValue("\"0x0\""); + writer.WriteRawValue("\"0x0\""u8); return; } NumberConversion usedConversion = ForcedNumberConversion.GetFinalConversion(); @@ -101,18 +101,21 @@ public override void Write( public override UInt256 ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => ReadInternal(ref reader, JsonTokenType.PropertyName); + [SkipLocalsInit] public override void WriteAsPropertyName(Utf8JsonWriter writer, UInt256 value, JsonSerializerOptions options) { if (value.IsZero) { - writer.WritePropertyName("\"0x0\""); + writer.WritePropertyName("0x0"u8); return; } NumberConversion usedConversion = ForcedNumberConversion.GetFinalConversion(); switch (usedConversion) { case NumberConversion.Hex: - writer.WritePropertyName(value.ToHexString(false)); + Span bytes = stackalloc byte[32]; + value.ToBigEndian(bytes); + writer.WritePropertyName(bytes); break; case NumberConversion.Decimal: writer.WritePropertyName(value.ToString(CultureInfo.InvariantCulture)); From 92f5c7eebd34109a6f2ccbcf55b53ec79f6fdecb Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 22 Jan 2024 05:35:28 +0000 Subject: [PATCH 118/213] Revert ` Extract revert messages #6226` --- .../Extensions/SpanExtensions.cs | 7 -- .../TransactionSubstateTests.cs | 88 +------------------ .../Nethermind.Evm/TransactionSubstate.cs | 80 +++++------------ 3 files changed, 24 insertions(+), 151 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs b/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs index a95f462a358..31060ce48bb 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs @@ -148,13 +148,6 @@ private static string ToHexStringWithEip55Checksum(ReadOnlySpan bytes, boo return result; } - public static ReadOnlySpan TakeAndMove(this ref ReadOnlySpan span, int length) - { - ReadOnlySpan s = span[..length]; - span = span[length..]; - return s; - } - public static bool IsNullOrEmpty(this in Span span) => span.Length == 0; public static bool IsNull(this in Span span) => Unsafe.IsNullRef(ref MemoryMarshal.GetReference(span)); public static bool IsNullOrEmpty(this in ReadOnlySpan span) => span.Length == 0; diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs index 96d1ed8ac5d..a6177beaf5a 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Collections.Generic; using FluentAssertions; using Nethermind.Core; using Nethermind.Core.Extensions; @@ -15,15 +14,12 @@ public class TransactionSubstateTests [Test] public void should_return_proper_revert_error_when_there_is_no_exception() { - byte[] data = - { - 0, 0, 0, 0, + byte[] data = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5, - 0x05, 0x06, 0x07, 0x08, 0x09 - }; + 0x05, 0x06, 0x07, 0x08, 0x09}; ReadOnlyMemory readOnlyMemory = new(data); TransactionSubstate transactionSubstate = new(readOnlyMemory, 0, @@ -68,92 +64,16 @@ public void should_return_proper_revert_error_when_revert_custom_error_badly_imp transactionSubstate.Error.Should().Be($"Reverted {hex}"); } - private static IEnumerable<(byte[], string)> ErrorFunctionTestCases() - { - yield return ( - new byte[] - { - 0x08, 0xc3, 0x79, 0xa0, // Function selector for Error(string) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, // Data offset - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, // String length - 0x4e, 0x6f, 0x74, 0x20, 0x65, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x45, 0x74, 0x68, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // String data - }, - "Reverted Not enough Ether provided."); - - yield return ( - new byte[] - { - 0x08, 0xc3, 0x79, 0xa0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, - 0x52, 0x65, 0x71, 0x3a, 0x3a, 0x55, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x41, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - "Reverted Req::UnAuthAuditor"); - - // Invalid case - yield return (new byte[] { 0x08, 0xc3, 0x79, 0xa0, 0xFF }, "Reverted 0x08c379a0ff"); - } - - private static IEnumerable<(byte[], string)> PanicFunctionTestCases() - { - yield return ( - new byte[] - { - 0x4e, 0x48, 0x7b, 0x71, // Function selector for Panic(uint256) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Panic code 0x0 - }, - "Reverted generic panic"); - - yield return ( - new byte[] - { - 0x4e, 0x48, 0x7b, 0x71, // Function selector for Panic(uint256) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22 // Panic code 0x22 - }, - "Reverted invalid encoded storage byte array accessed"); - - yield return ( - new byte[] - { - 0x4e, 0x48, 0x7b, 0x71, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF // Unknown panic code - }, - "Reverted unknown panic code (0xff)"); - - // Invalid case - yield return (new byte[] { 0x4e, 0x48, 0x7b, 0x71 }, "Reverted 0x4e487b71"); - } - - [Test] - [TestCaseSource(nameof(ErrorFunctionTestCases))] - [TestCaseSource(nameof(PanicFunctionTestCases))] - public void should_return_proper_revert_error_when_using_special_functions((byte[] data, string expected) tc) - { - // See: https://docs.soliditylang.org/en/latest/control-structures.html#revert - ReadOnlyMemory readOnlyMemory = new(tc.data); - TransactionSubstate transactionSubstate = new( - readOnlyMemory, - 0, - new ArraySegment
(), - new LogEntry[] { }, - true, - true); - - transactionSubstate.Error.Should().Be(tc.expected); - } - [Test] [Ignore("Badly implemented")] public void should_return_proper_revert_error_when_revert_custom_error() { - byte[] data = - { + byte[] data = { 0x22, 0x02, 0x66, 0xb6, // Keccak of `FailedOp(uint256,string)` == 0x220266b6 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x41, 0x41, 0x32, 0x31, 0x20, 0x64, 0x69, 0x64, 0x6e, 0x27, 0x74, 0x20, 0x70, 0x61, 0x79, 0x20, 0x70, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, // "AA21 didn't pay prefund" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ReadOnlyMemory readOnlyMemory = new(data); TransactionSubstate transactionSubstate = new( readOnlyMemory, diff --git a/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs b/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs index a5368120981..04a8c663a67 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using Nethermind.Core; -using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Int256; @@ -19,25 +18,8 @@ public class TransactionSubstate private const string Revert = "revert"; private const int RevertPrefix = 4; - private const int WordSize = EvmPooledMemory.WordSize; private const string RevertedErrorMessagePrefix = "Reverted "; - private readonly byte[] ErrorFunctionSelector = Keccak.Compute("Error(string)").BytesToArray()[..RevertPrefix]; - private readonly byte[] PanicFunctionSelector = Keccak.Compute("Panic(uint256)").BytesToArray()[..RevertPrefix]; - - private readonly IDictionary PanicReasons = new Dictionary - { - { 0x00, "generic panic" }, - { 0x01, "assert(false)" }, - { 0x11, "arithmetic underflow or overflow" }, - { 0x12, "division or modulo by zero" }, - { 0x21, "enum overflow" }, - { 0x22, "invalid encoded storage byte array accessed" }, - { 0x31, "out-of-bounds array access; popping on an empty array" }, - { 0x32, "out-of-bounds access of an array or bytesN" }, - { 0x41, "out of memory" }, - { 0x51, "uninitialized function" }, - }; public bool IsError => Error is not null && !ShouldRevert; public string? Error { get; } @@ -85,59 +67,37 @@ public TransactionSubstate( return; ReadOnlySpan span = Output.Span; - Error = string.Concat( - RevertedErrorMessagePrefix, - TryGetErrorMessage(span) ?? DefaultErrorMessage(span) - ); + Error = TryGetErrorMessage(span) + ?? DefaultErrorMessage(span); } - private static string DefaultErrorMessage(ReadOnlySpan span) => span.ToHexString(true); - - private string? TryGetErrorMessage(ReadOnlySpan span) + private string DefaultErrorMessage(ReadOnlySpan span) { - if (span.Length < RevertPrefix) { return null; } - ReadOnlySpan prefix = span.TakeAndMove(RevertPrefix); - - if (prefix.SequenceEqual(PanicFunctionSelector)) - { - if (span.Length < WordSize) { return null; } - - UInt256 panicCode = new(span.TakeAndMove(WordSize), isBigEndian: true); - if (!PanicReasons.TryGetValue(panicCode, out string panicReason)) - { - return $"unknown panic code ({panicCode.ToHexString(skipLeadingZeros: true)})"; - } - - return panicReason; - } + return string.Concat(RevertedErrorMessagePrefix, span.ToHexString(true)); + } - if (prefix.SequenceEqual(ErrorFunctionSelector)) + private unsafe string? TryGetErrorMessage(ReadOnlySpan span) + { + if (span.Length < RevertPrefix + sizeof(UInt256) * 2) { - if (span.Length < WordSize * 2) { return null; } - - int start = (int)new UInt256(span.TakeAndMove(WordSize), isBigEndian: true); - if (start != WordSize) { return null; } - - int length = (int)new UInt256(span.TakeAndMove(WordSize), isBigEndian: true); - if (length > span.Length) { return null; } - - ReadOnlySpan binaryMessage = span.TakeAndMove(length); - string message = System.Text.Encoding.UTF8.GetString(binaryMessage); - - return message; + return null; } try { - if (span.Length < WordSize * 2) { return null; } - - int start = (int)new UInt256(span.Slice(0, WordSize), isBigEndian: true); - if (checked(start + WordSize) > span.Length) { return null; } + int start = (int)new UInt256(span.Slice(RevertPrefix, sizeof(UInt256)), isBigEndian: true); + if (checked(RevertPrefix + start + sizeof(UInt256)) > span.Length) + { + return null; + } - int length = (int)new UInt256(span.Slice(start, WordSize), isBigEndian: true); - if (checked(start + WordSize + length) != span.Length) { return null; } + int length = (int)new UInt256(span.Slice(RevertPrefix + start, sizeof(UInt256)), isBigEndian: true); + if (checked(RevertPrefix + start + sizeof(UInt256) + length) != span.Length) + { + return null; + } - return span.Slice(start + WordSize, length).ToHexString(true); + return string.Concat(RevertedErrorMessagePrefix, span.Slice(RevertPrefix + start + sizeof(UInt256), length).ToHexString(true)); } catch (OverflowException) { From b7983f63b45de171657bfc30ac098e5ff2e739aa Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 22 Jan 2024 06:43:55 +0000 Subject: [PATCH 119/213] Moving to eth_simulate --- .../Nethermind.Api/NethermindApi.cs | 6 +- .../Nethermind.Cli/Modules/EthCliModule.cs | 2 +- .../BlockchainBridgeTests.cs | 10 +- .../Nethermind.Facade/BlockchainBridge.cs | 20 +-- .../Nethermind.Facade/IBlockchainBridge.cs | 4 +- ...lBlockResult.cs => SimulateBlockResult.cs} | 2 +- .../SimulateBlockTracer.cs} | 14 +-- .../SimulateBridgeHelper.cs} | 14 +-- .../SimulateOutput.cs} | 6 +- .../SimulateReadOnlyBlocksProcessingEnv.cs} | 12 +- .../SimulateTxTracer.cs} | 6 +- .../JsonRpcServiceTests.cs | 8 +- ...ulticallTestsPrecompilesWithRedirection.cs | 6 +- .../Multicall/EthMultiCallTestsHiveBase.cs | 114 +++++++++--------- .../EthMulticallTestsBlocksAndTransactions.cs | 14 +-- .../EthMulticallTestsSimplePrecompiles.cs | 4 +- .../Modules/TestRpcBlockchain.cs | 6 +- .../Modules/Eth/EthRpcModule.cs | 2 +- .../Modules/Eth/IEthRpcModule.cs | 2 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 18 +-- 20 files changed, 135 insertions(+), 135 deletions(-) rename src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/{MultiCallBlockResult.cs => SimulateBlockResult.cs} (95%) rename src/Nethermind/Nethermind.Facade/{Multicall/MultiCallBlockTracer.cs => Simulate/SimulateBlockTracer.cs} (84%) rename src/Nethermind/Nethermind.Facade/{Multicall/MulticallBridgeHelper.cs => Simulate/SimulateBridgeHelper.cs} (94%) rename src/Nethermind/Nethermind.Facade/{Multicall/MultiCallOutput.cs => Simulate/SimulateOutput.cs} (63%) rename src/Nethermind/Nethermind.Facade/{Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs => Simulate/SimulateReadOnlyBlocksProcessingEnv.cs} (93%) rename src/Nethermind/Nethermind.Facade/{Multicall/MultiCallTxTracer.cs => Simulate/SimulateTxTracer.cs} (93%) diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 6a040a417a3..58537b79e00 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -31,7 +31,7 @@ using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; using Nethermind.Facade.Eth; -using Nethermind.Facade.Multicall; +using Nethermind.Facade.Simulate; using Nethermind.Grpc; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; @@ -94,7 +94,7 @@ public IBlockchainBridge CreateBlockchainBridge() SpecProvider, LogManager); - MultiCallReadOnlyBlocksProcessingEnv multiCallReadOnlyBlocksProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create(false, + SimulateReadOnlyBlocksProcessingEnv simulateReadOnlyBlocksProcessingEnv = SimulateReadOnlyBlocksProcessingEnv.Create(false, WorldStateManager!, readOnlyTree, _multiCallReadOnlyDbProvider, @@ -107,7 +107,7 @@ public IBlockchainBridge CreateBlockchainBridge() return new BlockchainBridge( readOnlyTxProcessingEnv, - multiCallReadOnlyBlocksProcessingEnv, + simulateReadOnlyBlocksProcessingEnv, TxPool, ReceiptFinder, FilterStore, diff --git a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs index 67d5d444b8e..216343db2c9 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs @@ -53,7 +53,7 @@ public JsValue GetProof(string address, string[] storageKeys, string? blockParam [CliFunction("eth", "multicallV1")] public JsValue MultiCallV1(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) { - return NodeManager.PostJint("eth_multicallV1", 1, blockCalls, blockParameter ?? "latest", traceTransfers).Result; + return NodeManager.PostJint("eth_simulateV1", 1, blockCalls, blockParameter ?? "latest", traceTransfers).Result; } diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index cfc999ff12c..4ac4ab2cb6a 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -29,7 +29,7 @@ using NUnit.Framework; using Nethermind.Config; using Nethermind.Evm; -using Nethermind.Facade.Multicall; +using Nethermind.Facade.Simulate; using Nethermind.State; namespace Nethermind.Facade.Test @@ -75,7 +75,7 @@ public async Task SetUp() _specProvider, LimboLogs.Instance); - MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + SimulateReadOnlyBlocksProcessingEnv simulateProcessingEnv = SimulateReadOnlyBlocksProcessingEnv.Create( false, readOnlyWorldStateManager, roBlockTree, @@ -87,7 +87,7 @@ public async Task SetUp() _blockchainBridge = new BlockchainBridge( processingEnv, - multiCallProcessingEnv, + simulateProcessingEnv, _txPool, _receiptStorage, _filterStore, @@ -233,7 +233,7 @@ public void Bridge_head_is_correct(long headNumber) _specProvider, LimboLogs.Instance); - MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + SimulateReadOnlyBlocksProcessingEnv simulateProcessingEnv = SimulateReadOnlyBlocksProcessingEnv.Create( false, readOnlyWorldStateManager, roBlockTree, @@ -249,7 +249,7 @@ public void Bridge_head_is_correct(long headNumber) _blockchainBridge = new BlockchainBridge( processingEnv, - multiCallProcessingEnv, + simulateProcessingEnv, _txPool, _receiptStorage, _filterStore, diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 20d9193bb0e..0ba9c353d0a 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -28,7 +28,7 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using System.Transactions; using Microsoft.CSharp.RuntimeBinder; -using Nethermind.Facade.Multicall; +using Nethermind.Facade.Simulate; using Transaction = Nethermind.Core.Transaction; using Nethermind.Specs; @@ -52,10 +52,10 @@ public class BlockchainBridge : IBlockchainBridge private readonly ILogFinder _logFinder; private readonly ISpecProvider _specProvider; private readonly IBlocksConfig _blocksConfig; - private readonly MulticallBridgeHelper _multicallBridgeHelper; + private readonly SimulateBridgeHelper _simulateBridgeHelper; public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, - MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv, + SimulateReadOnlyBlocksProcessingEnv simulateProcessingEnv, ITxPool? txPool, IReceiptFinder? receiptStorage, IFilterStore? filterStore, @@ -78,8 +78,8 @@ public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _blocksConfig = blocksConfig; IsMining = isMining; - _multicallBridgeHelper = new MulticallBridgeHelper( - multiCallProcessingEnv ?? throw new ArgumentNullException(nameof(multiCallProcessingEnv)), + _simulateBridgeHelper = new SimulateBridgeHelper( + simulateProcessingEnv ?? throw new ArgumentNullException(nameof(simulateProcessingEnv)), _specProvider, _blocksConfig); } @@ -152,13 +152,13 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can }; } - public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken) + public SimulateOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken) { - MultiCallBlockTracer multiCallOutputTracer = new(payload.TraceTransfers); - MultiCallOutput result = new(); + SimulateBlockTracer simulateOutputTracer = new(payload.TraceTransfers); + SimulateOutput result = new(); //try //{ - (bool success, string error) = _multicallBridgeHelper.TryMultiCallTrace(header, payload, multiCallOutputTracer.WithCancellation(cancellationToken)); + (bool success, string error) = _simulateBridgeHelper.TryMultiCallTrace(header, payload, simulateOutputTracer.WithCancellation(cancellationToken)); if (!success) { @@ -170,7 +170,7 @@ public MultiCallOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken); + SimulateOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken); CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken); CallOutput CreateAccessList(BlockHeader header, Transaction tx, CancellationToken cancellationToken, bool optimize); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateBlockResult.cs similarity index 95% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateBlockResult.cs index 87173646a79..015c9bc82ed 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateBlockResult.cs @@ -10,7 +10,7 @@ namespace Nethermind.Facade.Proxy.Models.MultiCall; -public class MultiCallBlockResult +public class SimulateBlockResult { public ulong Number { get; set; } public Hash256 Hash { get; set; } = Keccak.Zero; diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs similarity index 84% rename from src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs rename to src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 077acaa2887..8d7defd305d 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -9,18 +9,18 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using ResultType = Nethermind.Facade.Proxy.Models.MultiCall.ResultType; -namespace Nethermind.Facade.Multicall; +namespace Nethermind.Facade.Simulate; -public class MultiCallBlockTracer : BlockTracer +public class SimulateBlockTracer : BlockTracer { private readonly bool _isTracingLogs; - public List Results { get; } = new(); + public List Results { get; } = new(); - private readonly List _txTracers = new(); + private readonly List _txTracers = new(); private Block _currentBlock = null!; - public MultiCallBlockTracer(bool isTracingLogs) + public SimulateBlockTracer(bool isTracingLogs) { _isTracingLogs = isTracingLogs; } @@ -35,7 +35,7 @@ public override ITxTracer StartNewTxTrace(Transaction? tx) { if (tx?.Hash is not null) { - MultiCallTxTracer result = new(_isTracingLogs); + SimulateTxTracer result = new(_isTracingLogs); _txTracers.Add(result); return result; } @@ -45,7 +45,7 @@ public override ITxTracer StartNewTxTrace(Transaction? tx) public override void EndBlockTrace() { - MultiCallBlockResult? result = new() + SimulateBlockResult? result = new() { Calls = _txTracers.Select(t => t.TraceResult), Number = (ulong)_currentBlock.Number, diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs similarity index 94% rename from src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs rename to src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 7be99e8f458..9cf444de65c 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MulticallBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -17,11 +17,11 @@ using Nethermind.Int256; using Nethermind.State; -namespace Nethermind.Facade.Multicall; +namespace Nethermind.Facade.Simulate; -public class MulticallBridgeHelper +public class SimulateBridgeHelper { - private readonly MultiCallReadOnlyBlocksProcessingEnv _multiCallProcessingEnv; + private readonly SimulateReadOnlyBlocksProcessingEnv _simulateProcessingEnv; private readonly ISpecProvider _specProvider; private readonly IBlocksConfig _blocksConfig; @@ -30,14 +30,14 @@ public class MulticallBridgeHelper ProcessingOptions.MarkAsProcessed | ProcessingOptions.StoreReceipts; - public MulticallBridgeHelper(MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv, ISpecProvider specProvider, IBlocksConfig blocksConfig) + public SimulateBridgeHelper(SimulateReadOnlyBlocksProcessingEnv simulateProcessingEnv, ISpecProvider specProvider, IBlocksConfig blocksConfig) { - _multiCallProcessingEnv = multiCallProcessingEnv; + _simulateProcessingEnv = simulateProcessingEnv; _specProvider = specProvider; _blocksConfig = blocksConfig; } - private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall blockStateCall, MultiCallReadOnlyBlocksProcessingEnv env) + private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall blockStateCall, SimulateReadOnlyBlocksProcessingEnv env) { IReleaseSpec currentSpec = env.SpecProvider.GetSpec(blockHeader); env.StateProvider.ApplyStateOverrides(env.CodeInfoRepository, blockStateCall.StateOverrides, currentSpec, blockHeader.Number); @@ -46,7 +46,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateC public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) { - using MultiCallReadOnlyBlocksProcessingEnv? env = _multiCallProcessingEnv.Clone(payload.TraceTransfers, payload.Validation); + using SimulateReadOnlyBlocksProcessingEnv? env = _simulateProcessingEnv.Clone(payload.TraceTransfers, payload.Validation); Block? latestPersistant = env.BlockTree.FindLatestBlock(); if (latestPersistant.Number < parent.Number) diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallOutput.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs similarity index 63% rename from src/Nethermind/Nethermind.Facade/Multicall/MultiCallOutput.cs rename to src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs index abc15424e76..9dcfd981dc3 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallOutput.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs @@ -4,11 +4,11 @@ using System.Collections.Generic; using Nethermind.Facade.Proxy.Models.MultiCall; -namespace Nethermind.Facade.Multicall; +namespace Nethermind.Facade.Simulate; -public class MultiCallOutput +public class SimulateOutput { public string? Error { get; set; } - public IReadOnlyList Items { get; set; } + public IReadOnlyList Items { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs similarity index 93% rename from src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs rename to src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 7c3deef7286..f7ebf22efc7 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -21,9 +21,9 @@ using Nethermind.State.Repositories; using Nethermind.Trie.Pruning; -namespace Nethermind.Facade.Multicall; +namespace Nethermind.Facade.Simulate; -public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IDisposable +public class SimulateReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IDisposable { //private readonly ITrieStore _trieStore; private readonly ILogManager? _logManager; @@ -35,7 +35,7 @@ public class MultiCallReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, public OverridableCodeInfoRepository CodeInfoRepository { get; } private readonly bool _doValidation = false; // We need ability to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning - public static MultiCallReadOnlyBlocksProcessingEnv Create( + public static SimulateReadOnlyBlocksProcessingEnv Create( bool traceTransfers, IWorldStateManager worldStateManager, IReadOnlyBlockTree roBlockTree, @@ -65,7 +65,7 @@ public static MultiCallReadOnlyBlocksProcessingEnv Create( logManager); var blockTree = new NonDistructiveBlockTreeOverlay(roBlockTree, tmpBlockTree); - return new MultiCallReadOnlyBlocksProcessingEnv( + return new SimulateReadOnlyBlocksProcessingEnv( traceTransfers, overlayWorldStateManager, roBlockTree, @@ -77,12 +77,12 @@ public static MultiCallReadOnlyBlocksProcessingEnv Create( doValidation); } - public MultiCallReadOnlyBlocksProcessingEnv Clone(bool traceTransfers, bool doValidation) => + public SimulateReadOnlyBlocksProcessingEnv Clone(bool traceTransfers, bool doValidation) => Create(traceTransfers, WorldStateManager, ReadOnlyBlockTree, DbProvider, SpecProvider, _logManager, doValidation); public IReadOnlyDbProvider DbProvider { get; } - private MultiCallReadOnlyBlocksProcessingEnv( + private SimulateReadOnlyBlocksProcessingEnv( bool traceTransfers, IWorldStateManager worldStateManager, IReadOnlyBlockTree roBlockTree, diff --git a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs similarity index 93% rename from src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs rename to src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs index 50da633471f..90c01461190 100644 --- a/src/Nethermind/Nethermind.Facade/Multicall/MultiCallTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs @@ -12,13 +12,13 @@ using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.Int256; -namespace Nethermind.Facade.Multicall; +namespace Nethermind.Facade.Simulate; -internal sealed class MultiCallTxTracer : TxTracer, ILogsTxTracer +internal sealed class SimulateTxTracer : TxTracer, ILogsTxTracer { private static readonly Hash256[] _topics = { Keccak.Zero }; - public MultiCallTxTracer(bool isTracingTransfers) + public SimulateTxTracer(bool isTracingTransfers) { IsTracingLogs = isTracingTransfers; IsTracingReceipt = true; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index e77d285e846..baacd7e2590 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -91,12 +91,12 @@ public void CanRunEthMulticallV1Empty() string serializedCall = serializer.Serialize(payload); IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_multicallV1(payload).ReturnsForAnyArgs(x => - ResultWrapper>.Success(Array.Empty())); + ethRpcModule.eth_simulateV1(payload).ReturnsForAnyArgs(x => + ResultWrapper>.Success(Array.Empty())); JsonRpcSuccessResponse? response = - TestRequest(ethRpcModule, "eth_multicallV1", serializedCall) as JsonRpcSuccessResponse; + TestRequest(ethRpcModule, "eth_simulateV1", serializedCall) as JsonRpcSuccessResponse; Assert.IsTrue(response != null); - Assert.That(response?.Result, Is.EqualTo(Array.Empty())); + Assert.That(response?.Result, Is.EqualTo(Array.Empty())); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs index 220b7ee1bb4..884ecbcad7b 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs @@ -84,7 +84,7 @@ public async Task Test_eth_multicall_create() //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); //Check results byte[]? returnData = result.Data[0].Calls.First().ReturnData; @@ -189,7 +189,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( new AccountOverride { Code = code, - MovePrecompileToAddress = new Address("0x0000000000000000000000000000000000000666"), + //MovePrecompileToAddress = new Address("0x0000000000000000000000000000000000000666"), } }, }, @@ -208,7 +208,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( Debug.Assert(contractAddress != null, nameof(contractAddress) + " != null"); Assert.IsTrue(chain.State.AccountExists(contractAddress)); - ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); //Check results byte[]? returnData = result.Data[0].Calls.First().ReturnData; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs index 00d71d6c6b0..906550d2e25 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs @@ -26,7 +26,7 @@ public async Task TestmulticallAddMoreNonDefinedBlockStateCallsThanFitButNowWith var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -39,7 +39,7 @@ public async Task TestmulticallAddMoreNonDefinedBlockStateCallsThanFit() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallAddMoreNonDefinedBlockStateCallsThanFit"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -52,7 +52,7 @@ public async Task TestmulticallBasefeeTooLowWithValidation38012() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBasefeeTooLowWithValidation38012"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.That(result.Data.First().PrevRandao, Is.EqualTo(new Hash256("0x0000000000000000000000000000000000000000000000000000000000000000").BytesToArray())); @@ -68,7 +68,7 @@ public async Task TestmulticallBasefeeTooLowWithoutValidation38012() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBasefeeTooLowWithoutValidation38012"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -81,7 +81,7 @@ public async Task TestmulticallBlockNumOrder38020() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBlockNumOrder38020"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -94,7 +94,7 @@ public async Task TestmulticallBlockOverrideReflectedInContractSimple() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBlockOverrideReflectedInContractSimple"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -107,7 +107,7 @@ public async Task TestmulticallBlockOverrideReflectedInContract() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBlockOverrideReflectedInContract"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -120,7 +120,7 @@ public async Task TestmulticallBlockTimestampAutoIncrement() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBlockTimestampAutoIncrement"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -133,7 +133,7 @@ public async Task TestmulticallBlockTimestampNonIncrement() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBlockTimestampNonIncrement"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -146,7 +146,7 @@ public async Task TestmulticallBlockTimestampOrder38021() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBlockTimestampOrder38021"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -159,7 +159,7 @@ public async Task TestmulticallBlockTimestampsIncrementing() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBlockTimestampsIncrementing"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -172,7 +172,7 @@ public async Task TestmulticallBlockhashComplex() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBlockhashComplex"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -185,7 +185,7 @@ public async Task TestmulticallBlockhashSimple() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBlockhashSimple"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -198,7 +198,7 @@ public async Task TestmulticallBlockhashStartBeforeHead() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallBlockhashStartBeforeHead"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -211,7 +211,7 @@ public async Task TestmulticallCheckInvalidNonce() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallCheckInvalidNonce"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -224,7 +224,7 @@ public async Task TestmulticallCheckThatBalanceIsThereAfterNewBlock() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallCheckThatBalanceIsThereAfterNewBlock"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -237,7 +237,7 @@ public async Task TestmulticallCheckThatNonceIncreases() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallCheckThatNonceIncreases"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -250,7 +250,7 @@ public async Task TestmulticallEmptyCallsAndOverridesMulticall() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallEmptyCallsAndOverridesMulticall"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -263,7 +263,7 @@ public async Task TestmulticallEthSendShouldNotProduceLogsByDefault() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallEthSendShouldNotProduceLogsByDefault"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -276,7 +276,7 @@ public async Task TestmulticallEthSendShouldNotProduceLogsOnRevert() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallEthSendShouldNotProduceLogsOnRevert"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -289,7 +289,7 @@ public async Task TestmulticallEthSendShouldProduceLogs() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallEthSendShouldProduceLogs"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -302,7 +302,7 @@ public async Task TestmulticallEthSendShouldProduceMoreLogsOnForward() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallEthSendShouldProduceMoreLogsOnForward"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -315,7 +315,7 @@ public async Task TestmulticallEthSendShouldProduceNoLogsOnForwardRevert() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallEthSendShouldProduceNoLogsOnForwardRevert"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -328,7 +328,7 @@ public async Task TestmulticallFeeRecipientReceivingFunds() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallFeeRecipientReceivingFunds"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -341,7 +341,7 @@ public async Task TestmulticallGasFeesAndValueError38014WithValidation() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallGasFeesAndValueError38014WithValidation"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -354,7 +354,7 @@ public async Task TestmulticallGasFeesAndValueError38014() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallGasFeesAndValueError38014"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -367,7 +367,7 @@ public async Task TestmulticallGetBlockProperties() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallGetBlockProperties"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -380,7 +380,7 @@ public async Task TestmulticallInstrictGas38013() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallInstrictGas38013"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -393,7 +393,7 @@ public async Task TestmulticallLogs() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallLogs"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -406,7 +406,7 @@ public async Task TestmulticallMoveAccountTwice() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallMoveAccountTwice"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -419,7 +419,7 @@ public async Task TestmulticallMoveEcrecoverAndCall() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallMoveEcrecoverAndCall"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -432,7 +432,7 @@ public async Task TestmulticallMoveToAddressItselfReference38022() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallMoveToAddressItselfReference38022"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -445,7 +445,7 @@ public async Task TestmulticallMoveTwoAccountsToSame38023() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallMoveTwoAccountsToSame38023"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -458,7 +458,7 @@ public async Task TestmulticallMoveTwoNonPrecompilesAccountsToSame() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallMoveTwoNonPrecompilesAccountsToSame"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -471,7 +471,7 @@ public async Task TestmulticallOverrideAddressTwiceInSeparateBlockStateCalls() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallOverrideAddressTwiceInSeparateBlockStateCalls"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -484,7 +484,7 @@ public async Task TestmulticallOverrideAddressTwice() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallOverrideAddressTwice"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -497,7 +497,7 @@ public async Task TestmulticallOverrideAllInBlockStateCalls() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallOverrideAllInBlockStateCalls"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -510,7 +510,7 @@ public async Task TestmulticallOverrideBlockNum() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallOverrideBlockNum"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -523,7 +523,7 @@ public async Task TestmulticallOverrideEcrecover() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallOverrideEcrecover"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -536,7 +536,7 @@ public async Task TestmulticallOverrideIdentity() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallOverrideIdentity"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -549,7 +549,7 @@ public async Task TestmulticallOverrideSha256() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallOverrideSha256"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -562,7 +562,7 @@ public async Task TestmulticallPrecompileIsSendingTransaction() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallPrecompileIsSendingTransaction"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -575,7 +575,7 @@ public async Task TestmulticallRunOutOfGasInBlock38015() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallRunOutOfGasInBlock38015"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -588,7 +588,7 @@ public async Task TestmulticallSelfDestructingStateOverride() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallSelfDestructingStateOverride"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -601,7 +601,7 @@ public async Task TestmulticallSetReadStorage() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallSetReadStorage"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -614,7 +614,7 @@ public async Task TestmulticallSimpleNoFundsWithBalanceQuerying() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallSimpleNoFundsWithBalanceQuerying"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -627,7 +627,7 @@ public async Task TestmulticallSimpleNoFundsWithValidationWithoutNonces() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallSimpleNoFundsWithValidationWithoutNonces"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -640,7 +640,7 @@ public async Task TestmulticallSimpleNoFundsWithValidation() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallSimpleNoFundsWithValidation"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -653,7 +653,7 @@ public async Task TestmulticallSimpleNoFunds() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallSimpleNoFunds"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -666,7 +666,7 @@ public async Task TestmulticallSimpleSendFromContractNoBalance() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallSimpleSendFromContractNoBalance"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -679,7 +679,7 @@ public async Task TestmulticallSimpleSendFromContractWithValidation() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallSimpleSendFromContractWithValidation"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -692,7 +692,7 @@ public async Task TestmulticallSimpleSendFromContract() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallSimpleSendFromContract"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -705,7 +705,7 @@ public async Task TestmulticallSimple() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallSimple"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -718,7 +718,7 @@ public async Task TestmulticallTransactionTooHighNonce() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallTransactionTooHighNonce"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -731,7 +731,7 @@ public async Task TestmulticallTransactionTooLowNonce38010() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallTransactionTooLowNonce38010"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -744,7 +744,7 @@ public async Task TestmulticallTransferOverBlockStateCalls() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallTransferOverBlockStateCalls"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -757,7 +757,7 @@ public async Task TestmulticallTryToMoveNonPrecompile() var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); Console.WriteLine("current test: multicallTryToMoveNonPrecompile"); - var result = chain.EthRpcModule.eth_multicallV1(payload!, BlockParameter.Latest); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs index 9714072f9b1..754136b3cdb 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs @@ -98,13 +98,13 @@ public async Task Test_eth_multicall_serialisation() //Assert.Equals(chain.BlockTree.BestPersistedState!, chain.BlockTree.Head!.Number); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - ResultWrapper> result = + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); - IReadOnlyList data = result.Data; + IReadOnlyList data = result.Data; Assert.That(data.Count, Is.EqualTo(1)); - foreach (MultiCallBlockResult blockResult in data) + foreach (SimulateBlockResult blockResult in data) { blockResult.Calls.Select(c => c.Type).Should().BeEquivalentTo(new[] { ResultType.Success, ResultType.Success }); } @@ -179,13 +179,13 @@ public async Task Test_eth_multicall_eth_moved() //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - ResultWrapper> result = + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); - IReadOnlyList data = result.Data; + IReadOnlyList data = result.Data; Assert.That(data.Count, Is.EqualTo(2)); - foreach (MultiCallBlockResult blockResult in data) + foreach (SimulateBlockResult blockResult in data) { Assert.That(blockResult.Calls.Count(), Is.EqualTo(2)); } @@ -260,7 +260,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - ResultWrapper> result = + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); Assert.IsTrue(result.Data[1].Calls.First().Error?.Message.StartsWith("insufficient")); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs index 4918359bce7..3b58a5e773a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs @@ -13,7 +13,7 @@ using Nethermind.Evm; using Nethermind.Evm.Precompiles; using Nethermind.Facade; -using Nethermind.Facade.Multicall; +using Nethermind.Facade.Simulate; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; using NUnit.Framework; @@ -109,7 +109,7 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe // Act - MultiCallOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head?.Header!, payload, CancellationToken.None); + SimulateOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head?.Header!, payload, CancellationToken.None); Log[]? logs = result.Items.First().Calls.First().Logs; byte[] addressBytes = result.Items.First().Calls.First().ReturnData! .SliceWithZeroPaddingEmptyOnError(12, 20); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 058effc0dbb..5aa4513a859 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -31,7 +31,7 @@ using Nethermind.Wallet; using Nethermind.Config; -using Nethermind.Facade.Multicall; +using Nethermind.Facade.Simulate; using Nethermind.Synchronization.ParallelSync; using NSubstitute; @@ -131,7 +131,7 @@ protected override async Task Build(ISpecProvider? specProvider SpecProvider, LimboLogs.Instance); - MultiCallReadOnlyBlocksProcessingEnv multiCallProcessingEnv = MultiCallReadOnlyBlocksProcessingEnv.Create( + SimulateReadOnlyBlocksProcessingEnv simulateProcessingEnv = SimulateReadOnlyBlocksProcessingEnv.Create( false, WorldStateManager, roBlockTree, @@ -140,7 +140,7 @@ protected override async Task Build(ISpecProvider? specProvider LimboLogs.Instance); ReceiptFinder ??= ReceiptStorage; - Bridge ??= new BlockchainBridge(processingEnv, multiCallProcessingEnv, TxPool, ReceiptFinder, filterStore, filterManager, EthereumEcdsa, Timestamper, LogFinder, SpecProvider, new BlocksConfig(), false); + Bridge ??= new BlockchainBridge(processingEnv, simulateProcessingEnv, TxPool, ReceiptFinder, filterStore, filterManager, EthereumEcdsa, Timestamper, LogFinder, SpecProvider, new BlocksConfig(), false); BlockFinder ??= BlockTree; GasPriceOracle ??= new GasPriceOracle(BlockFinder, SpecProvider, LogManager); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index c2e0e29ed4d..36f5dbf80ee 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -345,7 +345,7 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); - public ResultWrapper> eth_multicallV1(MultiCallPayload payload, BlockParameter? blockParameter = null) => + public ResultWrapper> eth_simulateV1(MultiCallPayload payload, BlockParameter? blockParameter = null) => new MultiCallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .Execute(payload, blockParameter); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index f7e62fecb10..7dee389d2b6 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -151,7 +151,7 @@ public interface IEthRpcModule : IRpcModule Description = "Executes a simulation across multiple blocks (does not create a transaction or block)", IsSharable = false, ExampleResponse = "0x")] - ResultWrapper> eth_multicallV1([JsonRpcParameter(ExampleValue = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"},\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}")] MultiCallPayload payload, + ResultWrapper> eth_simulateV1([JsonRpcParameter(ExampleValue = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"},\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}")] MultiCallPayload payload, BlockParameter? blockParameter = null); [JsonRpcMethod(IsImplemented = true, diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 9dda9ff6e64..222e441e65c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -10,7 +10,7 @@ using Nethermind.Core; using Nethermind.Core.Collections; using Nethermind.Facade; -using Nethermind.Facade.Multicall; +using Nethermind.Facade.Simulate; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.MultiCall; using Nethermind.JsonRpc.Data; @@ -18,7 +18,7 @@ namespace Nethermind.JsonRpc.Modules.Eth; -public class MultiCallTxExecutor : ExecutorBase, MultiCallPayload, MultiCallPayload> +public class MultiCallTxExecutor : ExecutorBase, MultiCallPayload, MultiCallPayload> { private long gasCapBudget; @@ -74,7 +74,7 @@ protected override MultiCallPayload Prepare(MultiC return result; } - public override ResultWrapper> Execute( + public override ResultWrapper> Execute( MultiCallPayload call, BlockParameter? blockParameter) { @@ -82,7 +82,7 @@ public override ResultWrapper> Execute( if (searchResult.IsError || searchResult.Object == null) { - return ResultWrapper>.Fail(searchResult); + return ResultWrapper>.Fail(searchResult); } BlockHeader header = searchResult.Object.Header; @@ -94,7 +94,7 @@ public override ResultWrapper> Execute( if (!_blockchainBridge.HasStateForBlock(header!)) { - return ResultWrapper>.Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable); + return ResultWrapper>.Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable); } using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); @@ -102,13 +102,13 @@ public override ResultWrapper> Execute( return Execute(header.Clone(), toProcess, cancellationTokenSource.Token); } - protected override ResultWrapper> Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) + protected override ResultWrapper> Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) { - MultiCallOutput results = _blockchainBridge.MultiCall(header, tx, token); + SimulateOutput results = _blockchainBridge.MultiCall(header, tx, token); return results.Error is null - ? ResultWrapper>.Success(results.Items) - : ResultWrapper>.Fail(results.Error, results.Items); + ? ResultWrapper>.Success(results.Items) + : ResultWrapper>.Fail(results.Error, results.Items); } } From c322262d9a9b44417e0456d6fb5ea17e951d425b Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 22 Jan 2024 08:15:37 +0000 Subject: [PATCH 120/213] fixing post merge --- .../TransactionProcessor.cs | 2 +- .../Nethermind.Evm/VirtualMachine.cs | 2 +- .../Nethermind.Facade/BlockchainBridge.cs | 14 +++--- .../OverridableCodeInfoRepository.cs | 2 +- .../EthModuleBenchmarks.cs | 6 ++- .../JsonRpcServiceTests.cs | 48 +++++++++---------- .../Pruning/OverlayTrieStore.cs | 2 +- 7 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 81e42449f2f..2c826b1f7b8 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -567,7 +567,7 @@ protected virtual bool ExecuteEvmCall( if (unspentGas >= codeDepositGasCost) { var code = substate.Output.ToArray(); - _codeInfoRepository.InsertCode(WorldState, code, env.ExecutingAccount, spec); + _codeInfoRepository.InsertCode(WorldState, code, env.ExecutingAccount, spec); unspentGas -= codeDepositGasCost; } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 38452defb48..c2eecb4ac48 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -81,7 +81,7 @@ public VirtualMachine( public TransactionSubstate Run(EvmState state, IWorldState worldState, ITxTracer txTracer) where TTracingActions : struct, IIsTracing => _evm.Run(state, worldState, txTracer); - + internal readonly ref struct CallResult { public static CallResult InvalidSubroutineEntry => new(EvmExceptionType.InvalidSubroutineEntry); diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 0ba9c353d0a..6e13925fab9 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -156,19 +156,19 @@ public SimulateOutput MultiCall(BlockHeader header, MultiCallPayload _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) ? result : _codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, vmSpec); - + public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) => _codeInfoRepository.GetOrAdd(codeHash, initCode); diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index aa593af5a3a..e2432dc0cb0 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -36,7 +36,7 @@ using BlockTree = Nethermind.Blockchain.BlockTree; using Nethermind.Blockchain.Synchronization; using Nethermind.Config; -using Nethermind.Facade.Multicall; +using Nethermind.Facade.Simulate; using Nethermind.Synchronization.ParallelSync; namespace Nethermind.JsonRpc.Benchmark @@ -129,8 +129,10 @@ TransactionProcessor transactionProcessor new ReadOnlyBlockTree(blockTree), specProvider, LimboLogs.Instance), - MultiCallReadOnlyBlocksProcessingEnv.Create( + SimulateReadOnlyBlocksProcessingEnv.Create( false, + stateManager, + new ReadOnlyBlockTree(blockTree), new ReadOnlyDbProvider(dbProvider, true), specProvider, LimboLogs.Instance), diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index baacd7e2590..8a858e4101f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -81,35 +81,35 @@ public void Eth_module_populates_size_when_returning_block_data() } - [Test] - public void CanRunEthMulticallV1Empty() - { - MultiCallPayload? payload = new() { BlockStateCalls = Array.Empty>() }; + [Test] + public void CanRunEthMulticallV1Empty() + { + MultiCallPayload? payload = new() { BlockStateCalls = Array.Empty>() }; - EthereumJsonSerializer serializer = new(); + EthereumJsonSerializer serializer = new(); - string serializedCall = serializer.Serialize(payload); + string serializedCall = serializer.Serialize(payload); - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_simulateV1(payload).ReturnsForAnyArgs(x => - ResultWrapper>.Success(Array.Empty())); - JsonRpcSuccessResponse? response = - TestRequest(ethRpcModule, "eth_simulateV1", serializedCall) as JsonRpcSuccessResponse; - Assert.IsTrue(response != null); - Assert.That(response?.Result, Is.EqualTo(Array.Empty())); - } + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_simulateV1(payload).ReturnsForAnyArgs(x => + ResultWrapper>.Success(Array.Empty())); + JsonRpcSuccessResponse? response = + TestRequest(ethRpcModule, "eth_simulateV1", serializedCall) as JsonRpcSuccessResponse; + Assert.IsTrue(response != null); + Assert.That(response?.Result, Is.EqualTo(Array.Empty())); + } - [Test] - public void CanHandleOptionalArguments() - { - EthereumJsonSerializer serializer = new(); - string serialized = serializer.Serialize(new TransactionForRpc()); - IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_call(Arg.Any()).ReturnsForAnyArgs(_ => ResultWrapper.Success("0x1")); - JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized) as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo("0x1")); - } + [Test] + public void CanHandleOptionalArguments() + { + EthereumJsonSerializer serializer = new(); + string serialized = serializer.Serialize(new TransactionForRpc()); + IEthRpcModule ethRpcModule = Substitute.For(); + ethRpcModule.eth_call(Arg.Any()).ReturnsForAnyArgs(_ => ResultWrapper.Success("0x1")); + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_call", serialized) as JsonRpcSuccessResponse; + Assert.That(response?.Result, Is.EqualTo("0x1")); + } [Test] public void Case_sensitivity_test() diff --git a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs index d0db76ca06e..c26453ee5d1 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only using System; From a4ae23888eb85e7c2ec82ecf474cda36b790764e Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 22 Jan 2024 09:09:31 +0000 Subject: [PATCH 121/213] Renaming to simulate missed stuff --- .../Nethermind.Api/NethermindApi.cs | 6 +- .../Nethermind.Cli/Modules/EthCliModule.cs | 4 +- ...roxy.cs => SimulateBlockValidatorProxy.cs} | 4 +- .../Nethermind.Facade/BlockchainBridge.cs | 6 +- .../Nethermind.Facade/IBlockchainBridge.cs | 4 +- .../Proxy/Models/MultiCall/BlockOverride.cs | 2 +- .../Proxy/Models/MultiCall/BlockStateCall.cs | 2 +- .../Proxy/Models/MultiCall/CallTransaction.cs | 2 +- .../Proxy/Models/MultiCall/Error.cs | 2 +- .../Proxy/Models/MultiCall/Log.cs | 2 +- .../Proxy/Models/MultiCall/ResultType.cs | 2 +- .../Models/MultiCall/SimulateBlockResult.cs | 4 +- ...allCallResult.cs => SimulateCallResult.cs} | 4 +- ...MultiCallPayload.cs => SimulatePayload.cs} | 6 +- .../MultiCall/TransactionWithSourceDetails.cs | 2 +- .../Simulate/SimulateBlockTracer.cs | 4 +- .../Simulate/SimulateBridgeHelper.cs | 8 +- .../Simulate/SimulateOutput.cs | 2 +- .../SimulateReadOnlyBlocksProcessingEnv.cs | 2 +- .../Simulate/SimulateTxTracer.cs | 8 +- .../JsonRpcServiceTests.cs | 6 +- ...estsBase.cs => EthRpcSimulateTestsBase.cs} | 2 +- ...imulateTestsPrecompilesWithRedirection.cs} | 28 +- ... EthSimulateTestsBlocksAndTransactions.cs} | 30 +- ...iveBase.cs => EthSimulateTestsHiveBase.cs} | 460 +++++++++--------- ...s => EthSimulateTestsSimplePrecompiles.cs} | 18 +- .../Modules/Eth/EthRpcModule.cs | 6 +- .../Modules/Eth/IEthRpcModule.cs | 4 +- ...MultiCallTxExecutor.MultiCallTxExecutor.cs | 18 +- 29 files changed, 324 insertions(+), 324 deletions(-) rename src/Nethermind/Nethermind.Consensus/Validators/{MultiCallBlockValidatorProxy.cs => SimulateBlockValidatorProxy.cs} (88%) rename src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/{MultiCallCallResult.cs => SimulateCallResult.cs} (87%) rename src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/{MultiCallPayload.cs => SimulatePayload.cs} (65%) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/{EthRpcMulticallTestsBase.cs => EthRpcSimulateTestsBase.cs} (99%) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/{EthMulticallTestsPrecompilesWithRedirection.cs => EthSimulateTestsPrecompilesWithRedirection.cs} (87%) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/{EthMulticallTestsBlocksAndTransactions.cs => EthSimulateTestsBlocksAndTransactions.cs} (90%) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/{EthMultiCallTestsHiveBase.cs => EthSimulateTestsHiveBase.cs} (80%) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/{EthMulticallTestsSimplePrecompiles.cs => EthSimulateTestsSimplePrecompiles.cs} (87%) diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 58537b79e00..76cbd028f87 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -79,13 +79,13 @@ public NethermindApi( } private IReadOnlyDbProvider? _readOnlyDbProvider; - private IReadOnlyDbProvider? _multiCallReadOnlyDbProvider; + private IReadOnlyDbProvider? _simulateReadOnlyDbProvider; public IBlockchainBridge CreateBlockchainBridge() { ReadOnlyBlockTree readOnlyTree = BlockTree!.AsReadOnly(); LazyInitializer.EnsureInitialized(ref _readOnlyDbProvider, () => new ReadOnlyDbProvider(DbProvider, false)); - LazyInitializer.EnsureInitialized(ref _multiCallReadOnlyDbProvider, () => new ReadOnlyDbProvider(DbProvider, true)); + LazyInitializer.EnsureInitialized(ref _simulateReadOnlyDbProvider, () => new ReadOnlyDbProvider(DbProvider, true)); // TODO: reuse the same trie cache here ReadOnlyTxProcessingEnv readOnlyTxProcessingEnv = new( @@ -97,7 +97,7 @@ public IBlockchainBridge CreateBlockchainBridge() SimulateReadOnlyBlocksProcessingEnv simulateReadOnlyBlocksProcessingEnv = SimulateReadOnlyBlocksProcessingEnv.Create(false, WorldStateManager!, readOnlyTree, - _multiCallReadOnlyDbProvider, + _simulateReadOnlyDbProvider, SpecProvider, LogManager); diff --git a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs index 216343db2c9..261be73ce46 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs @@ -50,8 +50,8 @@ public JsValue GetProof(string address, string[] storageKeys, string? blockParam } - [CliFunction("eth", "multicallV1")] - public JsValue MultiCallV1(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) + [CliFunction("eth", "simulateV1")] + public JsValue SimulateV1(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) { return NodeManager.PostJint("eth_simulateV1", 1, blockCalls, blockParameter ?? "latest", traceTransfers).Result; } diff --git a/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs b/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs similarity index 88% rename from src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs rename to src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs index 5d8f60d6495..589d38f447f 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/MultiCallBlockValidatorProxy.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs @@ -5,11 +5,11 @@ namespace Nethermind.Consensus.Validators; -public class MultiCallBlockValidatorProxy : IBlockValidator +public class SimulateBlockValidatorProxy : IBlockValidator { private readonly IBlockValidator _baseBlockValidator; - public MultiCallBlockValidatorProxy(IBlockValidator baseBlockValidator) => + public SimulateBlockValidatorProxy(IBlockValidator baseBlockValidator) => _baseBlockValidator = baseBlockValidator; public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle = false) => diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 6e13925fab9..9b5112dcbd4 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -25,7 +25,7 @@ using Nethermind.State; using Nethermind.Core.Extensions; using Nethermind.Config; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using System.Transactions; using Microsoft.CSharp.RuntimeBinder; using Nethermind.Facade.Simulate; @@ -152,13 +152,13 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can }; } - public SimulateOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken) + public SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, CancellationToken cancellationToken) { SimulateBlockTracer simulateOutputTracer = new(payload.TraceTransfers); SimulateOutput result = new(); try { - (bool success, string error) = _simulateBridgeHelper.TryMultiCallTrace(header, payload, simulateOutputTracer.WithCancellation(cancellationToken)); + (bool success, string error) = _simulateBridgeHelper.TrySimulateTrace(header, payload, simulateOutputTracer.WithCancellation(cancellationToken)); if (!success) { diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index 565daed3aa3..5d197f1ac97 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -10,7 +10,7 @@ using Nethermind.Evm; using Nethermind.Facade.Filters; using Nethermind.Facade.Simulate; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; using Nethermind.Trie; using static Nethermind.Facade.BlockchainBridge; @@ -28,7 +28,7 @@ public interface IBlockchainBridge : ILogFinder (TxReceipt? Receipt, TxGasInfo? GasInfo, int LogIndexStart) GetReceiptAndGasInfo(Hash256 txHash); (TxReceipt? Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Hash256 txHash, bool checkTxnPool = true); CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken); - SimulateOutput MultiCall(BlockHeader header, MultiCallPayload payload, CancellationToken cancellationToken); + SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, CancellationToken cancellationToken); CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken); CallOutput CreateAccessList(BlockHeader header, Transaction tx, CancellationToken cancellationToken, bool optimize); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs index abd4efd4757..4edb4501d8c 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs @@ -8,7 +8,7 @@ using Nethermind.Core.Crypto; using Nethermind.Int256; -namespace Nethermind.Facade.Proxy.Models.MultiCall; +namespace Nethermind.Facade.Proxy.Models.Simulate; public class BlockOverride { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs index 38fe1c0d142..db4efb549ba 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using Nethermind.Core; -namespace Nethermind.Facade.Proxy.Models.MultiCall; +namespace Nethermind.Facade.Proxy.Models.Simulate; public class BlockStateCall { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs index ba646f63809..a18c9cdceee 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs @@ -5,7 +5,7 @@ using Nethermind.Int256; using static Nethermind.Core.Extensions.MemoryExtensions; -namespace Nethermind.Facade.Proxy.Models.MultiCall +namespace Nethermind.Facade.Proxy.Models.Simulate { //A stub public class CallTransaction { } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs index 40e207a2908..b9a9b3b2aca 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -namespace Nethermind.Facade.Proxy.Models.MultiCall; +namespace Nethermind.Facade.Proxy.Models.Simulate; public class Error { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs index 8730e921bd2..080e358cd3f 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs @@ -4,7 +4,7 @@ using Nethermind.Core; using Nethermind.Core.Crypto; -namespace Nethermind.Facade.Proxy.Models.MultiCall; +namespace Nethermind.Facade.Proxy.Models.Simulate; public class Log { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/ResultType.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/ResultType.cs index 42788b77621..78e8707e914 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/ResultType.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/ResultType.cs @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -namespace Nethermind.Facade.Proxy.Models.MultiCall; +namespace Nethermind.Facade.Proxy.Models.Simulate; public enum ResultType { diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateBlockResult.cs index 015c9bc82ed..4a9b8140b38 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateBlockResult.cs @@ -8,7 +8,7 @@ using Nethermind.Core.Crypto; using Nethermind.Int256; -namespace Nethermind.Facade.Proxy.Models.MultiCall; +namespace Nethermind.Facade.Proxy.Models.Simulate; public class SimulateBlockResult { @@ -19,7 +19,7 @@ public class SimulateBlockResult public ulong GasUsed { get; set; } public Address FeeRecipient { get; set; } = Address.Zero; public UInt256 BaseFeePerGas { get; set; } - public IEnumerable Calls { get; set; } = Enumerable.Empty(); + public IEnumerable Calls { get; set; } = Enumerable.Empty(); public byte[]? PrevRandao { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs similarity index 87% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs index f3ea1a011b6..3bfe38142f0 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs @@ -3,9 +3,9 @@ using Nethermind.Evm; -namespace Nethermind.Facade.Proxy.Models.MultiCall; +namespace Nethermind.Facade.Proxy.Models.Simulate; -public class MultiCallCallResult +public class SimulateCallResult { public ResultType Type => Status switch diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulatePayload.cs similarity index 65% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulatePayload.cs index 9bc05a11868..eb090ed68d2 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/MultiCallPayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulatePayload.cs @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -namespace Nethermind.Facade.Proxy.Models.MultiCall; +namespace Nethermind.Facade.Proxy.Models.Simulate; -public class MultiCallPayload +public class SimulatePayload { /// /// Definition of blocks that can contain calls and overrides @@ -16,7 +16,7 @@ public class MultiCallPayload public bool TraceTransfers { get; set; } /// - /// When true, the multicall does all validations that a normal EVM would do, except contract sender and signature checks. When false, multicall behaves like eth_call. + /// When true, the simulate does all validations that a normal EVM would do, except contract sender and signature checks. When false, multicall behaves like eth_call. /// public bool Validation { get; set; } = false; } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/TransactionWithSourceDetails.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/TransactionWithSourceDetails.cs index ebb3f621282..2fce8df871a 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/TransactionWithSourceDetails.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/TransactionWithSourceDetails.cs @@ -3,7 +3,7 @@ using Nethermind.Core; -namespace Nethermind.Facade.Proxy.Models.MultiCall; +namespace Nethermind.Facade.Proxy.Models.Simulate; public class TransactionWithSourceDetails { diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 8d7defd305d..0c5e014fdbd 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -6,8 +6,8 @@ using Nethermind.Core; using Nethermind.Core.Collections; using Nethermind.Evm.Tracing; -using Nethermind.Facade.Proxy.Models.MultiCall; -using ResultType = Nethermind.Facade.Proxy.Models.MultiCall.ResultType; +using Nethermind.Facade.Proxy.Models.Simulate; +using ResultType = Nethermind.Facade.Proxy.Models.Simulate.ResultType; namespace Nethermind.Facade.Simulate; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 9cf444de65c..a1d98d99e4f 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -13,7 +13,7 @@ using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; using Nethermind.State; @@ -25,7 +25,7 @@ public class SimulateBridgeHelper private readonly ISpecProvider _specProvider; private readonly IBlocksConfig _blocksConfig; - private static readonly ProcessingOptions _multicallProcessingOptions = ProcessingOptions.ForceProcessing | + private static readonly ProcessingOptions _simulateProcessingOptions = ProcessingOptions.ForceProcessing | ProcessingOptions.IgnoreParentNotOnMainChain | ProcessingOptions.MarkAsProcessed | ProcessingOptions.StoreReceipts; @@ -44,7 +44,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateC blockHeader.StateRoot = env.StateProvider.StateRoot; } - public (bool Success, string Error) TryMultiCallTrace(BlockHeader parent, MultiCallPayload payload, IBlockTracer tracer) + public (bool Success, string Error) TrySimulateTrace(BlockHeader parent, SimulatePayload payload, IBlockTracer tracer) { using SimulateReadOnlyBlocksProcessingEnv? env = _simulateProcessingEnv.Clone(payload.TraceTransfers, payload.Validation); @@ -167,7 +167,7 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction Block? currentBlock = new(callHeader, transactions, Array.Empty()); currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); - ProcessingOptions processingFlags = _multicallProcessingOptions; + ProcessingOptions processingFlags = _simulateProcessingOptions; if (!payload.Validation) { diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs index 9dcfd981dc3..7cf0474407d 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Collections.Generic; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; namespace Nethermind.Facade.Simulate; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index f7ebf22efc7..4e833f91a57 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -118,7 +118,7 @@ private SimulateReadOnlyBlocksProcessingEnv( SpecProvider, _logManager); - _blockValidator = new MultiCallBlockValidatorProxy(blockValidator); + _blockValidator = new SimulateBlockValidatorProxy(blockValidator); } public IReadOnlyBlockTree ReadOnlyBlockTree { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs index 90c01461190..f6ec8481e15 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs @@ -9,7 +9,7 @@ using Nethermind.Core.Crypto; using Nethermind.Evm; using Nethermind.Evm.Tracing; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; namespace Nethermind.Facade.Simulate; @@ -24,11 +24,11 @@ public SimulateTxTracer(bool isTracingTransfers) IsTracingReceipt = true; } - public MultiCallCallResult? TraceResult { get; set; } + public SimulateCallResult? TraceResult { get; set; } public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Hash256? stateRoot = null) { - TraceResult = new MultiCallCallResult() + TraceResult = new SimulateCallResult() { GasUsed = (ulong)gasSpent, ReturnData = output, @@ -45,7 +45,7 @@ public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] outp public override void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Hash256? stateRoot = null) { - TraceResult = new MultiCallCallResult() + TraceResult = new SimulateCallResult() { GasUsed = (ulong)gasSpent, Error = new Error diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 8a858e4101f..d2cf839dad9 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -16,7 +16,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules; @@ -82,9 +82,9 @@ public void Eth_module_populates_size_when_returning_block_data() [Test] - public void CanRunEthMulticallV1Empty() + public void CanRunEthSimulateV1Empty() { - MultiCallPayload? payload = new() { BlockStateCalls = Array.Empty>() }; + SimulatePayload? payload = new() { BlockStateCalls = Array.Empty>() }; EthereumJsonSerializer serializer = new(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs similarity index 99% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs index a7324516611..fbce5182f52 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcMulticallTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs @@ -27,7 +27,7 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; -public class EthRpcMulticallTestsBase +public class EthRpcSimulateTestsBase { public static Task CreateChain(IReleaseSpec? releaseSpec = null) { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs similarity index 87% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs index c1797a4a667..440205139d7 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthMulticallTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs @@ -13,14 +13,14 @@ using Nethermind.Evm; using Nethermind.Evm.Precompiles; using Nethermind.Facade.Proxy.Models; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; using NUnit.Framework; namespace Nethermind.JsonRpc.Test.Modules.Eth; -public class EthMulticallTestsPrecompilesWithRedirection +public class EthSimulateTestsPrecompilesWithRedirection { public static byte[] HexStringToByteArray(string hex) { @@ -39,9 +39,9 @@ public static byte[] HexStringToByteArray(string hex) } [Test] - public async Task Test_eth_multicall_create() + public async Task Test_eth_simulate_create() { - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Transaction systemTransactionForModifiedVm = new() { @@ -55,7 +55,7 @@ public async Task Test_eth_multicall_create() TransactionForRpc transactionForRpc = new(systemTransactionForModifiedVm) { Nonce = null }; - MultiCallPayload payload = new() + SimulatePayload payload = new() { BlockStateCalls = new BlockStateCall[] { @@ -82,7 +82,7 @@ public async Task Test_eth_multicall_create() }; //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); @@ -95,9 +95,9 @@ public async Task Test_eth_multicall_create() /// This test verifies that a temporary forked blockchain can redirect precompiles /// [Test] - public async Task Test_eth_multicall_ecr_moved() + public async Task Test_eth_simulate_ecr_moved() { - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); //The following opcodes code is based on the following contract compiled: /* function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns(address) @@ -150,13 +150,13 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( .Op(Instruction.RETURN) .Done; - byte[] transactionData = EthRpcMulticallTestsBase.GetTxData(chain, TestItem.PrivateKeyA); + byte[] transactionData = EthRpcSimulateTestsBase.GetTxData(chain, TestItem.PrivateKeyA); var headHash = chain.BlockFinder.Head!.Hash!; - Address? contractAddress = await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, - EthMulticallTestsSimplePrecompiles.EcRecoverCallerContractBytecode); + Address? contractAddress = await EthRpcSimulateTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, + EthSimulateTestsSimplePrecompiles.EcRecoverCallerContractBytecode); - var tst = EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + var tst = EthRpcSimulateTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); @@ -176,7 +176,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( TransactionForRpc transactionForRpc = new(systemTransactionForModifiedVm) { Nonce = null }; - MultiCallPayload payload = new() + SimulatePayload payload = new() { BlockStateCalls = new BlockStateCall[] { @@ -204,7 +204,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( }; //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); Debug.Assert(contractAddress != null, nameof(contractAddress) + " != null"); Assert.IsTrue(chain.State.AccountExists(contractAddress)); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsBlocksAndTransactions.cs similarity index 90% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsBlocksAndTransactions.cs index 754136b3cdb..2c7bba8f972 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsBlocksAndTransactions.cs @@ -12,17 +12,17 @@ using Nethermind.Core.Test.Builders; using Nethermind.Crypto; using Nethermind.Facade.Proxy.Models; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Serialization.Json; using NUnit.Framework; -using ResultType = Nethermind.Facade.Proxy.Models.MultiCall.ResultType; +using ResultType = Nethermind.Facade.Proxy.Models.Simulate.ResultType; namespace Nethermind.JsonRpc.Test.Modules.Eth; -public class EthMulticallTestsBlocksAndTransactions +public class EthSimulateTestsBlocksAndTransactions { private static Transaction GetTransferTxData(UInt256 nonce, IEthereumEcdsa ethereumEcdsa, PrivateKey from, Address to, UInt256 ammount) { @@ -42,9 +42,9 @@ private static Transaction GetTransferTxData(UInt256 nonce, IEthereumEcdsa ether } [Test] - public async Task Test_eth_multicall_serialisation() + public async Task Test_eth_simulate_serialisation() { - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); PrivateKey pk = new("0xc7ba1a2892ec0ea1940eebeae739b1effe0543b3104469d5b66625f49ca86e94"); @@ -59,7 +59,7 @@ public async Task Test_eth_multicall_serialisation() GetTransferTxData(nextNonceA, chain.EthereumEcdsa, pk, new Address("0xA143c0eA6f8059f7B3651417ccD2bAA80FC2d4Ab"), 4_000_000); - MultiCallPayload payload = new() + SimulatePayload payload = new() { BlockStateCalls = new BlockStateCall[] { @@ -97,7 +97,7 @@ public async Task Test_eth_multicall_serialisation() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //Assert.Equals(chain.BlockTree.BestPersistedState!, chain.BlockTree.Head!.Number); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; @@ -117,9 +117,9 @@ public async Task Test_eth_multicall_serialisation() /// Note that if we get blocks before head we set simulation start state to one of that first block ///
[Test] - public async Task Test_eth_multicall_eth_moved() + public async Task Test_eth_simulate_eth_moved() { - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); UInt256 nonceA = chain.State.GetNonce(TestItem.AddressA); Transaction txMainnetAtoB = @@ -133,7 +133,7 @@ public async Task Test_eth_multicall_eth_moved() Transaction txAtoB4 = GetTransferTxData(nonceA + 4, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); - MultiCallPayload payload = new() + SimulatePayload payload = new() { BlockStateCalls = new BlockStateCall[] { @@ -178,7 +178,7 @@ public async Task Test_eth_multicall_eth_moved() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; @@ -195,9 +195,9 @@ public async Task Test_eth_multicall_eth_moved() /// This test verifies that a temporary forked blockchain can make transactions, blocks and report on them /// [Test] - public async Task Test_eth_multicall_transactions_forced_fail() + public async Task Test_eth_simulate_transactions_forced_fail() { - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); UInt256 nonceA = chain.State.GetNonce(TestItem.AddressA); @@ -212,7 +212,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, UInt256.MaxValue); TransactionForRpc transactionForRpc = new(txAtoB2) { Nonce = null }; TransactionForRpc transactionForRpc2 = new(txAtoB1) { Nonce = null }; - MultiCallPayload payload = new() + SimulatePayload payload = new() { BlockStateCalls = new BlockStateCall[] { @@ -258,7 +258,7 @@ public async Task Test_eth_multicall_transactions_forced_fail() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - MultiCallTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsHiveBase.cs similarity index 80% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsHiveBase.cs index 906550d2e25..12b6ebe56d1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMultiCallTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsHiveBase.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Nethermind.Blockchain.Find; using Nethermind.Core.Crypto; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.JsonRpc.Data; using Nethermind.Serialization.Json; using Newtonsoft.Json; @@ -15,43 +15,43 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; -public class EthMultiCallTestsHiveBase +public class EthSimulateTestsHiveBase { [Test] - public async Task TestmulticallAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit() + public async Task TestsimulateAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallAddMoreNonDefinedBlockStateCallsThanFit() + public async Task TestsimulateAddMoreNonDefinedBlockStateCallsThanFit() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0xb\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallAddMoreNonDefinedBlockStateCallsThanFit"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateAddMoreNonDefinedBlockStateCallsThanFit"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBasefeeTooLowWithValidation38012() + public async Task TestsimulateBasefeeTooLowWithValidation38012() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0x0\",\"maxPriorityFeePerGas\":\"0x0\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBasefeeTooLowWithValidation38012"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBasefeeTooLowWithValidation38012"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.That(result.Data.First().PrevRandao, Is.EqualTo(new Hash256("0x0000000000000000000000000000000000000000000000000000000000000000").BytesToArray())); @@ -61,702 +61,702 @@ public async Task TestmulticallBasefeeTooLowWithValidation38012() } [Test] - public async Task TestmulticallBasefeeTooLowWithoutValidation38012() + public async Task TestsimulateBasefeeTooLowWithoutValidation38012() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0x0\",\"maxPriorityFeePerGas\":\"0x0\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBasefeeTooLowWithoutValidation38012"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBasefeeTooLowWithoutValidation38012"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBlockNumOrder38020() + public async Task TestsimulateBlockNumOrder38020() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xc\"},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]},{\"blockOverrides\":{\"number\":\"0xb\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBlockNumOrder38020"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBlockNumOrder38020"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBlockOverrideReflectedInContractSimple() + public async Task TestsimulateBlockOverrideReflectedInContractSimple() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\",\"time\":\"0x64\"}},{\"blockOverrides\":{\"number\":\"0x14\",\"time\":\"0x65\"}},{\"blockOverrides\":{\"number\":\"0x15\",\"time\":\"0xc8\"}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBlockOverrideReflectedInContractSimple"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBlockOverrideReflectedInContractSimple"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBlockOverrideReflectedInContract() + public async Task TestsimulateBlockOverrideReflectedInContract() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\",\"time\":\"0x64\",\"gasLimit\":\"0xa\",\"feeRecipient\":\"0xc000000000000000000000000000000000000000\",\"prevRandao\":\"0x0000000000000000000000000000000000000000000000000000000000000012\",\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x14\",\"time\":\"0xc8\",\"gasLimit\":\"0x14\",\"feeRecipient\":\"0xc100000000000000000000000000000000000000\",\"prevRandao\":\"0x0000000000000000000000000000000000000000000000000000000000001234\",\"baseFeePerGas\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x15\",\"time\":\"0x12c\",\"gasLimit\":\"0x15\",\"feeRecipient\":\"0xc200000000000000000000000000000000000000\",\"prevRandao\":\"0x0000000000000000000000000000000000000000000000000000000000001234\",\"baseFeePerGas\":\"0x1e\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBlockOverrideReflectedInContract"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBlockOverrideReflectedInContract"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBlockTimestampAutoIncrement() + public async Task TestsimulateBlockTimestampAutoIncrement() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xb\"}},{\"blockOverrides\":{}},{\"blockOverrides\":{\"time\":\"0xc\"}},{\"blockOverrides\":{}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBlockTimestampAutoIncrement"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBlockTimestampAutoIncrement"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBlockTimestampNonIncrement() + public async Task TestsimulateBlockTimestampNonIncrement() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xc\"}},{\"blockOverrides\":{\"time\":\"0xc\"}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBlockTimestampNonIncrement"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBlockTimestampNonIncrement"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBlockTimestampOrder38021() + public async Task TestsimulateBlockTimestampOrder38021() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xc\"}},{\"blockOverrides\":{\"time\":\"0xb\"}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBlockTimestampOrder38021"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBlockTimestampOrder38021"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBlockTimestampsIncrementing() + public async Task TestsimulateBlockTimestampsIncrementing() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xb\"}},{\"blockOverrides\":{\"time\":\"0xc\"}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBlockTimestampsIncrementing"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBlockTimestampsIncrementing"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBlockhashComplex() + public async Task TestsimulateBlockhashComplex() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010\"}]},{\"blockOverrides\":{\"number\":\"0x1e\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e000000000000000000000000000000000000000000000000000000000000001d\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBlockhashComplex"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBlockhashComplex"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBlockhashSimple() + public async Task TestsimulateBlockhashSimple() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBlockhashSimple"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBlockhashSimple"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallBlockhashStartBeforeHead() + public async Task TestsimulateBlockhashStartBeforeHead() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000002\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000013\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallBlockhashStartBeforeHead"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateBlockhashStartBeforeHead"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallCheckInvalidNonce() + public async Task TestsimulateCheckInvalidNonce() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x4e20\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc000000000000000000000000000000000000000\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x1\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x0\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallCheckInvalidNonce"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateCheckInvalidNonce"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallCheckThatBalanceIsThereAfterNewBlock() + public async Task TestsimulateCheckThatBalanceIsThereAfterNewBlock() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x2710\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallCheckThatBalanceIsThereAfterNewBlock"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateCheckThatBalanceIsThereAfterNewBlock"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallCheckThatNonceIncreases() + public async Task TestsimulateCheckThatNonceIncreases() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x4e20\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc000000000000000000000000000000000000000\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x1\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x2\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallCheckThatNonceIncreases"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateCheckThatNonceIncreases"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallEmptyCallsAndOverridesMulticall() + public async Task TestsimulateEmptyCallsAndOverrides() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{},\"calls\":[{}]},{\"stateOverrides\":{},\"calls\":[{}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallEmptyCallsAndOverridesMulticall"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateEmptyCallsAndOverrides"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallEthSendShouldNotProduceLogsByDefault() + public async Task TestsimulateEthSendShouldNotProduceLogsByDefault() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallEthSendShouldNotProduceLogsByDefault"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateEthSendShouldNotProduceLogsByDefault"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallEthSendShouldNotProduceLogsOnRevert() + public async Task TestsimulateEthSendShouldNotProduceLogsOnRevert() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallEthSendShouldNotProduceLogsOnRevert"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateEthSendShouldNotProduceLogsOnRevert"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallEthSendShouldProduceLogs() + public async Task TestsimulateEthSendShouldProduceLogs() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallEthSendShouldProduceLogs"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateEthSendShouldProduceLogs"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallEthSendShouldProduceMoreLogsOnForward() + public async Task TestsimulateEthSendShouldProduceMoreLogsOnForward() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"input\":\"0x4b64e4920000000000000000000000000000000000000000000000000000000000000100\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallEthSendShouldProduceMoreLogsOnForward"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateEthSendShouldProduceMoreLogsOnForward"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallEthSendShouldProduceNoLogsOnForwardRevert() + public async Task TestsimulateEthSendShouldProduceNoLogsOnForwardRevert() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"input\":\"0x4b64e492c200000000000000000000000000000000000000000000000000000000000000\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallEthSendShouldProduceNoLogsOnForwardRevert"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateEthSendShouldProduceNoLogsOnForwardRevert"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallFeeRecipientReceivingFunds() + public async Task TestsimulateFeeRecipientReceivingFunds() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\",\"feeRecipient\":\"0xc200000000000000000000000000000000000000\",\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0xa\",\"maxPriorityFeePerGas\":\"0xa\",\"nonce\":\"0x0\",\"input\":\"0x\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x1\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x2\",\"input\":\"0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000\"}]}],\"traceTransfers\":true,\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallFeeRecipientReceivingFunds"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateFeeRecipientReceivingFunds"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallGasFeesAndValueError38014WithValidation() + public async Task TestsimulateGasFeesAndValueError38014WithValidation() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallGasFeesAndValueError38014WithValidation"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateGasFeesAndValueError38014WithValidation"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallGasFeesAndValueError38014() + public async Task TestsimulateGasFeesAndValueError38014() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallGasFeesAndValueError38014"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateGasFeesAndValueError38014"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallGetBlockProperties() + public async Task TestsimulateGetBlockProperties() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallGetBlockProperties"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateGetBlockProperties"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallInstrictGas38013() + public async Task TestsimulateInstrictGas38013() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"gas\":\"0x0\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallInstrictGas38013"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateInstrictGas38013"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallLogs() + public async Task TestsimulateLogs() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80600080a1600080f3\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x6057361d0000000000000000000000000000000000000000000000000000000000000005\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallLogs"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateLogs"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallMoveAccountTwice() + public async Task TestsimulateMoveAccountTwice() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x3e8\"},\"0xc200000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc300000000000000000000000000000000000000\":{\"balance\":\"0xbb8\"},\"0xc400000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}}},{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0xbb8\",\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"},\"0xc200000000000000000000000000000000000000\":{\"balance\":\"0xfa0\",\"MovePrecompileToAddress\":\"0xc300000000000000000000000000000000000000\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc400000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc400000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc400000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c300000000000000000000000000000000000000\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallMoveAccountTwice"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateMoveAccountTwice"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallMoveEcrecoverAndCall() + public async Task TestsimulateMoveEcrecoverAndCall() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}]},{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallMoveEcrecoverAndCall"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateMoveEcrecoverAndCall"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallMoveToAddressItselfReference38022() + public async Task TestsimulateMoveToAddressItselfReference38022() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"},\"0xc100000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc100000000000000000000000000000000000000\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x1\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallMoveToAddressItselfReference38022"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateMoveToAddressItselfReference38022"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallMoveTwoAccountsToSame38023() + public async Task TestsimulateMoveTwoAccountsToSame38023() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"},\"0x0000000000000000000000000000000000000002\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"}}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallMoveTwoAccountsToSame38023"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateMoveTwoAccountsToSame38023"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallMoveTwoNonPrecompilesAccountsToSame() + public async Task TestsimulateMoveTwoNonPrecompilesAccountsToSame() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0100000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"},\"0x0200000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"}}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallMoveTwoNonPrecompilesAccountsToSame"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateMoveTwoNonPrecompilesAccountsToSame"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallOverrideAddressTwiceInSeparateBlockStateCalls() + public async Task TestsimulateOverrideAddressTwiceInSeparateBlockStateCalls() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]},{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallOverrideAddressTwiceInSeparateBlockStateCalls"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateOverrideAddressTwiceInSeparateBlockStateCalls"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallOverrideAddressTwice() + public async Task TestsimulateOverrideAddressTwice() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallOverrideAddressTwice"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateOverrideAddressTwice"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallOverrideAllInBlockStateCalls() + public async Task TestsimulateOverrideAllInBlockStateCalls() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0x3e9\",\"time\":\"0x3eb\",\"gasLimit\":\"0x3ec\",\"feeRecipient\":\"0xc200000000000000000000000000000000000000\",\"prevRandao\":\"0xc300000000000000000000000000000000000000000000000000000000000000\",\"baseFeePerGas\":\"0x3ef\"}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallOverrideAllInBlockStateCalls"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateOverrideAllInBlockStateCalls"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallOverrideBlockNum() + public async Task TestsimulateOverrideBlockNum() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xb\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]},{\"blockOverrides\":{\"number\":\"0xc\"},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallOverrideBlockNum"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateOverrideBlockNum"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallOverrideEcrecover() + public async Task TestsimulateOverrideEcrecover() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"},\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallOverrideEcrecover"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateOverrideEcrecover"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallOverrideIdentity() + public async Task TestsimulateOverrideIdentity() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000004\":{\"code\":\"0x\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1234\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000004\",\"input\":\"0x1234\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallOverrideIdentity"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateOverrideIdentity"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallOverrideSha256() + public async Task TestsimulateOverrideSha256() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000002\":{\"code\":\"0x\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1234\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000002\",\"input\":\"0x1234\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallOverrideSha256"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateOverrideSha256"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallPrecompileIsSendingTransaction() + public async Task TestsimulatePrecompileIsSendingTransaction() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0x0000000000000000000000000000000000000004\",\"to\":\"0x0000000000000000000000000000000000000002\",\"input\":\"0x1234\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallPrecompileIsSendingTransaction"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulatePrecompileIsSendingTransaction"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallRunOutOfGasInBlock38015() + public async Task TestsimulateRunOutOfGasInBlock38015() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"gasLimit\":\"0x16e360\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063815b8ab414610030575b600080fd5b61004a600480360381019061004591906100b6565b61004c565b005b60005a90505b60011561007657815a826100669190610112565b106100715750610078565b610052565b505b50565b600080fd5b6000819050919050565b61009381610080565b811461009e57600080fd5b50565b6000813590506100b08161008a565b92915050565b6000602082840312156100cc576100cb61007b565b5b60006100da848285016100a1565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061011d82610080565b915061012883610080565b92508282039050818111156101405761013f6100e3565b5b9291505056fea2646970667358221220a659ba4db729a6ee4db02fcc5c1118db53246b0e5e686534fc9add6f2e93faec64736f6c63430008120033\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallRunOutOfGasInBlock38015"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateRunOutOfGasInBlock38015"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallSelfDestructingStateOverride() + public async Task TestsimulateSelfDestructingStateOverride() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033\"},\"0xc300000000000000000000000000000000000000\":{\"code\":\"0x73000000000000000000000000000000000000000030146080604052600436106100355760003560e01c8063dce4a4471461003a575b600080fd5b610054600480360381019061004f91906100f8565b61006a565b60405161006191906101b5565b60405180910390f35b6060813b6040519150601f19601f602083010116820160405280825280600060208401853c50919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100c58261009a565b9050919050565b6100d5816100ba565b81146100e057600080fd5b50565b6000813590506100f2816100cc565b92915050565b60006020828403121561010e5761010d610095565b5b600061011c848285016100e3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561015f578082015181840152602081019050610144565b60008484015250505050565b6000601f19601f8301169050919050565b600061018782610125565b6101918185610130565b93506101a1818560208601610141565b6101aa8161016b565b840191505092915050565b600060208201905081810360008301526101cf818461017c565b90509291505056fea26469706673582212206a5f0cd9f230619fa520fc4b9d4b518643258cad412f2fa33945ce528b4b895164736f6c63430008120033\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"input\":\"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x83197ef0\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"input\":\"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]},{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"input\":\"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallSelfDestructingStateOverride"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateSelfDestructingStateOverride"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallSetReadStorage() + public async Task TestsimulateSetReadStorage() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x6057361d0000000000000000000000000000000000000000000000000000000000000005\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x2e64cec1\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallSetReadStorage"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateSetReadStorage"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallSimpleNoFundsWithBalanceQuerying() + public async Task TestsimulateSimpleNoFundsWithBalanceQuerying() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallSimpleNoFundsWithBalanceQuerying"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateSimpleNoFundsWithBalanceQuerying"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallSimpleNoFundsWithValidationWithoutNonces() + public async Task TestsimulateSimpleNoFundsWithValidationWithoutNonces() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallSimpleNoFundsWithValidationWithoutNonces"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateSimpleNoFundsWithValidationWithoutNonces"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallSimpleNoFundsWithValidation() + public async Task TestsimulateSimpleNoFundsWithValidation() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"nonce\":\"0x1\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallSimpleNoFundsWithValidation"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateSimpleNoFundsWithValidation"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallSimpleNoFunds() + public async Task TestsimulateSimpleNoFunds() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallSimpleNoFunds"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateSimpleNoFunds"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallSimpleSendFromContractNoBalance() + public async Task TestsimulateSimpleSendFromContractNoBalance() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallSimpleSendFromContractNoBalance"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateSimpleSendFromContractNoBalance"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallSimpleSendFromContractWithValidation() + public async Task TestsimulateSimpleSendFromContractWithValidation() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\",\"balance\":\"0x3e8\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true,\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallSimpleSendFromContractWithValidation"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateSimpleSendFromContractWithValidation"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallSimpleSendFromContract() + public async Task TestsimulateSimpleSendFromContract() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\",\"balance\":\"0x3e8\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallSimpleSendFromContract"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateSimpleSendFromContract"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallSimple() + public async Task TestsimulateSimple() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x3e8\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallSimple"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateSimple"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallTransactionTooHighNonce() + public async Task TestsimulateTransactionTooHighNonce() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x64\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallTransactionTooHighNonce"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateTransactionTooHighNonce"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallTransactionTooLowNonce38010() + public async Task TestsimulateTransactionTooLowNonce38010() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"nonce\":\"0xa\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x0\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallTransactionTooLowNonce38010"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateTransactionTooLowNonce38010"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallTransferOverBlockStateCalls() + public async Task TestsimulateTransferOverBlockStateCalls() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]},{\"stateOverrides\":{\"0xc300000000000000000000000000000000000000\":{\"balance\":\"0x0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc300000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallTransferOverBlockStateCalls"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateTransferOverBlockStateCalls"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } [Test] - public async Task TestmulticallTryToMoveNonPrecompile() + public async Task TestsimulateTryToMoveNonPrecompile() { EthereumJsonSerializer serializer = new(); string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"nonce\":\"0x5\"}}},{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc100000000000000000000000000000000000000\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc000000000000000000000000000000000000000\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x5\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); - Console.WriteLine("current test: multicallTryToMoveNonPrecompile"); + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateTryToMoveNonPrecompile"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsSimplePrecompiles.cs similarity index 87% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsSimplePrecompiles.cs index 3b58a5e773a..5cce1fe913e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthMulticallTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsSimplePrecompiles.cs @@ -15,12 +15,12 @@ using Nethermind.Facade; using Nethermind.Facade.Simulate; using Nethermind.Facade.Proxy.Models; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using NUnit.Framework; namespace Nethermind.JsonRpc.Test.Modules.Eth; -public class EthMulticallTestsSimplePrecompiles +public class EthSimulateTestsSimplePrecompiles { /* Compiled contract * Call example for TestItem.AddressA @@ -44,11 +44,11 @@ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure return /// This test verifies that a temporary forked blockchain can updates precompiles /// [Test] - public async Task Test_eth_multicall_erc() + public async Task Test_eth_simulate_erc() { // Arrange - TestRpcBlockchain chain = await EthRpcMulticallTestsBase.CreateChain(); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); //Empose Opcode instead of EcRecoverPrecompile, it returns const TestItem.AddressE address byte[] code = Prepare.EvmCode @@ -71,10 +71,10 @@ public async Task Test_eth_multicall_erc() byte[] s = signature.S; Address? contractAddress = - await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, + await EthRpcSimulateTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EcRecoverCallerContractBytecode); - byte[] transactionData = EthRpcMulticallTestsBase.GenerateTransactionDataForEcRecover(messageHash, v, r, s); + byte[] transactionData = EthRpcSimulateTestsBase.GenerateTransactionDataForEcRecover(messageHash, v, r, s); SystemTransaction systemTransactionForModifiedVM = new() { @@ -90,7 +90,7 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe HadGasLimitInRequest = false, HadNonceInRequest = false }; - MultiCallPayload payload = new() + SimulatePayload payload = new() { BlockStateCalls = new[] { @@ -109,7 +109,7 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe // Act - SimulateOutput result = chain.Bridge.MultiCall(chain.BlockFinder.Head?.Header!, payload, CancellationToken.None); + SimulateOutput result = chain.Bridge.Simulate(chain.BlockFinder.Head?.Header!, payload, CancellationToken.None); Log[]? logs = result.Items.First().Calls.First().Logs; byte[] addressBytes = result.Items.First().Calls.First().ReturnData! .SliceWithZeroPaddingEmptyOnError(12, 20); @@ -118,7 +118,7 @@ await EthRpcMulticallTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKe //Check that initial VM is intact Address? mainChainRpcAddress = - EthRpcMulticallTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + EthRpcSimulateTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); Assert.NotNull(mainChainRpcAddress); Assert.That(mainChainRpcAddress, Is.EqualTo(TestItem.AddressA)); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 36f5dbf80ee..ce7f9311c0d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -19,7 +19,7 @@ using Nethermind.Facade; using Nethermind.Facade.Eth; using Nethermind.Facade.Filters; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth.FeeHistory; @@ -345,8 +345,8 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter); - public ResultWrapper> eth_simulateV1(MultiCallPayload payload, BlockParameter? blockParameter = null) => - new MultiCallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) + public ResultWrapper> eth_simulateV1(SimulatePayload payload, BlockParameter? blockParameter = null) => + new SimulateTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .Execute(payload, blockParameter); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 7dee389d2b6..f58cfcfc139 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -8,7 +8,7 @@ using Nethermind.Core.Crypto; using Nethermind.Facade.Eth; using Nethermind.Facade.Filters; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy; using Nethermind.Int256; @@ -151,7 +151,7 @@ public interface IEthRpcModule : IRpcModule Description = "Executes a simulation across multiple blocks (does not create a transaction or block)", IsSharable = false, ExampleResponse = "0x")] - ResultWrapper> eth_simulateV1([JsonRpcParameter(ExampleValue = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"},\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}")] MultiCallPayload payload, + ResultWrapper> eth_simulateV1([JsonRpcParameter(ExampleValue = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"},\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}")] SimulatePayload payload, BlockParameter? blockParameter = null); [JsonRpcMethod(IsImplemented = true, diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs index 222e441e65c..91013498980 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs @@ -12,25 +12,25 @@ using Nethermind.Facade; using Nethermind.Facade.Simulate; using Nethermind.Facade.Proxy.Models; -using Nethermind.Facade.Proxy.Models.MultiCall; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.JsonRpc.Data; using static Microsoft.FSharp.Core.ByRefKinds; namespace Nethermind.JsonRpc.Modules.Eth; -public class MultiCallTxExecutor : ExecutorBase, MultiCallPayload, MultiCallPayload> +public class SimulateTxExecutor : ExecutorBase, SimulatePayload, SimulatePayload> { private long gasCapBudget; - public MultiCallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : + public SimulateTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : base(blockchainBridge, blockFinder, rpcConfig) { gasCapBudget = rpcConfig.GasCap ?? long.MaxValue; } - protected override MultiCallPayload Prepare(MultiCallPayload call) + protected override SimulatePayload Prepare(SimulatePayload call) { - MultiCallPayload? result = new() + SimulatePayload? result = new() { TraceTransfers = call.TraceTransfers, Validation = call.Validation, @@ -75,7 +75,7 @@ protected override MultiCallPayload Prepare(MultiC return result; } public override ResultWrapper> Execute( - MultiCallPayload call, + SimulatePayload call, BlockParameter? blockParameter) { SearchResult searchResult = _blockFinder.SearchForBlock(blockParameter); @@ -98,13 +98,13 @@ public override ResultWrapper> Execute( } using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); - MultiCallPayload? toProcess = Prepare(call); + SimulatePayload? toProcess = Prepare(call); return Execute(header.Clone(), toProcess, cancellationTokenSource.Token); } - protected override ResultWrapper> Execute(BlockHeader header, MultiCallPayload tx, CancellationToken token) + protected override ResultWrapper> Execute(BlockHeader header, SimulatePayload tx, CancellationToken token) { - SimulateOutput results = _blockchainBridge.MultiCall(header, tx, token); + SimulateOutput results = _blockchainBridge.Simulate(header, tx, token); return results.Error is null ? ResultWrapper>.Success(results.Items) From 56960ae4b56ac641c6cd06157356b2bb85484fe0 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 23 Jan 2024 17:28:20 +0000 Subject: [PATCH 122/213] Fixing tree access --- .../NonDistructiveBlockTreeOverlay.cs | 14 ++++++++-- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 4 +-- .../SimulateReadOnlyBlocksProcessingEnv.cs | 26 ++++++++++++++----- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs b/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs index 96c072395ed..88142bd6406 100644 --- a/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs +++ b/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs @@ -301,12 +301,22 @@ public void RecalculateTreeLevels() public bool IsMainChain(BlockHeader blockHeader) { - return _overlayTree.IsMainChain(blockHeader) || _baseTree.IsMainChain(blockHeader); + return _baseTree.IsMainChain(blockHeader) || _overlayTree.IsMainChain(blockHeader); } public bool IsMainChain(Hash256 blockHash) { - return _overlayTree.IsMainChain(blockHash) || _baseTree.IsMainChain(blockHash); + + try + { + if (_baseTree.IsMainChain(blockHash)) return true; + } + catch + { + // ignored as we have _overlayTree to look into + } + + return _overlayTree.IsMainChain(blockHash); } public BlockHeader FindBestSuggestedHeader() diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index d8601f5d759..fdb2407bc47 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -15,8 +15,8 @@ public class ReadOnlyTxProcessingEnvBase { public IStateReader StateReader { get; } public IWorldState StateProvider { get; } - public IBlockTree BlockTree { get; } - public IBlockhashProvider BlockhashProvider { get; } + public IBlockTree BlockTree { get; protected set; } + public IBlockhashProvider BlockhashProvider { get; protected set; } protected ReadOnlyTxProcessingEnvBase( IWorldStateManager worldStateManager, diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 4e833f91a57..6002568e4a9 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -10,6 +10,7 @@ using Nethermind.Consensus.Processing; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; +using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Db; @@ -44,9 +45,16 @@ public static SimulateReadOnlyBlocksProcessingEnv Create( ILogManager? logManager = null, bool doValidation = false) { - IReadOnlyDbProvider dbProvider = new ReadOnlyDbProvider(readOnlyDbProvider, true); - OverlayTrieStore overlayTrieStore = new(dbProvider.StateDb, worldStateManager.TrieStore, logManager); - OverlayWorldStateManager overlayWorldStateManager = new(worldStateManager, dbProvider, overlayTrieStore, logManager); + IReadOnlyDbProvider editableDbProvider = new ReadOnlyDbProvider(readOnlyDbProvider, true); + + var emptyDbProvider = new DbProvider(); + StandardDbInitializer? standardDbInitializer = new StandardDbInitializer(emptyDbProvider, new MemDbFactory()); + standardDbInitializer.InitStandardDbs(true); + IReadOnlyDbProvider dbProvider = new ReadOnlyDbProvider(emptyDbProvider, true); + + OverlayTrieStore overlayTrieStore = new(editableDbProvider.StateDb, worldStateManager.TrieStore, logManager); + OverlayWorldStateManager overlayWorldStateManager = new(worldStateManager, editableDbProvider, overlayTrieStore, logManager); + IBlockStore blockStore = new BlockStore(dbProvider.BlocksDb); IHeaderStore headerStore = new HeaderStore(dbProvider.HeadersDb, dbProvider.BlockNumbersDb); @@ -63,15 +71,16 @@ public static SimulateReadOnlyBlocksProcessingEnv Create( NullBloomStorage.Instance, new SyncConfig(), logManager); - var blockTree = new NonDistructiveBlockTreeOverlay(roBlockTree, tmpBlockTree); + + //var blockTree = new NonDistructiveBlockTreeOverlay(roBlockTree, tmpBlockTree); return new SimulateReadOnlyBlocksProcessingEnv( traceTransfers, overlayWorldStateManager, roBlockTree, - dbProvider, + editableDbProvider, //trieStore, - blockTree, + tmpBlockTree, specProvider, logManager, doValidation); @@ -97,10 +106,15 @@ private SimulateReadOnlyBlocksProcessingEnv( ReadOnlyBlockTree = roBlockTree; DbProvider = readOnlyDbProvider; //_trieStore = trieStore; + WorldStateManager = worldStateManager; _logManager = logManager; SpecProvider = specProvider; _doValidation = doValidation; + + BlockTree = new NonDistructiveBlockTreeOverlay(ReadOnlyBlockTree, blockTree); + BlockhashProvider = new BlockhashProvider(BlockTree, logManager); + CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); VirtualMachine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); From df4aee11bcbf42b07c7be0477d88c63a1b15a977 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 7 Feb 2024 08:30:19 +0000 Subject: [PATCH 123/213] MissingTrieNodeException fix --- .../Simulate/SimulateReadOnlyBlocksProcessingEnv.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 6cae995dd11..3b5a864a330 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -114,8 +114,9 @@ private SimulateReadOnlyBlocksProcessingEnv( BlockTree = new NonDistructiveBlockTreeOverlay(ReadOnlyBlockTree, blockTree); BlockhashProvider = new BlockhashProvider(BlockTree, logManager); - var store = new TrieStore(DbProvider.StateDb, LimboLogs.Instance); - StateProvider = new WorldState(store, DbProvider.CodeDb, LimboLogs.Instance); + //var store = new TrieStore(DbProvider.StateDb, LimboLogs.Instance); + //StateProvider = new WorldState(store, DbProvider.CodeDb, LimboLogs.Instance); + StateProvider = WorldStateManager.GlobalWorldState; CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); From 1d07f619ac418bff5dee0a23f6e40022821ed5c3 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 8 Feb 2024 08:30:17 +0000 Subject: [PATCH 124/213] minor debuggability tree exploration fix --- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 2 +- .../SimulateReadOnlyBlocksProcessingEnv.cs | 5 +- .../OverlayWorldStateManager.cs | 11 ++-- .../Pruning/OverlayTrieStore.cs | 61 ++++++++++++++++--- .../Nethermind.Trie/Pruning/TrieStore.cs | 2 +- 5 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index 89962b8648d..e9a6bc181c4 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -13,7 +13,7 @@ namespace Nethermind.Consensus.Processing; public class ReadOnlyTxProcessingEnvBase { - public IStateReader StateReader { get; } + public IStateReader StateReader { get; protected set; } public IWorldState StateProvider { get; protected set; } public IBlockTree BlockTree { get; protected set; } public IBlockhashProvider BlockhashProvider { get; protected set; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 3b5a864a330..e6733b1c5aa 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -18,6 +18,7 @@ using Nethermind.Evm; using Nethermind.Evm.TransactionProcessing; using Nethermind.Logging; +using Nethermind.Specs.Forks; using Nethermind.State; using Nethermind.State.Repositories; using Nethermind.Trie.Pruning; @@ -53,8 +54,7 @@ public static SimulateReadOnlyBlocksProcessingEnv Create( IReadOnlyDbProvider dbProvider = new ReadOnlyDbProvider(emptyDbProvider, true); OverlayTrieStore overlayTrieStore = new(editableDbProvider.StateDb, worldStateManager.TrieStore, logManager); - OverlayWorldStateManager overlayWorldStateManager = new(worldStateManager, editableDbProvider, overlayTrieStore, logManager); - + OverlayWorldStateManager overlayWorldStateManager = new(editableDbProvider, overlayTrieStore, logManager); IBlockStore blockStore = new BlockStore(dbProvider.BlocksDb); IHeaderStore headerStore = new HeaderStore(dbProvider.HeadersDb, dbProvider.BlockNumbersDb); @@ -117,6 +117,7 @@ private SimulateReadOnlyBlocksProcessingEnv( //var store = new TrieStore(DbProvider.StateDb, LimboLogs.Instance); //StateProvider = new WorldState(store, DbProvider.CodeDb, LimboLogs.Instance); StateProvider = WorldStateManager.GlobalWorldState; + StateReader = WorldStateManager.GlobalStateReader; CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); diff --git a/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs b/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs index 140eb2663af..13dd8372627 100644 --- a/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs +++ b/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs @@ -9,17 +9,20 @@ namespace Nethermind.State; public class OverlayWorldStateManager( - IWorldStateManager worldStateManager, - IReadOnlyDbProvider dbProvider, + IReadOnlyDbProvider dbProvider, OverlayTrieStore overlayTrieStore, ILogManager? logManager) : IWorldStateManager { private readonly IDb _codeDb = dbProvider.GetDb(DbNames.Code); - public IWorldState GlobalWorldState => worldStateManager.GlobalWorldState; + private readonly WorldState _state = new WorldState(overlayTrieStore, dbProvider.GetDb(DbNames.Code), logManager); - public IStateReader GlobalStateReader => worldStateManager.GlobalStateReader; + private readonly StateReader _reader = new StateReader(overlayTrieStore, dbProvider.GetDb(DbNames.Code), logManager); + + public IWorldState GlobalWorldState => _state; + + public IStateReader GlobalStateReader => _reader; public IReadOnlyTrieStore TrieStore { get; } = overlayTrieStore.AsReadOnly(); diff --git a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs index c26453ee5d1..87f0d3bc690 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs @@ -17,14 +17,61 @@ public OverlayTrieStore(IKeyValueStoreWithBatching? keyValueStore, IReadOnlyTrie _store = store; } - public override TrieNode FindCachedOrUnknown(Hash256? hash) => _store.FindCachedOrUnknown(hash); - public override byte[] LoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) => - _store.TryLoadRlp(keccak, readFlags) ?? base.LoadRlp(keccak, readFlags); - public override byte[]? TryLoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) => - _store.TryLoadRlp(keccak, readFlags) ?? base.TryLoadRlp(keccak, readFlags); - public override byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) => - _store.GetByHash(key, flags) ?? base.GetByHash(key, flags); + public override bool IsPersisted(in ValueHash256 keccak) + { + var isPersisted = base.IsPersisted(in keccak); + if (!isPersisted) + { + isPersisted = _store.IsPersisted(in keccak); + } + return isPersisted; + } + + + public override TrieNode FindCachedOrUnknown(Hash256? hash) + { + TrieNode findCachedOrUnknown = base.FindCachedOrUnknown(hash); + if (findCachedOrUnknown.NodeType == NodeType.Unknown) + { + findCachedOrUnknown = _store.FindCachedOrUnknown(hash); + } + + return findCachedOrUnknown; + } + + public override byte[] LoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) + { + var rlp = base.TryLoadRlp(keccak, readFlags); + if (rlp != null) + { + return rlp; + } + + return _store.LoadRlp(keccak, readFlags); + } + + public override byte[]? TryLoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) + { + var rlp = base.TryLoadRlp(keccak, readFlags); + if (rlp != null) + { + return rlp; + } + + return _store.TryLoadRlp(keccak, readFlags); + } + + public override byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) + { + var hash = base.GetByHash(key, flags); + if (hash != null) + { + return hash; + } + + return _store.GetByHash(key, flags); + } } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs index f9e17e5b5ad..be5b11e3b44 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs @@ -349,7 +349,7 @@ public byte[] LoadRlp(Hash256 keccak, IKeyValueStore? keyValueStore, ReadFlags r public virtual byte[] LoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) => LoadRlp(keccak, null, readFlags); public virtual byte[]? TryLoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) => TryLoadRlp(keccak, null, readFlags); - public bool IsPersisted(in ValueHash256 keccak) + public virtual bool IsPersisted(in ValueHash256 keccak) { byte[]? rlp = _keyValueStore[keccak.Bytes]; From 8126d5b86f50010af028c656bd0b35f24f18c625 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 8 Feb 2024 13:48:55 +0000 Subject: [PATCH 125/213] Hive like Prunning And Persistence in tests Now all tests fail with same errors as in hive --- .../Blockchain/TestBlockchain.cs | 13 +++++++++++-- .../Modules/Eth/EthRpcSimulateTestsBase.cs | 2 +- .../EthSimulateTestsBlocksAndTransactions.cs | 0 .../EthSimulateTestsHiveBase.cs | 0 .../EthSimulateTestsSimplePrecompiles.cs | 0 .../Modules/TestRpcBlockchain.cs | 8 ++++---- 6 files changed, 16 insertions(+), 7 deletions(-) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/{Multicall => Simulate}/EthSimulateTestsBlocksAndTransactions.cs (100%) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/{Multicall => Simulate}/EthSimulateTestsHiveBase.cs (100%) rename src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/{Multicall => Simulate}/EthSimulateTestsSimplePrecompiles.cs (100%) diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index c8b0aa1082c..b8496e8cd38 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -8,6 +8,7 @@ using Nethermind.Blockchain; using Nethermind.Blockchain.Blocks; using Nethermind.Blockchain.Find; +using Nethermind.Blockchain.FullPruning; using Nethermind.Blockchain.Headers; using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Synchronization; @@ -118,14 +119,22 @@ protected TestBlockchain() public static TransactionBuilder BuildSimpleTransaction => Builders.Build.A.Transaction.SignedAndResolved(TestItem.PrivateKeyA).To(AccountB); - protected virtual async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true) + protected virtual async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) { Timestamper = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc)); JsonSerializer = new EthereumJsonSerializer(); SpecProvider = CreateSpecProvider(specProvider ?? MainnetSpecProvider.Instance); EthereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId, LogManager); DbProvider = await CreateDbProvider(); - TrieStore = new TrieStore(StateDb, LogManager); + if (!usePrunningAndPersistenceStrategies) + { + TrieStore = new TrieStore(StateDb, LogManager); + } + else + { + TrieStore = new TrieStore(StateDb, new MemoryLimit(10.KB()), new ConstantInterval(10), LogManager); + } + State = new WorldState(TrieStore, DbProvider.CodeDb, LogManager); // Eip4788 precompile state account diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs index fbce5182f52..b7cad174bd3 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs @@ -35,7 +35,7 @@ public static Task CreateChain(IReleaseSpec? releaseSpec = nu TestSpecProvider testSpecProvider = releaseSpec is not null ? new TestSpecProvider(releaseSpec) : new TestSpecProvider(London.Instance); - return TestRpcBlockchain.ForTest(testMevRpcBlockchain).Build(testSpecProvider); + return TestRpcBlockchain.ForTest(testMevRpcBlockchain).Build(testSpecProvider, null, true); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs similarity index 100% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsBlocksAndTransactions.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs similarity index 100% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsHiveBase.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs similarity index 100% rename from src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Multicall/EthSimulateTestsSimplePrecompiles.cs rename to src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 5aa4513a859..c1700f2bcb5 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -111,16 +111,16 @@ public Builder WithConfig(IJsonRpcConfig config) return this; } - public async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null) + public async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool usePrunningAndPersistenceStrategies = false) { - return (T)(await _blockchain.Build(specProvider, initialValues)); + return (T)(await _blockchain.Build(specProvider, initialValues, true, usePrunningAndPersistenceStrategies)); } } - protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true) + protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) { specProvider ??= new TestSpecProvider(Berlin.Instance); - await base.Build(specProvider, initialValues); + await base.Build(specProvider, initialValues, addBlockOnStart, usePrunningAndPersistenceStrategies); IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = new FilterManager(filterStore, BlockProcessor, TxPool, LimboLogs.Instance); var dbProvider = new ReadOnlyDbProvider(DbProvider, false); From 8eefe3e0f0d7c1235ff4be40fd47fc3fca7f579d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Fri, 9 Feb 2024 10:21:42 +0000 Subject: [PATCH 126/213] fixing most of the unit tests --- .../SimulateReadOnlyBlocksProcessingEnv.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index e6733b1c5aa..212592d233b 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -48,24 +48,24 @@ public static SimulateReadOnlyBlocksProcessingEnv Create( { IReadOnlyDbProvider editableDbProvider = new ReadOnlyDbProvider(readOnlyDbProvider, true); - var emptyDbProvider = new DbProvider(); - StandardDbInitializer? standardDbInitializer = new StandardDbInitializer(emptyDbProvider, new MemDbFactory()); - standardDbInitializer.InitStandardDbs(true); - IReadOnlyDbProvider dbProvider = new ReadOnlyDbProvider(emptyDbProvider, true); + //var emptyDbProvider = new DbProvider(); + //StandardDbInitializer? standardDbInitializer = new StandardDbInitializer(emptyDbProvider, new MemDbFactory()); + //standardDbInitializer.InitStandardDbs(true); + //IReadOnlyDbProvider dbProvider = new ReadOnlyDbProvider(emptyDbProvider, true); OverlayTrieStore overlayTrieStore = new(editableDbProvider.StateDb, worldStateManager.TrieStore, logManager); OverlayWorldStateManager overlayWorldStateManager = new(editableDbProvider, overlayTrieStore, logManager); - IBlockStore blockStore = new BlockStore(dbProvider.BlocksDb); - IHeaderStore headerStore = new HeaderStore(dbProvider.HeadersDb, dbProvider.BlockNumbersDb); + IBlockStore blockStore = new BlockStore(editableDbProvider.BlocksDb); + IHeaderStore headerStore = new HeaderStore(editableDbProvider.HeadersDb, editableDbProvider.BlockNumbersDb); const int badBlocksStored = 1; - IBlockStore badBlockStore = new BlockStore(dbProvider.BadBlocksDb, badBlocksStored); + IBlockStore badBlockStore = new BlockStore(editableDbProvider.BadBlocksDb, badBlocksStored); BlockTree tmpBlockTree = new(blockStore, headerStore, - dbProvider.BlockInfosDb, - dbProvider.MetadataDb, + editableDbProvider.BlockInfosDb, + editableDbProvider.MetadataDb, badBlockStore, new ChainLevelInfoRepository(readOnlyDbProvider.BlockInfosDb), specProvider, From 585927f635e30b32f9bec6eea7f9299a16a51d4d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 12 Feb 2024 11:14:13 +0000 Subject: [PATCH 127/213] Test fixes --- ...ractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs | 2 +- .../Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs | 2 +- .../FullPruning/FullPruningDiskTest.cs | 2 +- .../Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs | 2 +- .../MevRpcModuleTests.TestMevRpcBlockchain.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs index c56265edd8a..dcab07a60b9 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs @@ -251,7 +251,7 @@ protected override BlockProcessor CreateBlockProcessor() } protected override async Task Build(ISpecProvider? specProvider = null, - UInt256? initialValues = null, bool addBlockOnStart = true) + UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) { TestBlockchain chain = await base.Build(specProvider, initialValues); IList
entryPointContractAddresses = new List
(); diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs index 276671dab2a..6ba09493cb5 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs @@ -354,7 +354,7 @@ protected override ILocalDataSource> GetWhitelistLocalDataS protected override ILocalDataSource> GetMinGasPricesLocalDataStore() => LocalDataSource.GetMinGasPricesLocalDataSource(); - protected override Task Build(ISpecProvider specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true) + protected override Task Build(ISpecProvider specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) { TempFile = TempPath.GetTempFile(); LocalDataSource = new TxPriorityContract.LocalDataSource(TempFile.Path, new EthereumJsonSerializer(), new FileSystem(), LimboLogs.Instance, Interval); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs index 367f678ed3f..821bd1493a0 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs @@ -48,7 +48,7 @@ public PruningTestBlockchain() TempDirectory = TempPath.GetTempDirectory(); } - protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true) + protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) { TestBlockchain chain = await base.Build(specProvider, initialValues, addBlockOnStart); PruningDb = (IFullPruningDb)DbProvider.StateDb; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs index 487589c3712..afc98098901 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs @@ -259,7 +259,7 @@ protected IBlockValidator CreateBlockValidator() public IManualBlockFinalizationManager BlockFinalizationManager { get; } = new ManualBlockFinalizationManager(); - protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true) + protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) { TestBlockchain chain = await base.Build(specProvider, initialValues); return chain; diff --git a/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs b/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs index c0a3b4b1168..5c3686cc4ad 100644 --- a/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs @@ -220,7 +220,7 @@ protected override BlockProcessor CreateBlockProcessor() } protected override async Task Build(ISpecProvider? specProvider = null, - UInt256? initialValues = null, bool addBlockOnStart = true) + UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) { TestBlockchain chain = await base.Build(specProvider, initialValues); MevRpcModule = new MevRpcModule(new JsonRpcConfig(), From ced6a1b2bf5a88e31c62c3f1442c853476b297a9 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 12 Feb 2024 11:22:09 +0000 Subject: [PATCH 128/213] Getting ready for merge --- .../Nethermind.Facade/BlockchainBridgeExtensions.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs index 462cb6e211a..8114aa6ad22 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs @@ -10,8 +10,6 @@ public static class BlockchainBridgeExtensions { public static bool HasStateForBlock(this IBlockchainBridge blockchainBridge, BlockHeader header) { - RootCheckVisitor rootCheckVisitor = new(); - blockchainBridge.RunTreeVisitor(rootCheckVisitor, header.StateRoot!); - return rootCheckVisitor.HasRoot; + return blockchainBridge.HasStateForRoot(header.StateRoot!); } } From 2eeb00566ed811eda938bc9aaa76e86ebd4a9f6a Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 13 Feb 2024 13:40:59 +0100 Subject: [PATCH 129/213] initialize overlay tree with main tree head --- .../Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs b/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs index 88142bd6406..903d8f829d3 100644 --- a/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs +++ b/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs @@ -20,6 +20,7 @@ public NonDistructiveBlockTreeOverlay(IReadOnlyBlockTree baseTree, IBlockTree ov { _baseTree = baseTree ?? throw new ArgumentNullException(nameof(baseTree)); _overlayTree = overlayTree ?? throw new ArgumentNullException(nameof(overlayTree)); + _overlayTree.UpdateMainChain(new[] { _baseTree.Head }, true, true); } public ulong NetworkId => _baseTree.NetworkId; From d6e339b273462646b904f578e4b345fc930d2dd1 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 20 Feb 2024 15:12:04 +0100 Subject: [PATCH 130/213] FIx managing state --- .../Nethermind.Api/NethermindApi.cs | 4 +- .../Nethermind.Blockchain/BlockTree.cs | 3 +- .../NonDistructiveBlockTreeOverlay.cs | 253 +++++++----------- .../BlockchainBridgeTests.cs | 14 +- .../Nethermind.Facade/BlockchainBridge.cs | 6 +- .../OverridableCodeInfoRepository.cs | 25 +- .../Simulate/SimulateBridgeHelper.cs | 52 ++-- .../SimulateReadOnlyBlocksProcessingEnv.cs | 103 ++++--- .../Modules/TestRpcBlockchain.cs | 5 +- .../Pruning/OverlayTrieStore.cs | 71 +---- .../Nethermind.Trie/Pruning/TrieStore.cs | 2 +- 11 files changed, 203 insertions(+), 335 deletions(-) diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index fed27bf17cd..0a43ca7b65c 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -95,11 +95,11 @@ public IBlockchainBridge CreateBlockchainBridge() SpecProvider, LogManager); - SimulateReadOnlyBlocksProcessingEnv simulateReadOnlyBlocksProcessingEnv = SimulateReadOnlyBlocksProcessingEnv.Create(false, + SimulateReadOnlyBlocksProcessingEnvFactory simulateReadOnlyBlocksProcessingEnv = new SimulateReadOnlyBlocksProcessingEnvFactory( WorldStateManager!, readOnlyTree, _simulateReadOnlyDbProvider, - SpecProvider, + SpecProvider!, LogManager); diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index 89779c3b157..8deaff21ea1 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -127,8 +127,7 @@ public BlockTree( _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _bloomStorage = bloomStorage ?? throw new ArgumentNullException(nameof(bloomStorage)); _syncConfig = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig)); - _chainLevelInfoRepository = chainLevelInfoRepository ?? - throw new ArgumentNullException(nameof(chainLevelInfoRepository)); + _chainLevelInfoRepository = chainLevelInfoRepository ?? throw new ArgumentNullException(nameof(chainLevelInfoRepository)); byte[]? deletePointer = _blockInfoDb.Get(DeletePointerAddressInDb); if (deletePointer is not null) diff --git a/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs b/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs index 903d8f829d3..420ba2554f7 100644 --- a/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs +++ b/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs @@ -30,8 +30,7 @@ public NonDistructiveBlockTreeOverlay(IReadOnlyBlockTree baseTree, IBlockTree ov public BlockHeader? BestSuggestedHeader => _overlayTree.BestSuggestedHeader ?? _baseTree.BestSuggestedHeader; public Block? BestSuggestedBody => _overlayTree.BestSuggestedBody ?? _baseTree.BestSuggestedBody; - public BlockHeader? BestSuggestedBeaconHeader => - _overlayTree.BestSuggestedBeaconHeader ?? _baseTree.BestSuggestedBeaconHeader; + public BlockHeader? BestSuggestedBeaconHeader => _overlayTree.BestSuggestedBeaconHeader ?? _baseTree.BestSuggestedBeaconHeader; public BlockHeader? LowestInsertedHeader => _overlayTree.LowestInsertedHeader ?? _baseTree.LowestInsertedHeader; @@ -49,7 +48,6 @@ public BlockHeader? LowestInsertedBeaconHeader public long BestKnownNumber => Math.Max(_overlayTree.BestKnownNumber, _baseTree.BestKnownNumber); public long BestKnownBeaconNumber => Math.Max(_overlayTree.BestKnownBeaconNumber, _baseTree.BestKnownBeaconNumber); - public Hash256 HeadHash => _overlayTree.HeadHash ?? _baseTree.HeadHash; public Hash256 GenesisHash => _baseTree.GenesisHash; public Hash256? PendingHash => _overlayTree.PendingHash ?? _baseTree.PendingHash; @@ -58,138 +56,88 @@ public BlockHeader? LowestInsertedBeaconHeader public Block? Head => _overlayTree.Head ?? _baseTree.Head; public long? BestPersistedState { get => _overlayTree.BestPersistedState; set => _overlayTree.BestPersistedState = value; } - - public AddBlockResult Insert(BlockHeader header, - BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.None) - { - return _overlayTree.Insert(header, headerOptions); - } + public AddBlockResult Insert(BlockHeader header, BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.None) => + _overlayTree.Insert(header, headerOptions); public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOptions = BlockTreeInsertBlockOptions.None, BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None, - WriteFlags bodiesWriteFlags = WriteFlags.None) - { - return _overlayTree.Insert(block, insertBlockOptions, insertHeaderOptions, bodiesWriteFlags); - } + WriteFlags bodiesWriteFlags = WriteFlags.None) => + _overlayTree.Insert(block, insertBlockOptions, insertHeaderOptions, bodiesWriteFlags); - public void UpdateHeadBlock(Hash256 blockHash) - { + public void UpdateHeadBlock(Hash256 blockHash) => _overlayTree.UpdateHeadBlock(blockHash); - } public AddBlockResult SuggestBlock(Block block, - BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) - { - return _overlayTree.SuggestBlock(block, options); - } + BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) => + _overlayTree.SuggestBlock(block, options); public ValueTask SuggestBlockAsync(Block block, - BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) - { - return _overlayTree.SuggestBlockAsync(block, options); - } + BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) => + _overlayTree.SuggestBlockAsync(block, options); - public AddBlockResult SuggestHeader(BlockHeader header) - { - return _overlayTree.SuggestHeader(header); - } + public AddBlockResult SuggestHeader(BlockHeader header) => _overlayTree.SuggestHeader(header); - public bool IsKnownBlock(long number, Hash256 blockHash) - { - return _overlayTree.IsKnownBlock(number, blockHash) || _baseTree.IsKnownBlock(number, blockHash); - } + public bool IsKnownBlock(long number, Hash256 blockHash) => _overlayTree.IsKnownBlock(number, blockHash) || _baseTree.IsKnownBlock(number, blockHash); - public bool IsKnownBeaconBlock(long number, Hash256 blockHash) - { - return _overlayTree.IsKnownBeaconBlock(number, blockHash) || _baseTree.IsKnownBeaconBlock(number, blockHash); - } + public bool IsKnownBeaconBlock(long number, Hash256 blockHash) => _overlayTree.IsKnownBeaconBlock(number, blockHash) || _baseTree.IsKnownBeaconBlock(number, blockHash); - public bool WasProcessed(long number, Hash256 blockHash) - { - return _overlayTree.WasProcessed(number, blockHash) || _baseTree.WasProcessed(number, blockHash); - } + public bool WasProcessed(long number, Hash256 blockHash) => _overlayTree.WasProcessed(number, blockHash) || _baseTree.WasProcessed(number, blockHash); - public void UpdateMainChain(IReadOnlyList blocks, bool wereProcessed, bool forceHeadBlock = false) - { + public void UpdateMainChain(IReadOnlyList blocks, bool wereProcessed, bool forceHeadBlock = false) => _overlayTree.UpdateMainChain(blocks, wereProcessed, forceHeadBlock); - } - public void MarkChainAsProcessed(IReadOnlyList blocks) - { - _overlayTree.MarkChainAsProcessed(blocks); - } + public void MarkChainAsProcessed(IReadOnlyList blocks) => _overlayTree.MarkChainAsProcessed(blocks); - public bool CanAcceptNewBlocks { get; } - public Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken) - { - return _overlayTree.Accept(blockTreeVisitor, cancellationToken); - } - // Additional method implementations for the BlockTreeOverlay class + public bool CanAcceptNewBlocks => _overlayTree.CanAcceptNewBlocks; + + public Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken) => _overlayTree.Accept(blockTreeVisitor, cancellationToken); public (BlockInfo? Info, ChainLevelInfo? Level) GetInfo(long number, Hash256 blockHash) { - var overlayInfo = _overlayTree.GetInfo(number, blockHash); - if (overlayInfo.Info != null || overlayInfo.Level != null) - { - return overlayInfo; - } - - return _baseTree.GetInfo(number, blockHash); + (BlockInfo Info, ChainLevelInfo Level) overlayInfo = _overlayTree.GetInfo(number, blockHash); + return overlayInfo.Info is not null || overlayInfo.Level is not null ? overlayInfo : _baseTree.GetInfo(number, blockHash); } - public ChainLevelInfo? FindLevel(long number) - { - var overlayLevel = _overlayTree.FindLevel(number); - return overlayLevel ?? _baseTree.FindLevel(number); - } + public ChainLevelInfo? FindLevel(long number) => _overlayTree.FindLevel(number) ?? _baseTree.FindLevel(number); - public BlockInfo FindCanonicalBlockInfo(long blockNumber) - { - var overlayBlockInfo = _overlayTree.FindCanonicalBlockInfo(blockNumber); - return overlayBlockInfo ?? _baseTree.FindCanonicalBlockInfo(blockNumber); - } + public BlockInfo FindCanonicalBlockInfo(long blockNumber) => _overlayTree.FindCanonicalBlockInfo(blockNumber) ?? _baseTree.FindCanonicalBlockInfo(blockNumber); - public Hash256 FindHash(long blockNumber) - { - var overlayHash = _overlayTree.FindHash(blockNumber); - return overlayHash ?? _baseTree.FindHash(blockNumber); - } + public Hash256 FindHash(long blockNumber) => _overlayTree.FindHash(blockNumber) ?? _baseTree.FindHash(blockNumber); public BlockHeader[] FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) { - var overlayHeaders = _overlayTree.FindHeaders(hash, numberOfBlocks, skip, reverse); + BlockHeader[] overlayHeaders = _overlayTree.FindHeaders(hash, numberOfBlocks, skip, reverse); return overlayHeaders.Length > 0 ? overlayHeaders : _baseTree.FindHeaders(hash, numberOfBlocks, skip, reverse); } - public BlockHeader FindLowestCommonAncestor(BlockHeader firstDescendant, BlockHeader secondDescendant, long maxSearchDepth) - { - var overlayAncestor = _overlayTree.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth); - return overlayAncestor ?? _baseTree.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth); - } + public BlockHeader FindLowestCommonAncestor(BlockHeader firstDescendant, BlockHeader secondDescendant, long maxSearchDepth) => + _overlayTree.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth) ?? _baseTree.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth); - public void DeleteInvalidBlock(Block invalidBlock) - { + public void DeleteInvalidBlock(Block invalidBlock) => _overlayTree.DeleteInvalidBlock(invalidBlock); - } - public void ForkChoiceUpdated(Hash256? finalizedBlockHash, Hash256? safeBlockBlockHash) - { + public void ForkChoiceUpdated(Hash256? finalizedBlockHash, Hash256? safeBlockBlockHash) => _overlayTree.ForkChoiceUpdated(finalizedBlockHash, safeBlockBlockHash); - } // Event forwarding - public event EventHandler NewBestSuggestedBlock + public event EventHandler? NewBestSuggestedBlock { add { - _baseTree.NewBestSuggestedBlock += value; - _overlayTree.NewBestSuggestedBlock += value; + if (value is not null) + { + _baseTree.NewBestSuggestedBlock += value; + _overlayTree.NewBestSuggestedBlock += value; + } } remove { - _baseTree.NewBestSuggestedBlock -= value; - _overlayTree.NewBestSuggestedBlock -= value; + if (value is not null) + { + _baseTree.NewBestSuggestedBlock -= value; + _overlayTree.NewBestSuggestedBlock -= value; + } } } @@ -197,13 +145,19 @@ public event EventHandler? NewSuggestedBlock { add { - _baseTree.NewSuggestedBlock += value; - _overlayTree.NewSuggestedBlock += value; + if (value is not null) + { + _baseTree.NewSuggestedBlock += value; + _overlayTree.NewSuggestedBlock += value; + } } remove { - _baseTree.NewSuggestedBlock -= value; - _overlayTree.NewSuggestedBlock -= value; + if (value is not null) + { + _baseTree.NewSuggestedBlock -= value; + _overlayTree.NewSuggestedBlock -= value; + } } } @@ -211,13 +165,19 @@ public event EventHandler? BlockAddedToMain { add { - _baseTree.BlockAddedToMain += value; - _overlayTree.BlockAddedToMain += value; + if (value is not null) + { + _baseTree.BlockAddedToMain += value; + _overlayTree.BlockAddedToMain += value; + } } remove { - _baseTree.BlockAddedToMain -= value; - _overlayTree.BlockAddedToMain -= value; + if (value is not null) + { + _baseTree.BlockAddedToMain -= value; + _overlayTree.BlockAddedToMain -= value; + } } } @@ -225,13 +185,19 @@ public event EventHandler? NewHeadBlock { add { - _baseTree.NewHeadBlock += value; - _overlayTree.NewHeadBlock += value; + if (value is not null) + { + _baseTree.NewHeadBlock += value; + _overlayTree.NewHeadBlock += value; + } } remove { - _baseTree.NewHeadBlock -= value; - _overlayTree.NewHeadBlock -= value; + if (value is not null) + { + _baseTree.NewHeadBlock -= value; + _overlayTree.NewHeadBlock -= value; + } } } @@ -239,75 +205,52 @@ public event EventHandler? OnUpdateMainChain { add { - _baseTree.OnUpdateMainChain += value; - _overlayTree.OnUpdateMainChain += value; + if (value is not null) + { + _baseTree.OnUpdateMainChain += value; + _overlayTree.OnUpdateMainChain += value; + } } remove { - _baseTree.OnUpdateMainChain -= value; - _overlayTree.OnUpdateMainChain -= value; + if (value is not null) + { + _baseTree.OnUpdateMainChain -= value; + _overlayTree.OnUpdateMainChain -= value; + } } } + public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool force = false) => + _overlayTree.DeleteChainSlice(startNumber, endNumber, force); - public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool force = false) - { - return _overlayTree.DeleteChainSlice(startNumber, endNumber, force); - } - - public bool IsBetterThanHead(BlockHeader? header) - { - return _overlayTree.IsBetterThanHead(header) || _baseTree.IsBetterThanHead(header); - } + public bool IsBetterThanHead(BlockHeader? header) => _overlayTree.IsBetterThanHead(header) || _baseTree.IsBetterThanHead(header); - public void UpdateBeaconMainChain(BlockInfo[]? blockInfos, long clearBeaconMainChainStartPoint) - { + public void UpdateBeaconMainChain(BlockInfo[]? blockInfos, long clearBeaconMainChainStartPoint) => _overlayTree.UpdateBeaconMainChain(blockInfos, clearBeaconMainChainStartPoint); - } - public void RecalculateTreeLevels() - { - _overlayTree.RecalculateTreeLevels(); - } + public void RecalculateTreeLevels() => _overlayTree.RecalculateTreeLevels(); - public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) - { - var overlayBlock = _overlayTree.FindBlock(blockHash, options, blockNumber); - return overlayBlock ?? _baseTree.FindBlock(blockHash, options, blockNumber); - } + public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => + _overlayTree.FindBlock(blockHash, options, blockNumber) ?? _baseTree.FindBlock(blockHash, options, blockNumber); - public Block? FindBlock(long blockNumber, BlockTreeLookupOptions options) - { - var overlayBlock = _overlayTree.FindBlock(blockNumber, options); - return overlayBlock ?? _baseTree.FindBlock(blockNumber, options); - } + public Block? FindBlock(long blockNumber, BlockTreeLookupOptions options) => + _overlayTree.FindBlock(blockNumber, options) ?? _baseTree.FindBlock(blockNumber, options); - public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) - { - var overlayHeader = _overlayTree.FindHeader(blockHash, options, blockNumber); - return overlayHeader ?? _baseTree.FindHeader(blockHash, options, blockNumber); - } + public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => + _overlayTree.FindHeader(blockHash, options, blockNumber) ?? _baseTree.FindHeader(blockHash, options, blockNumber); - public BlockHeader? FindHeader(long blockNumber, BlockTreeLookupOptions options) - { - var overlayHeader = _overlayTree.FindHeader(blockNumber, options); - return overlayHeader ?? _baseTree.FindHeader(blockNumber, options); - } + public BlockHeader? FindHeader(long blockNumber, BlockTreeLookupOptions options) => + _overlayTree.FindHeader(blockNumber, options) ?? _baseTree.FindHeader(blockNumber, options); - public Hash256? FindBlockHash(long blockNumber) - { - var overlayBlockHash = _overlayTree.FindBlockHash(blockNumber); - return overlayBlockHash ?? _baseTree.FindBlockHash(blockNumber); - } + public Hash256? FindBlockHash(long blockNumber) => + _overlayTree.FindBlockHash(blockNumber) ?? _baseTree.FindBlockHash(blockNumber); - public bool IsMainChain(BlockHeader blockHeader) - { - return _baseTree.IsMainChain(blockHeader) || _overlayTree.IsMainChain(blockHeader); - } + public bool IsMainChain(BlockHeader blockHeader) => + _baseTree.IsMainChain(blockHeader) || _overlayTree.IsMainChain(blockHeader); public bool IsMainChain(Hash256 blockHash) { - try { if (_baseTree.IsMainChain(blockHash)) return true; @@ -322,7 +265,7 @@ public bool IsMainChain(Hash256 blockHash) public BlockHeader FindBestSuggestedHeader() { - var overlayHeader = _overlayTree.FindBestSuggestedHeader(); + BlockHeader? overlayHeader = _overlayTree.FindBestSuggestedHeader(); return overlayHeader ?? _baseTree.FindBestSuggestedHeader(); } diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index 4ac4ab2cb6a..7ab90c34461 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -68,17 +68,16 @@ public async Task SetUp() IWorldStateManager readOnlyWorldStateManager = new ReadOnlyWorldStateManager(dbProvider, trieStore, LimboLogs.Instance); - IReadOnlyBlockTree? roBlockTree = _blockTree!.AsReadOnly(); + IReadOnlyBlockTree? readOnlyBlockTree = _blockTree!.AsReadOnly(); ReadOnlyTxProcessingEnv processingEnv = new( readOnlyWorldStateManager, - roBlockTree, + readOnlyBlockTree, _specProvider, LimboLogs.Instance); - SimulateReadOnlyBlocksProcessingEnv simulateProcessingEnv = SimulateReadOnlyBlocksProcessingEnv.Create( - false, + SimulateReadOnlyBlocksProcessingEnvFactory simulateProcessingEnvFactory = new SimulateReadOnlyBlocksProcessingEnvFactory( readOnlyWorldStateManager, - roBlockTree, + readOnlyBlockTree, new ReadOnlyDbProvider(_dbProvider, true), _specProvider, LimboLogs.Instance); @@ -87,7 +86,7 @@ public async Task SetUp() _blockchainBridge = new BlockchainBridge( processingEnv, - simulateProcessingEnv, + simulateProcessingEnvFactory, _txPool, _receiptStorage, _filterStore, @@ -233,8 +232,7 @@ public void Bridge_head_is_correct(long headNumber) _specProvider, LimboLogs.Instance); - SimulateReadOnlyBlocksProcessingEnv simulateProcessingEnv = SimulateReadOnlyBlocksProcessingEnv.Create( - false, + SimulateReadOnlyBlocksProcessingEnvFactory simulateProcessingEnv = new SimulateReadOnlyBlocksProcessingEnvFactory( readOnlyWorldStateManager, roBlockTree, new ReadOnlyDbProvider(_dbProvider, true), diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 04331455fc8..cf8665f2535 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -55,7 +55,7 @@ public class BlockchainBridge : IBlockchainBridge private readonly SimulateBridgeHelper _simulateBridgeHelper; public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, - SimulateReadOnlyBlocksProcessingEnv simulateProcessingEnv, + SimulateReadOnlyBlocksProcessingEnvFactory simulateProcessingEnvFactory, ITxPool? txPool, IReceiptFinder? receiptStorage, IFilterStore? filterStore, @@ -68,7 +68,7 @@ public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, bool isMining) { _processingEnv = processingEnv ?? throw new ArgumentNullException(nameof(processingEnv)); - _txPool = txPool ?? throw new ArgumentNullException(nameof(_txPool)); + _txPool = txPool ?? throw new ArgumentNullException(nameof(txPool)); _receiptFinder = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage)); _filterStore = filterStore ?? throw new ArgumentNullException(nameof(filterStore)); _filterManager = filterManager ?? throw new ArgumentNullException(nameof(filterManager)); @@ -79,7 +79,7 @@ public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, _blocksConfig = blocksConfig; IsMining = isMining; _simulateBridgeHelper = new SimulateBridgeHelper( - simulateProcessingEnv ?? throw new ArgumentNullException(nameof(simulateProcessingEnv)), + simulateProcessingEnvFactory ?? throw new ArgumentNullException(nameof(simulateProcessingEnvFactory)), _specProvider, _blocksConfig); } diff --git a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs index 942f0ac7d1c..4225fd5862f 100644 --- a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs @@ -32,33 +32,22 @@ public void SetCodeOverwrite( { if (redirectAddress is not null) { - var tmp = GetCachedCodeInfo(worldState, key, vmSpec); - _codeOverwrites[redirectAddress] = tmp; - + _codeOverwrites[redirectAddress] = GetCachedCodeInfo(worldState, key, vmSpec); } + _codeOverwrites[key] = value; } public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) { - if (EcRecoverPrecompile.Address == codeSource) - { - var aaa = 666; - aaa += 1; - } - - if (_codeOverwrites.TryGetValue(codeSource, out CodeInfo result)) - return result; - else - return _codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, vmSpec); + return _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) ? result : _codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, vmSpec); } - - public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) - { - return _codeInfoRepository.GetOrAdd(codeHash, initCode); - } + public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) => + _codeInfoRepository.GetOrAdd(codeHash, initCode); public void InsertCode(IWorldState state, byte[] code, Address codeOwner, IReleaseSpec spec) => _codeInfoRepository.InsertCode(state, code, codeOwner, spec); + + public void Clear() => _codeOverwrites.Clear(); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 1445ec4a905..fe18748ff6b 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -22,23 +22,15 @@ namespace Nethermind.Facade.Simulate; -public class SimulateBridgeHelper +public class SimulateBridgeHelper( + SimulateReadOnlyBlocksProcessingEnvFactory simulateProcessingEnvFactory, + ISpecProvider specProvider, + IBlocksConfig blocksConfig) { - private readonly SimulateReadOnlyBlocksProcessingEnv _simulateProcessingEnv; - private readonly ISpecProvider _specProvider; - private readonly IBlocksConfig _blocksConfig; - private static readonly ProcessingOptions _simulateProcessingOptions = ProcessingOptions.ForceProcessing | - ProcessingOptions.IgnoreParentNotOnMainChain | - ProcessingOptions.MarkAsProcessed | - ProcessingOptions.StoreReceipts; - - public SimulateBridgeHelper(SimulateReadOnlyBlocksProcessingEnv simulateProcessingEnv, ISpecProvider specProvider, IBlocksConfig blocksConfig) - { - _simulateProcessingEnv = simulateProcessingEnv; - _specProvider = specProvider; - _blocksConfig = blocksConfig; - } + ProcessingOptions.IgnoreParentNotOnMainChain | + ProcessingOptions.MarkAsProcessed | + ProcessingOptions.StoreReceipts; private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall blockStateCall, SimulateReadOnlyBlocksProcessingEnv env) @@ -67,14 +59,18 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, blockHeader.StateRoot = env.StateProvider.StateRoot; } - public (bool Success, string Error) TrySimulateTrace(BlockHeader parent, SimulatePayload payload, IBlockTracer tracer) + public (bool Success, string Error) TrySimulateTrace(BlockHeader parent, SimulatePayload payload, IBlockTracer tracer) => + TrySimulateTrace(parent, payload, tracer, simulateProcessingEnvFactory.Create(payload.TraceTransfers, payload.Validation)); + + + private (bool Success, string Error) TrySimulateTrace(BlockHeader parent, SimulatePayload payload, IBlockTracer tracer, SimulateReadOnlyBlocksProcessingEnv env) { - using SimulateReadOnlyBlocksProcessingEnv? env = _simulateProcessingEnv.Clone(payload.TraceTransfers, payload.Validation); + Block? latestBlock = env.BlockTree.FindLatestBlock(); + long latestBlockNumber = latestBlock?.Number ?? 0; - Block? latestPersistant = env.BlockTree.FindLatestBlock(); - if (latestPersistant.Number < parent.Number) + if (latestBlockNumber < parent.Number) { - parent = latestPersistant.Header; + parent = latestBlock?.Header ?? env.BlockTree.Head!.Header; } IWorldState stateProvider = env.StateProvider; @@ -82,7 +78,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); - ulong lastKnown = (ulong)latestPersistant.Number; + ulong lastKnown = (ulong)latestBlockNumber; if (firstBlock?.BlockOverrides?.Number > 0 && firstBlock?.BlockOverrides?.Number < lastKnown) { Block? searchResult = env.BlockTree.FindBlock((long)firstBlock.BlockOverrides.Number); @@ -101,7 +97,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, foreach (BlockStateCall callInputBlock in payload.BlockStateCalls) { BlockHeader callHeader = callInputBlock.BlockOverrides is not null - ? callInputBlock.BlockOverrides.GetBlockHeader(parent, _blocksConfig) + ? callInputBlock.BlockOverrides.GetBlockHeader(parent, blocksConfig) : new BlockHeader( parent.Hash!, Keccak.OfAnEmptySequenceRlp, @@ -113,7 +109,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, parent.Timestamp + 1, Array.Empty()) { - BaseFeePerGas = BaseFeeCalculator.Calculate(parent, _specProvider.GetSpec(parent)), + BaseFeePerGas = BaseFeeCalculator.Calculate(parent, specProvider.GetSpec(parent)), MixHash = parent.MixHash, IsPostMerge = parent.Difficulty == 0 }; @@ -121,8 +117,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); using IReadOnlyTransactionProcessor? readOnlyTransactionProcessor = env.Build(env.StateProvider.StateRoot!); - GasEstimator gasEstimator = new(readOnlyTransactionProcessor, env.StateProvider, - _specProvider, _blocksConfig); + GasEstimator gasEstimator = new(readOnlyTransactionProcessor, env.StateProvider, specProvider, blocksConfig); long EstimateGas(Transaction transaction) { @@ -185,7 +180,7 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction return transaction; } - IReleaseSpec? spec = _specProvider.GetSpec(parent); + IReleaseSpec? spec = specProvider.GetSpec(parent); Transaction[] transactions = callInputBlock.Calls?.Select(t => SetTxHashAndMissingDefaults(t, spec)).ToArray() ?? Array.Empty(); @@ -206,9 +201,8 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction Block[]? currentBlocks = null; //try { - IBlockProcessor? processor = env.GetProcessor(currentBlock.StateRoot!); - currentBlocks = processor.Process(stateProvider.StateRoot, suggestedBlocks, - processingFlags, tracer); + IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!); + currentBlocks = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer); } //catch (Exception) //{ diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 212592d233b..0ada4a40e22 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -10,6 +10,7 @@ using Nethermind.Consensus.Processing; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; +using Nethermind.Consensus.Withdrawals; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; @@ -25,44 +26,39 @@ namespace Nethermind.Facade.Simulate; -public class SimulateReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IDisposable +public class SimulateReadOnlyBlocksProcessingEnvFactory( + IWorldStateManager worldStateManager, + IReadOnlyBlockTree baseBlockTree, + IReadOnlyDbProvider readOnlyDbProvider, + ISpecProvider specProvider, + ILogManager? logManager = null) { - //private readonly ITrieStore _trieStore; - private readonly ILogManager? _logManager; - private readonly IBlockValidator _blockValidator; - public ISpecProvider SpecProvider { get; } - public IWorldStateManager WorldStateManager { get; } - - public IVirtualMachine VirtualMachine { get; } - public OverridableCodeInfoRepository CodeInfoRepository { get; } - private readonly bool _doValidation = false; - // We need ability to get many instances that do not conflict in terms of editable tmp storage - thus we implement env cloning - public static SimulateReadOnlyBlocksProcessingEnv Create( - bool traceTransfers, - IWorldStateManager worldStateManager, - IReadOnlyBlockTree roBlockTree, - IReadOnlyDbProvider readOnlyDbProvider, - ISpecProvider? specProvider, - ILogManager? logManager = null, - bool doValidation = false) + public SimulateReadOnlyBlocksProcessingEnv Create(bool traceTransfers, bool validate) { IReadOnlyDbProvider editableDbProvider = new ReadOnlyDbProvider(readOnlyDbProvider, true); - - //var emptyDbProvider = new DbProvider(); - //StandardDbInitializer? standardDbInitializer = new StandardDbInitializer(emptyDbProvider, new MemDbFactory()); - //standardDbInitializer.InitStandardDbs(true); - //IReadOnlyDbProvider dbProvider = new ReadOnlyDbProvider(emptyDbProvider, true); - OverlayTrieStore overlayTrieStore = new(editableDbProvider.StateDb, worldStateManager.TrieStore, logManager); OverlayWorldStateManager overlayWorldStateManager = new(editableDbProvider, overlayTrieStore, logManager); + BlockTree tempBlockTree = CreateTempBlockTree(readOnlyDbProvider, specProvider, logManager, editableDbProvider); + return new SimulateReadOnlyBlocksProcessingEnv( + traceTransfers, + overlayWorldStateManager, + baseBlockTree, + editableDbProvider, + tempBlockTree, + specProvider, + logManager, + validate); + } + + private static BlockTree CreateTempBlockTree(IReadOnlyDbProvider readOnlyDbProvider, ISpecProvider? specProvider, ILogManager? logManager, IReadOnlyDbProvider editableDbProvider) + { IBlockStore blockStore = new BlockStore(editableDbProvider.BlocksDb); IHeaderStore headerStore = new HeaderStore(editableDbProvider.HeadersDb, editableDbProvider.BlockNumbersDb); const int badBlocksStored = 1; IBlockStore badBlockStore = new BlockStore(editableDbProvider.BadBlocksDb, badBlocksStored); - - BlockTree tmpBlockTree = new(blockStore, + return new(blockStore, headerStore, editableDbProvider.BlockInfosDb, editableDbProvider.MetadataDb, @@ -72,40 +68,36 @@ public static SimulateReadOnlyBlocksProcessingEnv Create( NullBloomStorage.Instance, new SyncConfig(), logManager); - - //var blockTree = new NonDistructiveBlockTreeOverlay(roBlockTree, tmpBlockTree); - - return new SimulateReadOnlyBlocksProcessingEnv( - traceTransfers, - overlayWorldStateManager, - roBlockTree, - editableDbProvider, - //trieStore, - tmpBlockTree, - specProvider, - logManager, - doValidation); } +} - public SimulateReadOnlyBlocksProcessingEnv Clone(bool traceTransfers, bool doValidation) => - Create(traceTransfers, WorldStateManager, ReadOnlyBlockTree, DbProvider, SpecProvider, _logManager, doValidation); +public class SimulateReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IDisposable +{ + private readonly ILogManager? _logManager; + private readonly IBlockValidator _blockValidator; + private readonly bool _doValidation = false; + private readonly TransactionProcessor _transactionProcessor; + public ISpecProvider SpecProvider { get; } + public IWorldStateManager WorldStateManager { get; } + public IVirtualMachine VirtualMachine { get; } public IReadOnlyDbProvider DbProvider { get; } + public IReadOnlyBlockTree ReadOnlyBlockTree { get; set; } + public OverridableCodeInfoRepository CodeInfoRepository { get; } - private SimulateReadOnlyBlocksProcessingEnv( + public SimulateReadOnlyBlocksProcessingEnv( bool traceTransfers, IWorldStateManager worldStateManager, - IReadOnlyBlockTree roBlockTree, + IReadOnlyBlockTree baseBlockTree, IReadOnlyDbProvider readOnlyDbProvider, IBlockTree blockTree, - ISpecProvider? specProvider, + ISpecProvider specProvider, ILogManager? logManager = null, bool doValidation = false) : base(worldStateManager, blockTree, logManager) { - ReadOnlyBlockTree = roBlockTree; + ReadOnlyBlockTree = baseBlockTree; DbProvider = readOnlyDbProvider; - WorldStateManager = worldStateManager; _logManager = logManager; SpecProvider = specProvider; @@ -122,7 +114,13 @@ private SimulateReadOnlyBlocksProcessingEnv( CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); VirtualMachine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); + _transactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !_doValidation); + _blockValidator = CreateValidator(); + } + + private SimulateBlockValidatorProxy CreateValidator() + { HeaderValidator headerValidator = new( BlockTree, Always.Valid, @@ -136,31 +134,26 @@ private SimulateReadOnlyBlocksProcessingEnv( SpecProvider, _logManager); - _blockValidator = new SimulateBlockValidatorProxy(blockValidator); + return new SimulateBlockValidatorProxy(blockValidator); } - public IReadOnlyBlockTree ReadOnlyBlockTree { get; set; } - public IBlockProcessor GetProcessor(Hash256 stateRoot) { - IReadOnlyTransactionProcessor transactionProcessor = Build(stateRoot); - return new BlockProcessor(SpecProvider, _blockValidator, NoBlockRewards.Instance, - new BlockProcessor.BlockValidationTransactionsExecutor(transactionProcessor, StateProvider), + new BlockProcessor.BlockValidationTransactionsExecutor(Build(stateRoot), StateProvider), StateProvider, NullReceiptStorage.Instance, NullWitnessCollector.Instance, _logManager); } - public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) => new ReadOnlyTransactionProcessor(new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !_doValidation), StateProvider, stateRoot); + public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) => new ReadOnlyTransactionProcessor(_transactionProcessor, StateProvider, stateRoot); public void Dispose() { //_trieStore.Dispose(); DbProvider.Dispose(); } - } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index c1700f2bcb5..77b6c3c8c67 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -131,8 +131,7 @@ protected override async Task Build(ISpecProvider? specProvider SpecProvider, LimboLogs.Instance); - SimulateReadOnlyBlocksProcessingEnv simulateProcessingEnv = SimulateReadOnlyBlocksProcessingEnv.Create( - false, + SimulateReadOnlyBlocksProcessingEnvFactory simulateProcessingEnvFactory = new SimulateReadOnlyBlocksProcessingEnvFactory( WorldStateManager, roBlockTree, new ReadOnlyDbProvider(dbProvider, true), @@ -140,7 +139,7 @@ protected override async Task Build(ISpecProvider? specProvider LimboLogs.Instance); ReceiptFinder ??= ReceiptStorage; - Bridge ??= new BlockchainBridge(processingEnv, simulateProcessingEnv, TxPool, ReceiptFinder, filterStore, filterManager, EthereumEcdsa, Timestamper, LogFinder, SpecProvider, new BlocksConfig(), false); + Bridge ??= new BlockchainBridge(processingEnv, simulateProcessingEnvFactory, TxPool, ReceiptFinder, filterStore, filterManager, EthereumEcdsa, Timestamper, LogFinder, SpecProvider, new BlocksConfig(), false); BlockFinder ??= BlockTree; GasPriceOracle ??= new GasPriceOracle(BlockFinder, SpecProvider, LogManager); diff --git a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs index 87f0d3bc690..dc221b8da83 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs @@ -8,70 +8,23 @@ namespace Nethermind.Trie.Pruning; -public class OverlayTrieStore : TrieStore +public class OverlayTrieStore(IKeyValueStoreWithBatching? keyValueStore, IReadOnlyTrieStore store, ILogManager? logManager) : TrieStore(keyValueStore, logManager) { - private readonly IReadOnlyTrieStore _store; + public override bool IsPersisted(in ValueHash256 keccak) => + base.IsPersisted(in keccak) || store.IsPersisted(in keccak); - public OverlayTrieStore(IKeyValueStoreWithBatching? keyValueStore, IReadOnlyTrieStore store, ILogManager? logManager) : base(keyValueStore, logManager) + public override TrieNode FindCachedOrUnknown(Hash256 hash) { - _store = store; + TrieNode node = base.FindCachedOrUnknown(hash); + return node.NodeType == NodeType.Unknown ? store.FindCachedOrUnknown(hash) : node; } + public override byte[]? LoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) => + base.TryLoadRlp(keccak, readFlags) ?? store.LoadRlp(keccak, readFlags); + public override byte[]? TryLoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) => + base.TryLoadRlp(keccak, readFlags) ?? store.TryLoadRlp(keccak, readFlags); - - public override bool IsPersisted(in ValueHash256 keccak) - { - var isPersisted = base.IsPersisted(in keccak); - if (!isPersisted) - { - isPersisted = _store.IsPersisted(in keccak); - } - return isPersisted; - } - - - public override TrieNode FindCachedOrUnknown(Hash256? hash) - { - TrieNode findCachedOrUnknown = base.FindCachedOrUnknown(hash); - if (findCachedOrUnknown.NodeType == NodeType.Unknown) - { - findCachedOrUnknown = _store.FindCachedOrUnknown(hash); - } - - return findCachedOrUnknown; - } - - public override byte[] LoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) - { - var rlp = base.TryLoadRlp(keccak, readFlags); - if (rlp != null) - { - return rlp; - } - - return _store.LoadRlp(keccak, readFlags); - } - - public override byte[]? TryLoadRlp(Hash256 keccak, ReadFlags readFlags = ReadFlags.None) - { - var rlp = base.TryLoadRlp(keccak, readFlags); - if (rlp != null) - { - return rlp; - } - - return _store.TryLoadRlp(keccak, readFlags); - } - - public override byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) - { - var hash = base.GetByHash(key, flags); - if (hash != null) - { - return hash; - } - - return _store.GetByHash(key, flags); - } + public override byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) => + base.GetByHash(key, flags) ?? store.GetByHash(key, flags); } diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs index 6207749ef47..be7ffcec064 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs @@ -381,7 +381,7 @@ public IReadOnlyTrieStore AsReadOnly(IKeyValueStore? keyValueStore) public bool IsNodeCached(Hash256 hash) => _dirtyNodes.IsNodeCached(hash); - public virtual TrieNode FindCachedOrUnknown(Hash256? hash) + public virtual TrieNode FindCachedOrUnknown(Hash256 hash) { return FindCachedOrUnknown(hash, false); } From 6626f1dab5edd4cc1fbc4e93c480f5e81a884dd1 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 20 Feb 2024 14:26:14 +0000 Subject: [PATCH 131/213] minor fix --- src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs index ee61bdcca6a..93af8c7a641 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs @@ -40,7 +40,7 @@ public void SaveInCache(TrieNode node) } } - public TrieNode FindCachedOrUnknown(Hash256 hash) + public virtual TrieNode FindCachedOrUnknown(Hash256 hash) { if (_objectsCache.TryGetValue(hash, out TrieNode trieNode)) { @@ -379,7 +379,7 @@ public IReadOnlyTrieStore AsReadOnly(IKeyValueStore? keyValueStore = null) => public bool IsNodeCached(Hash256 hash) => _dirtyNodes.IsNodeCached(hash); - public TrieNode FindCachedOrUnknown(Hash256? hash) => + public virtual TrieNode FindCachedOrUnknown(Hash256? hash) => FindCachedOrUnknown(hash, false); internal TrieNode FindCachedOrUnknown(Hash256? hash, bool isReadOnly) From 7766aeba30c7f7c191691b63a1ff725038b2ce73 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 10:50:14 +0000 Subject: [PATCH 132/213] minor bug fixes --- .../Nethermind.Api/NethermindApi.cs | 8 +----- .../BlockhashProvider.cs | 16 +++++------ .../Simulate/SimulateBlockhashProvider.cs | 27 +++++++++++++++++++ .../Simulate/SimulateBridgeHelper.cs | 2 -- .../SimulateReadOnlyBlocksProcessingEnv.cs | 5 +--- .../EthModuleBenchmarks.cs | 3 +-- 6 files changed, 38 insertions(+), 23 deletions(-) create mode 100644 src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 1058bb8842d..54de2b3aefc 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -61,15 +61,9 @@ namespace Nethermind.Api { public class NethermindApi : INethermindApi { - public NethermindApi( - IConfigProvider configProvider, - IJsonSerializer jsonSerializer, - ILogManager logManager, - ChainSpec chainSpec, - ISpecProvider? specProvider = null) + public NethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec) { ConfigProvider = configProvider; - SpecProvider = specProvider ?? new ChainSpecBasedSpecProvider(chainSpec, logManager); EthereumJsonSerializer = jsonSerializer; LogManager = logManager; ChainSpec = chainSpec; diff --git a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs index 065211ac7a2..8eaeebd0e47 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs @@ -14,16 +14,16 @@ namespace Nethermind.Blockchain public class BlockhashProvider : IBlockhashProvider { private static readonly int _maxDepth = 256; - private readonly IBlockTree _blockTree; + protected readonly IBlockTree BlockTree; private readonly ILogger _logger; public BlockhashProvider(IBlockTree blockTree, ILogManager? logManager) { - _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); + BlockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); } - public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) + public virtual Hash256 GetBlockhash(BlockHeader currentBlock, in long number) { long current = currentBlock.Number; if (number >= current || number < current - Math.Min(current, _maxDepth)) @@ -33,7 +33,7 @@ public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) bool isFastSyncSearch = false; - BlockHeader header = _blockTree.FindParentHeader(currentBlock, BlockTreeLookupOptions.TotalDifficultyNotNeeded); + BlockHeader header = BlockTree.FindParentHeader(currentBlock, BlockTreeLookupOptions.TotalDifficultyNotNeeded); if (header is null) { throw new InvalidDataException("Parent header cannot be found when executing BLOCKHASH operation"); @@ -47,18 +47,18 @@ public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) return header.Hash; } - header = _blockTree.FindParentHeader(header, BlockTreeLookupOptions.TotalDifficultyNotNeeded); + header = BlockTree.FindParentHeader(header, BlockTreeLookupOptions.TotalDifficultyNotNeeded); if (header is null) { throw new InvalidDataException("Parent header cannot be found when executing BLOCKHASH operation"); } - if (_blockTree.IsMainChain(header.Hash) && !isFastSyncSearch) + if (BlockTree.IsMainChain(header.Hash) && !isFastSyncSearch) { try { BlockHeader currentHeader = header; - header = _blockTree.FindHeader(number, BlockTreeLookupOptions.TotalDifficultyNotNeeded); + header = BlockTree.FindHeader(number, BlockTreeLookupOptions.TotalDifficultyNotNeeded); if (header is null) { isFastSyncSearch = true; @@ -66,7 +66,7 @@ public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) } else { - if (!_blockTree.IsMainChain(header)) + if (!BlockTree.IsMainChain(header)) { header = currentHeader; throw new InvalidOperationException("Invoke fast blocks chain search"); diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs new file mode 100644 index 00000000000..6634541a34a --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Blockchain; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Logging; + +namespace Nethermind.Facade.Simulate; + +public class SimulateBlockhashProvider : BlockhashProvider +{ + public SimulateBlockhashProvider(IBlockTree blockTree, ILogManager? logManager) : base(blockTree, logManager) + { + } + + public override Hash256 GetBlockhash(BlockHeader currentBlock, in long number) + { + var bestKnown = BlockTree.BestKnownNumber; + if (bestKnown < number && BlockTree.BestSuggestedHeader != null) + { + return base.GetBlockhash(BlockTree.BestSuggestedHeader!, in bestKnown); + } + + return base.GetBlockhash(currentBlock, in number); + } +} diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index fe18748ff6b..e8e57f93a76 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Transactions; using Nethermind.Config; using Nethermind.Consensus.Processing; using Nethermind.Core; @@ -13,7 +12,6 @@ using Nethermind.Crypto; using Nethermind.Evm; using Nethermind.Evm.Tracing; -using Nethermind.Evm.Tracing.GethStyle.JavaScript; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 0ada4a40e22..4a81f07e97e 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -10,8 +10,6 @@ using Nethermind.Consensus.Processing; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; -using Nethermind.Consensus.Withdrawals; -using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Db; @@ -19,7 +17,6 @@ using Nethermind.Evm; using Nethermind.Evm.TransactionProcessing; using Nethermind.Logging; -using Nethermind.Specs.Forks; using Nethermind.State; using Nethermind.State.Repositories; using Nethermind.Trie.Pruning; @@ -104,7 +101,7 @@ public SimulateReadOnlyBlocksProcessingEnv( _doValidation = doValidation; BlockTree = new NonDistructiveBlockTreeOverlay(ReadOnlyBlockTree, blockTree); - BlockhashProvider = new BlockhashProvider(BlockTree, logManager); + BlockhashProvider = new SimulateBlockhashProvider(BlockTree, logManager); //var store = new TrieStore(DbProvider.StateDb, LimboLogs.Instance); //StateProvider = new WorldState(store, DbProvider.CodeDb, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index e2432dc0cb0..d0b13d0a7e2 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -129,8 +129,7 @@ TransactionProcessor transactionProcessor new ReadOnlyBlockTree(blockTree), specProvider, LimboLogs.Instance), - SimulateReadOnlyBlocksProcessingEnv.Create( - false, + new SimulateReadOnlyBlocksProcessingEnvFactory( stateManager, new ReadOnlyBlockTree(blockTree), new ReadOnlyDbProvider(dbProvider, true), From 74203919fc0a1afc10c7629e673a715378b6483a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 11:59:46 +0000 Subject: [PATCH 133/213] minor trello fixes --- .../Nethermind.Facade/BlockchainBridge.cs | 21 +++--- .../Models/MultiCall/SimulateBlockResult.cs | 2 +- .../Simulate/SimulateBlockTracer.cs | 2 +- .../Simulate/SimulateBridgeHelper.cs | 31 ++++----- .../Eth/Simulate/EthSimulateTestsHiveBase.cs | 69 +++++++------------ ...SimulateTxExecutor.MultiCallTxExecutor.cs} | 39 ++++++++--- 6 files changed, 80 insertions(+), 84 deletions(-) rename src/Nethermind/Nethermind.JsonRpc/Modules/Eth/{MultiCallTxExecutor.MultiCallTxExecutor.cs => SimulateTxExecutor.MultiCallTxExecutor.cs} (78%) diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index cf8665f2535..12b55798e4f 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -156,19 +156,18 @@ public SimulateOutput Simulate(BlockHeader header, SimulatePayload Calls { get; set; } = Enumerable.Empty(); + public List Calls { get; set; } = new(); public byte[]? PrevRandao { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 0c5e014fdbd..92be7557ec5 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -47,7 +47,7 @@ public override void EndBlockTrace() { SimulateBlockResult? result = new() { - Calls = _txTracers.Select(t => t.TraceResult), + Calls = _txTracers.Select(t => t.TraceResult).ToList(), Number = (ulong)_currentBlock.Number, Hash = _currentBlock.Hash!, GasLimit = (ulong)_currentBlock.GasLimit, diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index e8e57f93a76..5831fda89dd 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -115,15 +115,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); using IReadOnlyTransactionProcessor? readOnlyTransactionProcessor = env.Build(env.StateProvider.StateRoot!); - GasEstimator gasEstimator = new(readOnlyTransactionProcessor, env.StateProvider, specProvider, blocksConfig); - - long EstimateGas(Transaction transaction) - { - EstimateGasTracer estimateGasTracer = new(); - return gasEstimator.Estimate(transaction, callHeader, estimateGasTracer); - } - - + Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transactionDetails, IReleaseSpec? spec) { Transaction? transaction = transactionDetails.Transaction; @@ -147,16 +139,6 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction transaction.Nonce = cachedNonce; } - if (!transactionDetails.HadGasLimitInRequest) - { - long limit = EstimateGas(transaction); - transaction.GasLimit = limit; - transaction.GasLimit = (long)callHeader.BaseFeePerGas - + Math.Max(IntrinsicGasCalculator.Calculate(transaction, spec) + 1, - transaction.GasLimit); - - } - if (payload.Validation) { if (transaction.GasPrice == 0) @@ -179,6 +161,17 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction return transaction; } IReleaseSpec? spec = specProvider.GetSpec(parent); + + var specifiedGasTxs = callInputBlock.Calls.Where(details => details.HadGasLimitInRequest).ToList(); + var notSpecifiedGasTxs = callInputBlock.Calls.Where(details => !details.HadGasLimitInRequest).ToList(); + var gasSpecified = + specifiedGasTxs.Sum(details => details.Transaction.GasLimit); + var gasPerTx = callHeader.GasLimit - gasSpecified / (callInputBlock.Calls.Length - specifiedGasTxs.Count); + foreach (TransactionWithSourceDetails? call in notSpecifiedGasTxs) + { + call.Transaction.GasLimit = gasPerTx; + } + Transaction[] transactions = callInputBlock.Calls?.Select(t => SetTxHashAndMissingDefaults(t, spec)).ToArray() ?? Array.Empty(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs index b75c587d54d..8d70d936f22 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs @@ -40,8 +40,7 @@ public async Task TestsimulateAddMoreNonDefinedBlockStateCallsThanFit() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateAddMoreNonDefinedBlockStateCallsThanFit"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -82,8 +81,7 @@ public async Task TestsimulateBlockNumOrder38020() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockNumOrder38020"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -95,7 +93,7 @@ public async Task TestsimulateBlockOverrideReflectedInContractSimple() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockOverrideReflectedInContractSimple"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); Assert.IsNotNull(result.Data); } @@ -108,8 +106,7 @@ public async Task TestsimulateBlockOverrideReflectedInContract() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockOverrideReflectedInContract"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -121,8 +118,7 @@ public async Task TestsimulateBlockTimestampAutoIncrement() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockTimestampAutoIncrement"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -134,8 +130,7 @@ public async Task TestsimulateBlockTimestampNonIncrement() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockTimestampNonIncrement"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -147,8 +142,7 @@ public async Task TestsimulateBlockTimestampOrder38021() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockTimestampOrder38021"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -160,8 +154,7 @@ public async Task TestsimulateBlockTimestampsIncrementing() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockTimestampsIncrementing"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -212,8 +205,7 @@ public async Task TestsimulateCheckInvalidNonce() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateCheckInvalidNonce"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -225,7 +217,7 @@ public async Task TestsimulateCheckThatBalanceIsThereAfterNewBlock() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateCheckThatBalanceIsThereAfterNewBlock"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); Assert.IsNotNull(result.Data); } @@ -238,7 +230,7 @@ public async Task TestsimulateCheckThatNonceIncreases() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateCheckThatNonceIncreases"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); Assert.IsNotNull(result.Data); } @@ -355,7 +347,7 @@ public async Task TestsimulateGasFeesAndValueError38014() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateGasFeesAndValueError38014"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); Assert.IsNotNull(result.Data); } @@ -381,7 +373,7 @@ public async Task TestsimulateInstrictGas38013() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateInstrictGas38013"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); Assert.IsNotNull(result.Data); } @@ -407,7 +399,7 @@ public async Task TestsimulateMoveAccountTwice() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateMoveAccountTwice"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); Assert.IsNotNull(result.Data); } @@ -446,8 +438,7 @@ public async Task TestsimulateMoveTwoAccountsToSame38023() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateMoveTwoAccountsToSame38023"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -459,8 +450,7 @@ public async Task TestsimulateMoveTwoNonPrecompilesAccountsToSame() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateMoveTwoNonPrecompilesAccountsToSame"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -485,8 +475,7 @@ public async Task TestsimulateOverrideAddressTwice() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateOverrideAddressTwice"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -498,8 +487,7 @@ public async Task TestsimulateOverrideAllInBlockStateCalls() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateOverrideAllInBlockStateCalls"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -576,8 +564,7 @@ public async Task TestsimulateRunOutOfGasInBlock38015() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateRunOutOfGasInBlock38015"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -589,8 +576,7 @@ public async Task TestsimulateSelfDestructingStateOverride() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateSelfDestructingStateOverride"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -615,8 +601,7 @@ public async Task TestsimulateSimpleNoFundsWithBalanceQuerying() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateSimpleNoFundsWithBalanceQuerying"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -654,8 +639,7 @@ public async Task TestsimulateSimpleNoFunds() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateSimpleNoFunds"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -667,8 +651,7 @@ public async Task TestsimulateSimpleSendFromContractNoBalance() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateSimpleSendFromContractNoBalance"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -745,8 +728,7 @@ public async Task TestsimulateTransferOverBlockStateCalls() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateTransferOverBlockStateCalls"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] @@ -758,7 +740,6 @@ public async Task TestsimulateTryToMoveNonPrecompile() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateTryToMoveNonPrecompile"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs similarity index 78% rename from src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs rename to src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs index d6f954dcf4c..16225091fca 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/MultiCallTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs @@ -3,18 +3,15 @@ using System; using System.Collections.Generic; -using System.Drawing.Drawing2D; using System.Linq; using System.Threading; using Nethermind.Blockchain.Find; using Nethermind.Core; -using Nethermind.Core.Collections; using Nethermind.Facade; using Nethermind.Facade.Simulate; -using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.JsonRpc.Data; -using static Microsoft.FSharp.Core.ByRefKinds; +using Newtonsoft.Json.Linq; namespace Nethermind.JsonRpc.Modules.Eth; @@ -79,6 +76,10 @@ public override ResultWrapper> Execute( SimulatePayload call, BlockParameter? blockParameter) { + if (call.BlockStateCalls!.Length > _rpcConfig.MaxSimulateBlocksCap) + { + return ResultWrapper>.Fail($"This node is configured to support only {_rpcConfig.MaxSimulateBlocksCap} blocks", ErrorCodes.InvalidRequest); + } SearchResult searchResult = _blockFinder.SearchForBlock(blockParameter); if (searchResult.IsError || searchResult.Object == null) @@ -103,12 +104,34 @@ public override ResultWrapper> Execute( return ResultWrapper>.Fail($"Too many blocks provided, node is configured to simulate up to {blocksLimit} while {call.BlockStateCalls?.Length} were given", ErrorCodes.InvalidParams); } - //todo resolve numbers and timestamps - //bool isInOrder = call.BlockStateCalls? - // .Zip(call.BlockStateCalls?.Skip(1), (current, next) => current.BlockOverrides?.Number < next.MyProperty) - // .All(x => x); + if (call.BlockStateCalls != null) + { + long lastBlockNumber = -1; + foreach (var blockToSimulate in call.BlockStateCalls!) + { + var givenNumber = blockToSimulate.BlockOverrides?.Number; + if (givenNumber == null) + { + givenNumber = lastBlockNumber == -1 ? (ulong)header.Number : (ulong)lastBlockNumber + 1; + } + + if (givenNumber > long.MaxValue) + { + return ResultWrapper>.Fail($"Block number too big {givenNumber}!", ErrorCodes.InvalidParams); + } + var given = (long)givenNumber; + if (given > lastBlockNumber) + { + lastBlockNumber = given; + } + else + { + return ResultWrapper>.Fail($"Block number out of order {givenNumber}!", ErrorCodes.InvalidParams); + } + } + } using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout * 100); SimulatePayload? toProcess = Prepare(call); From feeadf69d497cd1c4ea6b3bcca3f3eb58d734dcc Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 12:27:26 +0000 Subject: [PATCH 134/213] Minor tests fix --- .../Nethermind.Facade/Simulate/SimulateBridgeHelper.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 5831fda89dd..f9b7d52e524 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -166,10 +166,13 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction var notSpecifiedGasTxs = callInputBlock.Calls.Where(details => !details.HadGasLimitInRequest).ToList(); var gasSpecified = specifiedGasTxs.Sum(details => details.Transaction.GasLimit); - var gasPerTx = callHeader.GasLimit - gasSpecified / (callInputBlock.Calls.Length - specifiedGasTxs.Count); - foreach (TransactionWithSourceDetails? call in notSpecifiedGasTxs) + if (notSpecifiedGasTxs.Any()) { - call.Transaction.GasLimit = gasPerTx; + var gasPerTx = callHeader.GasLimit - gasSpecified / notSpecifiedGasTxs.Count; + foreach (TransactionWithSourceDetails? call in notSpecifiedGasTxs) + { + call.Transaction.GasLimit = gasPerTx; + } } Transaction[] transactions = callInputBlock.Calls?.Select(t => SetTxHashAndMissingDefaults(t, spec)).ToArray() ?? Array.Empty(); From dd9843a2348e46b2a9861cf64d635f93fa2e4a06 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 13:47:45 +0100 Subject: [PATCH 135/213] fix serialization of Uint256 as dictionary property name --- .../Nethermind.Core/ByteArrayConverter.cs | 37 +++++++++++++++---- .../UInt256Converter.cs | 8 +++- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs b/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs index be6229107f9..67ba0bad755 100644 --- a/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs +++ b/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs @@ -81,14 +81,28 @@ public override void Write( Convert(writer, bytes, skipLeadingZeros: false); } - [SkipLocalsInit] public static void Convert(Utf8JsonWriter writer, ReadOnlySpan bytes, bool skipLeadingZeros = true) + { + Convert(writer, + bytes, + static (w, h) => w.WriteRawValue(h, skipInputValidation: true), skipLeadingZeros); + } + + public delegate void WriteHex(Utf8JsonWriter writer, ReadOnlySpan hex); + + [SkipLocalsInit] + public static void Convert( + Utf8JsonWriter writer, + ReadOnlySpan bytes, + WriteHex writeAction, + bool skipLeadingZeros = true, + bool addQuotations = true) { const int maxStackLength = 128; const int stackLength = 256; int leadingNibbleZeros = skipLeadingZeros ? bytes.CountLeadingZeros() : 0; - int length = bytes.Length * 2 - leadingNibbleZeros + 4; + int length = bytes.Length * 2 - leadingNibbleZeros + 2 + (addQuotations ? 2 : 0); byte[]? array = null; if (length > maxStackLength) @@ -97,16 +111,23 @@ public static void Convert(Utf8JsonWriter writer, ReadOnlySpan bytes, bool } Span hex = (array ?? stackalloc byte[stackLength])[..length]; - hex[^1] = (byte)'"'; - hex[0] = (byte)'"'; - hex[1] = (byte)'0'; - hex[2] = (byte)'x'; + int start = 0; + Index end = ^0; + if (addQuotations) + { + end = ^1; + hex[^1] = (byte)'"'; + hex[start++] = (byte)'"'; + } + + hex[start++] = (byte)'0'; + hex[start++] = (byte)'x'; - Span output = hex[3..^1]; + Span output = hex[start..end]; ReadOnlySpan input = bytes.Slice(leadingNibbleZeros / 2); input.OutputBytesToByteHex(output, extraNibble: (leadingNibbleZeros & 1) != 0); - writer.WriteRawValue(hex, skipInputValidation: true); + writeAction(writer, hex); if (array is not null) { diff --git a/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs b/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs index 9617d19948a..91afeb71880 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs @@ -53,7 +53,7 @@ public static UInt256 Read(ReadOnlySpan hex) } else if (hex[0] != (byte)'0') { - if (UInt256.TryParse(Encoding.UTF8.GetString(hex), out var result)) + if (UInt256.TryParse(Encoding.UTF8.GetString(hex), out UInt256 result)) { return result; } @@ -115,7 +115,11 @@ public override void WriteAsPropertyName(Utf8JsonWriter writer, UInt256 value, J case NumberConversion.Hex: Span bytes = stackalloc byte[32]; value.ToBigEndian(bytes); - writer.WritePropertyName(bytes); + ByteArrayConverter.Convert( + writer, + bytes, + static (w, h) => w.WritePropertyName(h), + addQuotations: false); break; case NumberConversion.Decimal: writer.WritePropertyName(value.ToString(CultureInfo.InvariantCulture)); From c4bd38020c52a3970550ee7106ac922dadede3a5 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 14:01:28 +0100 Subject: [PATCH 136/213] add leading zeros --- src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs b/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs index 91afeb71880..50c18f966a9 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/UInt256Converter.cs @@ -119,6 +119,7 @@ public override void WriteAsPropertyName(Utf8JsonWriter writer, UInt256 value, J writer, bytes, static (w, h) => w.WritePropertyName(h), + skipLeadingZeros: false, addQuotations: false); break; case NumberConversion.Decimal: From e4a381cb2aa17559bb59f67e9016a78766ff420f Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 13:14:01 +0000 Subject: [PATCH 137/213] minor CI fixes --- .../Nethermind.Facade/Simulate/SimulateBridgeHelper.cs | 2 +- src/Nethermind/Nethermind.GitBook/docs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 160000 src/Nethermind/Nethermind.GitBook/docs diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index f9b7d52e524..4de4a61163c 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -115,7 +115,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); using IReadOnlyTransactionProcessor? readOnlyTransactionProcessor = env.Build(env.StateProvider.StateRoot!); - + Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transactionDetails, IReleaseSpec? spec) { Transaction? transaction = transactionDetails.Transaction; diff --git a/src/Nethermind/Nethermind.GitBook/docs b/src/Nethermind/Nethermind.GitBook/docs deleted file mode 160000 index a88697c8982..00000000000 --- a/src/Nethermind/Nethermind.GitBook/docs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a88697c89826fb12ea4976c21396d4a8f79cb196 From bd5fc592fb3434200323e32db9d4c9a14e501e15 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 14:05:57 +0100 Subject: [PATCH 138/213] cleanup --- ...Tests.TestAccountAbstractionRpcBlockchain.cs | 13 ++++--------- .../Contract/TxPriorityContractTests.cs | 2 +- .../FullPruning/FullPruningDiskTest.cs | 2 +- .../Blockchain/TestBlockchain.cs | 17 ++++++++--------- .../Modules/TestRpcBlockchain.cs | 17 +++++++++++------ .../EngineModuleTests.Setup.cs | 2 +- .../MevRpcModuleTests.TestMevRpcBlockchain.cs | 2 +- 7 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs index dcab07a60b9..e56fb9f1c0a 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs @@ -251,22 +251,17 @@ protected override BlockProcessor CreateBlockProcessor() } protected override async Task Build(ISpecProvider? specProvider = null, - UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) + UInt256? initialValues = null, bool addBlockOnStart = true, bool pruning = false) { TestBlockchain chain = await base.Build(specProvider, initialValues); IList
entryPointContractAddresses = new List
(); - IList _entryPointContractAddressesString = - _accountAbstractionConfig.GetEntryPointAddresses().ToList(); - foreach (string _addressString in _entryPointContractAddressesString) + foreach (string addressString in _accountAbstractionConfig.GetEntryPointAddresses()) { - bool parsed = Address.TryParse( - _addressString, - out Address? entryPointContractAddress); + Address.TryParse(addressString, out Address? entryPointContractAddress); entryPointContractAddresses.Add(entryPointContractAddress!); } - AccountAbstractionRpcModule = - new AccountAbstractionRpcModule(UserOperationPool, entryPointContractAddresses.ToArray()); + AccountAbstractionRpcModule = new AccountAbstractionRpcModule(UserOperationPool, entryPointContractAddresses.ToArray()); return chain; } diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs index 6ba09493cb5..e8f087fa105 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs @@ -354,7 +354,7 @@ protected override ILocalDataSource> GetWhitelistLocalDataS protected override ILocalDataSource> GetMinGasPricesLocalDataStore() => LocalDataSource.GetMinGasPricesLocalDataSource(); - protected override Task Build(ISpecProvider specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) + protected override Task Build(ISpecProvider specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool pruning = false) { TempFile = TempPath.GetTempFile(); LocalDataSource = new TxPriorityContract.LocalDataSource(TempFile.Path, new EthereumJsonSerializer(), new FileSystem(), LimboLogs.Instance, Interval); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs index 821bd1493a0..70db1f5a7d0 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs @@ -48,7 +48,7 @@ public PruningTestBlockchain() TempDirectory = TempPath.GetTempDirectory(); } - protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) + protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool pruning = false) { TestBlockchain chain = await base.Build(specProvider, initialValues, addBlockOnStart); PruningDb = (IFullPruningDb)DbProvider.StateDb; diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index b8496e8cd38..d1e4e538b45 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -119,21 +119,20 @@ protected TestBlockchain() public static TransactionBuilder BuildSimpleTransaction => Builders.Build.A.Transaction.SignedAndResolved(TestItem.PrivateKeyA).To(AccountB); - protected virtual async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) + protected virtual async Task Build( + ISpecProvider? specProvider = null, + UInt256? initialValues = null, + bool addBlockOnStart = true, + bool pruning = false) { Timestamper = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc)); JsonSerializer = new EthereumJsonSerializer(); SpecProvider = CreateSpecProvider(specProvider ?? MainnetSpecProvider.Instance); EthereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId, LogManager); DbProvider = await CreateDbProvider(); - if (!usePrunningAndPersistenceStrategies) - { - TrieStore = new TrieStore(StateDb, LogManager); - } - else - { - TrieStore = new TrieStore(StateDb, new MemoryLimit(10.KB()), new ConstantInterval(10), LogManager); - } + TrieStore = pruning + ? new TrieStore(StateDb, new MemoryLimit(10.KB()), new ConstantInterval(10), LogManager) + : new TrieStore(StateDb, LogManager); State = new WorldState(TrieStore, DbProvider.CodeDb, LogManager); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 77b6c3c8c67..b82f702a15d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -111,16 +111,21 @@ public Builder WithConfig(IJsonRpcConfig config) return this; } - public async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool usePrunningAndPersistenceStrategies = false) - { - return (T)(await _blockchain.Build(specProvider, initialValues, true, usePrunningAndPersistenceStrategies)); - } + public async Task Build( + ISpecProvider? specProvider = null, + UInt256? initialValues = null, + bool pruning = false) => + (T)(await _blockchain.Build(specProvider, initialValues, true, pruning)); } - protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) + protected override async Task Build( + ISpecProvider? specProvider = null, + UInt256? initialValues = null, + bool addBlockOnStart = true, + bool pruning = false) { specProvider ??= new TestSpecProvider(Berlin.Instance); - await base.Build(specProvider, initialValues, addBlockOnStart, usePrunningAndPersistenceStrategies); + await base.Build(specProvider, initialValues, addBlockOnStart, pruning); IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = new FilterManager(filterStore, BlockProcessor, TxPool, LimboLogs.Instance); var dbProvider = new ReadOnlyDbProvider(DbProvider, false); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs index afc98098901..b7df19aaabe 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs @@ -259,7 +259,7 @@ protected IBlockValidator CreateBlockValidator() public IManualBlockFinalizationManager BlockFinalizationManager { get; } = new ManualBlockFinalizationManager(); - protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) + protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool pruning = false) { TestBlockchain chain = await base.Build(specProvider, initialValues); return chain; diff --git a/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs b/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs index 5c3686cc4ad..b544ef31d0a 100644 --- a/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs @@ -220,7 +220,7 @@ protected override BlockProcessor CreateBlockProcessor() } protected override async Task Build(ISpecProvider? specProvider = null, - UInt256? initialValues = null, bool addBlockOnStart = true, bool usePrunningAndPersistenceStrategies = false) + UInt256? initialValues = null, bool addBlockOnStart = true, bool pruning = false) { TestBlockchain chain = await base.Build(specProvider, initialValues); MevRpcModule = new MevRpcModule(new JsonRpcConfig(), From 7d7c4999668c9357edc541c3445ab45056736f2c Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 14:23:25 +0100 Subject: [PATCH 139/213] More cleanups --- .../Nethermind.Api/NethermindApi.cs | 21 +++++++------------ .../Nethermind.Evm/CodeAnalysis/CodeInfo.cs | 4 +--- .../SimulateReadOnlyBlocksProcessingEnv.cs | 6 +++--- .../Eth/EthRpcModuleTests.FeeHistory.cs | 1 + .../Modules/Eth/EthRpcModuleTests.cs | 1 + 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 54de2b3aefc..833d9e06b47 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -71,14 +71,9 @@ public NethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSeriali DisposeStack.Push(CryptoRandom); } - private IReadOnlyDbProvider? _readOnlyDbProvider; - private IReadOnlyDbProvider? _simulateReadOnlyDbProvider; - public IBlockchainBridge CreateBlockchainBridge() { ReadOnlyBlockTree readOnlyTree = BlockTree!.AsReadOnly(); - LazyInitializer.EnsureInitialized(ref _readOnlyDbProvider, () => new ReadOnlyDbProvider(DbProvider, false)); - LazyInitializer.EnsureInitialized(ref _simulateReadOnlyDbProvider, () => new ReadOnlyDbProvider(DbProvider, true)); // TODO: reuse the same trie cache here ReadOnlyTxProcessingEnv readOnlyTxProcessingEnv = new( @@ -87,20 +82,20 @@ public IBlockchainBridge CreateBlockchainBridge() SpecProvider, LogManager); - SimulateReadOnlyBlocksProcessingEnvFactory simulateReadOnlyBlocksProcessingEnv = new SimulateReadOnlyBlocksProcessingEnvFactory( - WorldStateManager!, - readOnlyTree, - _simulateReadOnlyDbProvider, - SpecProvider!, - LogManager); - + SimulateReadOnlyBlocksProcessingEnvFactory simulateReadOnlyBlocksProcessingEnvFactory = + new SimulateReadOnlyBlocksProcessingEnvFactory( + WorldStateManager!, + readOnlyTree, + DbProvider!, + SpecProvider!, + LogManager); IMiningConfig miningConfig = ConfigProvider.GetConfig(); IBlocksConfig blocksConfig = ConfigProvider.GetConfig(); return new BlockchainBridge( readOnlyTxProcessingEnv, - simulateReadOnlyBlocksProcessingEnv, + simulateReadOnlyBlocksProcessingEnvFactory, TxPool, ReceiptFinder, FilterStore, diff --git a/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs b/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs index 6d167abac09..aac5b334306 100644 --- a/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs +++ b/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs @@ -16,10 +16,8 @@ public class CodeInfo : IThreadPoolWorkItem private static readonly JumpDestinationAnalyzer _emptyAnalyzer = new(Array.Empty()); public static CodeInfo Empty { get; } = new CodeInfo(Array.Empty()); - public CodeInfo(byte[] code) + public CodeInfo(byte[] code) : this(code.AsMemory()) { - MachineCode = code; - _analyzer = code.Length == 0 ? _emptyAnalyzer : new JumpDestinationAnalyzer(code); } public CodeInfo(ReadOnlyMemory code) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 4a81f07e97e..ba6a2f55753 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -26,16 +26,16 @@ namespace Nethermind.Facade.Simulate; public class SimulateReadOnlyBlocksProcessingEnvFactory( IWorldStateManager worldStateManager, IReadOnlyBlockTree baseBlockTree, - IReadOnlyDbProvider readOnlyDbProvider, + IDbProvider dbProvider, ISpecProvider specProvider, ILogManager? logManager = null) { public SimulateReadOnlyBlocksProcessingEnv Create(bool traceTransfers, bool validate) { - IReadOnlyDbProvider editableDbProvider = new ReadOnlyDbProvider(readOnlyDbProvider, true); + IReadOnlyDbProvider editableDbProvider = new ReadOnlyDbProvider(dbProvider, true); OverlayTrieStore overlayTrieStore = new(editableDbProvider.StateDb, worldStateManager.TrieStore, logManager); OverlayWorldStateManager overlayWorldStateManager = new(editableDbProvider, overlayTrieStore, logManager); - BlockTree tempBlockTree = CreateTempBlockTree(readOnlyDbProvider, specProvider, logManager, editableDbProvider); + BlockTree tempBlockTree = CreateTempBlockTree(editableDbProvider, specProvider, logManager, editableDbProvider); return new SimulateReadOnlyBlocksProcessingEnv( traceTransfers, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs index 90ddb8d4235..983f3a29fb1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.FeeHistory.cs @@ -9,6 +9,7 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; public partial class EthRpcModuleTests { + [SetCulture("en-US")] [TestCase(1, "latest", "{\"jsonrpc\":\"2.0\",\"result\":{\"baseFeePerGas\":[\"0x2da282a8\",\"0x27ee3253\"],\"gasUsedRatio\":[0.0],\"oldestBlock\":\"0x3\",\"reward\":[[\"0x0\",\"0x0\",\"0x0\",\"0x0\",\"0x0\"]]},\"id\":67}")] [TestCase(1, "pending", "{\"jsonrpc\":\"2.0\",\"result\":{\"baseFeePerGas\":[\"0x2da282a8\",\"0x27ee3253\"],\"gasUsedRatio\":[0.0],\"oldestBlock\":\"0x3\",\"reward\":[[\"0x0\",\"0x0\",\"0x0\",\"0x0\",\"0x0\"]]},\"id\":67}")] [TestCase(2, "0x01", "{\"jsonrpc\":\"2.0\",\"result\":{\"baseFeePerGas\":[\"0x0\",\"0x3b9aca00\",\"0x342770c0\"],\"gasUsedRatio\":[0.0,0.0],\"oldestBlock\":\"0x0\",\"reward\":[[\"0x0\",\"0x0\",\"0x0\",\"0x0\",\"0x0\"],[\"0x0\",\"0x0\",\"0x0\",\"0x0\",\"0x0\"]]},\"id\":67}")] diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs index ddf1ed2da5b..18475fe6e01 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs @@ -63,6 +63,7 @@ public async Task Eth_get_balance_default_block() } [Test] + [SetCulture("en-US")] public async Task Eth_get_eth_feeHistory() { using Context ctx = await Context.Create(); From 9fde5e0a3a5b90e4c422505b7d78eec4ba274194 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 14:34:51 +0100 Subject: [PATCH 140/213] BlockHash refactor --- ...iderTests.cs => BlockHashProviderTests.cs} | 50 +++++++++---------- .../Producers/DevBlockproducerTests.cs | 4 +- .../Nethermind.Blockchain.Test/ReorgTests.cs | 4 +- ...ckhashProvider.cs => BlockHashProvider.cs} | 45 ++++++++++------- .../CliqueBlockProducerTests.cs | 6 +-- .../Processing/ReadOnlyTxProcessingEnv.cs | 2 +- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 4 +- .../Blockchain/TestBlockchain.cs | 2 +- .../EvmPooledMemoryTests.cs | 2 +- ...shProvider.cs => TestBlockHashProvider.cs} | 8 +-- .../Tracing/GasEstimationTests.cs | 2 +- .../TransactionProcessorEip4844Tests.cs | 2 +- .../TransactionProcessorFeeTests.cs | 2 +- .../TransactionProcessorTests.cs | 2 +- .../VirtualMachineTestsBase.cs | 4 +- ...khashProvider.cs => IBlockHashProvider.cs} | 4 +- .../Nethermind.Evm/VirtualMachine.cs | 10 ++-- .../Simulate/SimulateBlockHashProvider.cs | 22 ++++++++ .../Simulate/SimulateBlockhashProvider.cs | 27 ---------- .../SimulateReadOnlyBlocksProcessingEnv.cs | 4 +- .../Steps/InitializeBlockchain.cs | 4 +- .../Modules/Trace/ParityStyleTracerTests.cs | 4 +- .../SyncThreadTests.cs | 6 +-- 23 files changed, 111 insertions(+), 109 deletions(-) rename src/Nethermind/Nethermind.Blockchain.Test/{BlockhashProviderTests.cs => BlockHashProviderTests.cs} (83%) rename src/Nethermind/Nethermind.Blockchain/{BlockhashProvider.cs => BlockHashProvider.cs} (55%) rename src/Nethermind/Nethermind.Evm.Test/{TestBlockhashProvider.cs => TestBlockHashProvider.cs} (57%) rename src/Nethermind/Nethermind.Evm/{IBlockhashProvider.cs => IBlockHashProvider.cs} (63%) create mode 100644 src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockHashProvider.cs delete mode 100644 src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs similarity index 83% rename from src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs rename to src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs index 9728dfb5475..9592b22dff1 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs @@ -10,7 +10,7 @@ namespace Nethermind.Blockchain.Test { [TestFixture] - public class BlockhashProviderTests + public class BlockHashProviderTests { [Test, Timeout(Timeout.MaxTestTime)] public void Can_get_parent_only_headers() @@ -21,10 +21,10 @@ public void Can_get_parent_only_headers() BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader? head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None); Block current = Build.A.Block.WithParent(head!).TestObject; - Hash256 result = provider.GetBlockhash(current.Header, chainLength - 1); + Hash256 result = provider.GetBlockHash(current.Header, chainLength - 1); Assert.That(result, Is.EqualTo(head?.Hash)); } @@ -36,10 +36,10 @@ public void Can_lookup_up_to_256_before_with_headers_only() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockhash(current.Header, chainLength - 256); + Hash256 result = provider.GetBlockHash(current.Header, chainLength - 256); Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash)); } @@ -51,10 +51,10 @@ public void Can_lookup_up_to_256_before_with_headers_only_and_competing_branches Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(out Block headBlock, chainLength).OfChainLength(out Block _, chainLength, 1).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); Block current = Build.A.Block.WithParent(headBlock).TestObject; long lookupNumber = chainLength - 256; - Hash256 result = provider.GetBlockhash(current.Header, lookupNumber); + Hash256 result = provider.GetBlockHash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -66,12 +66,12 @@ public void Can_lookup_up_to_256_before_soon_after_fast_sync() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(out Block headBlock, chainLength).OfChainLength(out Block _, chainLength, 1).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); Block current = Build.A.Block.WithParent(headBlock).TestObject; tree.SuggestBlock(current); tree.UpdateMainChain(current); long lookupNumber = chainLength - 256; - Hash256 result = provider.GetBlockhash(current.Header, lookupNumber); + Hash256 result = provider.GetBlockHash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -83,7 +83,7 @@ public void Can_lookup_up_to_256_before_some_blocks_after_fast_sync() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(out Block headBlock, chainLength).OfChainLength(out Block _, chainLength, 1).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); Block current = Build.A.Block.WithParent(headBlock).TestObject; for (int i = 0; i < 6; i++) @@ -94,7 +94,7 @@ public void Can_lookup_up_to_256_before_some_blocks_after_fast_sync() } long lookupNumber = current.Number - 256; - Hash256 result = provider.GetBlockhash(current.Header, lookupNumber); + Hash256 result = provider.GetBlockHash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -113,9 +113,9 @@ public void Can_handle_non_main_chain_in_fast_sync() current = Build.A.Block.WithParent(current).TestObject; } - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); - Hash256 result = provider.GetBlockhash(current.Header, 509); + Hash256 result = provider.GetBlockHash(current.Header, 509); Assert.NotNull(result); } @@ -128,10 +128,10 @@ public void Can_get_parent_hash() BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockhash(current.Header, chainLength - 1); + Hash256 result = provider.GetBlockHash(current.Header, chainLength - 1); Assert.That(result, Is.EqualTo(head.Hash)); } @@ -143,10 +143,10 @@ public void Cannot_ask_for_self() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockhash(current.Header, chainLength); + Hash256 result = provider.GetBlockHash(current.Header, chainLength); Assert.Null(result); } @@ -158,10 +158,10 @@ public void Cannot_ask_about_future() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockhash(current.Header, chainLength + 1); + Hash256 result = provider.GetBlockHash(current.Header, chainLength + 1); Assert.Null(result); } @@ -173,10 +173,10 @@ public void Can_lookup_up_to_256_before() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockhash(current.Header, chainLength - 256); + Hash256 result = provider.GetBlockHash(current.Header, chainLength - 256); Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash)); } @@ -188,10 +188,10 @@ public void No_lookup_more_than_256_before() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockhash(current.Header, chainLength - 257); + Hash256 result = provider.GetBlockHash(current.Header, chainLength - 257); Assert.Null(result); } @@ -203,10 +203,10 @@ public void UInt_256_overflow() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockhashProvider provider = new(tree, LimboLogs.Instance); + BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockhash(current.Header, 127); + Hash256 result = provider.GetBlockHash(current.Header, 127); Assert.That(result, Is.EqualTo(head.Hash)); } } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs index 1738debb60f..a823f7fc7ca 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs @@ -55,10 +55,10 @@ public void Test() dbProvider.RegisteredDbs[DbNames.Code], LimboLogs.Instance); StateReader stateReader = new(trieStore, dbProvider.GetDb(DbNames.State), LimboLogs.Instance); - BlockhashProvider blockhashProvider = new(blockTree, LimboLogs.Instance); + BlockHashProvider blockHashProvider = new(blockTree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( - blockhashProvider, + blockHashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs index 70c8deb1e48..8943b093ae7 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs @@ -56,10 +56,10 @@ public void Setup() new TxValidator(specProvider.ChainId), LimboLogs.Instance, transactionComparerProvider.GetDefaultComparer()); - BlockhashProvider blockhashProvider = new(_blockTree, LimboLogs.Instance); + BlockHashProvider blockHashProvider = new(_blockTree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( - blockhashProvider, + blockHashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs b/src/Nethermind/Nethermind.Blockchain/BlockHashProvider.cs similarity index 55% rename from src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs rename to src/Nethermind/Nethermind.Blockchain/BlockHashProvider.cs index 8eaeebd0e47..c7086eb5f78 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockHashProvider.cs @@ -2,6 +2,8 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using Nethermind.Blockchain.Find; using Nethermind.Core; @@ -11,19 +13,14 @@ namespace Nethermind.Blockchain { - public class BlockhashProvider : IBlockhashProvider + public sealed class BlockHashProvider(IBlockTree blockTree, ILogManager? logManager) + : IBlockHashProvider { private static readonly int _maxDepth = 256; - protected readonly IBlockTree BlockTree; - private readonly ILogger _logger; + private readonly IBlockTree _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); + private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - public BlockhashProvider(IBlockTree blockTree, ILogManager? logManager) - { - BlockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); - _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - } - - public virtual Hash256 GetBlockhash(BlockHeader currentBlock, in long number) + public Hash256? GetBlockHash(BlockHeader currentBlock, in long number) { long current = currentBlock.Number; if (number >= current || number < current - Math.Min(current, _maxDepth)) @@ -33,32 +30,32 @@ public virtual Hash256 GetBlockhash(BlockHeader currentBlock, in long number) bool isFastSyncSearch = false; - BlockHeader header = BlockTree.FindParentHeader(currentBlock, BlockTreeLookupOptions.TotalDifficultyNotNeeded); + BlockHeader? header = _blockTree.FindParentHeader(currentBlock, BlockTreeLookupOptions.TotalDifficultyNotNeeded); if (header is null) { - throw new InvalidDataException("Parent header cannot be found when executing BLOCKHASH operation"); + ThrowInvalidDataException(); } for (var i = 0; i < _maxDepth; i++) { - if (number == header.Number) + if (number == header!.Number) { if (_logger.IsTrace) _logger.Trace($"BLOCKHASH opcode returning {header.Number},{header.Hash} for {currentBlock.Number} -> {number}"); return header.Hash; } - header = BlockTree.FindParentHeader(header, BlockTreeLookupOptions.TotalDifficultyNotNeeded); + header = _blockTree.FindParentHeader(header, BlockTreeLookupOptions.TotalDifficultyNotNeeded); if (header is null) { - throw new InvalidDataException("Parent header cannot be found when executing BLOCKHASH operation"); + ThrowInvalidDataException(); } - if (BlockTree.IsMainChain(header.Hash) && !isFastSyncSearch) + if (_blockTree.IsMainChain(header.Hash!) && !isFastSyncSearch) { try { BlockHeader currentHeader = header; - header = BlockTree.FindHeader(number, BlockTreeLookupOptions.TotalDifficultyNotNeeded); + header = _blockTree.FindHeader(number, BlockTreeLookupOptions.TotalDifficultyNotNeeded); if (header is null) { isFastSyncSearch = true; @@ -66,10 +63,10 @@ public virtual Hash256 GetBlockhash(BlockHeader currentBlock, in long number) } else { - if (!BlockTree.IsMainChain(header)) + if (!_blockTree.IsMainChain(header)) { header = currentHeader; - throw new InvalidOperationException("Invoke fast blocks chain search"); + ThrowInvalidOperationException(); } } } @@ -83,5 +80,15 @@ public virtual Hash256 GetBlockhash(BlockHeader currentBlock, in long number) if (_logger.IsTrace) _logger.Trace($"BLOCKHASH opcode returning null for {currentBlock.Number} -> {number}"); return null; } + + [DoesNotReturn] + [StackTraceHidden] + private static void ThrowInvalidDataException() => + throw new InvalidDataException("Parent header cannot be found when executing BLOCKHASH operation"); + + [DoesNotReturn] + [StackTraceHidden] + private static void ThrowInvalidOperationException() => + throw new InvalidOperationException("Invoke fast blocks chain search"); } } diff --git a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs index b97aac0f85a..e5f397682d8 100644 --- a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs @@ -117,7 +117,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f transactionComparerProvider.GetDefaultComparer()); _pools[privateKey] = txPool; - BlockhashProvider blockhashProvider = new(blockTree, LimboLogs.Instance); + BlockHashProvider blockHashProvider = new(blockTree, LimboLogs.Instance); _blockTrees.Add(privateKey, blockTree); SnapshotManager snapshotManager = new(_cliqueConfig, blocksDb, blockTree, _ethereumEcdsa, nodeLogManager); @@ -130,7 +130,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f CodeInfoRepository codeInfoRepository = new(); TransactionProcessor transactionProcessor = new(goerliSpecProvider, stateProvider, - new VirtualMachine(blockhashProvider, specProvider, codeInfoRepository, nodeLogManager), + new VirtualMachine(blockHashProvider, specProvider, codeInfoRepository, nodeLogManager), codeInfoRepository, nodeLogManager); BlockProcessor blockProcessor = new( @@ -149,7 +149,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f IReadOnlyTrieStore minerTrieStore = trieStore.AsReadOnly(); WorldState minerStateProvider = new(minerTrieStore, codeDb, nodeLogManager); - VirtualMachine minerVirtualMachine = new(blockhashProvider, specProvider, codeInfoRepository, nodeLogManager); + VirtualMachine minerVirtualMachine = new(blockHashProvider, specProvider, codeInfoRepository, nodeLogManager); TransactionProcessor minerTransactionProcessor = new(goerliSpecProvider, minerStateProvider, minerVirtualMachine, codeInfoRepository, nodeLogManager); BlockProcessor minerBlockProcessor = new( diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index 25f0508b6ac..fa828ea6d2c 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -42,7 +42,7 @@ public ReadOnlyTxProcessingEnv( ArgumentNullException.ThrowIfNull(worldStateManager); CodeInfoRepository = new CodeInfoRepository(); - Machine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); + Machine = new VirtualMachine(BlockHashProvider, specProvider, CodeInfoRepository, logManager); TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, Machine, CodeInfoRepository, logManager); } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index e9a6bc181c4..099476b999a 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -16,7 +16,7 @@ public class ReadOnlyTxProcessingEnvBase public IStateReader StateReader { get; protected set; } public IWorldState StateProvider { get; protected set; } public IBlockTree BlockTree { get; protected set; } - public IBlockhashProvider BlockhashProvider { get; protected set; } + public IBlockHashProvider BlockHashProvider { get; protected set; } protected ReadOnlyTxProcessingEnvBase( IWorldStateManager worldStateManager, @@ -27,6 +27,6 @@ protected ReadOnlyTxProcessingEnvBase( StateReader = worldStateManager.GlobalStateReader; StateProvider = worldStateManager.CreateResettableWorldState(); BlockTree = readOnlyBlockTree ?? throw new ArgumentNullException(nameof(readOnlyBlockTree)); - BlockhashProvider = new BlockhashProvider(BlockTree, logManager); + BlockHashProvider = new BlockHashProvider(BlockTree, logManager); } } diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index d1e4e538b45..ac38e58c8e3 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -193,7 +193,7 @@ protected virtual async Task Build( _trieStoreWatcher = new TrieStoreBoundaryWatcher(WorldStateManager, BlockTree, LogManager); CodeInfoRepository codeInfoRepository = new(); ReceiptStorage = new InMemoryReceiptStorage(blockTree: BlockTree); - VirtualMachine virtualMachine = new(new BlockhashProvider(BlockTree, LogManager), SpecProvider, codeInfoRepository, LogManager); + VirtualMachine virtualMachine = new(new BlockHashProvider(BlockTree, LogManager), SpecProvider, codeInfoRepository, LogManager); TxProcessor = new TransactionProcessor(SpecProvider, State, virtualMachine, codeInfoRepository, LogManager); BlockPreprocessorStep = new RecoverSignatures(EthereumEcdsa, TxPool, SpecProvider, LogManager); diff --git a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs index dc5ee488cd6..8a16c8075d8 100644 --- a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs @@ -159,7 +159,7 @@ private static string run(byte[] input) ISpecProvider specProvider = new TestSpecProvider(London.Instance); CodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( - Nethermind.Evm.Test.TestBlockhashProvider.Instance, + Nethermind.Evm.Test.TestBlockHashProvider.Instance, specProvider, codeInfoRepository, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm.Test/TestBlockHashProvider.cs similarity index 57% rename from src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs rename to src/Nethermind/Nethermind.Evm.Test/TestBlockHashProvider.cs index b95fb719cc8..7d515a07fd0 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TestBlockHashProvider.cs @@ -6,15 +6,15 @@ namespace Nethermind.Evm.Test { - public class TestBlockhashProvider : IBlockhashProvider + public class TestBlockHashProvider : IBlockHashProvider { - public static TestBlockhashProvider Instance = new(); + public static TestBlockHashProvider Instance = new(); - private TestBlockhashProvider() + private TestBlockHashProvider() { } - public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) + public Hash256 GetBlockHash(BlockHeader currentBlock, in long number) { return Keccak.Compute(number.ToString()); } diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs index ff1a8b3683d..bf346725858 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs @@ -278,7 +278,7 @@ public TestEnvironment() _stateProvider.CommitTree(0); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(TestBlockHashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs index b9284dc48fe..cb92572223c 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs @@ -36,7 +36,7 @@ public void Setup() TrieStore trieStore = new(stateDb, LimboLogs.Instance); _stateProvider = new WorldState(trieStore, new MemDb(), LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(TestBlockHashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); } diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs index 3cf8e81c276..c981aa1ca2c 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -43,7 +43,7 @@ public void Setup() _stateProvider.CommitTree(0); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(TestBlockHashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); } diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs index de3153f6537..76ef0fe7925 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs @@ -59,7 +59,7 @@ public void Setup() _stateProvider.CommitTree(0); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(TestBlockHashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); } diff --git a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs index 5b834eaf1d6..20d0756b610 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs @@ -67,9 +67,9 @@ public virtual void Setup() ITrieStore trieStore = new TrieStore(_stateDb, logManager); TestState = new WorldState(trieStore, codeDb, logManager); _ethereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId, logManager); - IBlockhashProvider blockhashProvider = TestBlockhashProvider.Instance; + IBlockHashProvider blockHashProvider = TestBlockHashProvider.Instance; CodeInfoRepository = new CodeInfoRepository(); - Machine = new VirtualMachine(blockhashProvider, SpecProvider, CodeInfoRepository, logManager); + Machine = new VirtualMachine(blockHashProvider, SpecProvider, CodeInfoRepository, logManager); _processor = new TransactionProcessor(SpecProvider, TestState, Machine, CodeInfoRepository, logManager); } diff --git a/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm/IBlockHashProvider.cs similarity index 63% rename from src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs rename to src/Nethermind/Nethermind.Evm/IBlockHashProvider.cs index 3cbc1b9335d..d133e56e12c 100644 --- a/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm/IBlockHashProvider.cs @@ -6,8 +6,8 @@ namespace Nethermind.Evm { - public interface IBlockhashProvider + public interface IBlockHashProvider { - Hash256 GetBlockhash(BlockHeader currentBlock, in long number); + Hash256? GetBlockHash(BlockHeader currentBlock, in long number); } } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index b30e96bdba9..90e40b743de 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -69,7 +69,7 @@ public class VirtualMachine : IVirtualMachine private readonly IVirtualMachine _evm; public VirtualMachine( - IBlockhashProvider? blockhashProvider, + IBlockHashProvider? blockhashProvider, ISpecProvider? specProvider, ICodeInfoRepository codeInfoRepository, ILogManager? logManager) @@ -151,7 +151,7 @@ internal sealed class VirtualMachine : IVirtualMachine where TLogger : { private readonly byte[] _chainId; - private readonly IBlockhashProvider _blockhashProvider; + private readonly IBlockHashProvider _blockHashProvider; private readonly ISpecProvider _specProvider; private readonly ILogger _logger; private IWorldState _worldState; @@ -163,13 +163,13 @@ internal sealed class VirtualMachine : IVirtualMachine where TLogger : private readonly ICodeInfoRepository _codeInfoRepository; public VirtualMachine( - IBlockhashProvider? blockhashProvider, + IBlockHashProvider? blockhashProvider, ISpecProvider? specProvider, ICodeInfoRepository codeInfoRepository, ILogger? logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _blockhashProvider = blockhashProvider ?? throw new ArgumentNullException(nameof(blockhashProvider)); + _blockHashProvider = blockhashProvider ?? throw new ArgumentNullException(nameof(blockhashProvider)); _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _codeInfoRepository = codeInfoRepository ?? throw new ArgumentNullException(nameof(codeInfoRepository)); _chainId = ((UInt256)specProvider.ChainId).ToBigEndian(); @@ -1400,7 +1400,7 @@ private CallResult ExecuteCode long.MaxValue ? long.MaxValue : (long)a; - Hash256 blockHash = _blockhashProvider.GetBlockhash(blkCtx.Header, number); + Hash256 blockHash = _blockHashProvider.GetBlockHash(blkCtx.Header, number); stack.PushBytes(blockHash is not null ? blockHash.Bytes : BytesZero32); if (typeof(TLogger) == typeof(IsTracing)) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockHashProvider.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockHashProvider.cs new file mode 100644 index 00000000000..dbf8b12653d --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockHashProvider.cs @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Blockchain; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Evm; +using Nethermind.Logging; + +namespace Nethermind.Facade.Simulate; + +public sealed class SimulateBlockHashProvider(IBlockHashProvider blockHashProvider, IBlockTree blockTree) + : IBlockHashProvider +{ + public Hash256? GetBlockHash(BlockHeader currentBlock, in long number) + { + var bestKnown = blockTree.BestKnownNumber; + return bestKnown < number && blockTree.BestSuggestedHeader is not null + ? blockHashProvider.GetBlockHash(blockTree.BestSuggestedHeader!, in bestKnown) + : blockHashProvider.GetBlockHash(currentBlock, in number); + } +} diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs deleted file mode 100644 index 6634541a34a..00000000000 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Blockchain; -using Nethermind.Core; -using Nethermind.Core.Crypto; -using Nethermind.Logging; - -namespace Nethermind.Facade.Simulate; - -public class SimulateBlockhashProvider : BlockhashProvider -{ - public SimulateBlockhashProvider(IBlockTree blockTree, ILogManager? logManager) : base(blockTree, logManager) - { - } - - public override Hash256 GetBlockhash(BlockHeader currentBlock, in long number) - { - var bestKnown = BlockTree.BestKnownNumber; - if (bestKnown < number && BlockTree.BestSuggestedHeader != null) - { - return base.GetBlockhash(BlockTree.BestSuggestedHeader!, in bestKnown); - } - - return base.GetBlockhash(currentBlock, in number); - } -} diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index ba6a2f55753..f62d5b612fe 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -101,7 +101,7 @@ public SimulateReadOnlyBlocksProcessingEnv( _doValidation = doValidation; BlockTree = new NonDistructiveBlockTreeOverlay(ReadOnlyBlockTree, blockTree); - BlockhashProvider = new SimulateBlockhashProvider(BlockTree, logManager); + BlockHashProvider = new SimulateBlockHashProvider(new BlockHashProvider(BlockTree, logManager), BlockTree); //var store = new TrieStore(DbProvider.StateDb, LimboLogs.Instance); //StateProvider = new WorldState(store, DbProvider.CodeDb, LimboLogs.Instance); @@ -110,7 +110,7 @@ public SimulateReadOnlyBlocksProcessingEnv( CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); - VirtualMachine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); + VirtualMachine = new VirtualMachine(BlockHashProvider, specProvider, CodeInfoRepository, logManager); _transactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !_doValidation); _blockValidator = CreateValidator(); diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs index bebae0411c1..4c85426e63c 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs @@ -178,13 +178,13 @@ protected virtual (VirtualMachine, CodeInfoRepository) CreateVirtualMachine() if (_api.SpecProvider is null) throw new StepDependencyException(nameof(_api.SpecProvider)); // blockchain processing - BlockhashProvider blockhashProvider = new( + BlockHashProvider blockHashProvider = new( _api.BlockTree, _api.LogManager); CodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( - blockhashProvider, + blockHashProvider, _api.SpecProvider, codeInfoRepository, _api.LogManager); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs index be7f60d297d..997ee8df6e3 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs @@ -61,9 +61,9 @@ public void Setup() WorldState stateProvider = new(trieStore, codeDb, LimboLogs.Instance); _stateReader = new StateReader(trieStore, codeDb, LimboLogs.Instance); - BlockhashProvider blockhashProvider = new(_blockTree, LimboLogs.Instance); + BlockHashProvider blockHashProvider = new(_blockTree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(blockhashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(blockHashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); TransactionProcessor transactionProcessor = new(specProvider, stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _poSSwitcher = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs index 5d9fb20936f..315547b0fc8 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs @@ -272,9 +272,9 @@ private SyncTestContext CreateSyncManager(int index) new TxValidator(specProvider.ChainId), logManager, transactionComparerProvider.GetDefaultComparer()); - BlockhashProvider blockhashProvider = new(tree, LimboLogs.Instance); + BlockHashProvider blockHashProvider = new(tree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(blockhashProvider, specProvider, codeInfoRepository, logManager); + VirtualMachine virtualMachine = new(blockHashProvider, specProvider, codeInfoRepository, logManager); Always sealValidator = Always.Valid; HeaderValidator headerValidator = new(tree, sealValidator, specProvider, logManager); @@ -310,7 +310,7 @@ private SyncTestContext CreateSyncManager(int index) SyncPeerPool syncPeerPool = new(tree, nodeStatsManager, new TotalDifficultyBetterPeerStrategy(LimboLogs.Instance), logManager, 25); WorldState devState = new(trieStore, codeDb, logManager); - VirtualMachine devEvm = new(blockhashProvider, specProvider, codeInfoRepository, logManager); + VirtualMachine devEvm = new(blockHashProvider, specProvider, codeInfoRepository, logManager); TransactionProcessor devTxProcessor = new(specProvider, devState, devEvm, codeInfoRepository, logManager); BlockProcessor devBlockProcessor = new( From 4c2110e6aea89d59bba439b7b4d520f5317b71ec Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 14:44:43 +0100 Subject: [PATCH 141/213] BlockTree refactor --- .../Nethermind.Blockchain/BlockTree.cs | 21 ++-- ...lockTreeOverlay.cs => BlockTreeOverlay.cs} | 31 ++---- .../Find/IBlockFinder.cs | 3 +- .../ReadOnlyBlockTree.cs | 96 +++++++++---------- .../SimulateReadOnlyBlocksProcessingEnv.cs | 2 +- 5 files changed, 61 insertions(+), 92 deletions(-) rename src/Nethermind/Nethermind.Blockchain/{NonDistructiveBlockTreeOverlay.cs => BlockTreeOverlay.cs} (93%) diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index 8deaff21ea1..3a2ef8285e7 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -824,22 +824,17 @@ private void DeleteBlocks(Hash256 deletePointer) return childHash; } - public bool IsMainChain(BlockHeader blockHeader) - { - ChainLevelInfo? chainLevelInfo = LoadLevel(blockHeader.Number); - bool isMain = chainLevelInfo is not null && chainLevelInfo.MainChainBlock?.BlockHash.Equals(blockHeader.Hash) == true; - return isMain; - } + public bool IsMainChain(BlockHeader blockHeader) => + LoadLevel(blockHeader.Number)?.MainChainBlock?.BlockHash.Equals(blockHeader.Hash) == true; - public bool IsMainChain(Hash256 blockHash) + public bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true) { BlockHeader? header = FindHeader(blockHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded); - if (header is null) - { - throw new InvalidOperationException($"Not able to retrieve block number for an unknown block {blockHash}"); - } - - return IsMainChain(header); + return header is not null + ? IsMainChain(header) + : throwOnMissingHash + ? throw new InvalidOperationException($"Not able to retrieve block number for an unknown block {blockHash}") + : false; } public BlockHeader? FindBestSuggestedHeader() => BestSuggestedHeader; diff --git a/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs b/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs similarity index 93% rename from src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs rename to src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs index 420ba2554f7..2d278d42ff1 100644 --- a/src/Nethermind/Nethermind.Blockchain/NonDistructiveBlockTreeOverlay.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs @@ -11,12 +11,12 @@ namespace Nethermind.Blockchain; -public class NonDistructiveBlockTreeOverlay : IBlockTree +public class BlockTreeOverlay : IBlockTree { private readonly IBlockTree _baseTree; private readonly IBlockTree _overlayTree; - public NonDistructiveBlockTreeOverlay(IReadOnlyBlockTree baseTree, IBlockTree overlayTree) + public BlockTreeOverlay(IReadOnlyBlockTree baseTree, IBlockTree overlayTree) { _baseTree = baseTree ?? throw new ArgumentNullException(nameof(baseTree)); _overlayTree = overlayTree ?? throw new ArgumentNullException(nameof(overlayTree)); @@ -26,12 +26,9 @@ public NonDistructiveBlockTreeOverlay(IReadOnlyBlockTree baseTree, IBlockTree ov public ulong NetworkId => _baseTree.NetworkId; public ulong ChainId => _baseTree.ChainId; public BlockHeader? Genesis => _baseTree.Genesis; - public BlockHeader? BestSuggestedHeader => _overlayTree.BestSuggestedHeader ?? _baseTree.BestSuggestedHeader; public Block? BestSuggestedBody => _overlayTree.BestSuggestedBody ?? _baseTree.BestSuggestedBody; - public BlockHeader? BestSuggestedBeaconHeader => _overlayTree.BestSuggestedBeaconHeader ?? _baseTree.BestSuggestedBeaconHeader; - public BlockHeader? LowestInsertedHeader => _overlayTree.LowestInsertedHeader ?? _baseTree.LowestInsertedHeader; public long? LowestInsertedBodyNumber @@ -120,7 +117,6 @@ public void DeleteInvalidBlock(Block invalidBlock) => public void ForkChoiceUpdated(Hash256? finalizedBlockHash, Hash256? safeBlockBlockHash) => _overlayTree.ForkChoiceUpdated(finalizedBlockHash, safeBlockBlockHash); - // Event forwarding public event EventHandler? NewBestSuggestedBlock { add @@ -249,24 +245,9 @@ public void UpdateBeaconMainChain(BlockInfo[]? blockInfos, long clearBeaconMainC public bool IsMainChain(BlockHeader blockHeader) => _baseTree.IsMainChain(blockHeader) || _overlayTree.IsMainChain(blockHeader); - public bool IsMainChain(Hash256 blockHash) - { - try - { - if (_baseTree.IsMainChain(blockHash)) return true; - } - catch - { - // ignored as we have _overlayTree to look into - } - - return _overlayTree.IsMainChain(blockHash); - } - - public BlockHeader FindBestSuggestedHeader() - { - BlockHeader? overlayHeader = _overlayTree.FindBestSuggestedHeader(); - return overlayHeader ?? _baseTree.FindBestSuggestedHeader(); - } + public bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true) => + _baseTree.IsMainChain(blockHash, false) || _overlayTree.IsMainChain(blockHash, throwOnMissingHash); + public BlockHeader FindBestSuggestedHeader() => + _overlayTree.FindBestSuggestedHeader() ?? _baseTree.FindBestSuggestedHeader(); } diff --git a/src/Nethermind/Nethermind.Blockchain/Find/IBlockFinder.cs b/src/Nethermind/Nethermind.Blockchain/Find/IBlockFinder.cs index 5b715002db7..034c9909348 100644 --- a/src/Nethermind/Nethermind.Blockchain/Find/IBlockFinder.cs +++ b/src/Nethermind/Nethermind.Blockchain/Find/IBlockFinder.cs @@ -43,8 +43,9 @@ public interface IBlockFinder /// Checks if the block is currently in the canonical chain /// /// Hash of the block to check + /// If should throw when hash is not found /// True if part of the canonical chain, otherwise False - bool IsMainChain(Hash256 blockHash); + bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true); public Block? FindBlock(Hash256 blockHash, long? blockNumber = null) => FindBlock(blockHash, BlockTreeLookupOptions.None, blockNumber); diff --git a/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs b/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs index 8fdeb68242a..46c40744db3 100644 --- a/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs @@ -9,63 +9,55 @@ using Nethermind.Blockchain.Visitors; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Int256; namespace Nethermind.Blockchain { /// /// Safe to be reused for all classes reading the same wrapped block tree. /// - public class ReadOnlyBlockTree : IReadOnlyBlockTree + public class ReadOnlyBlockTree(IBlockTree wrapped) : IReadOnlyBlockTree { - private readonly IBlockTree _wrapped; - - public ReadOnlyBlockTree(IBlockTree wrapped) - { - _wrapped = wrapped; - } - - public ulong NetworkId => _wrapped.NetworkId; - public ulong ChainId => _wrapped.ChainId; - public BlockHeader Genesis => _wrapped.Genesis; - public BlockHeader BestSuggestedHeader => _wrapped.BestSuggestedHeader; - public BlockHeader BestSuggestedBeaconHeader => _wrapped.BestSuggestedBeaconHeader; - public BlockHeader LowestInsertedHeader => _wrapped.LowestInsertedHeader; + public ulong NetworkId => wrapped.NetworkId; + public ulong ChainId => wrapped.ChainId; + public BlockHeader? Genesis => wrapped.Genesis; + public BlockHeader? BestSuggestedHeader => wrapped.BestSuggestedHeader; + public BlockHeader? BestSuggestedBeaconHeader => wrapped.BestSuggestedBeaconHeader; + public BlockHeader? LowestInsertedHeader => wrapped.LowestInsertedHeader; public long? LowestInsertedBodyNumber { - get => _wrapped.LowestInsertedBodyNumber; - set => _wrapped.LowestInsertedBodyNumber = value; + get => wrapped.LowestInsertedBodyNumber; + set => wrapped.LowestInsertedBodyNumber = value; } public long? BestPersistedState { - get => _wrapped.BestPersistedState; - set => _wrapped.BestPersistedState = value; + get => wrapped.BestPersistedState; + set => wrapped.BestPersistedState = value; } public BlockHeader? LowestInsertedBeaconHeader { - get => _wrapped.LowestInsertedBeaconHeader; - set => _wrapped.LowestInsertedBeaconHeader = value; + get => wrapped.LowestInsertedBeaconHeader; + set => wrapped.LowestInsertedBeaconHeader = value; } - public Block BestSuggestedBody => _wrapped.BestSuggestedBody; - public long BestKnownNumber => _wrapped.BestKnownNumber; - public long BestKnownBeaconNumber => _wrapped.BestKnownBeaconNumber; - public Block Head => _wrapped.Head; + public Block? BestSuggestedBody => wrapped.BestSuggestedBody; + public long BestKnownNumber => wrapped.BestKnownNumber; + public long BestKnownBeaconNumber => wrapped.BestKnownBeaconNumber; + public Block? Head => wrapped.Head; public void MarkChainAsProcessed(IReadOnlyList blocks) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(MarkChainAsProcessed)} calls"); - public (BlockInfo Info, ChainLevelInfo Level) GetInfo(long number, Hash256 blockHash) => _wrapped.GetInfo(number, blockHash); + public (BlockInfo Info, ChainLevelInfo Level) GetInfo(long number, Hash256 blockHash) => wrapped.GetInfo(number, blockHash); public bool CanAcceptNewBlocks { get; } = false; public async Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken) { - await _wrapped.Accept(blockTreeVisitor, cancellationToken); + await wrapped.Accept(blockTreeVisitor, cancellationToken); } - public ChainLevelInfo FindLevel(long number) => _wrapped.FindLevel(number); - public BlockInfo FindCanonicalBlockInfo(long blockNumber) => _wrapped.FindCanonicalBlockInfo(blockNumber); + public ChainLevelInfo? FindLevel(long number) => wrapped.FindLevel(number); + public BlockInfo FindCanonicalBlockInfo(long blockNumber) => wrapped.FindCanonicalBlockInfo(blockNumber); public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOptions = BlockTreeInsertBlockOptions.None, BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None, WriteFlags blockWriteFlags = WriteFlags.None) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(Insert)} calls"); @@ -75,7 +67,7 @@ public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBloc public void UpdateHeadBlock(Hash256 blockHash) { // hacky while there is not special tree for RPC - _wrapped.UpdateHeadBlock(blockHash); + wrapped.UpdateHeadBlock(blockHash); } public AddBlockResult SuggestBlock(Block block, BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(SuggestBlock)} calls"); @@ -86,40 +78,40 @@ public void UpdateHeadBlock(Hash256 blockHash) public AddBlockResult SuggestHeader(BlockHeader header) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(SuggestHeader)} calls"); - public Hash256 HeadHash => _wrapped.HeadHash; - public Hash256 GenesisHash => _wrapped.GenesisHash; - public Hash256 PendingHash => _wrapped.PendingHash; - public Hash256 FinalizedHash => _wrapped.FinalizedHash; - public Hash256 SafeHash => _wrapped.SafeHash; + public Hash256 HeadHash => wrapped.HeadHash; + public Hash256 GenesisHash => wrapped.GenesisHash; + public Hash256? PendingHash => wrapped.PendingHash; + public Hash256? FinalizedHash => wrapped.FinalizedHash; + public Hash256? SafeHash => wrapped.SafeHash; - public Block FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => _wrapped.FindBlock(blockHash, options, blockNumber); + public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => wrapped.FindBlock(blockHash, options, blockNumber); - public BlockHeader FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => _wrapped.FindHeader(blockHash, options, blockNumber: blockNumber); + public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => wrapped.FindHeader(blockHash, options, blockNumber: blockNumber); - public BlockHeader FindHeader(long blockNumber, BlockTreeLookupOptions options) => _wrapped.FindHeader(blockNumber, options); - public Hash256 FindBlockHash(long blockNumber) => _wrapped.FindBlockHash(blockNumber); + public BlockHeader? FindHeader(long blockNumber, BlockTreeLookupOptions options) => wrapped.FindHeader(blockNumber, options); + public Hash256? FindBlockHash(long blockNumber) => wrapped.FindBlockHash(blockNumber); - public bool IsMainChain(BlockHeader blockHeader) => _wrapped.IsMainChain(blockHeader); + public bool IsMainChain(BlockHeader blockHeader) => wrapped.IsMainChain(blockHeader); - public Hash256 FindHash(long blockNumber) => _wrapped.FindHash(blockNumber); + public Hash256 FindHash(long blockNumber) => wrapped.FindHash(blockNumber); - public BlockHeader[] FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) => _wrapped.FindHeaders(hash, numberOfBlocks, skip, reverse); + public BlockHeader[] FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) => wrapped.FindHeaders(hash, numberOfBlocks, skip, reverse); - public BlockHeader FindLowestCommonAncestor(BlockHeader firstDescendant, BlockHeader secondDescendant, long maxSearchDepth) => _wrapped.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth); + public BlockHeader FindLowestCommonAncestor(BlockHeader firstDescendant, BlockHeader secondDescendant, long maxSearchDepth) => wrapped.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth); - public Block FindBlock(long blockNumber, BlockTreeLookupOptions options) => _wrapped.FindBlock(blockNumber, options); + public Block? FindBlock(long blockNumber, BlockTreeLookupOptions options) => wrapped.FindBlock(blockNumber, options); public void DeleteInvalidBlock(Block invalidBlock) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(DeleteInvalidBlock)} calls"); - public bool IsMainChain(Hash256 blockHash) => _wrapped.IsMainChain(blockHash); + public bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true) => wrapped.IsMainChain(blockHash, throwOnMissingHash); - public BlockHeader FindBestSuggestedHeader() => _wrapped.FindBestSuggestedHeader(); + public BlockHeader FindBestSuggestedHeader() => wrapped.FindBestSuggestedHeader(); - public bool IsKnownBlock(long number, Hash256 blockHash) => _wrapped.IsKnownBlock(number, blockHash); + public bool IsKnownBlock(long number, Hash256 blockHash) => wrapped.IsKnownBlock(number, blockHash); - public bool IsKnownBeaconBlock(long number, Hash256 blockHash) => _wrapped.IsKnownBeaconBlock(number, blockHash); + public bool IsKnownBeaconBlock(long number, Hash256 blockHash) => wrapped.IsKnownBeaconBlock(number, blockHash); - public bool WasProcessed(long number, Hash256 blockHash) => _wrapped.WasProcessed(number, blockHash); + public bool WasProcessed(long number, Hash256 blockHash) => wrapped.WasProcessed(number, blockHash); public event EventHandler NewBestSuggestedBlock { @@ -167,13 +159,13 @@ public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool fo { for (long i = start; i <= endSearch; i++) { - yield return _wrapped.FindHeader(i, BlockTreeLookupOptions.None); + yield return wrapped.FindHeader(i, BlockTreeLookupOptions.None); } } if (force || GetPotentiallyCorruptedBlocks(startNumber).Any(b => b is null)) { - return _wrapped.DeleteChainSlice(startNumber, endNumber, force); + return wrapped.DeleteChainSlice(startNumber, endNumber, force); } throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} cannot {nameof(DeleteChainSlice)} if searched blocks [{startNumber}, {endSearch}] are not corrupted."); @@ -189,7 +181,7 @@ public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool fo } - public bool IsBetterThanHead(BlockHeader? header) => _wrapped.IsBetterThanHead(header); + public bool IsBetterThanHead(BlockHeader? header) => wrapped.IsBetterThanHead(header); public void UpdateBeaconMainChain(BlockInfo[]? blockInfos, long clearBeaconMainChainStartPoint) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(UpdateBeaconMainChain)} calls"); public void RecalculateTreeLevels() => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(RecalculateTreeLevels)} calls"); diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index f62d5b612fe..41326c81e1c 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -100,7 +100,7 @@ public SimulateReadOnlyBlocksProcessingEnv( SpecProvider = specProvider; _doValidation = doValidation; - BlockTree = new NonDistructiveBlockTreeOverlay(ReadOnlyBlockTree, blockTree); + BlockTree = new BlockTreeOverlay(ReadOnlyBlockTree, blockTree); BlockHashProvider = new SimulateBlockHashProvider(new BlockHashProvider(BlockTree, logManager), BlockTree); //var store = new TrieStore(DbProvider.StateDb, LimboLogs.Instance); From a03fc3621224922ee65b8db9a9517a0868f3547e Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 14:51:39 +0000 Subject: [PATCH 142/213] restoring hive tests --- .../Eth/Simulate/EthSimulateTestsHiveBase.cs | 69 ++++++++++++------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs index 8d70d936f22..b75c587d54d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs @@ -40,7 +40,8 @@ public async Task TestsimulateAddMoreNonDefinedBlockStateCallsThanFit() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateAddMoreNonDefinedBlockStateCallsThanFit"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -81,7 +82,8 @@ public async Task TestsimulateBlockNumOrder38020() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockNumOrder38020"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -93,7 +95,7 @@ public async Task TestsimulateBlockOverrideReflectedInContractSimple() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockOverrideReflectedInContractSimple"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -106,7 +108,8 @@ public async Task TestsimulateBlockOverrideReflectedInContract() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockOverrideReflectedInContract"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -118,7 +121,8 @@ public async Task TestsimulateBlockTimestampAutoIncrement() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockTimestampAutoIncrement"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -130,7 +134,8 @@ public async Task TestsimulateBlockTimestampNonIncrement() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockTimestampNonIncrement"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -142,7 +147,8 @@ public async Task TestsimulateBlockTimestampOrder38021() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockTimestampOrder38021"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -154,7 +160,8 @@ public async Task TestsimulateBlockTimestampsIncrementing() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockTimestampsIncrementing"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -205,7 +212,8 @@ public async Task TestsimulateCheckInvalidNonce() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateCheckInvalidNonce"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -217,7 +225,7 @@ public async Task TestsimulateCheckThatBalanceIsThereAfterNewBlock() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateCheckThatBalanceIsThereAfterNewBlock"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -230,7 +238,7 @@ public async Task TestsimulateCheckThatNonceIncreases() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateCheckThatNonceIncreases"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -347,7 +355,7 @@ public async Task TestsimulateGasFeesAndValueError38014() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateGasFeesAndValueError38014"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -373,7 +381,7 @@ public async Task TestsimulateInstrictGas38013() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateInstrictGas38013"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -399,7 +407,7 @@ public async Task TestsimulateMoveAccountTwice() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateMoveAccountTwice"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } @@ -438,7 +446,8 @@ public async Task TestsimulateMoveTwoAccountsToSame38023() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateMoveTwoAccountsToSame38023"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -450,7 +459,8 @@ public async Task TestsimulateMoveTwoNonPrecompilesAccountsToSame() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateMoveTwoNonPrecompilesAccountsToSame"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -475,7 +485,8 @@ public async Task TestsimulateOverrideAddressTwice() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateOverrideAddressTwice"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -487,7 +498,8 @@ public async Task TestsimulateOverrideAllInBlockStateCalls() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateOverrideAllInBlockStateCalls"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -564,7 +576,8 @@ public async Task TestsimulateRunOutOfGasInBlock38015() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateRunOutOfGasInBlock38015"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -576,7 +589,8 @@ public async Task TestsimulateSelfDestructingStateOverride() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateSelfDestructingStateOverride"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -601,7 +615,8 @@ public async Task TestsimulateSimpleNoFundsWithBalanceQuerying() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateSimpleNoFundsWithBalanceQuerying"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -639,7 +654,8 @@ public async Task TestsimulateSimpleNoFunds() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateSimpleNoFunds"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -651,7 +667,8 @@ public async Task TestsimulateSimpleSendFromContractNoBalance() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateSimpleSendFromContractNoBalance"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -728,7 +745,8 @@ public async Task TestsimulateTransferOverBlockStateCalls() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateTransferOverBlockStateCalls"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } [Test] @@ -740,6 +758,7 @@ public async Task TestsimulateTryToMoveNonPrecompile() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateTryToMoveNonPrecompile"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); + Assert.IsNotNull(result.Data); } } From db876c12926e27eef9321a512961db3b1b752208 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 15:26:03 +0000 Subject: [PATCH 143/213] minor blockHashProvider related fixes --- .../Ethereum.Test.Base/BlockchainTestBase.cs | 4 ++-- src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs | 4 ++-- .../Ethereum.Test.Base/TestBlockhashProvider.cs | 4 ++-- .../Nethermind.Evm.Benchmark/EvmBenchmarks.cs | 4 ++-- .../MultipleUnsignedOperations.cs | 4 ++-- .../Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs | 4 ++-- .../Nethermind.Evm.Benchmark/TestBlockhashProvider.cs | 6 ++++-- src/Nethermind/Nethermind.Evm/VirtualMachine.cs | 10 +++++----- .../EthModuleBenchmarks.cs | 6 +++--- 9 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs index a181a397004..f25035b1506 100644 --- a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs @@ -142,14 +142,14 @@ protected async Task RunTest(BlockchainTest test, Stopwatch? IStateReader stateReader = new StateReader(trieStore, codeDb, _logManager); IReceiptStorage receiptStorage = NullReceiptStorage.Instance; - IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, _logManager); + IBlockHashProvider blockHashProvider = new BlockHashProvider(blockTree, _logManager); ITxValidator txValidator = new TxValidator(TestBlockchainIds.ChainId); IHeaderValidator headerValidator = new HeaderValidator(blockTree, Sealer, specProvider, _logManager); IUnclesValidator unclesValidator = new UnclesValidator(blockTree, headerValidator, _logManager); IBlockValidator blockValidator = new BlockValidator(txValidator, headerValidator, unclesValidator, specProvider, _logManager); CodeInfoRepository codeInfoRepository = new(); IVirtualMachine virtualMachine = new VirtualMachine( - blockhashProvider, + blockHashProvider, specProvider, codeInfoRepository, _logManager); diff --git a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs index e58f75b30af..321bbebe1f4 100644 --- a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs @@ -66,10 +66,10 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) TrieStore trieStore = new(stateDb, _logManager); WorldState stateProvider = new(trieStore, codeDb, _logManager); - IBlockhashProvider blockhashProvider = new TestBlockhashProvider(); + IBlockHashProvider blockHashProvider = new TestBlockHashProvider(); CodeInfoRepository codeInfoRepository = new(); IVirtualMachine virtualMachine = new VirtualMachine( - blockhashProvider, + blockHashProvider, specProvider, codeInfoRepository, _logManager); diff --git a/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs b/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs index 786ddde0b16..3e4ed367eb0 100644 --- a/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs +++ b/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs @@ -7,9 +7,9 @@ namespace Ethereum.Test.Base { - public class TestBlockhashProvider : IBlockhashProvider + public class TestBlockHashProvider : IBlockHashProvider { - public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) + public Hash256 GetBlockHash(BlockHeader currentBlock, in long number) { if (number != 0) return Keccak.Zero; diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs index 9d8e167b7a7..52754c5276d 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs @@ -28,7 +28,7 @@ public class EvmBenchmarks private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; private BlockHeader _header = new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.IstanbulBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private IBlockhashProvider _blockhashProvider = new TestBlockhashProvider(); + private IBlockHashProvider _blockHashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; @@ -45,7 +45,7 @@ public void GlobalSetup() _stateProvider.CreateAccount(Address.Zero, 1000.Ether()); _stateProvider.Commit(_spec); CodeInfoRepository codeInfoRepository = new(); - _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, codeInfoRepository, LimboLogs.Instance); + _virtualMachine = new VirtualMachine(_blockHashProvider, MainnetSpecProvider.Instance, codeInfoRepository, LimboLogs.Instance); _environment = new ExecutionEnvironment ( diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs index f2018a02ed8..25eb311bf4d 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs @@ -27,7 +27,7 @@ public class MultipleUnsignedOperations private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; private readonly BlockHeader _header = new(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.MuirGlacierBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private readonly IBlockhashProvider _blockhashProvider = new TestBlockhashProvider(); + private readonly IBlockHashProvider _blockHashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; @@ -77,7 +77,7 @@ public void GlobalSetup() Console.WriteLine(MuirGlacier.Instance); CodeInfoRepository codeInfoRepository = new(); - _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, codeInfoRepository, new OneLoggerLogManager(NullLogger.Instance)); + _virtualMachine = new VirtualMachine(_blockHashProvider, MainnetSpecProvider.Instance, codeInfoRepository, new OneLoggerLogManager(NullLogger.Instance)); _environment = new ExecutionEnvironment ( diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs index b4d3792de3e..7fd0e42e8f1 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs @@ -28,7 +28,7 @@ public class StaticCallBenchmarks private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; private BlockHeader _header = new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.MuirGlacierBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private IBlockhashProvider _blockhashProvider = new TestBlockhashProvider(); + private IBlockHashProvider _blockHashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; @@ -88,7 +88,7 @@ public void GlobalSetup() Console.WriteLine(MuirGlacier.Instance); CodeInfoRepository codeInfoRepository = new(); - _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, codeInfoRepository, new OneLoggerLogManager(NullLogger.Instance)); + _virtualMachine = new VirtualMachine(_blockHashProvider, MainnetSpecProvider.Instance, codeInfoRepository, new OneLoggerLogManager(NullLogger.Instance)); _environment = new ExecutionEnvironment ( diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs index c95162989f5..c6a6119e3b0 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs @@ -6,11 +6,13 @@ namespace Nethermind.Evm.Benchmark { - public class TestBlockhashProvider : IBlockhashProvider + public class TestBlockhashProvider : IBlockHashProvider { - public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) + public Hash256 GetBlockHash(BlockHeader currentBlock, in long number) { return Keccak.Compute(number.ToString()); } + + } } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 90e40b743de..fdce8af2b28 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -69,15 +69,15 @@ public class VirtualMachine : IVirtualMachine private readonly IVirtualMachine _evm; public VirtualMachine( - IBlockHashProvider? blockhashProvider, + IBlockHashProvider? blockHashProvider, ISpecProvider? specProvider, ICodeInfoRepository codeInfoRepository, ILogManager? logManager) { ILogger logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); _evm = logger.IsTrace - ? new VirtualMachine(blockhashProvider, specProvider, codeInfoRepository, logger) - : new VirtualMachine(blockhashProvider, specProvider, codeInfoRepository, logger); + ? new VirtualMachine(blockHashProvider, specProvider, codeInfoRepository, logger) + : new VirtualMachine(blockHashProvider, specProvider, codeInfoRepository, logger); } public TransactionSubstate Run(EvmState state, IWorldState worldState, ITxTracer txTracer) @@ -163,13 +163,13 @@ internal sealed class VirtualMachine : IVirtualMachine where TLogger : private readonly ICodeInfoRepository _codeInfoRepository; public VirtualMachine( - IBlockHashProvider? blockhashProvider, + IBlockHashProvider? blockHashProvider, ISpecProvider? specProvider, ICodeInfoRepository codeInfoRepository, ILogger? logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _blockHashProvider = blockhashProvider ?? throw new ArgumentNullException(nameof(blockhashProvider)); + _blockHashProvider = blockHashProvider ?? throw new ArgumentNullException(nameof(blockHashProvider)); _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _codeInfoRepository = codeInfoRepository ?? throw new ArgumentNullException(nameof(codeInfoRepository)); _chainId = ((UInt256)specProvider.ChainId).ToBigEndian(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index d0b13d0a7e2..ea8712659d4 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -44,7 +44,7 @@ namespace Nethermind.JsonRpc.Benchmark public class EthModuleBenchmarks { private IVirtualMachine _virtualMachine; - private IBlockhashProvider _blockhashProvider; + private IBlockHashProvider _blockHashProvider; private EthRpcModule _ethModule; [GlobalSetup] @@ -80,9 +80,9 @@ public void GlobalSetup() NullBloomStorage.Instance, new SyncConfig(), LimboLogs.Instance); - _blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance); + _blockHashProvider = new BlockHashProvider(blockTree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); - _virtualMachine = new VirtualMachine(_blockhashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); + _virtualMachine = new VirtualMachine(_blockHashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); Block genesisBlock = Build.A.Block.Genesis.TestObject; blockTree.SuggestBlock(genesisBlock); From 6ef4946b1df5d516866c11cb51e6531fad06bda3 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 16:33:51 +0100 Subject: [PATCH 144/213] fix tests --- .../BlockHashProviderTests.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs index 9592b22dff1..2a8eebe486d 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs @@ -24,7 +24,7 @@ public void Can_get_parent_only_headers() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader? head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None); Block current = Build.A.Block.WithParent(head!).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength - 1); + Hash256? result = provider.GetBlockHash(current.Header, chainLength - 1); Assert.That(result, Is.EqualTo(head?.Hash)); } @@ -39,7 +39,7 @@ public void Can_lookup_up_to_256_before_with_headers_only() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength - 256); + Hash256? result = provider.GetBlockHash(current.Header, chainLength - 256); Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash)); } @@ -54,7 +54,7 @@ public void Can_lookup_up_to_256_before_with_headers_only_and_competing_branches BlockHashProvider provider = new(tree, LimboLogs.Instance); Block current = Build.A.Block.WithParent(headBlock).TestObject; long lookupNumber = chainLength - 256; - Hash256 result = provider.GetBlockHash(current.Header, lookupNumber); + Hash256? result = provider.GetBlockHash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -71,7 +71,7 @@ public void Can_lookup_up_to_256_before_soon_after_fast_sync() tree.SuggestBlock(current); tree.UpdateMainChain(current); long lookupNumber = chainLength - 256; - Hash256 result = provider.GetBlockHash(current.Header, lookupNumber); + Hash256? result = provider.GetBlockHash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -94,7 +94,7 @@ public void Can_lookup_up_to_256_before_some_blocks_after_fast_sync() } long lookupNumber = current.Number - 256; - Hash256 result = provider.GetBlockHash(current.Header, lookupNumber); + Hash256? result = provider.GetBlockHash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -115,7 +115,7 @@ public void Can_handle_non_main_chain_in_fast_sync() BlockHashProvider provider = new(tree, LimboLogs.Instance); - Hash256 result = provider.GetBlockHash(current.Header, 509); + Hash256? result = provider.GetBlockHash(current.Header, 509); Assert.NotNull(result); } @@ -131,7 +131,7 @@ public void Can_get_parent_hash() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength - 1); + Hash256? result = provider.GetBlockHash(current.Header, chainLength - 1); Assert.That(result, Is.EqualTo(head.Hash)); } @@ -146,7 +146,7 @@ public void Cannot_ask_for_self() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength); + Hash256? result = provider.GetBlockHash(current.Header, chainLength); Assert.Null(result); } @@ -161,7 +161,7 @@ public void Cannot_ask_about_future() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength + 1); + Hash256? result = provider.GetBlockHash(current.Header, chainLength + 1); Assert.Null(result); } @@ -176,7 +176,7 @@ public void Can_lookup_up_to_256_before() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength - 256); + Hash256? result = provider.GetBlockHash(current.Header, chainLength - 256); Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash)); } @@ -191,7 +191,7 @@ public void No_lookup_more_than_256_before() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength - 257); + Hash256? result = provider.GetBlockHash(current.Header, chainLength - 257); Assert.Null(result); } @@ -206,7 +206,7 @@ public void UInt_256_overflow() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, 127); + Hash256? result = provider.GetBlockHash(current.Header, 127); Assert.That(result, Is.EqualTo(head.Hash)); } } From e08353576de8d7c28ecf3492bd0aad8c98e67a00 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 16:34:16 +0100 Subject: [PATCH 145/213] refactor EthCliModule --- .../Nethermind.Cli/Modules/EthCliModule.cs | 213 +++++------------- 1 file changed, 56 insertions(+), 157 deletions(-) diff --git a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs index 261be73ce46..426f605340f 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs @@ -13,177 +13,110 @@ namespace Nethermind.Cli.Modules { [CliModule("eth")] - public class EthCliModule : CliModuleBase + public class EthCliModule(ICliEngine cliEngine, INodeManager nodeManager) : CliModuleBase(cliEngine, nodeManager) { private string? SendEth(Address from, Address address, in UInt256 amountInWei) { long blockNumber = NodeManager.Post("eth_blockNumber").Result; - TransactionForRpc tx = new(); - tx.Value = amountInWei; - tx.Gas = Transaction.BaseTxGasCost; - tx.GasPrice = (UInt256)Engine.JintEngine.GetValue("gasPrice").AsNumber(); - tx.To = address; - tx.Nonce = (ulong)NodeManager.Post("eth_getTransactionCount", from, blockNumber).Result; - tx.From = from; + TransactionForRpc tx = new() + { + Value = amountInWei, + Gas = Transaction.BaseTxGasCost, + GasPrice = (UInt256)Engine.JintEngine.GetValue("gasPrice").AsNumber(), + To = address, + Nonce = (ulong)NodeManager.Post("eth_getTransactionCount", from, blockNumber).Result, + From = from + }; Hash256? keccak = NodeManager.Post("eth_sendTransaction", tx).Result; return keccak?.Bytes.ToHexString(); } [CliFunction("eth", "syncing")] - public JsValue Syncing() - { - return NodeManager.PostJint("eth_syncing").Result; - } + public JsValue Syncing() => NodeManager.PostJint("eth_syncing").Result; [CliFunction("eth", "getProof")] - public JsValue GetProof(string address, string[] storageKeys, string? blockParameter = null) - { - return NodeManager.PostJint("eth_getProof", CliParseAddress(address), storageKeys.Select(CliParseHash), blockParameter ?? "latest").Result; - } + public JsValue GetProof(string address, string[] storageKeys, string? blockParameter = null) => + NodeManager.PostJint("eth_getProof", CliParseAddress(address), storageKeys.Select(CliParseHash), blockParameter ?? "latest").Result; [CliFunction("eth", "call")] - public string? Call(object tx, string? blockParameter = null) - { - return NodeManager.Post("eth_call", tx, blockParameter ?? "latest").Result; - } - + public string? Call(object tx, string? blockParameter = null) => + NodeManager.Post("eth_call", tx, blockParameter ?? "latest").Result; [CliFunction("eth", "simulateV1")] - public JsValue SimulateV1(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) - { - return NodeManager.PostJint("eth_simulateV1", 1, blockCalls, blockParameter ?? "latest", traceTransfers).Result; - } - + public JsValue SimulateV1(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) => + NodeManager.PostJint("eth_simulateV1", 1, blockCalls, blockParameter ?? "latest", traceTransfers).Result; [CliFunction("eth", "getBlockByHash")] - public JsValue GetBlockByHash(string hash, bool returnFullTransactionObjects) - { - return NodeManager.PostJint("eth_getBlockByHash", CliParseHash(hash), returnFullTransactionObjects).Result; - } + public JsValue GetBlockByHash(string hash, bool returnFullTransactionObjects) => + NodeManager.PostJint("eth_getBlockByHash", CliParseHash(hash), returnFullTransactionObjects).Result; [CliFunction("eth", "getTransactionCount")] - public string? GetTransactionCount(string address, string? blockParameter = null) - { - return NodeManager.Post("eth_getTransactionCount", CliParseAddress(address), blockParameter ?? "latest").Result; - } + public string? GetTransactionCount(string address, string? blockParameter = null) => + NodeManager.Post("eth_getTransactionCount", CliParseAddress(address), blockParameter ?? "latest").Result; [CliFunction("eth", "getStorageAt")] - public string? GetStorageAt(string address, string positionIndex, string? blockParameter = null) - { - return NodeManager.Post("eth_getStorageAt", CliParseAddress(address), positionIndex, blockParameter ?? "latest").Result; - } + public string? GetStorageAt(string address, string positionIndex, string? blockParameter = null) => + NodeManager.Post("eth_getStorageAt", CliParseAddress(address), positionIndex, blockParameter ?? "latest").Result; [CliFunction("eth", "getBlockByNumber")] - public JsValue GetBlockByNumber(string blockParameter, bool returnFullTransactionObjects = false) - { - return NodeManager.PostJint("eth_getBlockByNumber", blockParameter, returnFullTransactionObjects).Result; - } + public JsValue GetBlockByNumber(string blockParameter, bool returnFullTransactionObjects = false) => + NodeManager.PostJint("eth_getBlockByNumber", blockParameter, returnFullTransactionObjects).Result; [CliFunction("eth", "sendEth")] - public string? SendEth(string from, string to, decimal amountInEth) - { - return SendEth(CliParseAddress(from), CliParseAddress(to), (UInt256)(amountInEth * (decimal)1.Ether())); - } + public string? SendEth(string from, string to, decimal amountInEth) => + SendEth(CliParseAddress(from), CliParseAddress(to), (UInt256)(amountInEth * (decimal)1.Ether())); [CliFunction("eth", "estimateGas")] - public string? EstimateGas(object json, string? blockParameter = null) - { - return NodeManager.Post("eth_estimateGas", json, blockParameter ?? "latest").Result; - } + public string? EstimateGas(object json, string? blockParameter = null) => + NodeManager.Post("eth_estimateGas", json, blockParameter ?? "latest").Result; [CliFunction("eth", "createAccessList")] - public JsValue CreateAccessList(object tx, string? blockParameter = null, bool optimize = true) - { - if (optimize) - { + public JsValue CreateAccessList(object tx, string? blockParameter = null, bool optimize = true) => + optimize ? // to support Geth - return NodeManager.PostJint("eth_createAccessList", tx, blockParameter ?? "latest").Result; - } - else - { - return NodeManager.PostJint("eth_createAccessList", tx, blockParameter ?? "latest", optimize).Result; - } - } + NodeManager.PostJint("eth_createAccessList", tx, blockParameter ?? "latest").Result + : NodeManager.PostJint("eth_createAccessList", tx, blockParameter ?? "latest", optimize).Result; [CliFunction("eth", "sendWei")] - public string? SendWei(string from, string to, BigInteger amountInWei) - { - return SendEth(CliParseAddress(from), CliParseAddress(to), (UInt256)amountInWei); - } + public string? SendWei(string from, string to, BigInteger amountInWei) => SendEth(CliParseAddress(from), CliParseAddress(to), (UInt256)amountInWei); [CliFunction("eth", "sendRawTransaction")] - public string? SendRawTransaction(string txRlp) - { - return NodeManager.Post("eth_sendRawTransaction", txRlp).Result; - } + public string? SendRawTransaction(string txRlp) => NodeManager.Post("eth_sendRawTransaction", txRlp).Result; [CliFunction("eth", "sendTransaction")] - public string? SendTransaction(object tx) - { - return NodeManager.Post("eth_sendTransaction", tx).Result; - } + public string? SendTransaction(object tx) => NodeManager.Post("eth_sendTransaction", tx).Result; [CliProperty("eth", "blockNumber")] - public long BlockNumber() - { - return NodeManager.Post("eth_blockNumber").Result; - } + public long BlockNumber() => NodeManager.Post("eth_blockNumber").Result; [CliFunction("eth", "getCode")] - public string? GetCode(string address, string? blockParameter = null) - { - return NodeManager.Post("eth_getCode", CliParseAddress(address), blockParameter ?? "latest").Result; - } + public string? GetCode(string address, string? blockParameter = null) => NodeManager.Post("eth_getCode", CliParseAddress(address), blockParameter ?? "latest").Result; [CliFunction("eth", "getBlockTransactionCountByNumber")] - public long GetBlockTransactionCountByNumber(string? blockParameter) - { - return NodeManager.Post("eth_getBlockTransactionCountByNumber", blockParameter).Result; - } + public long GetBlockTransactionCountByNumber(string? blockParameter) => NodeManager.Post("eth_getBlockTransactionCountByNumber", blockParameter).Result; [CliFunction("eth", "getBlockTransactionCountByHash")] - public long GetBlockTransactionCountByHash(string hash) - { - return NodeManager.Post("eth_getBlockTransactionCountByHash", CliParseHash(hash)).Result; - } + public long GetBlockTransactionCountByHash(string hash) => NodeManager.Post("eth_getBlockTransactionCountByHash", CliParseHash(hash)).Result; [CliFunction("eth", "getUncleCountByBlockNumber")] - public long GetUncleCountByBlockNumber(string blockParameter) - { - return NodeManager.Post("eth_getUncleCountByBlockNumber", blockParameter).Result; - } + public long GetUncleCountByBlockNumber(string blockParameter) => NodeManager.Post("eth_getUncleCountByBlockNumber", blockParameter).Result; [CliFunction("eth", "getUncleByBlockNumberAndIndex")] - public JsValue GetUncleByBlockNumberAndIndex(string blockParameter, int index) - { - return NodeManager.PostJint("eth_getUncleByBlockNumberAndIndex", blockParameter, index).Result; - } + public JsValue GetUncleByBlockNumberAndIndex(string blockParameter, int index) => NodeManager.PostJint("eth_getUncleByBlockNumberAndIndex", blockParameter, index).Result; [CliFunction("eth", "getUncleByBlockHashAndIndex")] - public JsValue GetUncleByBlockHashAndIndex(string hash, int index) - { - return NodeManager.PostJint("eth_getUncleByBlockHashAndIndex", CliParseHash(hash), index).Result; - } + public JsValue GetUncleByBlockHashAndIndex(string hash, int index) => NodeManager.PostJint("eth_getUncleByBlockHashAndIndex", CliParseHash(hash), index).Result; [CliFunction("eth", "getTransactionByBlockNumberAndIndex")] - public JsValue GetTransactionByBlockNumberAndIndex(string blockParameter, string index) - { - return NodeManager.PostJint("eth_getTransactionByBlockNumberAndIndex", blockParameter, index).Result; - } + public JsValue GetTransactionByBlockNumberAndIndex(string blockParameter, string index) => NodeManager.PostJint("eth_getTransactionByBlockNumberAndIndex", blockParameter, index).Result; [CliFunction("eth", "getTransactionByHash")] - public JsValue GetTransactionByHash(string txHash) - { - return NodeManager.PostJint("eth_getTransactionByHash", CliParseHash(txHash)).Result; - } + public JsValue GetTransactionByHash(string txHash) => NodeManager.PostJint("eth_getTransactionByHash", CliParseHash(txHash)).Result; [CliProperty("eth", "pendingTransactions")] - public JsValue PendingTransactions() - { - return NodeManager.PostJint("eth_pendingTransactions").Result; - } + public JsValue PendingTransactions() => NodeManager.PostJint("eth_pendingTransactions").Result; [CliFunction("eth", "getTransactionReceipt")] public JsValue GetTransactionReceipt(string txHash) @@ -192,67 +125,33 @@ public JsValue GetTransactionReceipt(string txHash) } [CliFunction("eth", "getBalance")] - public BigInteger GetBalance(string address, string? blockParameter = null) - { - return NodeManager.Post("eth_getBalance", CliParseAddress(address), blockParameter ?? "latest").Result; - } + public BigInteger GetBalance(string address, string? blockParameter = null) => NodeManager.Post("eth_getBalance", CliParseAddress(address), blockParameter ?? "latest").Result; [CliProperty("eth", "chainId")] - public string? ChainId() - { - return NodeManager.Post("eth_chainId").Result; - } + public string? ChainId() => NodeManager.Post("eth_chainId").Result; [CliProperty("eth", "protocolVersion")] - public JsValue ProtocolVersion() - { - return NodeManager.PostJint("eth_protocolVersion").Result; - } + public JsValue ProtocolVersion() => NodeManager.PostJint("eth_protocolVersion").Result; [CliFunction("eth", "getLogs")] - public JsValue GetLogs(object filter) - { - return NodeManager.PostJint("eth_getLogs", filter).Result; - } + public JsValue GetLogs(object filter) => NodeManager.PostJint("eth_getLogs", filter).Result; [CliFunction("eth", "getFilterChanges")] - public JsValue GetFilterChanges(long filterId) - { - return NodeManager.PostJint("eth_getFilterChanges", filterId).Result; - } + public JsValue GetFilterChanges(long filterId) => NodeManager.PostJint("eth_getFilterChanges", filterId).Result; [CliFunction("eth", "newPendingTransactionFilter")] - public long NewPendingTransactionFilter() - { - return NodeManager.Post("eth_newPendingTransactionFilter").Result; - } + public long NewPendingTransactionFilter() => NodeManager.Post("eth_newPendingTransactionFilter").Result; [CliFunction("eth", "feeHistory")] - public JsValue FeeHistory(long blockCount, string newestBlock, double[]? rewardPercentiles = null) - { - return NodeManager.PostJint("eth_feeHistory", blockCount, newestBlock, rewardPercentiles!).Result; - } + public JsValue FeeHistory(long blockCount, string newestBlock, double[]? rewardPercentiles = null) => NodeManager.PostJint("eth_feeHistory", blockCount, newestBlock, rewardPercentiles!).Result; [CliFunction("eth", "gasPrice")] - public JsValue GasPrice() - { - return NodeManager.PostJint("eth_gasPrice").Result; - } + public JsValue GasPrice() => NodeManager.PostJint("eth_gasPrice").Result; [CliFunction("eth", "maxPriorityFeePerGas")] - public JsValue MaxPriorityFeePerGas() - { - return NodeManager.PostJint("eth_maxPriorityFeePerGas").Result; - } + public JsValue MaxPriorityFeePerGas() => NodeManager.PostJint("eth_maxPriorityFeePerGas").Result; [CliFunction("eth", "getAccount")] - public JsValue GetAccount(Address accountAddress, string? blockParam = null) - { - return NodeManager.PostJint("eth_getAccount", accountAddress, blockParam ?? "latest").Result; - } - - public EthCliModule(ICliEngine cliEngine, INodeManager nodeManager) : base(cliEngine, nodeManager) - { - } + public JsValue GetAccount(Address accountAddress, string? blockParam = null) => NodeManager.PostJint("eth_getAccount", accountAddress, blockParam ?? "latest").Result; } } From 44e67c7b631da63f5a8c44bd8cf85f9a490bd887 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 15:35:47 +0000 Subject: [PATCH 146/213] Fixing project build --- .../BlockHashProviderTests.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs index 9592b22dff1..2a8eebe486d 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs @@ -24,7 +24,7 @@ public void Can_get_parent_only_headers() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader? head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None); Block current = Build.A.Block.WithParent(head!).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength - 1); + Hash256? result = provider.GetBlockHash(current.Header, chainLength - 1); Assert.That(result, Is.EqualTo(head?.Hash)); } @@ -39,7 +39,7 @@ public void Can_lookup_up_to_256_before_with_headers_only() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength - 256); + Hash256? result = provider.GetBlockHash(current.Header, chainLength - 256); Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash)); } @@ -54,7 +54,7 @@ public void Can_lookup_up_to_256_before_with_headers_only_and_competing_branches BlockHashProvider provider = new(tree, LimboLogs.Instance); Block current = Build.A.Block.WithParent(headBlock).TestObject; long lookupNumber = chainLength - 256; - Hash256 result = provider.GetBlockHash(current.Header, lookupNumber); + Hash256? result = provider.GetBlockHash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -71,7 +71,7 @@ public void Can_lookup_up_to_256_before_soon_after_fast_sync() tree.SuggestBlock(current); tree.UpdateMainChain(current); long lookupNumber = chainLength - 256; - Hash256 result = provider.GetBlockHash(current.Header, lookupNumber); + Hash256? result = provider.GetBlockHash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -94,7 +94,7 @@ public void Can_lookup_up_to_256_before_some_blocks_after_fast_sync() } long lookupNumber = current.Number - 256; - Hash256 result = provider.GetBlockHash(current.Header, lookupNumber); + Hash256? result = provider.GetBlockHash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -115,7 +115,7 @@ public void Can_handle_non_main_chain_in_fast_sync() BlockHashProvider provider = new(tree, LimboLogs.Instance); - Hash256 result = provider.GetBlockHash(current.Header, 509); + Hash256? result = provider.GetBlockHash(current.Header, 509); Assert.NotNull(result); } @@ -131,7 +131,7 @@ public void Can_get_parent_hash() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength - 1); + Hash256? result = provider.GetBlockHash(current.Header, chainLength - 1); Assert.That(result, Is.EqualTo(head.Hash)); } @@ -146,7 +146,7 @@ public void Cannot_ask_for_self() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength); + Hash256? result = provider.GetBlockHash(current.Header, chainLength); Assert.Null(result); } @@ -161,7 +161,7 @@ public void Cannot_ask_about_future() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength + 1); + Hash256? result = provider.GetBlockHash(current.Header, chainLength + 1); Assert.Null(result); } @@ -176,7 +176,7 @@ public void Can_lookup_up_to_256_before() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength - 256); + Hash256? result = provider.GetBlockHash(current.Header, chainLength - 256); Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash)); } @@ -191,7 +191,7 @@ public void No_lookup_more_than_256_before() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, chainLength - 257); + Hash256? result = provider.GetBlockHash(current.Header, chainLength - 257); Assert.Null(result); } @@ -206,7 +206,7 @@ public void UInt_256_overflow() BlockHashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256 result = provider.GetBlockHash(current.Header, 127); + Hash256? result = provider.GetBlockHash(current.Header, 127); Assert.That(result, Is.EqualTo(head.Hash)); } } From 6bca09f970474e83c4f1e75be72448038036ca67 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 16:54:29 +0100 Subject: [PATCH 147/213] revert BlockHashProvider rename --- ...iderTests.cs => BlockhashProviderTests.cs} | 26 +++++++++---------- .../Producers/DevBlockproducerTests.cs | 4 +-- .../Nethermind.Blockchain.Test/ReorgTests.cs | 4 +-- ...ckHashProvider.cs => BlockhashProvider.cs} | 4 +-- .../CliqueBlockProducerTests.cs | 6 ++--- .../Processing/ReadOnlyTxProcessingEnv.cs | 9 +++---- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 4 +-- .../Validators/SimulateBlockValidatorProxy.cs | 17 +++++------- .../Blockchain/TestBlockchain.cs | 25 ++++++------------ .../UInt256DictionaryKeyConverterTests.cs | 25 +----------------- src/Nethermind/Nethermind.Core/Account.cs | 1 - .../EvmPooledMemoryTests.cs | 2 +- ...shProvider.cs => TestBlockhashProvider.cs} | 6 ++--- .../Tracing/GasEstimationTests.cs | 2 +- .../TransactionProcessorEip4844Tests.cs | 2 +- .../TransactionProcessorFeeTests.cs | 2 +- .../TransactionProcessorTests.cs | 2 +- .../VirtualMachineTestsBase.cs | 4 +-- ...kHashProvider.cs => IBlockhashProvider.cs} | 2 +- .../Nethermind.Evm/VirtualMachine.cs | 10 +++---- ...ovider.cs => SimulateBlockhashProvider.cs} | 8 +++--- .../SimulateReadOnlyBlocksProcessingEnv.cs | 4 +-- .../StateOverridesExtensions.cs | 12 ++++----- .../Steps/InitializeBlockchain.cs | 4 +-- .../Modules/Trace/ParityStyleTracerTests.cs | 4 +-- .../EthereumJsonSerializer.cs | 2 +- .../SyncThreadTests.cs | 6 ++--- 27 files changed, 79 insertions(+), 118 deletions(-) rename src/Nethermind/Nethermind.Blockchain.Test/{BlockHashProviderTests.cs => BlockhashProviderTests.cs} (91%) rename src/Nethermind/Nethermind.Blockchain/{BlockHashProvider.cs => BlockhashProvider.cs} (97%) rename src/Nethermind/Nethermind.Evm.Test/{TestBlockHashProvider.cs => TestBlockhashProvider.cs} (69%) rename src/Nethermind/Nethermind.Evm/{IBlockHashProvider.cs => IBlockhashProvider.cs} (87%) rename src/Nethermind/Nethermind.Facade/Simulate/{SimulateBlockHashProvider.cs => SimulateBlockhashProvider.cs} (67%) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs similarity index 91% rename from src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs rename to src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs index 2a8eebe486d..baba09b7f42 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockHashProviderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs @@ -10,7 +10,7 @@ namespace Nethermind.Blockchain.Test { [TestFixture] - public class BlockHashProviderTests + public class BlockhashProviderTests { [Test, Timeout(Timeout.MaxTestTime)] public void Can_get_parent_only_headers() @@ -21,7 +21,7 @@ public void Can_get_parent_only_headers() BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader? head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None); Block current = Build.A.Block.WithParent(head!).TestObject; Hash256? result = provider.GetBlockHash(current.Header, chainLength - 1); @@ -36,7 +36,7 @@ public void Can_lookup_up_to_256_before_with_headers_only() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(chainLength).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; Hash256? result = provider.GetBlockHash(current.Header, chainLength - 256); @@ -51,7 +51,7 @@ public void Can_lookup_up_to_256_before_with_headers_only_and_competing_branches Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(out Block headBlock, chainLength).OfChainLength(out Block _, chainLength, 1).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); Block current = Build.A.Block.WithParent(headBlock).TestObject; long lookupNumber = chainLength - 256; Hash256? result = provider.GetBlockHash(current.Header, lookupNumber); @@ -66,7 +66,7 @@ public void Can_lookup_up_to_256_before_soon_after_fast_sync() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(out Block headBlock, chainLength).OfChainLength(out Block _, chainLength, 1).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); Block current = Build.A.Block.WithParent(headBlock).TestObject; tree.SuggestBlock(current); tree.UpdateMainChain(current); @@ -83,7 +83,7 @@ public void Can_lookup_up_to_256_before_some_blocks_after_fast_sync() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfHeadersOnly.OfChainLength(out Block headBlock, chainLength).OfChainLength(out Block _, chainLength, 1).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); Block current = Build.A.Block.WithParent(headBlock).TestObject; for (int i = 0; i < 6; i++) @@ -113,7 +113,7 @@ public void Can_handle_non_main_chain_in_fast_sync() current = Build.A.Block.WithParent(current).TestObject; } - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); Hash256? result = provider.GetBlockHash(current.Header, 509); Assert.NotNull(result); @@ -128,7 +128,7 @@ public void Can_get_parent_hash() BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; Hash256? result = provider.GetBlockHash(current.Header, chainLength - 1); @@ -143,7 +143,7 @@ public void Cannot_ask_for_self() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; Hash256? result = provider.GetBlockHash(current.Header, chainLength); @@ -158,7 +158,7 @@ public void Cannot_ask_about_future() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; Hash256? result = provider.GetBlockHash(current.Header, chainLength + 1); @@ -173,7 +173,7 @@ public void Can_lookup_up_to_256_before() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; Hash256? result = provider.GetBlockHash(current.Header, chainLength - 256); @@ -188,7 +188,7 @@ public void No_lookup_more_than_256_before() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; Hash256? result = provider.GetBlockHash(current.Header, chainLength - 257); @@ -203,7 +203,7 @@ public void UInt_256_overflow() Block genesis = Build.A.Block.Genesis.TestObject; BlockTree tree = Build.A.BlockTree(genesis).OfChainLength(chainLength).TestObject; - BlockHashProvider provider = new(tree, LimboLogs.Instance); + BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; Hash256? result = provider.GetBlockHash(current.Header, 127); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs index a823f7fc7ca..1738debb60f 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs @@ -55,10 +55,10 @@ public void Test() dbProvider.RegisteredDbs[DbNames.Code], LimboLogs.Instance); StateReader stateReader = new(trieStore, dbProvider.GetDb(DbNames.State), LimboLogs.Instance); - BlockHashProvider blockHashProvider = new(blockTree, LimboLogs.Instance); + BlockhashProvider blockhashProvider = new(blockTree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( - blockHashProvider, + blockhashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs index 8943b093ae7..70c8deb1e48 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs @@ -56,10 +56,10 @@ public void Setup() new TxValidator(specProvider.ChainId), LimboLogs.Instance, transactionComparerProvider.GetDefaultComparer()); - BlockHashProvider blockHashProvider = new(_blockTree, LimboLogs.Instance); + BlockhashProvider blockhashProvider = new(_blockTree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( - blockHashProvider, + blockhashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Blockchain/BlockHashProvider.cs b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs similarity index 97% rename from src/Nethermind/Nethermind.Blockchain/BlockHashProvider.cs rename to src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs index c7086eb5f78..6f694d399fb 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockHashProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs @@ -13,8 +13,8 @@ namespace Nethermind.Blockchain { - public sealed class BlockHashProvider(IBlockTree blockTree, ILogManager? logManager) - : IBlockHashProvider + public sealed class BlockhashProvider(IBlockTree blockTree, ILogManager? logManager) + : IBlockhashProvider { private static readonly int _maxDepth = 256; private readonly IBlockTree _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); diff --git a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs index e5f397682d8..b97aac0f85a 100644 --- a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs @@ -117,7 +117,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f transactionComparerProvider.GetDefaultComparer()); _pools[privateKey] = txPool; - BlockHashProvider blockHashProvider = new(blockTree, LimboLogs.Instance); + BlockhashProvider blockhashProvider = new(blockTree, LimboLogs.Instance); _blockTrees.Add(privateKey, blockTree); SnapshotManager snapshotManager = new(_cliqueConfig, blocksDb, blockTree, _ethereumEcdsa, nodeLogManager); @@ -130,7 +130,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f CodeInfoRepository codeInfoRepository = new(); TransactionProcessor transactionProcessor = new(goerliSpecProvider, stateProvider, - new VirtualMachine(blockHashProvider, specProvider, codeInfoRepository, nodeLogManager), + new VirtualMachine(blockhashProvider, specProvider, codeInfoRepository, nodeLogManager), codeInfoRepository, nodeLogManager); BlockProcessor blockProcessor = new( @@ -149,7 +149,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f IReadOnlyTrieStore minerTrieStore = trieStore.AsReadOnly(); WorldState minerStateProvider = new(minerTrieStore, codeDb, nodeLogManager); - VirtualMachine minerVirtualMachine = new(blockHashProvider, specProvider, codeInfoRepository, nodeLogManager); + VirtualMachine minerVirtualMachine = new(blockhashProvider, specProvider, codeInfoRepository, nodeLogManager); TransactionProcessor minerTransactionProcessor = new(goerliSpecProvider, minerStateProvider, minerVirtualMachine, codeInfoRepository, nodeLogManager); BlockProcessor minerBlockProcessor = new( diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index fa828ea6d2c..95b7661e696 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -23,26 +23,25 @@ public class ReadOnlyTxProcessingEnv : ReadOnlyTxProcessingEnvBase, IReadOnlyTxP public ICodeInfoRepository CodeInfoRepository { get; } public ReadOnlyTxProcessingEnv( IWorldStateManager worldStateManager, - IBlockTree? blockTree, + IBlockTree blockTree, ISpecProvider? specProvider, ILogManager? logManager) - : this(worldStateManager, blockTree?.AsReadOnly(), specProvider, logManager) + : this(worldStateManager, blockTree.AsReadOnly(), specProvider, logManager) { } public ReadOnlyTxProcessingEnv( IWorldStateManager worldStateManager, - IReadOnlyBlockTree? readOnlyBlockTree, + IReadOnlyBlockTree readOnlyBlockTree, ISpecProvider? specProvider, ILogManager? logManager ) : base(worldStateManager, readOnlyBlockTree, logManager) { - //TO DO CHECK AGAIN!!! ArgumentNullException.ThrowIfNull(specProvider); ArgumentNullException.ThrowIfNull(worldStateManager); CodeInfoRepository = new CodeInfoRepository(); - Machine = new VirtualMachine(BlockHashProvider, specProvider, CodeInfoRepository, logManager); + Machine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, Machine, CodeInfoRepository, logManager); } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index 099476b999a..e9a6bc181c4 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -16,7 +16,7 @@ public class ReadOnlyTxProcessingEnvBase public IStateReader StateReader { get; protected set; } public IWorldState StateProvider { get; protected set; } public IBlockTree BlockTree { get; protected set; } - public IBlockHashProvider BlockHashProvider { get; protected set; } + public IBlockhashProvider BlockhashProvider { get; protected set; } protected ReadOnlyTxProcessingEnvBase( IWorldStateManager worldStateManager, @@ -27,6 +27,6 @@ protected ReadOnlyTxProcessingEnvBase( StateReader = worldStateManager.GlobalStateReader; StateProvider = worldStateManager.CreateResettableWorldState(); BlockTree = readOnlyBlockTree ?? throw new ArgumentNullException(nameof(readOnlyBlockTree)); - BlockHashProvider = new BlockHashProvider(BlockTree, logManager); + BlockhashProvider = new BlockhashProvider(BlockTree, logManager); } } diff --git a/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs b/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs index 589d38f447f..5a775551c8f 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs @@ -5,27 +5,22 @@ namespace Nethermind.Consensus.Validators; -public class SimulateBlockValidatorProxy : IBlockValidator +public class SimulateBlockValidatorProxy(IBlockValidator baseBlockValidator) : IBlockValidator { - private readonly IBlockValidator _baseBlockValidator; - - public SimulateBlockValidatorProxy(IBlockValidator baseBlockValidator) => - _baseBlockValidator = baseBlockValidator; - public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle = false) => - _baseBlockValidator.Validate(header, parent, isUncle); + baseBlockValidator.Validate(header, parent, isUncle); public bool Validate(BlockHeader header, bool isUncle = false) => - _baseBlockValidator.Validate(header, isUncle); + baseBlockValidator.Validate(header, isUncle); public bool ValidateWithdrawals(Block block, out string? error) => - _baseBlockValidator.ValidateWithdrawals(block, out error); + baseBlockValidator.ValidateWithdrawals(block, out error); public bool ValidateOrphanedBlock(Block block, out string? error) => - _baseBlockValidator.ValidateOrphanedBlock(block, out error); + baseBlockValidator.ValidateOrphanedBlock(block, out error); public bool ValidateSuggestedBlock(Block block) => - _baseBlockValidator.ValidateSuggestedBlock(block); + baseBlockValidator.ValidateSuggestedBlock(block); public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) => true; } diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index ac38e58c8e3..c24bd4ec1e0 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -161,24 +161,15 @@ protected virtual async Task Build( WorldStateManager = new WorldStateManager(State, TrieStore, DbProvider, LimboLogs.Instance); StateReader = new StateReader(ReadOnlyTrieStore, CodeDb, LogManager); - IDb blockInfoDb = DbProvider.BlockInfosDb; - IDb metadataDb = DbProvider.MetadataDb; - SyncConfig syncConfig = new(); - - IBlockStore blockStore = new BlockStore(DbProvider.BlocksDb); - IHeaderStore headerStore = new HeaderStore(DbProvider.HeadersDb, DbProvider.BlockNumbersDb); - IDb badBlocksDb = new TestMemDb(); - var badBlockStore = new BlockStore(badBlocksDb, 100); - - BlockTree = new BlockTree(blockStore, - headerStore, - blockInfoDb, - metadataDb, - badBlockStore, - new ChainLevelInfoRepository(blockInfoDb), + BlockTree = new BlockTree(new BlockStore(DbProvider.BlocksDb), + new HeaderStore(DbProvider.HeadersDb, DbProvider.BlockNumbersDb), + DbProvider.BlockInfosDb, + DbProvider.MetadataDb, + new BlockStore(new TestMemDb(), 100), + new ChainLevelInfoRepository(DbProvider.BlockInfosDb), SpecProvider, NullBloomStorage.Instance, - syncConfig, + new SyncConfig(), LimboLogs.Instance); ReadOnlyState = new ChainHeadReadOnlyStateProvider(BlockTree, StateReader); @@ -193,7 +184,7 @@ protected virtual async Task Build( _trieStoreWatcher = new TrieStoreBoundaryWatcher(WorldStateManager, BlockTree, LogManager); CodeInfoRepository codeInfoRepository = new(); ReceiptStorage = new InMemoryReceiptStorage(blockTree: BlockTree); - VirtualMachine virtualMachine = new(new BlockHashProvider(BlockTree, LogManager), SpecProvider, codeInfoRepository, LogManager); + VirtualMachine virtualMachine = new(new BlockhashProvider(BlockTree, LogManager), SpecProvider, codeInfoRepository, LogManager); TxProcessor = new TransactionProcessor(SpecProvider, State, virtualMachine, codeInfoRepository, LogManager); BlockPreprocessorStep = new RecoverSignatures(EthereumEcdsa, TxPool, SpecProvider, LogManager); diff --git a/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs index 450848baf10..9b86b54525a 100644 --- a/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs @@ -14,30 +14,7 @@ namespace Nethermind.Core.Test.Json; [TestFixture] public class UInt256DictionaryKeyConverterTests { - private static readonly JsonSerializerOptions Options = new() - { - Converters = - { - new LongConverter(), - new UInt256Converter(), - new ULongConverter(), - new IntConverter(), - new ByteArrayConverter(), - new NullableLongConverter(), - new NullableULongConverter(), - new NullableUInt256Converter(), - new NullableIntConverter(), - new TxTypeConverter(), - new DoubleConverter(), - new DoubleArrayConverter(), - new BooleanConverter(), - new DictionaryAddressKeyConverter(), - new MemoryByteConverter(), - new BigIntegerConverter(), - new NullableBigIntegerConverter(), - new JavaScriptObjectConverter() - } - }; + private static readonly JsonSerializerOptions Options = EthereumJsonSerializer.CreateOptions(true); [Test] public void ReadJson_NestedValidJson_ReturnsCorrectDictionary() diff --git a/src/Nethermind/Nethermind.Core/Account.cs b/src/Nethermind/Nethermind.Core/Account.cs index b393ffec754..144b088caa9 100644 --- a/src/Nethermind/Nethermind.Core/Account.cs +++ b/src/Nethermind/Nethermind.Core/Account.cs @@ -139,6 +139,5 @@ public AccountStruct(in UInt256 balance) public bool IsTotallyEmpty => _storageRoot == Keccak.EmptyTreeHash.ValueHash256 && IsEmpty; public bool IsEmpty => _codeHash == Keccak.OfAnEmptyString.ValueHash256 && Balance.IsZero && Nonce.IsZero; public bool IsContract => _codeHash != Keccak.OfAnEmptyString.ValueHash256; - public Account ToOldAccount() => new(Nonce, Balance, StorageRoot.ToCommitment(), CodeHash.ToCommitment()); } } diff --git a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs index 8a16c8075d8..dc5ee488cd6 100644 --- a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs @@ -159,7 +159,7 @@ private static string run(byte[] input) ISpecProvider specProvider = new TestSpecProvider(London.Instance); CodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( - Nethermind.Evm.Test.TestBlockHashProvider.Instance, + Nethermind.Evm.Test.TestBlockhashProvider.Instance, specProvider, codeInfoRepository, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Evm.Test/TestBlockHashProvider.cs b/src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs similarity index 69% rename from src/Nethermind/Nethermind.Evm.Test/TestBlockHashProvider.cs rename to src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs index 7d515a07fd0..a602b36168f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TestBlockHashProvider.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs @@ -6,11 +6,11 @@ namespace Nethermind.Evm.Test { - public class TestBlockHashProvider : IBlockHashProvider + public class TestBlockhashProvider : IBlockhashProvider { - public static TestBlockHashProvider Instance = new(); + public static TestBlockhashProvider Instance = new(); - private TestBlockHashProvider() + private TestBlockhashProvider() { } diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs index bf346725858..ff1a8b3683d 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs @@ -278,7 +278,7 @@ public TestEnvironment() _stateProvider.CommitTree(0); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(TestBlockHashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs index cb92572223c..b9284dc48fe 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs @@ -36,7 +36,7 @@ public void Setup() TrieStore trieStore = new(stateDb, LimboLogs.Instance); _stateProvider = new WorldState(trieStore, new MemDb(), LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(TestBlockHashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); } diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs index c981aa1ca2c..3cf8e81c276 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -43,7 +43,7 @@ public void Setup() _stateProvider.CommitTree(0); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(TestBlockHashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); } diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs index 76ef0fe7925..de3153f6537 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs @@ -59,7 +59,7 @@ public void Setup() _stateProvider.CommitTree(0); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(TestBlockHashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); } diff --git a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs index 20d0756b610..5b834eaf1d6 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs @@ -67,9 +67,9 @@ public virtual void Setup() ITrieStore trieStore = new TrieStore(_stateDb, logManager); TestState = new WorldState(trieStore, codeDb, logManager); _ethereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId, logManager); - IBlockHashProvider blockHashProvider = TestBlockHashProvider.Instance; + IBlockhashProvider blockhashProvider = TestBlockhashProvider.Instance; CodeInfoRepository = new CodeInfoRepository(); - Machine = new VirtualMachine(blockHashProvider, SpecProvider, CodeInfoRepository, logManager); + Machine = new VirtualMachine(blockhashProvider, SpecProvider, CodeInfoRepository, logManager); _processor = new TransactionProcessor(SpecProvider, TestState, Machine, CodeInfoRepository, logManager); } diff --git a/src/Nethermind/Nethermind.Evm/IBlockHashProvider.cs b/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs similarity index 87% rename from src/Nethermind/Nethermind.Evm/IBlockHashProvider.cs rename to src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs index d133e56e12c..56f1bcb3b3a 100644 --- a/src/Nethermind/Nethermind.Evm/IBlockHashProvider.cs +++ b/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs @@ -6,7 +6,7 @@ namespace Nethermind.Evm { - public interface IBlockHashProvider + public interface IBlockhashProvider { Hash256? GetBlockHash(BlockHeader currentBlock, in long number); } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index fdce8af2b28..2fd851e7556 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -69,7 +69,7 @@ public class VirtualMachine : IVirtualMachine private readonly IVirtualMachine _evm; public VirtualMachine( - IBlockHashProvider? blockHashProvider, + IBlockhashProvider? blockHashProvider, ISpecProvider? specProvider, ICodeInfoRepository codeInfoRepository, ILogManager? logManager) @@ -151,7 +151,7 @@ internal sealed class VirtualMachine : IVirtualMachine where TLogger : { private readonly byte[] _chainId; - private readonly IBlockHashProvider _blockHashProvider; + private readonly IBlockhashProvider _blockhashProvider; private readonly ISpecProvider _specProvider; private readonly ILogger _logger; private IWorldState _worldState; @@ -163,13 +163,13 @@ internal sealed class VirtualMachine : IVirtualMachine where TLogger : private readonly ICodeInfoRepository _codeInfoRepository; public VirtualMachine( - IBlockHashProvider? blockHashProvider, + IBlockhashProvider? blockHashProvider, ISpecProvider? specProvider, ICodeInfoRepository codeInfoRepository, ILogger? logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _blockHashProvider = blockHashProvider ?? throw new ArgumentNullException(nameof(blockHashProvider)); + _blockhashProvider = blockHashProvider ?? throw new ArgumentNullException(nameof(blockHashProvider)); _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _codeInfoRepository = codeInfoRepository ?? throw new ArgumentNullException(nameof(codeInfoRepository)); _chainId = ((UInt256)specProvider.ChainId).ToBigEndian(); @@ -1400,7 +1400,7 @@ private CallResult ExecuteCode long.MaxValue ? long.MaxValue : (long)a; - Hash256 blockHash = _blockHashProvider.GetBlockHash(blkCtx.Header, number); + Hash256 blockHash = _blockhashProvider.GetBlockHash(blkCtx.Header, number); stack.PushBytes(blockHash is not null ? blockHash.Bytes : BytesZero32); if (typeof(TLogger) == typeof(IsTracing)) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockHashProvider.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs similarity index 67% rename from src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockHashProvider.cs rename to src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs index dbf8b12653d..68c0abf811c 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockHashProvider.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs @@ -9,14 +9,14 @@ namespace Nethermind.Facade.Simulate; -public sealed class SimulateBlockHashProvider(IBlockHashProvider blockHashProvider, IBlockTree blockTree) - : IBlockHashProvider +public sealed class SimulateBlockhashProvider(IBlockhashProvider blockhashProvider, IBlockTree blockTree) + : IBlockhashProvider { public Hash256? GetBlockHash(BlockHeader currentBlock, in long number) { var bestKnown = blockTree.BestKnownNumber; return bestKnown < number && blockTree.BestSuggestedHeader is not null - ? blockHashProvider.GetBlockHash(blockTree.BestSuggestedHeader!, in bestKnown) - : blockHashProvider.GetBlockHash(currentBlock, in number); + ? blockhashProvider.GetBlockHash(blockTree.BestSuggestedHeader!, in bestKnown) + : blockhashProvider.GetBlockHash(currentBlock, in number); } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 41326c81e1c..2c9204c068a 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -101,7 +101,7 @@ public SimulateReadOnlyBlocksProcessingEnv( _doValidation = doValidation; BlockTree = new BlockTreeOverlay(ReadOnlyBlockTree, blockTree); - BlockHashProvider = new SimulateBlockHashProvider(new BlockHashProvider(BlockTree, logManager), BlockTree); + BlockhashProvider = new SimulateBlockhashProvider(new BlockhashProvider(BlockTree, logManager), BlockTree); //var store = new TrieStore(DbProvider.StateDb, LimboLogs.Instance); //StateProvider = new WorldState(store, DbProvider.CodeDb, LimboLogs.Instance); @@ -110,7 +110,7 @@ public SimulateReadOnlyBlocksProcessingEnv( CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); - VirtualMachine = new VirtualMachine(BlockHashProvider, specProvider, CodeInfoRepository, logManager); + VirtualMachine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); _transactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !_doValidation); _blockValidator = CreateValidator(); diff --git a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs index 55d225ed9e7..a513059f82c 100644 --- a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs +++ b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs @@ -39,7 +39,7 @@ public static void ApplyStateOverrides( Address address = overrideData.Key; AccountOverride? accountOverride = overrideData.Value; - if (!state.TryGetAccount(address, out Account? account)) + if (!state.TryGetAccount(address, out AccountStruct account)) { state.CreateAccount(address, accountOverride.Balance ?? UInt256.Zero, accountOverride.Nonce ?? UInt256.Zero); } @@ -59,15 +59,15 @@ public static void ApplyStateOverrides( state.RecalculateStateRoot(); } - private static bool TryGetAccount(this IWorldState stateProvider, Address address, out Account account) + private static bool TryGetAccount(this IWorldState stateProvider, Address address, out AccountStruct account) { try { - account = stateProvider.GetAccount(address).ToOldAccount(); + account = stateProvider.GetAccount(address); } catch (TrieException) { - account = Account.TotallyEmpty; + account = new AccountStruct(); } return !account.IsTotallyEmpty; @@ -114,7 +114,7 @@ private static void UpdateCode( private static void UpdateNonce( this IWorldState stateProvider, - Account account, + in AccountStruct account, AccountOverride accountOverride, Address address) { @@ -136,7 +136,7 @@ private static void UpdateNonce( private static void UpdateBalance( this IWorldState stateProvider, IReleaseSpec spec, - Account account, + in AccountStruct account, AccountOverride accountOverride, Address address) { diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs index 4c85426e63c..bebae0411c1 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs @@ -178,13 +178,13 @@ protected virtual (VirtualMachine, CodeInfoRepository) CreateVirtualMachine() if (_api.SpecProvider is null) throw new StepDependencyException(nameof(_api.SpecProvider)); // blockchain processing - BlockHashProvider blockHashProvider = new( + BlockhashProvider blockhashProvider = new( _api.BlockTree, _api.LogManager); CodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( - blockHashProvider, + blockhashProvider, _api.SpecProvider, codeInfoRepository, _api.LogManager); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs index 997ee8df6e3..be7f60d297d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs @@ -61,9 +61,9 @@ public void Setup() WorldState stateProvider = new(trieStore, codeDb, LimboLogs.Instance); _stateReader = new StateReader(trieStore, codeDb, LimboLogs.Instance); - BlockHashProvider blockHashProvider = new(_blockTree, LimboLogs.Instance); + BlockhashProvider blockhashProvider = new(_blockTree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(blockHashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(blockhashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); TransactionProcessor transactionProcessor = new(specProvider, stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _poSSwitcher = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs index 4a991b09170..d501614269f 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs @@ -54,7 +54,7 @@ public string Serialize(T value, bool indented = false) return JsonSerializer.Serialize(value, indented ? JsonOptionsIndented : _jsonOptions); } - private static JsonSerializerOptions CreateOptions(bool indented, IEnumerable converters = null, int maxDepth = 64) + public static JsonSerializerOptions CreateOptions(bool indented, IEnumerable converters = null, int maxDepth = 64) { var options = new JsonSerializerOptions { diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs index 315547b0fc8..5d9fb20936f 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs @@ -272,9 +272,9 @@ private SyncTestContext CreateSyncManager(int index) new TxValidator(specProvider.ChainId), logManager, transactionComparerProvider.GetDefaultComparer()); - BlockHashProvider blockHashProvider = new(tree, LimboLogs.Instance); + BlockhashProvider blockhashProvider = new(tree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(blockHashProvider, specProvider, codeInfoRepository, logManager); + VirtualMachine virtualMachine = new(blockhashProvider, specProvider, codeInfoRepository, logManager); Always sealValidator = Always.Valid; HeaderValidator headerValidator = new(tree, sealValidator, specProvider, logManager); @@ -310,7 +310,7 @@ private SyncTestContext CreateSyncManager(int index) SyncPeerPool syncPeerPool = new(tree, nodeStatsManager, new TotalDifficultyBetterPeerStrategy(LimboLogs.Instance), logManager, 25); WorldState devState = new(trieStore, codeDb, logManager); - VirtualMachine devEvm = new(blockHashProvider, specProvider, codeInfoRepository, logManager); + VirtualMachine devEvm = new(blockhashProvider, specProvider, codeInfoRepository, logManager); TransactionProcessor devTxProcessor = new(specProvider, devState, devEvm, codeInfoRepository, logManager); BlockProcessor devBlockProcessor = new( From 64d350368dec7e8b84c5342dffd59785dd5e350f Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 16:55:30 +0100 Subject: [PATCH 148/213] more revert --- .../BlockhashProviderTests.cs | 24 +++++++++---------- .../BlockhashProvider.cs | 2 +- .../TestBlockhashProvider.cs | 2 +- .../Nethermind.Evm/IBlockhashProvider.cs | 2 +- .../Nethermind.Evm/VirtualMachine.cs | 2 +- .../Simulate/SimulateBlockhashProvider.cs | 6 ++--- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs index baba09b7f42..2113a984395 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs @@ -24,7 +24,7 @@ public void Can_get_parent_only_headers() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader? head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None); Block current = Build.A.Block.WithParent(head!).TestObject; - Hash256? result = provider.GetBlockHash(current.Header, chainLength - 1); + Hash256? result = provider.GetBlockhash(current.Header, chainLength - 1); Assert.That(result, Is.EqualTo(head?.Hash)); } @@ -39,7 +39,7 @@ public void Can_lookup_up_to_256_before_with_headers_only() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockHash(current.Header, chainLength - 256); + Hash256? result = provider.GetBlockhash(current.Header, chainLength - 256); Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash)); } @@ -54,7 +54,7 @@ public void Can_lookup_up_to_256_before_with_headers_only_and_competing_branches BlockhashProvider provider = new(tree, LimboLogs.Instance); Block current = Build.A.Block.WithParent(headBlock).TestObject; long lookupNumber = chainLength - 256; - Hash256? result = provider.GetBlockHash(current.Header, lookupNumber); + Hash256? result = provider.GetBlockhash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -71,7 +71,7 @@ public void Can_lookup_up_to_256_before_soon_after_fast_sync() tree.SuggestBlock(current); tree.UpdateMainChain(current); long lookupNumber = chainLength - 256; - Hash256? result = provider.GetBlockHash(current.Header, lookupNumber); + Hash256? result = provider.GetBlockhash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -94,7 +94,7 @@ public void Can_lookup_up_to_256_before_some_blocks_after_fast_sync() } long lookupNumber = current.Number - 256; - Hash256? result = provider.GetBlockHash(current.Header, lookupNumber); + Hash256? result = provider.GetBlockhash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -115,7 +115,7 @@ public void Can_handle_non_main_chain_in_fast_sync() BlockhashProvider provider = new(tree, LimboLogs.Instance); - Hash256? result = provider.GetBlockHash(current.Header, 509); + Hash256? result = provider.GetBlockhash(current.Header, 509); Assert.NotNull(result); } @@ -131,7 +131,7 @@ public void Can_get_parent_hash() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockHash(current.Header, chainLength - 1); + Hash256? result = provider.GetBlockhash(current.Header, chainLength - 1); Assert.That(result, Is.EqualTo(head.Hash)); } @@ -146,7 +146,7 @@ public void Cannot_ask_for_self() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockHash(current.Header, chainLength); + Hash256? result = provider.GetBlockhash(current.Header, chainLength); Assert.Null(result); } @@ -161,7 +161,7 @@ public void Cannot_ask_about_future() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockHash(current.Header, chainLength + 1); + Hash256? result = provider.GetBlockhash(current.Header, chainLength + 1); Assert.Null(result); } @@ -176,7 +176,7 @@ public void Can_lookup_up_to_256_before() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockHash(current.Header, chainLength - 256); + Hash256? result = provider.GetBlockhash(current.Header, chainLength - 256); Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash)); } @@ -191,7 +191,7 @@ public void No_lookup_more_than_256_before() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockHash(current.Header, chainLength - 257); + Hash256? result = provider.GetBlockhash(current.Header, chainLength - 257); Assert.Null(result); } @@ -206,7 +206,7 @@ public void UInt_256_overflow() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockHash(current.Header, 127); + Hash256? result = provider.GetBlockhash(current.Header, 127); Assert.That(result, Is.EqualTo(head.Hash)); } } diff --git a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs index 6f694d399fb..a376c944962 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs @@ -20,7 +20,7 @@ public sealed class BlockhashProvider(IBlockTree blockTree, ILogManager? logMana private readonly IBlockTree _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - public Hash256? GetBlockHash(BlockHeader currentBlock, in long number) + public Hash256? GetBlockhash(BlockHeader currentBlock, in long number) { long current = currentBlock.Number; if (number >= current || number < current - Math.Min(current, _maxDepth)) diff --git a/src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs index a602b36168f..b95fb719cc8 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TestBlockhashProvider.cs @@ -14,7 +14,7 @@ private TestBlockhashProvider() { } - public Hash256 GetBlockHash(BlockHeader currentBlock, in long number) + public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) { return Keccak.Compute(number.ToString()); } diff --git a/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs index 56f1bcb3b3a..ff225c7790d 100644 --- a/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs @@ -8,6 +8,6 @@ namespace Nethermind.Evm { public interface IBlockhashProvider { - Hash256? GetBlockHash(BlockHeader currentBlock, in long number); + Hash256? GetBlockhash(BlockHeader currentBlock, in long number); } } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 2fd851e7556..13fdef1b6c6 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -1400,7 +1400,7 @@ private CallResult ExecuteCode long.MaxValue ? long.MaxValue : (long)a; - Hash256 blockHash = _blockhashProvider.GetBlockHash(blkCtx.Header, number); + Hash256 blockHash = _blockhashProvider.GetBlockhash(blkCtx.Header, number); stack.PushBytes(blockHash is not null ? blockHash.Bytes : BytesZero32); if (typeof(TLogger) == typeof(IsTracing)) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs index 68c0abf811c..1ace83cf3a4 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs @@ -12,11 +12,11 @@ namespace Nethermind.Facade.Simulate; public sealed class SimulateBlockhashProvider(IBlockhashProvider blockhashProvider, IBlockTree blockTree) : IBlockhashProvider { - public Hash256? GetBlockHash(BlockHeader currentBlock, in long number) + public Hash256? GetBlockhash(BlockHeader currentBlock, in long number) { var bestKnown = blockTree.BestKnownNumber; return bestKnown < number && blockTree.BestSuggestedHeader is not null - ? blockhashProvider.GetBlockHash(blockTree.BestSuggestedHeader!, in bestKnown) - : blockhashProvider.GetBlockHash(currentBlock, in number); + ? blockhashProvider.GetBlockhash(blockTree.BestSuggestedHeader!, in bestKnown) + : blockhashProvider.GetBlockhash(currentBlock, in number); } } From 9431c736a6117010041cd303a8d114624840a8a9 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 16:59:41 +0100 Subject: [PATCH 149/213] fix --- src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs | 2 +- src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs | 2 +- .../Ethereum.Test.Base/TestBlockhashProvider.cs | 4 ++-- src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs | 8 ++++---- .../MultipleUnsignedOperations.cs | 2 +- .../Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs | 8 ++++---- .../Nethermind.Evm.Benchmark/TestBlockhashProvider.cs | 4 ++-- .../Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs index f25035b1506..5f83e7b493b 100644 --- a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs @@ -142,7 +142,7 @@ protected async Task RunTest(BlockchainTest test, Stopwatch? IStateReader stateReader = new StateReader(trieStore, codeDb, _logManager); IReceiptStorage receiptStorage = NullReceiptStorage.Instance; - IBlockHashProvider blockHashProvider = new BlockHashProvider(blockTree, _logManager); + IBlockhashProvider blockHashProvider = new BlockhashProvider(blockTree, _logManager); ITxValidator txValidator = new TxValidator(TestBlockchainIds.ChainId); IHeaderValidator headerValidator = new HeaderValidator(blockTree, Sealer, specProvider, _logManager); IUnclesValidator unclesValidator = new UnclesValidator(blockTree, headerValidator, _logManager); diff --git a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs index 321bbebe1f4..968ae5847b6 100644 --- a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs @@ -66,7 +66,7 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) TrieStore trieStore = new(stateDb, _logManager); WorldState stateProvider = new(trieStore, codeDb, _logManager); - IBlockHashProvider blockHashProvider = new TestBlockHashProvider(); + IBlockhashProvider blockHashProvider = new TestBlockHashProvider(); CodeInfoRepository codeInfoRepository = new(); IVirtualMachine virtualMachine = new VirtualMachine( blockHashProvider, diff --git a/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs b/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs index 3e4ed367eb0..51dc7017348 100644 --- a/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs +++ b/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs @@ -7,9 +7,9 @@ namespace Ethereum.Test.Base { - public class TestBlockHashProvider : IBlockHashProvider + public class TestBlockHashProvider : IBlockhashProvider { - public Hash256 GetBlockHash(BlockHeader currentBlock, in long number) + public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) { if (number != 0) return Keccak.Zero; diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs index 52754c5276d..2e672934c13 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs @@ -23,12 +23,12 @@ public class EvmBenchmarks { public static byte[] ByteCode { get; set; } - private IReleaseSpec _spec = MainnetSpecProvider.Instance.GetSpec((ForkActivation)MainnetSpecProvider.IstanbulBlockNumber); - private ITxTracer _txTracer = NullTxTracer.Instance; + private readonly IReleaseSpec _spec = MainnetSpecProvider.Instance.GetSpec((ForkActivation)MainnetSpecProvider.IstanbulBlockNumber); + private readonly ITxTracer _txTracer = NullTxTracer.Instance; private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; - private BlockHeader _header = new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.IstanbulBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private IBlockHashProvider _blockHashProvider = new TestBlockhashProvider(); + private readonly BlockHeader _header = new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.IstanbulBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); + private readonly IBlockhashProvider _blockHashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs index 25eb311bf4d..4972bed2718 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs @@ -27,7 +27,7 @@ public class MultipleUnsignedOperations private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; private readonly BlockHeader _header = new(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.MuirGlacierBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private readonly IBlockHashProvider _blockHashProvider = new TestBlockhashProvider(); + private readonly IBlockhashProvider _blockHashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs index 7fd0e42e8f1..92b7f4b0e90 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs @@ -23,12 +23,12 @@ namespace Nethermind.Evm.Benchmark [MemoryDiagnoser] public class StaticCallBenchmarks { - private IReleaseSpec _spec = MainnetSpecProvider.Instance.GetSpec((ForkActivation)MainnetSpecProvider.IstanbulBlockNumber); - private ITxTracer _txTracer = NullTxTracer.Instance; + private readonly IReleaseSpec _spec = MainnetSpecProvider.Instance.GetSpec((ForkActivation)MainnetSpecProvider.IstanbulBlockNumber); + private readonly ITxTracer _txTracer = NullTxTracer.Instance; private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; - private BlockHeader _header = new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.MuirGlacierBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private IBlockHashProvider _blockHashProvider = new TestBlockhashProvider(); + private readonly BlockHeader _header = new(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.MuirGlacierBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); + private readonly IBlockhashProvider _blockHashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs index c6a6119e3b0..eec9a33aa36 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs @@ -6,9 +6,9 @@ namespace Nethermind.Evm.Benchmark { - public class TestBlockhashProvider : IBlockHashProvider + public class TestBlockhashProvider : IBlockhashProvider { - public Hash256 GetBlockHash(BlockHeader currentBlock, in long number) + public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) { return Keccak.Compute(number.ToString()); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index ea8712659d4..832d175f0a7 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -44,7 +44,7 @@ namespace Nethermind.JsonRpc.Benchmark public class EthModuleBenchmarks { private IVirtualMachine _virtualMachine; - private IBlockHashProvider _blockHashProvider; + private IBlockhashProvider _blockHashProvider; private EthRpcModule _ethModule; [GlobalSetup] From f9ec7d1b8b220dbd7e6198d21596dcfe680752f5 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 17:02:52 +0100 Subject: [PATCH 150/213] more revert --- .../Ethereum.Test.Base/BlockchainTestBase.cs | 4 ++-- src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs | 4 ++-- .../Nethermind.Evm.Benchmark/EvmBenchmarks.cs | 4 ++-- .../MultipleUnsignedOperations.cs | 4 ++-- .../Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs | 4 ++-- src/Nethermind/Nethermind.Evm/VirtualMachine.cs | 10 +++++----- .../EthModuleBenchmarks.cs | 6 +++--- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs index 5f83e7b493b..a181a397004 100644 --- a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs @@ -142,14 +142,14 @@ protected async Task RunTest(BlockchainTest test, Stopwatch? IStateReader stateReader = new StateReader(trieStore, codeDb, _logManager); IReceiptStorage receiptStorage = NullReceiptStorage.Instance; - IBlockhashProvider blockHashProvider = new BlockhashProvider(blockTree, _logManager); + IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, _logManager); ITxValidator txValidator = new TxValidator(TestBlockchainIds.ChainId); IHeaderValidator headerValidator = new HeaderValidator(blockTree, Sealer, specProvider, _logManager); IUnclesValidator unclesValidator = new UnclesValidator(blockTree, headerValidator, _logManager); IBlockValidator blockValidator = new BlockValidator(txValidator, headerValidator, unclesValidator, specProvider, _logManager); CodeInfoRepository codeInfoRepository = new(); IVirtualMachine virtualMachine = new VirtualMachine( - blockHashProvider, + blockhashProvider, specProvider, codeInfoRepository, _logManager); diff --git a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs index 968ae5847b6..733ac1b3bd4 100644 --- a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs @@ -66,10 +66,10 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) TrieStore trieStore = new(stateDb, _logManager); WorldState stateProvider = new(trieStore, codeDb, _logManager); - IBlockhashProvider blockHashProvider = new TestBlockHashProvider(); + IBlockhashProvider blockhashProvider = new TestBlockHashProvider(); CodeInfoRepository codeInfoRepository = new(); IVirtualMachine virtualMachine = new VirtualMachine( - blockHashProvider, + blockhashProvider, specProvider, codeInfoRepository, _logManager); diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs index 2e672934c13..076a597ab8c 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs @@ -28,7 +28,7 @@ public class EvmBenchmarks private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; private readonly BlockHeader _header = new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.IstanbulBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private readonly IBlockhashProvider _blockHashProvider = new TestBlockhashProvider(); + private readonly IBlockhashProvider _blockhashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; @@ -45,7 +45,7 @@ public void GlobalSetup() _stateProvider.CreateAccount(Address.Zero, 1000.Ether()); _stateProvider.Commit(_spec); CodeInfoRepository codeInfoRepository = new(); - _virtualMachine = new VirtualMachine(_blockHashProvider, MainnetSpecProvider.Instance, codeInfoRepository, LimboLogs.Instance); + _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, codeInfoRepository, LimboLogs.Instance); _environment = new ExecutionEnvironment ( diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs index 4972bed2718..f2018a02ed8 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs @@ -27,7 +27,7 @@ public class MultipleUnsignedOperations private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; private readonly BlockHeader _header = new(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.MuirGlacierBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private readonly IBlockhashProvider _blockHashProvider = new TestBlockhashProvider(); + private readonly IBlockhashProvider _blockhashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; @@ -77,7 +77,7 @@ public void GlobalSetup() Console.WriteLine(MuirGlacier.Instance); CodeInfoRepository codeInfoRepository = new(); - _virtualMachine = new VirtualMachine(_blockHashProvider, MainnetSpecProvider.Instance, codeInfoRepository, new OneLoggerLogManager(NullLogger.Instance)); + _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, codeInfoRepository, new OneLoggerLogManager(NullLogger.Instance)); _environment = new ExecutionEnvironment ( diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs index 92b7f4b0e90..15f21963011 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs @@ -28,7 +28,7 @@ public class StaticCallBenchmarks private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; private readonly BlockHeader _header = new(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.MuirGlacierBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private readonly IBlockhashProvider _blockHashProvider = new TestBlockhashProvider(); + private readonly IBlockhashProvider _blockhashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; @@ -88,7 +88,7 @@ public void GlobalSetup() Console.WriteLine(MuirGlacier.Instance); CodeInfoRepository codeInfoRepository = new(); - _virtualMachine = new VirtualMachine(_blockHashProvider, MainnetSpecProvider.Instance, codeInfoRepository, new OneLoggerLogManager(NullLogger.Instance)); + _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, codeInfoRepository, new OneLoggerLogManager(NullLogger.Instance)); _environment = new ExecutionEnvironment ( diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 13fdef1b6c6..b30e96bdba9 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -69,15 +69,15 @@ public class VirtualMachine : IVirtualMachine private readonly IVirtualMachine _evm; public VirtualMachine( - IBlockhashProvider? blockHashProvider, + IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, ICodeInfoRepository codeInfoRepository, ILogManager? logManager) { ILogger logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); _evm = logger.IsTrace - ? new VirtualMachine(blockHashProvider, specProvider, codeInfoRepository, logger) - : new VirtualMachine(blockHashProvider, specProvider, codeInfoRepository, logger); + ? new VirtualMachine(blockhashProvider, specProvider, codeInfoRepository, logger) + : new VirtualMachine(blockhashProvider, specProvider, codeInfoRepository, logger); } public TransactionSubstate Run(EvmState state, IWorldState worldState, ITxTracer txTracer) @@ -163,13 +163,13 @@ internal sealed class VirtualMachine : IVirtualMachine where TLogger : private readonly ICodeInfoRepository _codeInfoRepository; public VirtualMachine( - IBlockhashProvider? blockHashProvider, + IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, ICodeInfoRepository codeInfoRepository, ILogger? logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _blockhashProvider = blockHashProvider ?? throw new ArgumentNullException(nameof(blockHashProvider)); + _blockhashProvider = blockhashProvider ?? throw new ArgumentNullException(nameof(blockhashProvider)); _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _codeInfoRepository = codeInfoRepository ?? throw new ArgumentNullException(nameof(codeInfoRepository)); _chainId = ((UInt256)specProvider.ChainId).ToBigEndian(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index 832d175f0a7..4bef8f76460 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -44,7 +44,7 @@ namespace Nethermind.JsonRpc.Benchmark public class EthModuleBenchmarks { private IVirtualMachine _virtualMachine; - private IBlockhashProvider _blockHashProvider; + private IBlockhashProvider _blockhashProvider; private EthRpcModule _ethModule; [GlobalSetup] @@ -80,9 +80,9 @@ public void GlobalSetup() NullBloomStorage.Instance, new SyncConfig(), LimboLogs.Instance); - _blockHashProvider = new BlockHashProvider(blockTree, LimboLogs.Instance); + _blockhashProvider = new BlockHashProvider(blockTree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); - _virtualMachine = new VirtualMachine(_blockHashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); + _virtualMachine = new VirtualMachine(_blockhashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); Block genesisBlock = Build.A.Block.Genesis.TestObject; blockTree.SuggestBlock(genesisBlock); From be04bdf680f1367b44c85c3876734a6972b39e65 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 16:16:02 +0000 Subject: [PATCH 151/213] minor trello fixes --- .../Proxy/Models/MultiCall/SimulateCallResult.cs | 12 ++++++------ .../Simulate/SimulateBlockTracer.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs index 05ec2127c4a..c02c70dac74 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs @@ -7,17 +7,17 @@ namespace Nethermind.Facade.Proxy.Models.Simulate; public class SimulateCallResult { - public ResultType Type => + public short Type => Status switch { - StatusCode.Success => ResultType.Success, - StatusCode.Failure when ReturnData is not null => ResultType.Failure, - _ => ResultType.Invalid, + StatusCode.Success => (short)ResultType.Success, + StatusCode.Failure when ReturnData is not null => (short)ResultType.Failure, + _ => (short)ResultType.Invalid, }; - public byte Status { get; set; } + public short Status { get; set; } public byte[]? ReturnData { get; set; } public ulong? GasUsed { get; set; } public Error? Error { get; set; } - public Log[] Logs { get; set; } = { }; + public Log[] Logs { get; set; } = []; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 92be7557ec5..56402bbf741 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -60,7 +60,7 @@ public override void EndBlockTrace() result.Calls.ForEach(callResult => { - if (callResult.Type == ResultType.Success) + if (callResult.Type == (short)ResultType.Success) { callResult.Logs?.ForEach(log => { From 6664f2f244ea7a3adce8da0694bb872f35dc4c23 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 16:22:21 +0000 Subject: [PATCH 152/213] status text issue fix --- .../Proxy/Models/MultiCall/SimulateCallResult.cs | 10 +++++----- .../Nethermind.Facade/Simulate/SimulateBlockTracer.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs index c02c70dac74..09f32efe55e 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs @@ -7,15 +7,15 @@ namespace Nethermind.Facade.Proxy.Models.Simulate; public class SimulateCallResult { - public short Type => + public ulong Type => Status switch { - StatusCode.Success => (short)ResultType.Success, - StatusCode.Failure when ReturnData is not null => (short)ResultType.Failure, - _ => (short)ResultType.Invalid, + StatusCode.Success => (ulong)ResultType.Success, + StatusCode.Failure when ReturnData is not null => (ulong)ResultType.Failure, + _ => (ulong)ResultType.Invalid, }; - public short Status { get; set; } + public ulong Status { get; set; } public byte[]? ReturnData { get; set; } public ulong? GasUsed { get; set; } public Error? Error { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 56402bbf741..11e642555c0 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -60,7 +60,7 @@ public override void EndBlockTrace() result.Calls.ForEach(callResult => { - if (callResult.Type == (short)ResultType.Success) + if (callResult.Type == (ulong)ResultType.Success) { callResult.Logs?.ForEach(log => { From 4cb263db7ea82889e237decc3147c0c8364c7c5b Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 16:59:12 +0000 Subject: [PATCH 153/213] changing test that shall fail on current setup due to gas fees --- .../Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs index b75c587d54d..e663dbb4cc1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs @@ -745,8 +745,7 @@ public async Task TestsimulateTransferOverBlockStateCalls() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateTransferOverBlockStateCalls"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } [Test] From 0408f1d38d1b04db6923e9d322c988c071ffe81a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 21 Feb 2024 17:17:36 +0000 Subject: [PATCH 154/213] Fixing project build --- .../Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index 4bef8f76460..d0b13d0a7e2 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -80,7 +80,7 @@ public void GlobalSetup() NullBloomStorage.Instance, new SyncConfig(), LimboLogs.Instance); - _blockhashProvider = new BlockHashProvider(blockTree, LimboLogs.Instance); + _blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance); CodeInfoRepository codeInfoRepository = new(); _virtualMachine = new VirtualMachine(_blockhashProvider, specProvider, codeInfoRepository, LimboLogs.Instance); From 0df45dc4f370f1e5d7e903add3434ce64d5fcea2 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 18:20:47 +0100 Subject: [PATCH 155/213] more revert --- src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs | 2 +- .../Ethereum.Test.Base/TestBlockhashProvider.cs | 10 +++------- .../Nethermind.Evm.Benchmark/TestBlockhashProvider.cs | 8 ++------ 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs index 733ac1b3bd4..e58f75b30af 100644 --- a/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs @@ -66,7 +66,7 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) TrieStore trieStore = new(stateDb, _logManager); WorldState stateProvider = new(trieStore, codeDb, _logManager); - IBlockhashProvider blockhashProvider = new TestBlockHashProvider(); + IBlockhashProvider blockhashProvider = new TestBlockhashProvider(); CodeInfoRepository codeInfoRepository = new(); IVirtualMachine virtualMachine = new VirtualMachine( blockhashProvider, diff --git a/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs b/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs index 51dc7017348..fbc91fd2459 100644 --- a/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs +++ b/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs @@ -7,13 +7,9 @@ namespace Ethereum.Test.Base { - public class TestBlockHashProvider : IBlockhashProvider + public class TestBlockhashProvider : IBlockhashProvider { - public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) - { - if (number != 0) - return Keccak.Zero; - return Keccak.Compute(number.ToString()); - } + public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) => + number != 0 ? Keccak.Zero : Keccak.Compute(number.ToString()); } } diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs index eec9a33aa36..d53a1cf96f0 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs @@ -8,11 +8,7 @@ namespace Nethermind.Evm.Benchmark { public class TestBlockhashProvider : IBlockhashProvider { - public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) - { - return Keccak.Compute(number.ToString()); - } - - + public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) => + Keccak.Compute(number.ToString()); } } From 67425a697ff97d1a278e9ce67a760e003d97aace Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 18:43:14 +0100 Subject: [PATCH 156/213] fix CodeInfoRepository --- .../Nethermind.Evm/CodeAnalysis/CodeInfo.cs | 6 +--- .../Nethermind.Evm/CodeInfoRepository.cs | 30 +++++++++++-------- .../Nethermind.Evm/ICodeInfoRepository.cs | 2 +- .../Nethermind.Evm/VirtualMachine.cs | 12 ++++---- .../BlockchainBridgeTests.cs | 26 ++++++++-------- .../OverridableCodeInfoRepository.cs | 23 ++++---------- 6 files changed, 45 insertions(+), 54 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs b/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs index aac5b334306..8cf6358c051 100644 --- a/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs +++ b/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs @@ -14,11 +14,7 @@ public class CodeInfo : IThreadPoolWorkItem public IPrecompile? Precompile { get; set; } private readonly JumpDestinationAnalyzer _analyzer; private static readonly JumpDestinationAnalyzer _emptyAnalyzer = new(Array.Empty()); - public static CodeInfo Empty { get; } = new CodeInfo(Array.Empty()); - - public CodeInfo(byte[] code) : this(code.AsMemory()) - { - } + public static CodeInfo Empty { get; } = new(Array.Empty()); public CodeInfo(ReadOnlyMemory code) { diff --git a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs index d8ab77f5e11..91272ffbf52 100644 --- a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Diagnostics; @@ -20,22 +21,30 @@ namespace Nethermind.Evm; public class CodeInfoRepository : ICodeInfoRepository { - private static readonly Dictionary? _precompiles; + private static readonly FrozenDictionary _precompiles; private static readonly LruCache _codeCache = new(MemoryAllowance.CodeCacheSize, MemoryAllowance.CodeCacheSize, "VM bytecodes"); static CodeInfoRepository() { - _precompiles = new Dictionary + _precompiles = InitializePrecompiledContracts(); + } + + private static FrozenDictionary InitializePrecompiledContracts() + { + return new Dictionary { [EcRecoverPrecompile.Address] = new(EcRecoverPrecompile.Instance), [Sha256Precompile.Address] = new(Sha256Precompile.Instance), [Ripemd160Precompile.Address] = new(Ripemd160Precompile.Instance), [IdentityPrecompile.Address] = new(IdentityPrecompile.Instance), + [Bn254AddPrecompile.Address] = new(Bn254AddPrecompile.Instance), [Bn254MulPrecompile.Address] = new(Bn254MulPrecompile.Instance), [Bn254PairingPrecompile.Address] = new(Bn254PairingPrecompile.Instance), [ModExpPrecompile.Address] = new(ModExpPrecompile.Instance), + [Blake2FPrecompile.Address] = new(Blake2FPrecompile.Instance), + [G1AddPrecompile.Address] = new(G1AddPrecompile.Instance), [G1MulPrecompile.Address] = new(G1MulPrecompile.Instance), [G1MultiExpPrecompile.Address] = new(G1MultiExpPrecompile.Instance), @@ -45,19 +54,15 @@ static CodeInfoRepository() [PairingPrecompile.Address] = new(PairingPrecompile.Instance), [MapToG1Precompile.Address] = new(MapToG1Precompile.Instance), [MapToG2Precompile.Address] = new(MapToG2Precompile.Instance), + [PointEvaluationPrecompile.Address] = new(PointEvaluationPrecompile.Instance), - }; + }.ToFrozenDictionary(); } public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) { if (codeSource.IsPrecompile(vmSpec)) { - if (_precompiles is null) - { - throw new InvalidOperationException("EVM precompile have not been initialized properly."); - } - return _precompiles[codeSource]; } @@ -68,9 +73,8 @@ public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IR cachedCodeInfo = CodeInfo.Empty; } - bool haveCached = _codeCache.TryGet(codeHash, out cachedCodeInfo); - - if (!haveCached) + cachedCodeInfo ??= _codeCache.Get(codeHash); + if (cachedCodeInfo is null) { byte[]? code = worldState.GetCode(codeHash); @@ -113,13 +117,13 @@ public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) } - public void InsertCode(IWorldState state, byte[] code, Address codeOwner, IReleaseSpec spec) + public void InsertCode(IWorldState state, ReadOnlyMemory code, Address codeOwner, IReleaseSpec spec) { var codeInfo = new CodeInfo(code); // Start generating the JumpDestinationBitmap in background. ThreadPool.UnsafeQueueUserWorkItem(codeInfo, preferLocal: false); - Hash256 codeHash = code.Length == 0 ? Keccak.OfAnEmptyString : Keccak.Compute(code.AsSpan()); + Hash256 codeHash = code.Length == 0 ? Keccak.OfAnEmptyString : Keccak.Compute(code.Span); state.InsertCode(codeOwner, codeHash, code, spec); _codeCache.Set(codeHash, codeInfo); } diff --git a/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs index 3d2b3561e52..6fde3cbfe7f 100644 --- a/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs @@ -14,5 +14,5 @@ public interface ICodeInfoRepository { CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec); CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode); - void InsertCode(IWorldState state, byte[] code, Address codeOwner, IReleaseSpec spec); + void InsertCode(IWorldState state, ReadOnlyMemory code, Address codeOwner, IReleaseSpec spec); } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index b30e96bdba9..65c9e233528 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -360,8 +360,8 @@ public TransactionSubstate Run(EvmState state, IWorldState worl bool invalidCode = CodeDepositHandler.CodeIsInvalid(spec, callResult.Output); if (gasAvailableForCodeDeposit >= codeDepositGasCost && !invalidCode) { - var code = callResult.Output; - _codeInfoRepository.InsertCode(_state, code.ToArray(), callCodeOwner, spec); + ReadOnlyMemory code = callResult.Output; + _codeInfoRepository.InsertCode(_state, code, callCodeOwner, spec); currentState.GasAvailable -= codeDepositGasCost; @@ -654,7 +654,7 @@ private CallResult ExecuteCall(EvmState vmState, ReadOnlyM } } - if (env.CodeInfo.MachineCode is { Length: 0 }) + if (env.CodeInfo.MachineCode.Length == 0) { if (!vmState.IsTopLevel) { @@ -2446,8 +2446,10 @@ private EvmExceptionType InstructionSelfDestruct(EvmState vmState, ref _state.SubtractFromBalance(env.ExecutingAccount, value, spec); - ValueHash256 codeHash = ValueKeccak.Compute(initCode.Span); - CodeInfo codeInfo = _codeInfoRepository.GetOrAdd(codeHash, initCode.Span); + // Do not add the initCode to the cache as it is + // pointing to data in this tx and will become invalid + // for another tx as returned to pool. + CodeInfo codeInfo = new(initCode); ExecutionEnvironment callEnv = new ( diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index 7ab90c34461..27832931fc8 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -36,17 +36,17 @@ namespace Nethermind.Facade.Test { public class BlockchainBridgeTests { - private BlockchainBridge _blockchainBridge; - private IBlockTree _blockTree; - private ITxPool _txPool; - private IReceiptStorage _receiptStorage; - private IFilterStore _filterStore; - private IFilterManager _filterManager; - private ITransactionProcessor _transactionProcessor; - private IEthereumEcdsa _ethereumEcdsa; - private ManualTimestamper _timestamper; - private ISpecProvider _specProvider; - private IDbProvider _dbProvider; + private BlockchainBridge _blockchainBridge = null!; + private IBlockTree _blockTree = null!; + private ITxPool _txPool = null!; + private IReceiptStorage _receiptStorage = null!; + private IFilterStore _filterStore = null!; + private IFilterManager _filterManager = null!; + private ITransactionProcessor _transactionProcessor = null!; + private IEthereumEcdsa _ethereumEcdsa = null!; + private ManualTimestamper _timestamper = null!; + private ISpecProvider _specProvider = null!; + private IDbProvider _dbProvider = null!; [SetUp] public async Task SetUp() @@ -68,7 +68,7 @@ public async Task SetUp() IWorldStateManager readOnlyWorldStateManager = new ReadOnlyWorldStateManager(dbProvider, trieStore, LimboLogs.Instance); - IReadOnlyBlockTree? readOnlyBlockTree = _blockTree!.AsReadOnly(); + IReadOnlyBlockTree readOnlyBlockTree = _blockTree.AsReadOnly(); ReadOnlyTxProcessingEnv processingEnv = new( readOnlyWorldStateManager, readOnlyBlockTree, @@ -225,7 +225,7 @@ public void Bridge_head_is_correct(long headNumber) IWorldStateManager readOnlyWorldStateManager = new ReadOnlyWorldStateManager(dbProvider, trieStore, LimboLogs.Instance); - IReadOnlyBlockTree? roBlockTree = _blockTree!.AsReadOnly(); + IReadOnlyBlockTree roBlockTree = _blockTree.AsReadOnly(); ReadOnlyTxProcessingEnv processingEnv = new( readOnlyWorldStateManager, roBlockTree, diff --git a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs index 4225fd5862f..312080cf5d1 100644 --- a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs @@ -8,21 +8,14 @@ using Nethermind.Core.Specs; using Nethermind.Evm; using Nethermind.Evm.CodeAnalysis; -using Nethermind.Evm.Precompiles; using Nethermind.State; namespace Nethermind.Facade; -public class OverridableCodeInfoRepository : ICodeInfoRepository +public class OverridableCodeInfoRepository(ICodeInfoRepository codeInfoRepository) : ICodeInfoRepository { - private readonly ICodeInfoRepository _codeInfoRepository; private readonly Dictionary _codeOverwrites = new(); - public OverridableCodeInfoRepository(ICodeInfoRepository codeInfoRepository) - { - _codeInfoRepository = codeInfoRepository; - } - public void SetCodeOverwrite( IWorldState worldState, IReleaseSpec vmSpec, @@ -38,16 +31,12 @@ public void SetCodeOverwrite( _codeOverwrites[key] = value; } - public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) - { - return _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) ? result : _codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, vmSpec); - } + public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) => + _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) ? result : codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, vmSpec); public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) => - _codeInfoRepository.GetOrAdd(codeHash, initCode); - - public void InsertCode(IWorldState state, byte[] code, Address codeOwner, IReleaseSpec spec) => - _codeInfoRepository.InsertCode(state, code, codeOwner, spec); + codeInfoRepository.GetOrAdd(codeHash, initCode); - public void Clear() => _codeOverwrites.Clear(); + public void InsertCode(IWorldState state, ReadOnlyMemory code, Address codeOwner, IReleaseSpec spec) => + codeInfoRepository.InsertCode(state, code, codeOwner, spec); } From cd8d307d4db51af5a476fde910de6f0dc7f6f80c Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 21 Feb 2024 23:51:16 +0100 Subject: [PATCH 157/213] more refactor --- .../BlockchainProcessorTests.cs | 2 +- .../Processing/BlockProcessor.cs | 8 +- .../Processing/IBlockProcessor.cs | 7 +- .../Processing/NullBlockProcessor.cs | 3 +- .../Nethermind.Evm/ByteCodeBuilder.cs | 10 +- .../Nethermind.Facade/IBlockchainBridge.cs | 5 - .../Proxy/Models/MultiCall/CallTransaction.cs | 12 -- .../{MultiCall => Simulate}/BlockOverride.cs | 2 +- .../{MultiCall => Simulate}/BlockStateCall.cs | 0 .../Models/{MultiCall => Simulate}/Error.cs | 0 .../Models/{MultiCall => Simulate}/Log.cs | 0 .../{MultiCall => Simulate}/ResultType.cs | 0 .../SimulateBlockResult.cs | 0 .../SimulateCallResult.cs | 15 +- .../SimulatePayload.cs | 2 +- .../TransactionWithSourceDetails.cs | 0 .../Simulate/SimulateBlockTracer.cs | 14 +- .../Simulate/SimulateBridgeHelper.cs | 161 ++++++++++-------- .../SimulateReadOnlyBlocksProcessingEnv.cs | 63 +------ ...ulateReadOnlyBlocksProcessingEnvFactory.cs | 61 +++++++ .../Simulate/SimulateTxTracer.cs | 6 +- .../StateOverridesExtensions.cs | 19 +-- .../Steps/InitializeBlockchain.cs | 13 +- .../JsonRpcServiceTests.cs | 14 +- .../Modules/Eth/EthRpcSimulateTestsBase.cs | 111 ++++-------- ...SimulateTestsPrecompilesWithRedirection.cs | 94 ++++------ .../EthSimulateTestsBlocksAndTransactions.cs | 68 +++----- .../EthSimulateTestsSimplePrecompiles.cs | 86 ++++------ .../Modules/TestRpcBlockchain.cs | 10 +- .../EngineModuleTests.Setup.cs | 2 +- .../InitializeBlockchainOptimism.cs | 3 +- 31 files changed, 322 insertions(+), 469 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs rename src/Nethermind/Nethermind.Facade/Proxy/Models/{MultiCall => Simulate}/BlockOverride.cs (98%) rename src/Nethermind/Nethermind.Facade/Proxy/Models/{MultiCall => Simulate}/BlockStateCall.cs (100%) rename src/Nethermind/Nethermind.Facade/Proxy/Models/{MultiCall => Simulate}/Error.cs (100%) rename src/Nethermind/Nethermind.Facade/Proxy/Models/{MultiCall => Simulate}/Log.cs (100%) rename src/Nethermind/Nethermind.Facade/Proxy/Models/{MultiCall => Simulate}/ResultType.cs (100%) rename src/Nethermind/Nethermind.Facade/Proxy/Models/{MultiCall => Simulate}/SimulateBlockResult.cs (100%) rename src/Nethermind/Nethermind.Facade/Proxy/Models/{MultiCall => Simulate}/SimulateCallResult.cs (53%) rename src/Nethermind/Nethermind.Facade/Proxy/Models/{MultiCall => Simulate}/SimulatePayload.cs (93%) rename src/Nethermind/Nethermind.Facade/Proxy/Models/{MultiCall => Simulate}/TransactionWithSourceDetails.cs (100%) create mode 100644 src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs index aa50d09e96d..773628f9b9f 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs @@ -73,7 +73,7 @@ public void AllowToFail(Hash256 hash) _allowedToFail.Add(hash); } - public Block[] Process(Hash256 newBranchStateRoot, List suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer) + public Block[] Process(Hash256 newBranchStateRoot, IReadOnlyList suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer) { if (blockTracer != NullBlockTracer.Instance) { diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index f3ae94af802..ed414ba0ed8 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -84,7 +84,7 @@ public event EventHandler TransactionProcessed } // TODO: move to branch processor - public Block[] Process(Hash256 newBranchStateRoot, List suggestedBlocks, ProcessingOptions options, IBlockTracer blockTracer) + public Block[] Process(Hash256 newBranchStateRoot, IReadOnlyList suggestedBlocks, ProcessingOptions options, IBlockTracer blockTracer) { if (suggestedBlocks.Count == 0) return Array.Empty(); @@ -375,9 +375,9 @@ private void ApplyDaoTransition(Block block) } } - private class TxHashCalculator(List suggestedBlocks) : IThreadPoolWorkItem + private class TxHashCalculator(IReadOnlyList suggestedBlocks) : IThreadPoolWorkItem { - public static void CalculateInBackground(List suggestedBlocks) + public static void CalculateInBackground(IReadOnlyList suggestedBlocks) { // Memory has been reserved on the transactions to delay calculate the hashes // We calculate the hashes in the background to release that memory @@ -389,7 +389,7 @@ void IThreadPoolWorkItem.Execute() // Hashes will be required for PersistentReceiptStorage in UpdateMainChain ForkchoiceUpdatedHandler // Which occurs after the block has been processed; however the block is stored in cache and picked up // from there so we can calculate the hashes now for that later use. - foreach (Block block in CollectionsMarshal.AsSpan(suggestedBlocks)) + foreach (Block block in suggestedBlocks) { foreach (Transaction tx in block.Transactions) { diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs index ceb8da16d7c..ec6473ef6d4 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs @@ -19,12 +19,11 @@ public interface IBlockProcessor /// List of blocks to be processed. /// Options to use for processor and transaction processor. /// - /// Block tracer to use. By default either or + /// Block tracer to use. By default either or /// /// List of processed blocks. - Block[] Process( - Hash256 newBranchStateRoot, - List suggestedBlocks, + Block[] Process(Hash256 newBranchStateRoot, + IReadOnlyList suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/NullBlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/NullBlockProcessor.cs index ad47599ff84..979aad8c506 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/NullBlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/NullBlockProcessor.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Evm.Tracing; @@ -15,7 +16,7 @@ private NullBlockProcessor() { } public static IBlockProcessor Instance { get; } = new NullBlockProcessor(); - public Block[] Process(Hash256 newBranchStateRoot, List suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer) + public Block[] Process(Hash256 newBranchStateRoot, IReadOnlyList suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer) { return suggestedBlocks.ToArray(); } diff --git a/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs b/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs index 8ebdf5fb439..526ef98db21 100644 --- a/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs +++ b/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs @@ -252,9 +252,17 @@ public Prepare PushData(byte[] data) return this; } + public Prepare PushData(ReadOnlyMemory data) + { + _byteCode.Add((byte)(Instruction.PUSH1 + (byte)data.Length - 1)); + _byteCode.AddRange(data.Span); + return this; + } + + public Prepare PushData(byte data) { - PushData(new[] { data }); + PushData([data]); return this; } diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index 5d197f1ac97..102b05470d2 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -29,11 +29,9 @@ public interface IBlockchainBridge : ILogFinder (TxReceipt? Receipt, Transaction Transaction, UInt256? baseFee) GetTransaction(Hash256 txHash, bool checkTxnPool = true); CallOutput Call(BlockHeader header, Transaction tx, CancellationToken cancellationToken); SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, CancellationToken cancellationToken); - CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken); CallOutput CreateAccessList(BlockHeader header, Transaction tx, CancellationToken cancellationToken, bool optimize); ulong GetChainId(); - int NewBlockFilter(); int NewPendingTransactionFilter(); int NewFilter(BlockParameter? fromBlock, BlockParameter? toBlock, object? address = null, IEnumerable? topics = null); @@ -42,14 +40,11 @@ public interface IBlockchainBridge : ILogFinder Hash256[] GetBlockFilterChanges(int filterId); Hash256[] GetPendingTransactionFilterChanges(int filterId); FilterLog[] GetLogFilterChanges(int filterId); - FilterType GetFilterType(int filterId); FilterLog[] GetFilterLogs(int filterId); - LogFilter GetFilter(BlockParameter fromBlock, BlockParameter toBlock, object? address = null, IEnumerable? topics = null); IEnumerable GetLogs(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock, CancellationToken cancellationToken = default); IEnumerable GetLogs(BlockParameter fromBlock, BlockParameter toBlock, object? address = null, IEnumerable? topics = null, CancellationToken cancellationToken = default); - bool TryGetLogs(int filterId, out IEnumerable filterLogs, CancellationToken cancellationToken = default); void RunTreeVisitor(ITreeVisitor treeVisitor, Hash256 stateRoot); bool HasStateForRoot(Hash256 stateRoot); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs deleted file mode 100644 index a18c9cdceee..00000000000 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/CallTransaction.cs +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Core; -using Nethermind.Int256; -using static Nethermind.Core.Extensions.MemoryExtensions; - -namespace Nethermind.Facade.Proxy.Models.Simulate -{ - //A stub - public class CallTransaction { } -} diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs similarity index 98% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs index 4edb4501d8c..cd4a3846727 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs @@ -39,7 +39,7 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) Address newFeeRecipientAddress = FeeRecipient ?? parent.Beneficiary!; UInt256 newDifficulty = parent.Difficulty == 0 ? 0 : parent.Difficulty + 1; - BlockHeader? result = new( + BlockHeader result = new( parent.Hash!, Keccak.OfAnEmptySequenceRlp, newFeeRecipientAddress, diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockStateCall.cs similarity index 100% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/BlockStateCall.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockStateCall.cs diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Error.cs similarity index 100% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Error.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Error.cs diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Log.cs similarity index 100% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/Log.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Log.cs diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/ResultType.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/ResultType.cs similarity index 100% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/ResultType.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/ResultType.cs diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs similarity index 100% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateBlockResult.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs similarity index 53% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs index 09f32efe55e..78f75a5ac04 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulateCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; +using System.Collections.Generic; +using System.Linq; using Nethermind.Evm; namespace Nethermind.Facade.Proxy.Models.Simulate; @@ -8,16 +11,16 @@ namespace Nethermind.Facade.Proxy.Models.Simulate; public class SimulateCallResult { public ulong Type => - Status switch + (ulong)(Status switch { - StatusCode.Success => (ulong)ResultType.Success, - StatusCode.Failure when ReturnData is not null => (ulong)ResultType.Failure, - _ => (ulong)ResultType.Invalid, - }; + StatusCode.Success => ResultType.Success, + StatusCode.Failure when ReturnData is not null => ResultType.Failure, + _ => ResultType.Invalid, + }); public ulong Status { get; set; } public byte[]? ReturnData { get; set; } public ulong? GasUsed { get; set; } public Error? Error { get; set; } - public Log[] Logs { get; set; } = []; + public IEnumerable Logs { get; set; } = Enumerable.Empty(); } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulatePayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs similarity index 93% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulatePayload.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs index eb090ed68d2..820a8dece1e 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/SimulatePayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs @@ -18,5 +18,5 @@ public class SimulatePayload /// /// When true, the simulate does all validations that a normal EVM would do, except contract sender and signature checks. When false, multicall behaves like eth_call. /// - public bool Validation { get; set; } = false; + public bool Validation { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/TransactionWithSourceDetails.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/TransactionWithSourceDetails.cs similarity index 100% rename from src/Nethermind/Nethermind.Facade/Proxy/Models/MultiCall/TransactionWithSourceDetails.cs rename to src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/TransactionWithSourceDetails.cs diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 11e642555c0..47a53c67f53 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -11,20 +11,14 @@ namespace Nethermind.Facade.Simulate; -public class SimulateBlockTracer : BlockTracer +public class SimulateBlockTracer(bool isTracingLogs) : BlockTracer { - private readonly bool _isTracingLogs; public List Results { get; } = new(); private readonly List _txTracers = new(); private Block _currentBlock = null!; - public SimulateBlockTracer(bool isTracingLogs) - { - _isTracingLogs = isTracingLogs; - } - public override void StartNewBlockTrace(Block block) { _txTracers.Clear(); @@ -35,7 +29,7 @@ public override ITxTracer StartNewTxTrace(Transaction? tx) { if (tx?.Hash is not null) { - SimulateTxTracer result = new(_isTracingLogs); + SimulateTxTracer result = new(isTracingLogs); _txTracers.Add(result); return result; } @@ -51,11 +45,11 @@ public override void EndBlockTrace() Number = (ulong)_currentBlock.Number, Hash = _currentBlock.Hash!, GasLimit = (ulong)_currentBlock.GasLimit, - GasUsed = _txTracers.Aggregate(0ul, (s, t) => s + t.TraceResult!.GasUsed.Value), + GasUsed = _txTracers.Aggregate(0ul, (s, t) => s + t.TraceResult!.GasUsed ?? 0ul), Timestamp = _currentBlock.Timestamp, FeeRecipient = _currentBlock.Beneficiary!, BaseFeePerGas = _currentBlock.BaseFeePerGas, - PrevRandao = _currentBlock.Header!.Random!.BytesToArray(), + PrevRandao = _currentBlock.Header!.Random?.BytesToArray(), }; result.Calls.ForEach(callResult => diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 4de4a61163c..43aa93a2191 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -7,6 +7,7 @@ using Nethermind.Config; using Nethermind.Consensus.Processing; using Nethermind.Core; +using Nethermind.Core.Collections; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Crypto; @@ -30,17 +31,19 @@ public class SimulateBridgeHelper( ProcessingOptions.MarkAsProcessed | ProcessingOptions.StoreReceipts; - private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, - BlockStateCall blockStateCall, SimulateReadOnlyBlocksProcessingEnv env) + private void UpdateStateByModifyingAccounts( + BlockHeader blockHeader, + BlockStateCall blockStateCall, + SimulateReadOnlyBlocksProcessingEnv env) { IReleaseSpec currentSpec = env.SpecProvider.GetSpec(blockHeader); env.StateProvider.ApplyStateOverrides(env.CodeInfoRepository, blockStateCall.StateOverrides, currentSpec, blockHeader.Number); - IEnumerable? senders = blockStateCall.Calls.Select(details => details.Transaction.SenderAddress); - IEnumerable? targets = blockStateCall.Calls.Select(details => details.Transaction.To!); + IEnumerable senders = blockStateCall.Calls?.Select(details => details.Transaction.SenderAddress) ?? Enumerable.Empty(); + IEnumerable targets = blockStateCall.Calls?.Select(details => details.Transaction.To!) ?? Enumerable.Empty(); var all = senders.Union(targets) - .Where(address => address != null) + .Where(address => address is null) .Distinct() .ToList(); @@ -49,7 +52,7 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, env.StateProvider.CreateAccountIfNotExists(address, 0, 0); } - IWorldState? state = env.StateProvider; + IWorldState state = env.StateProvider; state.Commit(currentSpec); state.CommitTree(blockHeader.Number); state.RecalculateStateRoot(); @@ -90,77 +93,16 @@ private void UpdateStateByModifyingAccounts(BlockHeader blockHeader, if (payload.BlockStateCalls is not null) { Dictionary nonceCache = new(); - List suggestedBlocks = new(); + using ArrayPoolList suggestedBlocks = new(payload.BlockStateCalls.Length); foreach (BlockStateCall callInputBlock in payload.BlockStateCalls) { - BlockHeader callHeader = callInputBlock.BlockOverrides is not null - ? callInputBlock.BlockOverrides.GetBlockHeader(parent, blocksConfig) - : new BlockHeader( - parent.Hash!, - Keccak.OfAnEmptySequenceRlp, - Address.Zero, - UInt256.Zero, - parent.Number + 1, - parent.GasLimit, - - parent.Timestamp + 1, - Array.Empty()) - { - BaseFeePerGas = BaseFeeCalculator.Calculate(parent, specProvider.GetSpec(parent)), - MixHash = parent.MixHash, - IsPostMerge = parent.Difficulty == 0 - }; - + BlockHeader callHeader = GetCallHeader(callInputBlock, parent); UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); using IReadOnlyTransactionProcessor? readOnlyTransactionProcessor = env.Build(env.StateProvider.StateRoot!); - Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transactionDetails, IReleaseSpec? spec) - { - Transaction? transaction = transactionDetails.Transaction; - transaction.SenderAddress ??= Address.Zero; - transaction.To ??= Address.Zero; - transaction.Data ??= Memory.Empty; - - if (!transactionDetails.HadNonceInRequest) - { - if (!nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) - { - cachedNonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; - nonceCache[transaction.SenderAddress] = cachedNonce; - } - else - { - cachedNonce++; - nonceCache[transaction.SenderAddress] = cachedNonce; - } - - transaction.Nonce = cachedNonce; - } - - if (payload.Validation) - { - if (transaction.GasPrice == 0) - { - transaction.GasPrice = callHeader.BaseFeePerGas; - } - - if (transaction.Type == TxType.EIP1559 && transaction.DecodedMaxFeePerGas == 0) - { - transaction.DecodedMaxFeePerGas = transaction.GasPrice == 0 - ? callHeader.BaseFeePerGas + 1 - : transaction.GasPrice; - //UInt256.MultiplyOverflow((UInt256)transaction.GasLimit, transaction.MaxFeePerGas, out UInt256 maxGasFee); - //string err = $"insufficient sender balance for MaxFeePerGas: {callHeader.Number}, {transaction.SenderAddress} balance should be at least {maxGasFee + 1 + transaction.Value }"; - } - } - - transaction.Hash ??= transaction.CalculateHash(); - - return transaction; - } - IReleaseSpec? spec = specProvider.GetSpec(parent); + IReleaseSpec spec = specProvider.GetSpec(parent); var specifiedGasTxs = callInputBlock.Calls.Where(details => details.HadGasLimitInRequest).ToList(); var notSpecifiedGasTxs = callInputBlock.Calls.Where(details => !details.HadGasLimitInRequest).ToList(); @@ -175,10 +117,10 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction } } - Transaction[] transactions = callInputBlock.Calls?.Select(t => SetTxHashAndMissingDefaults(t, spec)).ToArray() ?? Array.Empty(); + IEnumerable transactions = callInputBlock.Calls?.Select(t => CreateTransaction(t, callHeader, env, nonceCache, payload.Validation)) + ?? Array.Empty(); - - Block? currentBlock = new(callHeader, transactions, Array.Empty()); + Block currentBlock = new Block(callHeader, transactions, Array.Empty()); currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); ProcessingOptions processingFlags = _simulateProcessingOptions; @@ -192,7 +134,7 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction suggestedBlocks.Add(currentBlock); stateProvider.RecalculateStateRoot(); - Block[]? currentBlocks = null; + Block[] currentBlocks; //try { IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!); @@ -203,7 +145,7 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction // return (false, $"invalid on block {callHeader.Number}"); //} - Block? processedBlock = currentBlocks[0]; + Block processedBlock = currentBlocks[0]; parent = processedBlock.Header; if (processedBlock is not null) { @@ -215,4 +157,73 @@ Transaction SetTxHashAndMissingDefaults(TransactionWithSourceDetails transaction return (true, ""); } + + private Transaction CreateTransaction( + TransactionWithSourceDetails transactionDetails, + BlockHeader callHeader, + SimulateReadOnlyBlocksProcessingEnv env, + Dictionary nonceCache, + bool validate) + { + Transaction? transaction = transactionDetails.Transaction; + transaction.SenderAddress ??= Address.Zero; + transaction.To ??= Address.Zero; + transaction.Data ??= Memory.Empty; + + if (!transactionDetails.HadNonceInRequest) + { + if (!nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) + { + cachedNonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; + nonceCache[transaction.SenderAddress] = cachedNonce; + } + else + { + cachedNonce++; + nonceCache[transaction.SenderAddress] = cachedNonce; + } + + transaction.Nonce = cachedNonce; + } + + if (validate) + { + if (transaction.GasPrice == 0) + { + transaction.GasPrice = callHeader.BaseFeePerGas; + } + + if (transaction.Type == TxType.EIP1559 && transaction.DecodedMaxFeePerGas == 0) + { + transaction.DecodedMaxFeePerGas = transaction.GasPrice == 0 + ? callHeader.BaseFeePerGas + 1 + : transaction.GasPrice; + //UInt256.MultiplyOverflow((UInt256)transaction.GasLimit, transaction.MaxFeePerGas, out UInt256 maxGasFee); + //string err = $"insufficient sender balance for MaxFeePerGas: {callHeader.Number}, {transaction.SenderAddress} balance should be at least {maxGasFee + 1 + transaction.Value }"; + } + } + + transaction.Hash ??= transaction.CalculateHash(); + + return transaction; + } + + private BlockHeader GetCallHeader(BlockStateCall block, BlockHeader parent) => + block.BlockOverrides is not null + ? block.BlockOverrides.GetBlockHeader(parent, blocksConfig) + : new BlockHeader( + parent.Hash!, + Keccak.OfAnEmptySequenceRlp, + Address.Zero, + UInt256.Zero, + parent.Number + 1, + parent.GasLimit, + + parent.Timestamp + 1, + Array.Empty()) + { + BaseFeePerGas = BaseFeeCalculator.Calculate(parent, specProvider.GetSpec(parent)), + MixHash = parent.MixHash, + IsPostMerge = parent.Difficulty == 0 + }; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 2c9204c068a..e7bdc54a32a 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -3,77 +3,24 @@ using System; using Nethermind.Blockchain; -using Nethermind.Blockchain.Blocks; -using Nethermind.Blockchain.Headers; using Nethermind.Blockchain.Receipts; -using Nethermind.Blockchain.Synchronization; using Nethermind.Consensus.Processing; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Db; -using Nethermind.Db.Blooms; using Nethermind.Evm; using Nethermind.Evm.TransactionProcessing; using Nethermind.Logging; using Nethermind.State; -using Nethermind.State.Repositories; -using Nethermind.Trie.Pruning; namespace Nethermind.Facade.Simulate; -public class SimulateReadOnlyBlocksProcessingEnvFactory( - IWorldStateManager worldStateManager, - IReadOnlyBlockTree baseBlockTree, - IDbProvider dbProvider, - ISpecProvider specProvider, - ILogManager? logManager = null) -{ - public SimulateReadOnlyBlocksProcessingEnv Create(bool traceTransfers, bool validate) - { - IReadOnlyDbProvider editableDbProvider = new ReadOnlyDbProvider(dbProvider, true); - OverlayTrieStore overlayTrieStore = new(editableDbProvider.StateDb, worldStateManager.TrieStore, logManager); - OverlayWorldStateManager overlayWorldStateManager = new(editableDbProvider, overlayTrieStore, logManager); - BlockTree tempBlockTree = CreateTempBlockTree(editableDbProvider, specProvider, logManager, editableDbProvider); - - return new SimulateReadOnlyBlocksProcessingEnv( - traceTransfers, - overlayWorldStateManager, - baseBlockTree, - editableDbProvider, - tempBlockTree, - specProvider, - logManager, - validate); - } - - private static BlockTree CreateTempBlockTree(IReadOnlyDbProvider readOnlyDbProvider, ISpecProvider? specProvider, ILogManager? logManager, IReadOnlyDbProvider editableDbProvider) - { - IBlockStore blockStore = new BlockStore(editableDbProvider.BlocksDb); - IHeaderStore headerStore = new HeaderStore(editableDbProvider.HeadersDb, editableDbProvider.BlockNumbersDb); - const int badBlocksStored = 1; - IBlockStore badBlockStore = new BlockStore(editableDbProvider.BadBlocksDb, badBlocksStored); - - return new(blockStore, - headerStore, - editableDbProvider.BlockInfosDb, - editableDbProvider.MetadataDb, - badBlockStore, - new ChainLevelInfoRepository(readOnlyDbProvider.BlockInfosDb), - specProvider, - NullBloomStorage.Instance, - new SyncConfig(), - logManager); - } -} - - public class SimulateReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IDisposable { private readonly ILogManager? _logManager; private readonly IBlockValidator _blockValidator; - private readonly bool _doValidation = false; private readonly TransactionProcessor _transactionProcessor; public ISpecProvider SpecProvider { get; } public IWorldStateManager WorldStateManager { get; } @@ -98,21 +45,14 @@ public SimulateReadOnlyBlocksProcessingEnv( WorldStateManager = worldStateManager; _logManager = logManager; SpecProvider = specProvider; - _doValidation = doValidation; BlockTree = new BlockTreeOverlay(ReadOnlyBlockTree, blockTree); BlockhashProvider = new SimulateBlockhashProvider(new BlockhashProvider(BlockTree, logManager), BlockTree); - - //var store = new TrieStore(DbProvider.StateDb, LimboLogs.Instance); - //StateProvider = new WorldState(store, DbProvider.CodeDb, LimboLogs.Instance); StateProvider = WorldStateManager.GlobalWorldState; StateReader = WorldStateManager.GlobalStateReader; - CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); - VirtualMachine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); - _transactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !_doValidation); - + _transactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !doValidation); _blockValidator = CreateValidator(); } @@ -150,7 +90,6 @@ public IBlockProcessor GetProcessor(Hash256 stateRoot) public void Dispose() { - //_trieStore.Dispose(); DbProvider.Dispose(); } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs new file mode 100644 index 00000000000..9aefb1675fc --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Blockchain; +using Nethermind.Blockchain.Blocks; +using Nethermind.Blockchain.Headers; +using Nethermind.Blockchain.Synchronization; +using Nethermind.Core.Specs; +using Nethermind.Db; +using Nethermind.Db.Blooms; +using Nethermind.Logging; +using Nethermind.State; +using Nethermind.State.Repositories; +using Nethermind.Trie.Pruning; + +namespace Nethermind.Facade.Simulate; + +public class SimulateReadOnlyBlocksProcessingEnvFactory( + IWorldStateManager worldStateManager, + IReadOnlyBlockTree baseBlockTree, + IDbProvider dbProvider, + ISpecProvider specProvider, + ILogManager? logManager = null) +{ + public SimulateReadOnlyBlocksProcessingEnv Create(bool traceTransfers, bool validate) + { + IReadOnlyDbProvider editableDbProvider = new ReadOnlyDbProvider(dbProvider, true); + OverlayTrieStore overlayTrieStore = new(editableDbProvider.StateDb, worldStateManager.TrieStore, logManager); + OverlayWorldStateManager overlayWorldStateManager = new(editableDbProvider, overlayTrieStore, logManager); + BlockTree tempBlockTree = CreateTempBlockTree(editableDbProvider, specProvider, logManager, editableDbProvider); + + return new SimulateReadOnlyBlocksProcessingEnv( + traceTransfers, + overlayWorldStateManager, + baseBlockTree, + editableDbProvider, + tempBlockTree, + specProvider, + logManager, + validate); + } + + private static BlockTree CreateTempBlockTree(IReadOnlyDbProvider readOnlyDbProvider, ISpecProvider? specProvider, ILogManager? logManager, IReadOnlyDbProvider editableDbProvider) + { + IBlockStore blockStore = new BlockStore(editableDbProvider.BlocksDb); + IHeaderStore headerStore = new HeaderStore(editableDbProvider.HeadersDb, editableDbProvider.BlockNumbersDb); + const int badBlocksStored = 1; + IBlockStore badBlockStore = new BlockStore(editableDbProvider.BadBlocksDb, badBlocksStored); + + return new(blockStore, + headerStore, + editableDbProvider.BlockInfosDb, + editableDbProvider.MetadataDb, + badBlockStore, + new ChainLevelInfoRepository(readOnlyDbProvider.BlockInfosDb), + specProvider, + NullBloomStorage.Instance, + new SyncConfig(), + logManager); + } +} diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs index 5e6ee5eadf6..080eb974c95 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs @@ -16,7 +16,7 @@ namespace Nethermind.Facade.Simulate; internal sealed class SimulateTxTracer : TxTracer, ILogsTxTracer { - private static readonly Hash256[] _topics = { Keccak.Zero }; + private static readonly Hash256[] _topics = [Keccak.Zero]; public SimulateTxTracer(bool isTracingTransfers) { @@ -39,7 +39,7 @@ public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] outp Address = entry.LoggersAddress, Topics = entry.Topics, LogIndex = (ulong)i - }).ToArray() + }) }; } @@ -63,7 +63,7 @@ public override void MarkAsFailed(Address recipient, long gasSpent, byte[] outpu IEnumerable ILogsTxTracer.ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall) { base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); - byte[]? data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, + byte[] data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256), from, to, value); yield return new LogEntry(Address.Zero, data, _topics); } diff --git a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs index a513059f82c..cf0a623a970 100644 --- a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs +++ b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs @@ -17,14 +17,6 @@ namespace Nethermind.Facade; public static class StateOverridesExtensions { - - public static void ApplyStateOverrides( - this IWorldState state, - - long blockNumber) - { - } - public static void ApplyStateOverrides( this IWorldState state, OverridableCodeInfoRepository overridableCodeInfoRepository, @@ -34,11 +26,8 @@ public static void ApplyStateOverrides( { if (overrides is not null) { - foreach (KeyValuePair overrideData in overrides) + foreach ((Address address, AccountOverride accountOverride) in overrides) { - Address address = overrideData.Key; - AccountOverride? accountOverride = overrideData.Value; - if (!state.TryGetAccount(address, out AccountStruct account)) { state.CreateAccount(address, accountOverride.Balance ?? UInt256.Zero, accountOverride.Nonce ?? UInt256.Zero); @@ -77,9 +66,9 @@ private static void UpdateState(this IWorldState stateProvider, AccountOverride { void ApplyState(Dictionary diff) { - foreach (KeyValuePair storage in diff) + foreach ((UInt256 index, Hash256 value) in diff) { - stateProvider.Set(new StorageCell(address, storage.Key), storage.Value.Bytes.WithoutLeadingZeros().ToArray()); + stateProvider.Set(new StorageCell(address, index), value.Bytes.WithoutLeadingZeros().ToArray()); } } @@ -118,9 +107,9 @@ private static void UpdateNonce( AccountOverride accountOverride, Address address) { - UInt256 nonce = account.Nonce; if (accountOverride.Nonce is not null) { + UInt256 nonce = account.Nonce; UInt256 newNonce = accountOverride.Nonce.Value; if (nonce > newNonce) { diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs index bebae0411c1..dcb426ed932 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs @@ -160,7 +160,8 @@ protected virtual ITransactionProcessor CreateTransactionProcessor() { if (_api.SpecProvider is null) throw new StepDependencyException(nameof(_api.SpecProvider)); - (VirtualMachine virtualMachine, CodeInfoRepository codeInfoRepository) = CreateVirtualMachine(); + CodeInfoRepository codeInfoRepository = new(); + VirtualMachine virtualMachine = CreateVirtualMachine(codeInfoRepository); TransactionProcessor transactionProcessor = new( _api.SpecProvider, @@ -172,16 +173,12 @@ protected virtual ITransactionProcessor CreateTransactionProcessor() return transactionProcessor; } - protected virtual (VirtualMachine, CodeInfoRepository) CreateVirtualMachine() + protected VirtualMachine CreateVirtualMachine(CodeInfoRepository codeInfoRepository) { if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); if (_api.SpecProvider is null) throw new StepDependencyException(nameof(_api.SpecProvider)); - // blockchain processing - BlockhashProvider blockhashProvider = new( - _api.BlockTree, _api.LogManager); - - CodeInfoRepository codeInfoRepository = new(); + BlockhashProvider blockhashProvider = new(_api.BlockTree, _api.LogManager); VirtualMachine virtualMachine = new( blockhashProvider, @@ -189,7 +186,7 @@ protected virtual (VirtualMachine, CodeInfoRepository) CreateVirtualMachine() codeInfoRepository, _api.LogManager); - return (virtualMachine, codeInfoRepository); + return virtualMachine; } protected virtual IHealthHintService CreateHealthHintService() => diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index d2cf839dad9..c0ddb56057d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -84,18 +84,12 @@ public void Eth_module_populates_size_when_returning_block_data() [Test] public void CanRunEthSimulateV1Empty() { - SimulatePayload? payload = new() { BlockStateCalls = Array.Empty>() }; - - EthereumJsonSerializer serializer = new(); - - string serializedCall = serializer.Serialize(payload); - + SimulatePayload payload = new() { BlockStateCalls = Array.Empty>() }; + string serializedCall = new EthereumJsonSerializer().Serialize(payload); IEthRpcModule ethRpcModule = Substitute.For(); - ethRpcModule.eth_simulateV1(payload).ReturnsForAnyArgs(x => + ethRpcModule.eth_simulateV1(payload).ReturnsForAnyArgs(_ => ResultWrapper>.Success(Array.Empty())); - JsonRpcSuccessResponse? response = - TestRequest(ethRpcModule, "eth_simulateV1", serializedCall) as JsonRpcSuccessResponse; - Assert.IsTrue(response != null); + JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_simulateV1", serializedCall) as JsonRpcSuccessResponse; Assert.That(response?.Result, Is.EqualTo(Array.Empty())); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs index b7cad174bd3..a303132ab20 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs @@ -8,6 +8,7 @@ using Nethermind.Abi; using Nethermind.Blockchain.Contracts.Json; using Nethermind.Blockchain.Find; +using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; @@ -24,6 +25,7 @@ using Nethermind.Specs.Forks; using Nethermind.TxPool; using Nethermind.Wallet; +using Org.BouncyCastle.Asn1.X509; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -38,7 +40,6 @@ public static Task CreateChain(IReleaseSpec? releaseSpec = nu return TestRpcBlockchain.ForTest(testMevRpcBlockchain).Build(testSpecProvider, null, true); } - private static string GetEcRecoverContractJsonAbi(string name = "recover") { return $@" @@ -84,23 +85,16 @@ private static string GetEcRecoverContractJsonAbi(string name = "recover") public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, string name = "recover") { - // Step 1: Take an account - // Step 2: Hash the message + // Step 1: Hash the message Hash256 messageHash = Keccak.Compute("Hello, world!"); - // Step 3: Sign the hash + // Step 2: Sign the hash Signature signature = chain.EthereumEcdsa.Sign(account, messageHash); - ulong v = signature.V; - byte[] r = signature.R; - byte[] s = signature.S; - //Check real address - - byte[] transactionData = GenerateTransactionDataForEcRecover(messageHash, v, r, s, name); - return transactionData; + return GenerateTransactionDataForEcRecover(messageHash, signature, name); } - public static async Task DeployEcRecoverContract(TestRpcBlockchain chain1, PrivateKey fromPrivateKey, string contractBytecode) + public static async Task
DeployEcRecoverContract(TestRpcBlockchain chain, PrivateKey privateKey, string contractBytecode) { byte[] bytecode = Bytes.FromHexString(contractBytecode); Transaction tx = new() @@ -109,96 +103,53 @@ public static byte[] GetTxData(TestRpcBlockchain chain, PrivateKey account, stri Nonce = 0, Data = bytecode, GasLimit = 3_000_000, - SenderAddress = fromPrivateKey.Address, + SenderAddress = privateKey.Address, To = null, GasPrice = 20.GWei() }; - // calculate contract address - - ILogManager logManager = SimpleConsoleLogManager.Instance; - IKeyStoreConfig config = new KeyStoreConfig(); - config.KeyStoreDirectory = TempPath.GetTempDirectory().Path; - ISymmetricEncrypter encrypter = new AesEncrypter(config, LimboLogs.Instance); - - IWallet? wallet = new DevKeyStoreWallet( - new FileKeyStore(config, - new EthereumJsonSerializer(), encrypter, new CryptoRandom(), - LimboLogs.Instance, new PrivateKeyStoreIOSettingsProvider(config)), - LimboLogs.Instance); - - ITxSigner txSigner = new WalletTxSigner(wallet, chain1.SpecProvider.ChainId); - TxSealer txSealer = new(txSigner, chain1.Timestamper); - TxPoolSender txSender = new(chain1.TxPool, txSealer, chain1.NonceManager, chain1.EthereumEcdsa); - - //Tested Alternative, often faster - //chain1.EthereumEcdsa.Sign(TestItem.PrivateKeyB, tx, true); - //tx.Hash = tx.CalculateHash(); - //wait chain1.AddBlock(true, tx); - //TxReceipt? createContractTxReceipt2 = chain1.Bridge.GetReceipt(tx.Hash); - //createContractTxReceipt2.ContractAddress - // .Should().NotBeNull($"Contract transaction {tx.Hash} was not deployed."); - - using SecureStringWrapper pass = new("testB"); - wallet.Import(fromPrivateKey.KeyBytes, pass.SecureData); - wallet.UnlockAccount(fromPrivateKey.Address, pass.SecureData, TimeSpan.MaxValue); - (Hash256 hash, AcceptTxResult? code) = await txSender.SendTransaction(tx, - TxHandlingOptions.ManagedNonce | TxHandlingOptions.PersistentBroadcast); - code?.Should().Be(AcceptTxResult.Accepted); - Transaction[] txs = chain1.TxPool.GetPendingTransactions(); + TxPoolSender txSender = new(chain.TxPool, + new TxSealer(new Signer(chain.SpecProvider.ChainId, privateKey, LimboLogs.Instance), chain.Timestamper), + chain.NonceManager, + chain.EthereumEcdsa); - await chain1.AddBlock(true, txs); + (Hash256 hash, AcceptTxResult? code) = await txSender.SendTransaction(tx, TxHandlingOptions.ManagedNonce | TxHandlingOptions.PersistentBroadcast); + + code?.Should().Be(AcceptTxResult.Accepted); + Transaction[] txs = chain.TxPool.GetPendingTransactions(); + await chain.AddBlock(true, txs); TxReceipt? createContractTxReceipt = null; - while (createContractTxReceipt == null) + while (createContractTxReceipt is null) { - await Task.Delay(100); // wait... todo enforce! - createContractTxReceipt = chain1.Bridge.GetReceipt(tx.Hash!); + await Task.Delay(100); + createContractTxReceipt = chain.Bridge.GetReceipt(hash); } - createContractTxReceipt.ContractAddress.Should() - .NotBeNull($"Contract transaction {tx.Hash!} was not deployed."); - Address? contractAddress1 = createContractTxReceipt.ContractAddress; - - return contractAddress1; + createContractTxReceipt.ContractAddress.Should().NotBeNull($"Contract transaction {tx.Hash!} was not deployed."); + return createContractTxReceipt.ContractAddress!; } - public static byte[] GenerateTransactionDataForEcRecover(Hash256 keccak, ulong @ulong, byte[] bytes1, byte[] bytes2, - string name = "recover") + protected static byte[] GenerateTransactionDataForEcRecover(Hash256 keccak, Signature signature, string name = "recover") { - AbiDefinitionParser parser = new(); - AbiDefinition call = parser.Parse(GetEcRecoverContractJsonAbi(name)); + AbiDefinition call = new AbiDefinitionParser().Parse(GetEcRecoverContractJsonAbi(name)); AbiEncodingInfo functionInfo = call.GetFunction(name).GetCallInfo(); - byte[] transactionData1 = AbiEncoder.Instance.Encode(functionInfo.EncodingStyle, - functionInfo.Signature, - keccak, @ulong, bytes1, bytes2); - return transactionData1; + return AbiEncoder.Instance.Encode(functionInfo.EncodingStyle, functionInfo.Signature, keccak, signature.V, signature.R, signature.S); } - private static Address? GetTransactionResultFromEcRecover(byte[] data, string name = "recover") + private static Address? ParseEcRecoverAddress(byte[] data, string name = "recover") { - AbiDefinitionParser parser = new(); - AbiDefinition call = parser.Parse(GetEcRecoverContractJsonAbi(name)); - AbiEncodingInfo functionInfo = call.GetFunction("recover").GetReturnInfo(); - Address? transactionData1 = AbiEncoder.Instance.Decode(functionInfo.EncodingStyle, - functionInfo.Signature, data).FirstOrDefault() as Address; - return transactionData1; + AbiDefinition call = new AbiDefinitionParser().Parse(GetEcRecoverContractJsonAbi(name)); + AbiEncodingInfo functionInfo = call.GetFunction(name).GetReturnInfo(); + return AbiEncoder.Instance.Decode(functionInfo.EncodingStyle, functionInfo.Signature, data).FirstOrDefault() as Address; } - public static Address? MainChainTransaction(byte[] bytes, Address? toAddress, TestRpcBlockchain testRpcBlockchain, - Address senderAddress) + public static Address? EcRecoverCall(TestRpcBlockchain testRpcBlockchain, Address senderAddress, byte[] bytes, Address? toAddress = null) { SystemTransaction transaction = new() { Data = bytes, To = toAddress, SenderAddress = senderAddress }; transaction.Hash = transaction.CalculateHash(); TransactionForRpc transactionForRpc = new(transaction); - ResultWrapper mainChainResult = - testRpcBlockchain.EthRpcModule.eth_call(transactionForRpc, BlockParameter.Pending); - - //byte[] mainChainResultBytes = - // Bytes.FromHexString(mainChainResult.Data).SliceWithZeroPaddingEmptyOnError(12, 20); - Address? mainChainRpcAddress = - GetTransactionResultFromEcRecover(Bytes.FromHexString(mainChainResult.Data)); //new(mainChainResultBytes); - return mainChainRpcAddress; + ResultWrapper mainChainResult = testRpcBlockchain.EthRpcModule.eth_call(transactionForRpc, BlockParameter.Pending); + return ParseEcRecoverAddress(Bytes.FromHexString(mainChainResult.Data)); } - } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs index 440205139d7..4da303b977e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Nethermind.Blockchain.Find; using Nethermind.Core; +using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; using Nethermind.Evm; @@ -22,22 +23,6 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; public class EthSimulateTestsPrecompilesWithRedirection { - public static byte[] HexStringToByteArray(string hex) - { - if (hex.StartsWith("0x")) - { - hex = hex.Substring(2); - } - - int NumberChars = hex.Length; - byte[] bytes = new byte[NumberChars / 2]; - for (int i = 0; i < NumberChars; i += 2) - { - bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); - } - return bytes; - } - [Test] public async Task Test_eth_simulate_create() { @@ -45,9 +30,9 @@ public async Task Test_eth_simulate_create() Transaction systemTransactionForModifiedVm = new() { - SenderAddress = new Address("0xc000000000000000000000000000000000000000"), - Data = HexStringToByteArray("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), - To = new Address("0xc200000000000000000000000000000000000000"), + SenderAddress = TestItem.AddressB, + Data = Bytes.FromHexString("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), + To = TestItem.AddressA, GasLimit = 3_500_000, GasPrice = 20.GWei(), @@ -57,28 +42,23 @@ public async Task Test_eth_simulate_create() SimulatePayload payload = new() { - BlockStateCalls = new BlockStateCall[] - { + BlockStateCalls = + [ new() { StateOverrides = new Dictionary { { - new Address("0xc200000000000000000000000000000000000000"), + TestItem.AddressA, new AccountOverride { - Code = HexStringToByteArray("0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033") + Code = Bytes.FromHexString("0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033") } }, }, - Calls = new[] - { - transactionForRpc, - } + Calls = [transactionForRpc] } - }, - TraceTransfers = false, - Validation = false + ] }; //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not @@ -122,64 +102,63 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( } } */ - byte[] zeroByte = { 0 }; + byte[] code = Prepare.EvmCode .JUMPDEST() - .PushData(zeroByte) + .PushData(Bytes.ZeroByte) .Op(Instruction.DUP1) - .PushData(Bytes.FromHexString("0x0666")) // 666 + .PushData(TestItem.AddressB.Bytes) .Op(Instruction.SWAP1) .Op(Instruction.POP) .Op(Instruction.CALLDATASIZE) - .PushData(zeroByte) + .PushData(Bytes.ZeroByte) .Op(Instruction.DUP1) .Op(Instruction.CALLDATACOPY) - .PushData(zeroByte) + .PushData(Bytes.ZeroByte) .Op(Instruction.DUP1) .Op(Instruction.CALLDATASIZE) - .PushData(zeroByte) + .PushData(Bytes.ZeroByte) .Op(Instruction.DUP5) .Op(Instruction.GAS) .Op(Instruction.DELEGATECALL) .Op(Instruction.RETURNDATASIZE) - .PushData(zeroByte) + .PushData(Bytes.ZeroByte) .Op(Instruction.DUP1) .Op(Instruction.RETURNDATACOPY) .Op(Instruction.RETURNDATASIZE) - .PushData(zeroByte) + .PushData(Bytes.ZeroByte) .Op(Instruction.RETURN) .Done; byte[] transactionData = EthRpcSimulateTestsBase.GetTxData(chain, TestItem.PrivateKeyA); - var headHash = chain.BlockFinder.Head!.Hash!; - Address? contractAddress = await EthRpcSimulateTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, - EthSimulateTestsSimplePrecompiles.EcRecoverCallerContractBytecode); + Hash256 headHash = chain.BlockFinder.Head!.Hash!; + Address contractAddress = await EthRpcSimulateTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EthSimulateTestsSimplePrecompiles.EcRecoverCallerContractBytecode); - var tst = EthRpcSimulateTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + EthRpcSimulateTestsBase.EcRecoverCall(chain, TestItem.AddressB, transactionData, contractAddress); chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); - var headHashAfterPost = chain.BlockFinder.Head!.Hash!; - Assert.That(headHash != headHashAfterPost); + Assert.That(headHash != chain.BlockFinder.Head!.Hash!); chain.State.StateRoot = chain.BlockFinder.Head!.StateRoot!; - Transaction systemTransactionForModifiedVm = new() + TransactionForRpc transactionForRpc = new(new Transaction { Data = transactionData, To = contractAddress, SenderAddress = TestItem.AddressA, GasLimit = 3_500_000, GasPrice = 20.GWei() + }) + { + Nonce = null }; - TransactionForRpc transactionForRpc = new(systemTransactionForModifiedVm) { Nonce = null }; - SimulatePayload payload = new() { - BlockStateCalls = new BlockStateCall[] - { + BlockStateCalls = + [ new() { StateOverrides = new Dictionary @@ -189,30 +168,25 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( new AccountOverride { Code = code, - MovePrecompileToAddress = new Address("0x0000000000000000000000000000000000000666"), + MovePrecompileToAddress = TestItem.AddressB, } }, }, - Calls = new[] - { - transactionForRpc, - } + Calls = [transactionForRpc] } - }, - TraceTransfers = false, - Validation = false + ] }; //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - Debug.Assert(contractAddress != null, nameof(contractAddress) + " != null"); + Debug.Assert(contractAddress is not null, nameof(contractAddress) + " != null"); Assert.IsTrue(chain.State.AccountExists(contractAddress)); + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); //Check results - byte[]? returnData = result.Data[0].Calls.First().ReturnData; - byte[] addressBytes = returnData!.SliceWithZeroPaddingEmptyOnError(12, 20); + byte[] addressBytes = result.Data[0].Calls[0].ReturnData!.SliceWithZeroPaddingEmptyOnError(12, 20); Address resultingAddress = new(addressBytes); Assert.That(resultingAddress, Is.EqualTo(TestItem.AddressA)); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 2c7bba8f972..1e7133b9af7 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -46,67 +46,42 @@ public async Task Test_eth_simulate_serialisation() { TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - - PrivateKey pk = new("0xc7ba1a2892ec0ea1940eebeae739b1effe0543b3104469d5b66625f49ca86e94"); - - UInt256 nonceA = chain.State.GetNonce(pk.Address); - Transaction txMainnetAtoBtoFail = - GetTransferTxData(nonceA, - chain.EthereumEcdsa, pk, new Address("0xA143c0eA6f8059f7B3651417ccD2bAA80FC2d4Ab"), 10_000_000); - + UInt256 nonceA = chain.State.GetNonce(TestItem.AddressA); + Transaction txToFail = GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 10_000_000); UInt256 nextNonceA = ++nonceA; - Transaction txMainnetAtoBToComplete = - GetTransferTxData(nextNonceA, - chain.EthereumEcdsa, pk, new Address("0xA143c0eA6f8059f7B3651417ccD2bAA80FC2d4Ab"), 4_000_000); + Transaction tx = GetTransferTxData(nextNonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 4_000_000); SimulatePayload payload = new() { - BlockStateCalls = new BlockStateCall[] - { + BlockStateCalls = + [ new() { - BlockOverrides = new BlockOverride() { Number = 18000000 }, - Calls = new[] + BlockOverrides = new BlockOverride { Number = 18000000 }, + Calls = [new TransactionForRpc(txToFail), new TransactionForRpc(tx)], + StateOverrides = new Dictionary { - new TransactionForRpc(txMainnetAtoBtoFail), - new TransactionForRpc(txMainnetAtoBToComplete), - }, - StateOverrides = new Dictionary() - { - { - pk.Address, - new AccountOverride() - { - Balance = Math.Max(420_000_004_000_001UL, 1_000_000_004_000_001UL) - } - } + { TestItem.AddressA, new AccountOverride { Balance = Math.Max(420_000_004_000_001UL, 1_000_000_004_000_001UL) } } } } - }, + ], TraceTransfers = true, Validation = true }; - EthereumJsonSerializer serializer = new(); - - string serializedCall = serializer.Serialize(payload); - Console.WriteLine(serializedCall); - - //Force persistancy of head block in main chain + //Force persistence of head block in main chain chain.BlockTree.UpdateMainChain(new List { chain.BlockFinder.Head! }, true, true); chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); - //Assert.Equals(chain.BlockTree.BestPersistedState!, chain.BlockTree.Head!.Number); + //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); - ResultWrapper> result = - executor.Execute(payload, BlockParameter.Latest); + ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; - Assert.That(data.Count, Is.EqualTo(1)); foreach (SimulateBlockResult blockResult in data) { - blockResult.Calls.Select(c => c.Type).Should().BeEquivalentTo(new[] { ResultType.Success, ResultType.Success }); + blockResult.Calls.Select(c => c.Type).Should().BeEquivalentTo(new[] { (ulong)ResultType.Success, (ulong)ResultType.Success }); } } @@ -122,16 +97,11 @@ public async Task Test_eth_simulate_eth_moved() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); UInt256 nonceA = chain.State.GetNonce(TestItem.AddressA); - Transaction txMainnetAtoB = - GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); - Transaction txAtoB1 = - GetTransferTxData(nonceA + 1, chain.EthereumEcdsa, TestItem.PrivateKeyC, TestItem.AddressB, 1); - Transaction txAtoB2 = - GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); - Transaction txAtoB3 = - GetTransferTxData(nonceA + 3, chain.EthereumEcdsa, TestItem.PrivateKeyC, TestItem.AddressB, 1); - Transaction txAtoB4 = - GetTransferTxData(nonceA + 4, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); + Transaction txMainnetAtoB = GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); + Transaction txAtoB1 = GetTransferTxData(nonceA + 1, chain.EthereumEcdsa, TestItem.PrivateKeyC, TestItem.AddressB, 1); + Transaction txAtoB2 = GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); + Transaction txAtoB3 = GetTransferTxData(nonceA + 3, chain.EthereumEcdsa, TestItem.PrivateKeyC, TestItem.AddressB, 1); + Transaction txAtoB4 = GetTransferTxData(nonceA + 4, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); SimulatePayload payload = new() { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs index 5cce1fe913e..3386db3c88f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs @@ -20,21 +20,23 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; -public class EthSimulateTestsSimplePrecompiles +public class EthSimulateTestsSimplePrecompiles : EthRpcSimulateTestsBase { + /* Compiled contract -* Call example for TestItem.AddressA -* recover 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 28 0x7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c4403 0x7e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055 -* returns address: 0xb7705aE4c6F81B66cdB323C65f4E8133690fC099 + * Call example for TestItem.AddressA + * recover 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 28 0x7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c4403 0x7e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055 + * returns address: 0xb7705aE4c6F81B66cdB323C65f4E8133690fC099 -pragma solidity ^0.8.7; + pragma solidity ^0.8.7; -contract EcrecoverProxy { - function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure returns (address) { - return ecrecover(hash, v, r, s); + contract EcrecoverProxy { + function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure returns (address) { + return ecrecover(hash, v, r, s); + } } -} -*/ + */ + //Taken from contract compiler output metadata public const string EcRecoverCallerContractBytecode = "608060405234801561001057600080fd5b5061028b806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c2bf17b014610030575b600080fd5b61004a6004803603810190610045919061012f565b610060565b60405161005791906101d7565b60405180910390f35b6000600185858585604051600081526020016040526040516100859493929190610210565b6020604051602081039080840390855afa1580156100a7573d6000803e3d6000fd5b505050602060405103519050949350505050565b600080fd5b6000819050919050565b6100d3816100c0565b81146100de57600080fd5b50565b6000813590506100f0816100ca565b92915050565b600060ff82169050919050565b61010c816100f6565b811461011757600080fd5b50565b60008135905061012981610103565b92915050565b60008060008060808587031215610149576101486100bb565b5b6000610157878288016100e1565b94505060206101688782880161011a565b9350506040610179878288016100e1565b925050606061018a878288016100e1565b91505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101c182610196565b9050919050565b6101d1816101b6565b82525050565b60006020820190506101ec60008301846101c8565b92915050565b6101fb816100c0565b82525050565b61020a816100f6565b82525050565b600060808201905061022560008301876101f2565b6102326020830186610201565b61023f60408301856101f2565b61024c60608301846101f2565b9594505050505056fea26469706673582212204855668ab62273dde1249722b61c57ad057ef3d17384f21233e1b7bb309db7e464736f6c63430008120033"; @@ -46,11 +48,9 @@ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure return [Test] public async Task Test_eth_simulate_erc() { + TestRpcBlockchain chain = await CreateChain(); - // Arrange - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - - //Empose Opcode instead of EcRecoverPrecompile, it returns const TestItem.AddressE address + //Impose Opcode instead of EcRecoverPrecompile, it returns const TestItem.AddressE address byte[] code = Prepare.EvmCode .StoreDataInMemory(0, TestItem.AddressE .ToString(false, false) @@ -59,69 +59,53 @@ public async Task Test_eth_simulate_erc() .PushData(Bytes.FromHexString("0x0")) .Op(Instruction.RETURN).Done; - // Step 1: Take an account - Address account = TestItem.AddressA; - // Step 2: Hash the message + // Step 1: Hash the message Hash256 messageHash = Keccak.Compute("Hello, world!"); - // Step 3: Sign the hash + // Step 2: Sign the hash Signature signature = chain.EthereumEcdsa.Sign(TestItem.PrivateKeyA, messageHash); - ulong v = signature.V; - byte[] r = signature.R; - byte[] s = signature.S; - - Address? contractAddress = - await EthRpcSimulateTestsBase.DeployEcRecoverContract(chain, TestItem.PrivateKeyB, - EcRecoverCallerContractBytecode); - - byte[] transactionData = EthRpcSimulateTestsBase.GenerateTransactionDataForEcRecover(messageHash, v, r, s); + Address contractAddress = await DeployEcRecoverContract(chain, TestItem.PrivateKeyB, EcRecoverCallerContractBytecode); + byte[] transactionData = GenerateTransactionDataForEcRecover(messageHash, signature); - SystemTransaction systemTransactionForModifiedVM = new() + SystemTransaction tx = new() { Data = transactionData, To = contractAddress, SenderAddress = TestItem.PublicKeyB.Address }; + tx.Hash = tx.CalculateHash(); - systemTransactionForModifiedVM.Hash = systemTransactionForModifiedVM.CalculateHash(); - TransactionWithSourceDetails systemTransactionForModifiedVMDetails = new() + TransactionWithSourceDetails txDetails = new() { - Transaction = systemTransactionForModifiedVM, + Transaction = tx, HadGasLimitInRequest = false, HadNonceInRequest = false }; + SimulatePayload payload = new() { - BlockStateCalls = new[] - { - new BlockStateCall() + BlockStateCalls = + [ + new BlockStateCall { - StateOverrides = new Dictionary() + StateOverrides = new Dictionary { { EcRecoverPrecompile.Address, new AccountOverride { Code = code } } }, - Calls = new[] { systemTransactionForModifiedVMDetails } + Calls = [txDetails] } - }, - TraceTransfers = true, - Validation = false + ], + TraceTransfers = true }; - // Act - SimulateOutput result = chain.Bridge.Simulate(chain.BlockFinder.Head?.Header!, payload, CancellationToken.None); - Log[]? logs = result.Items.First().Calls.First().Logs; - byte[] addressBytes = result.Items.First().Calls.First().ReturnData! - .SliceWithZeroPaddingEmptyOnError(12, 20); - //Address resultingAddress = new(addressBytes); - //Assert.That(resultingAddress, Is.EqualTo(TestItem.AddressE)); - //Check that initial VM is intact - Address? mainChainRpcAddress = - EthRpcSimulateTestsBase.MainChainTransaction(transactionData, contractAddress, chain, TestItem.AddressB); + byte[] addressBytes = result.Items[0].Calls[0].ReturnData!.SliceWithZeroPaddingEmptyOnError(12, 20); + Address resultingAddress = new(addressBytes); + Assert.That(resultingAddress, Is.EqualTo(TestItem.AddressE)); - Assert.NotNull(mainChainRpcAddress); + //Check that initial VM is intact + Address? mainChainRpcAddress = EcRecoverCall(chain, TestItem.AddressB, transactionData, contractAddress); Assert.That(mainChainRpcAddress, Is.EqualTo(TestItem.AddressA)); - } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index b82f702a15d..4cc8c718eba 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -61,14 +61,9 @@ public class TestRpcBlockchain : TestBlockchain public static Builder ForTest(T blockchain) where T : TestRpcBlockchain => new(blockchain); - public class Builder where T : TestRpcBlockchain + public class Builder(T blockchain) where T : TestRpcBlockchain { - private readonly TestRpcBlockchain _blockchain; - - public Builder(T blockchain) - { - _blockchain = blockchain; - } + private readonly TestRpcBlockchain _blockchain = blockchain; public Builder WithBlockchainBridge(IBlockchainBridge blockchainBridge) { @@ -148,7 +143,6 @@ protected override async Task Build( BlockFinder ??= BlockTree; GasPriceOracle ??= new GasPriceOracle(BlockFinder, SpecProvider, LogManager); - ITxSigner txSigner = new WalletTxSigner(TestWallet, specProvider.ChainId); TxSealer = new TxSealer(txSigner, Timestamper); TxSender ??= new TxPoolSender(TxPool, TxSealer, NonceManager, EthereumEcdsa ?? new EthereumEcdsa(specProvider.ChainId, LogManager)); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs index b7df19aaabe..8072a43d5ac 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs @@ -282,7 +282,7 @@ public TestBlockProcessorInterceptor(IBlockProcessor baseBlockProcessor, int del DelayMs = delayMs; } - public Block[] Process(Hash256 newBranchStateRoot, List suggestedBlocks, ProcessingOptions processingOptions, + public Block[] Process(Hash256 newBranchStateRoot, IReadOnlyList suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer) { if (DelayMs > 0) diff --git a/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs b/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs index 31ff17de456..1f81fd43f50 100644 --- a/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs +++ b/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs @@ -40,7 +40,8 @@ protected override ITransactionProcessor CreateTransactionProcessor() if (_api.SpecHelper is null) throw new StepDependencyException(nameof(_api.SpecHelper)); if (_api.L1CostHelper is null) throw new StepDependencyException(nameof(_api.L1CostHelper)); - (VirtualMachine virtualMachine, CodeInfoRepository codeInfoRepository) = CreateVirtualMachine(); + CodeInfoRepository codeInfoRepository = new(); + VirtualMachine virtualMachine = CreateVirtualMachine(codeInfoRepository); return new OptimismTransactionProcessor( _api.SpecProvider, From c7507db2fddaa73777ff1bfefd42e6be86dba69d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 25 Mar 2024 13:38:29 +0000 Subject: [PATCH 158/213] majour protocol fixes --- ...cessor.BlockProductionTransactionPicker.cs | 6 +- .../Nethermind.Facade/BlockchainBridge.cs | 4 +- .../Proxy/Models/Simulate/BlockOverride.cs | 5 +- .../Models/Simulate/SimulateBlockResult.cs | 5 ++ .../Simulate/SimulateBlockTracer.cs | 6 ++ .../Simulate/SimulateBridgeHelper.cs | 84 +++++++++++++++---- .../SimulateReadOnlyBlocksProcessingEnv.cs | 6 +- .../EthSimulateTestsBlocksAndTransactions.cs | 10 +-- .../Eth/Simulate/EthSimulateTestsHiveBase.cs | 19 ++--- .../Nethermind.JsonRpc/ErrorType.cs | 10 +++ .../SimulateTxExecutor.MultiCallTxExecutor.cs | 30 ++++--- 11 files changed, 140 insertions(+), 45 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs index 10aa4a3a9e2..e5c1c8d1543 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs @@ -16,10 +16,12 @@ public partial class BlockProcessor public class BlockProductionTransactionPicker : IBlockProductionTransactionPicker { protected readonly ISpecProvider _specProvider; + private readonly bool _ignoreEip3607; - public BlockProductionTransactionPicker(ISpecProvider specProvider) + public BlockProductionTransactionPicker(ISpecProvider specProvider, bool ignoreEip3607 = false) { _specProvider = specProvider; + _ignoreEip3607 = ignoreEip3607; } public event EventHandler? AddingTransaction; @@ -63,7 +65,7 @@ public virtual AddingTxEventArgs CanAddTransaction(Block block, Transaction curr return args.Set(TxAction.Skip, $"EIP-3860 - transaction size over max init code size"); } - if (stateProvider.IsInvalidContractSender(spec, currentTx.SenderAddress)) + if (!_ignoreEip3607 && stateProvider.IsInvalidContractSender(spec, currentTx.SenderAddress)) { return args.Set(TxAction.Skip, $"Sender is contract"); } diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 12b55798e4f..e76c5f7d053 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -155,10 +155,12 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can public SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, CancellationToken cancellationToken) { SimulateBlockTracer simulateOutputTracer = new(payload.TraceTransfers); + BlockReceiptsTracer tracer = new BlockReceiptsTracer(); + tracer.SetOtherTracer(simulateOutputTracer); SimulateOutput result = new(); try { - (bool success, string error) = _simulateBridgeHelper.TrySimulateTrace(header, payload, simulateOutputTracer.WithCancellation(cancellationToken)); + (bool success, string error) = _simulateBridgeHelper.TrySimulateTrace(header, payload, tracer.WithCancellation(cancellationToken)); if (!success) { result.Error = error; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs index cd4a3846727..7f833aaedfc 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs @@ -6,6 +6,7 @@ using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; using Nethermind.Int256; namespace Nethermind.Facade.Proxy.Models.Simulate; @@ -19,7 +20,7 @@ public class BlockOverride public Address? FeeRecipient { get; set; } public UInt256? BaseFeePerGas { get; set; } - public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) + public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg, IReleaseSpec spec) { ulong newTime = Time ?? checked(parent.Timestamp + cfg.SecondsPerSlot); @@ -49,7 +50,7 @@ public BlockHeader GetBlockHeader(BlockHeader parent, IBlocksConfig cfg) newTime, Array.Empty()) { - BaseFeePerGas = BaseFeePerGas ?? parent.BaseFeePerGas, + BaseFeePerGas = BaseFeePerGas ?? BaseFeeCalculator.Calculate(parent, spec), MixHash = PrevRandao, IsPostMerge = parent.Difficulty == 0, TotalDifficulty = parent.TotalDifficulty + newDifficulty, diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs index d01a42e8927..4eea0fd2cf2 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs @@ -21,5 +21,10 @@ public class SimulateBlockResult public UInt256 BaseFeePerGas { get; set; } public List Calls { get; set; } = new(); public byte[]? PrevRandao { get; set; } + public Withdrawal[] Withdrawals { get; set; } + + public ulong BlobGasUsed { get; set; } + public UInt256 ExcessBlobGas { get; set; } + public UInt256 BlobBaseFee { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 47a53c67f53..37ae55a56ca 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -1,10 +1,12 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Collections.Generic; using System.Linq; using Nethermind.Core; using Nethermind.Core.Collections; +using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.Simulate; using ResultType = Nethermind.Facade.Proxy.Models.Simulate.ResultType; @@ -50,6 +52,10 @@ public override void EndBlockTrace() FeeRecipient = _currentBlock.Beneficiary!, BaseFeePerGas = _currentBlock.BaseFeePerGas, PrevRandao = _currentBlock.Header!.Random?.BytesToArray(), + BlobGasUsed = _currentBlock.BlobGasUsed ?? 0, + ExcessBlobGas = _currentBlock.ExcessBlobGas ?? 0, + BlobBaseFee = new BlockExecutionContext(_currentBlock.Header).BlobBaseFee ?? 0, + Withdrawals = _currentBlock.Withdrawals ?? Array.Empty() }; result.Calls.ForEach(callResult => diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 43aa93a2191..08e9d8acbe1 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Nethermind.Blockchain; using Nethermind.Config; using Nethermind.Consensus.Processing; using Nethermind.Core; @@ -54,7 +55,7 @@ private void UpdateStateByModifyingAccounts( IWorldState state = env.StateProvider; state.Commit(currentSpec); - state.CommitTree(blockHeader.Number); + state.CommitTree(blockHeader.Number - 1); state.RecalculateStateRoot(); blockHeader.StateRoot = env.StateProvider.StateRoot; @@ -74,8 +75,6 @@ private void UpdateStateByModifyingAccounts( parent = latestBlock?.Header ?? env.BlockTree.Head!.Header; } - IWorldState stateProvider = env.StateProvider; - stateProvider.StateRoot = parent.StateRoot!; BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); @@ -86,10 +85,10 @@ private void UpdateStateByModifyingAccounts( if (searchResult is not null) { parent = searchResult.Header; - stateProvider.StateRoot = parent.StateRoot!; } } - + IWorldState stateProvider = env.StateProvider; + stateProvider.StateRoot = parent.StateRoot!; if (payload.BlockStateCalls is not null) { Dictionary nonceCache = new(); @@ -97,10 +96,14 @@ private void UpdateStateByModifyingAccounts( foreach (BlockStateCall callInputBlock in payload.BlockStateCalls) { + stateProvider.StateRoot = parent.StateRoot!; + + BlockHeader callHeader = GetCallHeader(callInputBlock, parent); UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); + callHeader.StateRoot = stateProvider.StateRoot!; - using IReadOnlyTransactionProcessor? readOnlyTransactionProcessor = env.Build(env.StateProvider.StateRoot!); + using IReadOnlyTransactionProcessor? readOnlyTransactionProcessor = env.Build(stateProvider.StateRoot!); IReleaseSpec spec = specProvider.GetSpec(parent); @@ -117,12 +120,41 @@ private void UpdateStateByModifyingAccounts( } } - IEnumerable transactions = callInputBlock.Calls?.Select(t => CreateTransaction(t, callHeader, env, nonceCache, payload.Validation)) + Transaction[] transactions = callInputBlock.Calls?.Select(t => CreateTransaction(t, callHeader, env, nonceCache, payload.Validation)).ToArray() ?? Array.Empty(); - Block currentBlock = new Block(callHeader, transactions, Array.Empty()); + nonceCache.Clear(); + + + + Block currentBlock = new Block(callHeader, Array.Empty(), Array.Empty()); currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); + var shoot = stateProvider.TakeSnapshot(); + var testedTxs = new HashSet(); + for (var index = 0; index < transactions.Length; index++) + { + Transaction transaction = transactions[index]; + BlockProcessor.AddingTxEventArgs? args = env.BlockTransactionPicker.CanAddTransaction(currentBlock, transaction, + testedTxs, + stateProvider); + stateProvider.IncrementNonce(transaction.SenderAddress); + if (args.Action is BlockProcessor.TxAction.Stop or BlockProcessor.TxAction.Skip) + { + return (false, $"invalid transaction index: {index} at block number: {callHeader.Number}, Reason: {args.Reason}"); + } + + + testedTxs.Add(transaction); + } + + stateProvider.Restore(shoot); + stateProvider.RecalculateStateRoot(); + + currentBlock = + currentBlock.WithReplacedBody(currentBlock.Body.WithChangedTransactions(testedTxs.ToArray())); + + ProcessingOptions processingFlags = _simulateProcessingOptions; if (!payload.Validation) @@ -133,12 +165,13 @@ private void UpdateStateByModifyingAccounts( suggestedBlocks.Clear(); suggestedBlocks.Add(currentBlock); - stateProvider.RecalculateStateRoot(); + Block[] currentBlocks; //try { IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!); currentBlocks = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer); + } //catch (Exception) //{ @@ -146,11 +179,19 @@ private void UpdateStateByModifyingAccounts( //} Block processedBlock = currentBlocks[0]; - parent = processedBlock.Header; + if (processedBlock is not null) { - //env.BlockTree.UpdateMainChain(new[] { currentBlock }, true, true); - env.BlockTree.UpdateHeadBlock(currentBlock.Hash!); + //var res = env.BlockTree.SuggestBlock(processedBlock, BlockTreeSuggestOptions.ForceSetAsMain); + //env.BlockTree.UpdateMainChain(new[] { processedBlock }, true, true); + //env. + ////env.BlockTree.UpdateHeadBlock(processedBlock.Hash!); + parent = processedBlock.Header; + stateProvider.StateRoot = processedBlock.StateRoot; + env.StateProvider.StateRoot = processedBlock.StateRoot; + //env.StateProvider.Commit(currentSpec); + //env.StateProvider.RecalculateStateRoot(); + //env.StateProvider.CommitTree(currentBlock.Number); } } } @@ -174,7 +215,22 @@ private Transaction CreateTransaction( { if (!nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) { - cachedNonce = env.StateProvider.GetAccount(transaction.SenderAddress).Nonce; + //try + //{ + env.StateProvider.CreateAccountIfNotExists(transaction.SenderAddress, 0, 0); + var test = env.StateProvider.GetAccount(transaction.SenderAddress); + cachedNonce = test.Nonce; + //} catch () + + //if (env.StateProvider.TryGetAccount(transaction.SenderAddress, out AccountStruct test)) + //{ + // cachedNonce = test.Nonce; + //} + //else + //{ + // cachedNonce = 0; // Todo think if we shall create account here + //} + nonceCache[transaction.SenderAddress] = cachedNonce; } else @@ -210,7 +266,7 @@ private Transaction CreateTransaction( private BlockHeader GetCallHeader(BlockStateCall block, BlockHeader parent) => block.BlockOverrides is not null - ? block.BlockOverrides.GetBlockHeader(parent, blocksConfig) + ? block.BlockOverrides.GetBlockHeader(parent, blocksConfig, specProvider.GetSpec(parent)) : new BlockHeader( parent.Hash!, Keccak.OfAnEmptySequenceRlp, diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index e7bdc54a32a..63d2dbf9106 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -14,6 +14,7 @@ using Nethermind.Evm.TransactionProcessing; using Nethermind.Logging; using Nethermind.State; +using static Nethermind.Consensus.Processing.BlockProcessor; namespace Nethermind.Facade.Simulate; @@ -28,6 +29,7 @@ public class SimulateReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, public IReadOnlyDbProvider DbProvider { get; } public IReadOnlyBlockTree ReadOnlyBlockTree { get; set; } public OverridableCodeInfoRepository CodeInfoRepository { get; } + public BlockProductionTransactionPicker BlockTransactionPicker { get; } public SimulateReadOnlyBlocksProcessingEnv( bool traceTransfers, @@ -54,6 +56,8 @@ public SimulateReadOnlyBlocksProcessingEnv( VirtualMachine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); _transactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !doValidation); _blockValidator = CreateValidator(); + BlockTransactionPicker = new BlockProductionTransactionPicker(specProvider, true); + } private SimulateBlockValidatorProxy CreateValidator() @@ -79,7 +83,7 @@ public IBlockProcessor GetProcessor(Hash256 stateRoot) return new BlockProcessor(SpecProvider, _blockValidator, NoBlockRewards.Instance, - new BlockProcessor.BlockValidationTransactionsExecutor(Build(stateRoot), StateProvider), + new BlockProcessor.BlockValidationTransactionsExecutor(_transactionProcessor, StateProvider), StateProvider, NullReceiptStorage.Instance, NullWitnessCollector.Instance, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 1e7133b9af7..3eb68667830 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -98,9 +98,9 @@ public async Task Test_eth_simulate_eth_moved() UInt256 nonceA = chain.State.GetNonce(TestItem.AddressA); Transaction txMainnetAtoB = GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); - Transaction txAtoB1 = GetTransferTxData(nonceA + 1, chain.EthereumEcdsa, TestItem.PrivateKeyC, TestItem.AddressB, 1); + Transaction txAtoB1 = GetTransferTxData(nonceA + 1, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); Transaction txAtoB2 = GetTransferTxData(nonceA + 2, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); - Transaction txAtoB3 = GetTransferTxData(nonceA + 3, chain.EthereumEcdsa, TestItem.PrivateKeyC, TestItem.AddressB, 1); + Transaction txAtoB3 = GetTransferTxData(nonceA + 3, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); Transaction txAtoB4 = GetTransferTxData(nonceA + 4, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); SimulatePayload payload = new() @@ -112,7 +112,7 @@ public async Task Test_eth_simulate_eth_moved() BlockOverrides = new BlockOverride { - Number = 2, + Number = (ulong)chain.BlockFinder.Head!.Number+2, GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 @@ -175,7 +175,7 @@ public async Task Test_eth_simulate_transactions_forced_fail() GetTransferTxData(nonceA, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); //shall be Ok Transaction txAtoB1 = - GetTransferTxData(nonceA + 1, chain.EthereumEcdsa, TestItem.PrivateKeyC, TestItem.AddressB, 1); + GetTransferTxData(nonceA + 1, chain.EthereumEcdsa, TestItem.PrivateKeyA, TestItem.AddressB, 1); //shall fail Transaction txAtoB2 = @@ -232,6 +232,6 @@ public async Task Test_eth_simulate_transactions_forced_fail() ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); - Assert.IsTrue(result.Data[1].Calls.First().Error?.Message.StartsWith("insufficient")); + Assert.IsTrue(result.Result!.Error!.Contains("higher than sender balance")); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs index e663dbb4cc1..1fef9cdcb81 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs @@ -40,22 +40,21 @@ public async Task TestsimulateAddMoreNonDefinedBlockStateCallsThanFit() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateAddMoreNonDefinedBlockStateCallsThanFit"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.Error!.Contains("number out of order")); } [Test] public async Task TestsimulateBasefeeTooLowWithValidation38012() { EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0x0\",\"maxPriorityFeePerGas\":\"0x0\"}]}],\"validation\":true}"; + string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0x0\",\"maxPriorityFeePerGas\":\"0x0\"}]}],\"validation\":true}"; var payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBasefeeTooLowWithValidation38012"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.That(result.Data.First().PrevRandao, Is.EqualTo(new Hash256("0x0000000000000000000000000000000000000000000000000000000000000000").BytesToArray())); - + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.Error!.Contains("Transaction cost (40000000) is higher than sender balance (2000)")); Assert.IsNotNull(result.Data); } @@ -82,8 +81,8 @@ public async Task TestsimulateBlockNumOrder38020() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockNumOrder38020"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.Error!.Contains("Block number out of order")); } [Test] @@ -121,8 +120,8 @@ public async Task TestsimulateBlockTimestampAutoIncrement() TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateBlockTimestampAutoIncrement"); var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); + Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); + Assert.That(result.Result.Error!.Contains("Block timestamp out of order")); } [Test] diff --git a/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs b/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs index 8ae4af13215..e43f55e95ca 100644 --- a/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs +++ b/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs @@ -91,5 +91,15 @@ public static class ErrorCodes /// Unsupported fork error /// public const int UnsupportedFork = -38005; + + /// + /// Invalid RPC simulate call block number out of order + /// + public const int InvalidInputBlocksOutOfOrder = -38020; + + /// + /// Invalid RPC simulate call containing too many blocks + /// + public const int InvalidInputTooManyBlocks = -38026; } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs index 16225091fca..aba56283e85 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs @@ -78,7 +78,7 @@ public override ResultWrapper> Execute( { if (call.BlockStateCalls!.Length > _rpcConfig.MaxSimulateBlocksCap) { - return ResultWrapper>.Fail($"This node is configured to support only {_rpcConfig.MaxSimulateBlocksCap} blocks", ErrorCodes.InvalidRequest); + return ResultWrapper>.Fail($"This node is configured to support only {_rpcConfig.MaxSimulateBlocksCap} blocks", ErrorCodes.InvalidInputTooManyBlocks); } SearchResult searchResult = _blockFinder.SearchForBlock(blockParameter); @@ -104,17 +104,14 @@ public override ResultWrapper> Execute( return ResultWrapper>.Fail($"Too many blocks provided, node is configured to simulate up to {blocksLimit} while {call.BlockStateCalls?.Length} were given", ErrorCodes.InvalidParams); } - if (call.BlockStateCalls != null) { long lastBlockNumber = -1; - foreach (var blockToSimulate in call.BlockStateCalls!) - { - var givenNumber = blockToSimulate.BlockOverrides?.Number; - if (givenNumber == null) + ulong lastBlockTime = 0; + + foreach (BlockStateCall? blockToSimulate in call.BlockStateCalls!) { - givenNumber = lastBlockNumber == -1 ? (ulong)header.Number : (ulong)lastBlockNumber + 1; - } + var givenNumber = blockToSimulate.BlockOverrides?.Number ?? (lastBlockNumber == -1 ? (ulong)header.Number : (ulong)lastBlockNumber + 1); if (givenNumber > long.MaxValue) { @@ -128,12 +125,25 @@ public override ResultWrapper> Execute( } else { - return ResultWrapper>.Fail($"Block number out of order {givenNumber}!", ErrorCodes.InvalidParams); + return ResultWrapper>.Fail($"Block number out of order {givenNumber}!", ErrorCodes.InvalidInputBlocksOutOfOrder); } + + var givenTime = blockToSimulate.BlockOverrides?.Time ?? (lastBlockTime == 0 ? header.Timestamp : lastBlockTime + 1); + + if (givenTime > lastBlockTime) + { + lastBlockTime = givenTime; } + else + { + return ResultWrapper>.Fail($"Block timestamp out of order {givenTime}!", ErrorCodes.InvalidInputBlocksOutOfOrder); + } + } + + } - using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout * 100); + using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); //TODO remove! SimulatePayload? toProcess = Prepare(call); return Execute(header.Clone(), toProcess, cancellationTokenSource.Token); } From 43738499526db2f92df6e64c050810ed3329358b Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 25 Mar 2024 13:40:23 +0000 Subject: [PATCH 159/213] minor fixes --- .../Nethermind.Facade/Simulate/SimulateBridgeHelper.cs | 10 +++++----- .../Simulate/EthSimulateTestsBlocksAndTransactions.cs | 2 +- .../Eth/SimulateTxExecutor.MultiCallTxExecutor.cs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 08e9d8acbe1..2c9d116236d 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -171,7 +171,7 @@ private void UpdateStateByModifyingAccounts( { IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!); currentBlocks = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer); - + } //catch (Exception) //{ @@ -179,7 +179,7 @@ private void UpdateStateByModifyingAccounts( //} Block processedBlock = currentBlocks[0]; - + if (processedBlock is not null) { //var res = env.BlockTree.SuggestBlock(processedBlock, BlockTreeSuggestOptions.ForceSetAsMain); @@ -217,9 +217,9 @@ private Transaction CreateTransaction( { //try //{ - env.StateProvider.CreateAccountIfNotExists(transaction.SenderAddress, 0, 0); - var test = env.StateProvider.GetAccount(transaction.SenderAddress); - cachedNonce = test.Nonce; + env.StateProvider.CreateAccountIfNotExists(transaction.SenderAddress, 0, 0); + var test = env.StateProvider.GetAccount(transaction.SenderAddress); + cachedNonce = test.Nonce; //} catch () //if (env.StateProvider.TryGetAccount(transaction.SenderAddress, out AccountStruct test)) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 3eb68667830..36b01b84fbe 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -36,7 +36,7 @@ private static Transaction GetTransferTxData(UInt256 nonce, IEthereumEcdsa ether GasPrice = 20.GWei() }; - ethereumEcdsa.Sign(TestItem.PrivateKeyB, tx); + ethereumEcdsa.Sign(from, tx); tx.Hash = tx.CalculateHash(); return tx; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs index aba56283e85..00dd3586b79 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs @@ -110,7 +110,7 @@ public override ResultWrapper> Execute( ulong lastBlockTime = 0; foreach (BlockStateCall? blockToSimulate in call.BlockStateCalls!) - { + { var givenNumber = blockToSimulate.BlockOverrides?.Number ?? (lastBlockNumber == -1 ? (ulong)header.Number : (ulong)lastBlockNumber + 1); if (givenNumber > long.MaxValue) @@ -133,7 +133,7 @@ public override ResultWrapper> Execute( if (givenTime > lastBlockTime) { lastBlockTime = givenTime; - } + } else { return ResultWrapper>.Fail($"Block timestamp out of order {givenTime}!", ErrorCodes.InvalidInputBlocksOutOfOrder); From 29ae661cbf7d97c39a18197b3b7afc1b51062b20 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 25 Mar 2024 13:53:24 +0000 Subject: [PATCH 160/213] post merge fixes --- .../Nethermind.Blockchain/BlockTreeOverlay.cs | 7 +++--- .../Validators/SimulateBlockValidatorProxy.cs | 24 +++++++++++++++---- .../Extensions/SpanExtensions.cs | 6 +++++ .../Nethermind.Evm/TransactionSubstate.cs | 2 ++ .../Simulate/SimulateBridgeHelper.cs | 23 +++++++----------- .../StateOverridesExtensions.cs | 14 ----------- .../EthSimulateTestsBlocksAndTransactions.cs | 8 +++---- .../Modules/TestRpcBlockchain.cs | 1 + 8 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs b/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs index 2d278d42ff1..d58629e367e 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Nethermind.Blockchain.Visitors; using Nethermind.Core; +using Nethermind.Core.Collections; using Nethermind.Core.Crypto; namespace Nethermind.Blockchain; @@ -102,10 +103,10 @@ public void UpdateMainChain(IReadOnlyList blocks, bool wereProcessed, boo public Hash256 FindHash(long blockNumber) => _overlayTree.FindHash(blockNumber) ?? _baseTree.FindHash(blockNumber); - public BlockHeader[] FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) + public IOwnedReadOnlyList FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) { - BlockHeader[] overlayHeaders = _overlayTree.FindHeaders(hash, numberOfBlocks, skip, reverse); - return overlayHeaders.Length > 0 ? overlayHeaders : _baseTree.FindHeaders(hash, numberOfBlocks, skip, reverse); + IOwnedReadOnlyList overlayHeaders = _overlayTree.FindHeaders(hash, numberOfBlocks, skip, reverse); + return overlayHeaders.Count > 0 ? overlayHeaders : _baseTree.FindHeaders(hash, numberOfBlocks, skip, reverse); } public BlockHeader FindLowestCommonAncestor(BlockHeader firstDescendant, BlockHeader secondDescendant, long maxSearchDepth) => diff --git a/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs b/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs index 5a775551c8f..80401f518f1 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs @@ -19,8 +19,24 @@ public bool ValidateWithdrawals(Block block, out string? error) => public bool ValidateOrphanedBlock(Block block, out string? error) => baseBlockValidator.ValidateOrphanedBlock(block, out error); - public bool ValidateSuggestedBlock(Block block) => - baseBlockValidator.ValidateSuggestedBlock(block); - - public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) => true; + public bool ValidateSuggestedBlock(Block block, out string? error) + { + return baseBlockValidator.ValidateSuggestedBlock(block, out error); + } + + public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock, out string? error) + { + error = ""; + return true; + } + + public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle, out string? error) + { + return baseBlockValidator.Validate(header, parent, isUncle, out error); + } + + public bool Validate(BlockHeader header, bool isUncle, out string? error) + { + return baseBlockValidator.Validate(header, isUncle, out error); + } } diff --git a/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs b/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs index bdcfada1283..0ba94c59549 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs @@ -148,6 +148,12 @@ private static string ToHexStringWithEip55Checksum(ReadOnlySpan bytes, boo return result; } + public static ReadOnlySpan TakeAndMove(this ref ReadOnlySpan span, int length) + { + ReadOnlySpan s = span[..length]; + span = span[length..]; + return s; + } public static bool IsNullOrEmpty(this in Span span) => span.Length == 0; public static bool IsNull(this in Span span) => Unsafe.IsNullRef(ref MemoryMarshal.GetReference(span)); public static bool IsNullOrEmpty(this in ReadOnlySpan span) => span.Length == 0; diff --git a/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs b/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs index 7618128a5b0..32e40f6a175 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionSubstate.cs @@ -7,6 +7,7 @@ using System.Text; using System.Text.Unicode; using Nethermind.Core; +using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Int256; using Nethermind.Logging; @@ -23,6 +24,7 @@ public class TransactionSubstate private const string Revert = "revert"; private const int RevertPrefix = 4; + private const int WordSize = EvmPooledMemory.WordSize; private const string RevertedErrorMessagePrefix = "Reverted "; public static readonly byte[] ErrorFunctionSelector = Keccak.Compute("Error(string)").BytesToArray()[..RevertPrefix]; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 2c9d116236d..3b7aaf37c88 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -215,21 +215,14 @@ private Transaction CreateTransaction( { if (!nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) { - //try - //{ - env.StateProvider.CreateAccountIfNotExists(transaction.SenderAddress, 0, 0); - var test = env.StateProvider.GetAccount(transaction.SenderAddress); - cachedNonce = test.Nonce; - //} catch () - - //if (env.StateProvider.TryGetAccount(transaction.SenderAddress, out AccountStruct test)) - //{ - // cachedNonce = test.Nonce; - //} - //else - //{ - // cachedNonce = 0; // Todo think if we shall create account here - //} + if (env.StateProvider.TryGetAccount(transaction.SenderAddress, out AccountStruct test)) + { + cachedNonce = test.Nonce; + } + else + { + cachedNonce = 0; // Todo think if we shall create account here + } nonceCache[transaction.SenderAddress] = cachedNonce; } diff --git a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs index cf0a623a970..080e6c2a81b 100644 --- a/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs +++ b/src/Nethermind/Nethermind.Facade/StateOverridesExtensions.cs @@ -48,20 +48,6 @@ public static void ApplyStateOverrides( state.RecalculateStateRoot(); } - private static bool TryGetAccount(this IWorldState stateProvider, Address address, out AccountStruct account) - { - try - { - account = stateProvider.GetAccount(address); - } - catch (TrieException) - { - account = new AccountStruct(); - } - - return !account.IsTotallyEmpty; - } - private static void UpdateState(this IWorldState stateProvider, AccountOverride accountOverride, Address address) { void ApplyState(Dictionary diff) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 36b01b84fbe..d0216f5e8dd 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -136,9 +136,9 @@ public async Task Test_eth_simulate_eth_moved() }; //Test that transfer tx works on mainchain - UInt256 before = chain.State.GetAccount(TestItem.AddressA).Balance; + UInt256 before = chain.State.GetBalance(TestItem.AddressA); await chain.AddBlock(true, txMainnetAtoB); - UInt256 after = chain.State.GetAccount(TestItem.AddressA).Balance; + UInt256 after = chain.State.GetBalance(TestItem.AddressA); Assert.Less(after, before); chain.Bridge.GetReceipt(txMainnetAtoB.Hash!); @@ -216,9 +216,9 @@ public async Task Test_eth_simulate_transactions_forced_fail() }; //Test that transfer tx works on mainchain - UInt256 before = chain.State.GetAccount(TestItem.AddressA).Balance; + UInt256 before = chain.State.GetBalance(TestItem.AddressA); await chain.AddBlock(true, txMainnetAtoB); - UInt256 after = chain.State.GetAccount(TestItem.AddressA).Balance; + UInt256 after = chain.State.GetBalance(TestItem.AddressA); Assert.Less(after, before); chain.Bridge.GetReceipt(txMainnetAtoB.Hash!); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index e6108a1ad45..fbc924dc57d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -29,6 +29,7 @@ using Nethermind.Wallet; using Nethermind.Config; +using Nethermind.Db; using Nethermind.Facade.Simulate; using Nethermind.Synchronization.ParallelSync; using NSubstitute; From 79e6a728237fc4e40de36e2bb0bb3419d559d495 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 27 Mar 2024 13:20:56 +0000 Subject: [PATCH 161/213] fixing hive tests --- .../Processing/BlockProcessor.cs | 23 +++++++++++++++---- .../Simulate/SimulateBridgeHelper.cs | 18 +++++++-------- .../SimulateTxExecutor.MultiCallTxExecutor.cs | 4 ++-- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index cf4e277c86f..bd2bdeb1ddf 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Numerics; using System.Runtime.InteropServices; @@ -88,7 +89,9 @@ public Block[] Process(Hash256 newBranchStateRoot, IReadOnlyList suggeste { if (suggestedBlocks.Count == 0) return Array.Empty(); - TxHashCalculator.CalculateInBackground(suggestedBlocks); + using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); + TxHashCalculator.CalculateInBackground(suggestedBlocks, cancellationTokenSource.Token); + BlocksProcessing?.Invoke(this, new BlocksProcessingEventArgs(suggestedBlocks)); /* We need to save the snapshot state root before reorganization in case the new branch has invalid blocks. @@ -149,6 +152,10 @@ the previous head state.*/ RestoreBranch(previousBranchStateRoot); throw; } + finally + { + cancellationTokenSource.Cancel(); + } } public event EventHandler? BlocksProcessing; @@ -375,17 +382,21 @@ private void ApplyDaoTransition(Block block) } } - private class TxHashCalculator(IReadOnlyList suggestedBlocks) : IThreadPoolWorkItem + private class TxHashCalculator(IReadOnlyList suggestedBlocks, CancellationToken cancellationToken) : IThreadPoolWorkItem { - public static void CalculateInBackground(IReadOnlyList suggestedBlocks) + public static void CalculateInBackground(IReadOnlyList suggestedBlocks, CancellationToken cancellationToken) { // Memory has been reserved on the transactions to delay calculate the hashes // We calculate the hashes in the background to release that memory - ThreadPool.UnsafeQueueUserWorkItem(new TxHashCalculator(suggestedBlocks), preferLocal: false); + ThreadPool.UnsafeQueueUserWorkItem(new TxHashCalculator(suggestedBlocks, cancellationToken), preferLocal: false); } void IThreadPoolWorkItem.Execute() { + if (cancellationToken.IsCancellationRequested) + { + return; + } // Hashes will be required for PersistentReceiptStorage in UpdateMainChain ForkchoiceUpdatedHandler // Which occurs after the block has been processed; however the block is stored in cache and picked up // from there so we can calculate the hashes now for that later use. @@ -393,6 +404,10 @@ void IThreadPoolWorkItem.Execute() { foreach (Transaction tx in block.Transactions) { + if (cancellationToken.IsCancellationRequested) + { + return; + } // Calculate the hashes to release the memory from the transactionSequence tx.CalculateHashInternal(); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 3b7aaf37c88..f8642c94d55 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -10,6 +10,7 @@ using Nethermind.Core; using Nethermind.Core.Collections; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Evm; @@ -44,19 +45,18 @@ private void UpdateStateByModifyingAccounts( IEnumerable senders = blockStateCall.Calls?.Select(details => details.Transaction.SenderAddress) ?? Enumerable.Empty(); IEnumerable targets = blockStateCall.Calls?.Select(details => details.Transaction.To!) ?? Enumerable.Empty(); var all = senders.Union(targets) - .Where(address => address is null) + .Where(address => address is not null && !env.StateProvider.AccountExists(address)) .Distinct() .ToList(); foreach (Address address in all) { - env.StateProvider.CreateAccountIfNotExists(address, 0, 0); + env.StateProvider.CreateAccountIfNotExists(address, 0, 1); } - IWorldState state = env.StateProvider; - state.Commit(currentSpec); - state.CommitTree(blockHeader.Number - 1); - state.RecalculateStateRoot(); + env.StateProvider.Commit(currentSpec); + env.StateProvider.CommitTree(blockHeader.Number - 1); + env.StateProvider.RecalculateStateRoot(); blockHeader.StateRoot = env.StateProvider.StateRoot; } @@ -101,7 +101,7 @@ private void UpdateStateByModifyingAccounts( BlockHeader callHeader = GetCallHeader(callInputBlock, parent); UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); - callHeader.StateRoot = stateProvider.StateRoot!; + stateProvider.StateRoot = env.StateProvider.StateRoot; using IReadOnlyTransactionProcessor? readOnlyTransactionProcessor = env.Build(stateProvider.StateRoot!); @@ -138,12 +138,12 @@ private void UpdateStateByModifyingAccounts( BlockProcessor.AddingTxEventArgs? args = env.BlockTransactionPicker.CanAddTransaction(currentBlock, transaction, testedTxs, stateProvider); - stateProvider.IncrementNonce(transaction.SenderAddress); + if (args.Action is BlockProcessor.TxAction.Stop or BlockProcessor.TxAction.Skip) { return (false, $"invalid transaction index: {index} at block number: {callHeader.Number}, Reason: {args.Reason}"); } - + stateProvider.IncrementNonce(transaction.SenderAddress); testedTxs.Add(transaction); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs index 00dd3586b79..5f3e23873dc 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs @@ -111,7 +111,7 @@ public override ResultWrapper> Execute( foreach (BlockStateCall? blockToSimulate in call.BlockStateCalls!) { - var givenNumber = blockToSimulate.BlockOverrides?.Number ?? (lastBlockNumber == -1 ? (ulong)header.Number : (ulong)lastBlockNumber + 1); + var givenNumber = blockToSimulate.BlockOverrides?.Number ?? (lastBlockNumber == -1 ? (ulong)header.Number + 1 : (ulong)lastBlockNumber + 1); if (givenNumber > long.MaxValue) { @@ -128,7 +128,7 @@ public override ResultWrapper> Execute( return ResultWrapper>.Fail($"Block number out of order {givenNumber}!", ErrorCodes.InvalidInputBlocksOutOfOrder); } - var givenTime = blockToSimulate.BlockOverrides?.Time ?? (lastBlockTime == 0 ? header.Timestamp : lastBlockTime + 1); + var givenTime = blockToSimulate.BlockOverrides?.Time ?? (lastBlockTime == 0 ? header.Timestamp + 1 : lastBlockTime + 1); if (givenTime > lastBlockTime) { From 1614e121f3dced039bdef3dd556b75d95621e9c8 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 2 Apr 2024 14:19:32 +0100 Subject: [PATCH 162/213] fix formating --- src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs index a0ffaf13544..418d2e60240 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs @@ -493,7 +493,7 @@ public void FinishBlockCommit(TrieType trieType, long blockNumber, Hash256? addr public event EventHandler? ReorgBoundaryReached; - public byte[]? TryLoadRlp(Hash256? address, in TreePath path, Hash256 keccak, INodeStorage? nodeStorage, ReadFlags readFlags = ReadFlags.None) + public byte[]? TryLoadRlp(Hash256? address, in TreePath path, Hash256 keccak, INodeStorage? nodeStorage, ReadFlags readFlags = ReadFlags.None) { nodeStorage ??= _nodeStorage; byte[]? rlp = nodeStorage.Get(address, path, keccak, readFlags); From 4472169d68e9413f071ffc948fc70a7ae513bb5c Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 3 Apr 2024 19:26:54 +0100 Subject: [PATCH 163/213] fixing protocol issues --- .../Tracing/BlockReceiptsTracer.cs | 20 +++++++++++- .../Tracing/CancellationTxTracer.cs | 26 +++++++++++++-- .../Nethermind.Evm/Tracing/ITxTracer.cs | 2 +- .../Nethermind.Evm/VirtualMachine.cs | 2 +- .../Proxy/Models/Simulate/Error.cs | 2 +- .../Proxy/Models/Simulate/Log.cs | 12 ++++--- .../Simulate/SimulateBlockTracer.cs | 18 +++-------- .../Simulate/SimulateTxTracer.cs | 32 ++++++++++++++----- 8 files changed, 82 insertions(+), 32 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index 2014b720904..087a0e26177 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -10,7 +10,7 @@ namespace Nethermind.Evm.Tracing; -public class BlockReceiptsTracer : IBlockTracer, ITxTracer, IJournal, ITxTracerWrapper +public class BlockReceiptsTracer : IBlockTracer, ITxTracer, IJournal, ITxTracerWrapper, ILogsTxTracer { protected Block Block = null!; public bool IsTracingReceipt => true; @@ -28,6 +28,9 @@ public class BlockReceiptsTracer : IBlockTracer, ITxTracer, IJournal, ITxTr public bool IsTracingAccess => _currentTxTracer.IsTracingAccess; public bool IsTracingFees => _currentTxTracer.IsTracingFees; + public bool IsTracingLogs => _logsTxTracer != null && _logsTxTracer!.IsTracingLogs; + + private ILogsTxTracer? _logsTxTracer; private IBlockTracer _otherTracer = NullBlockTracer.Instance; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Hash256? stateRoot = null) @@ -237,6 +240,8 @@ public ITxTracer StartNewTxTrace(Transaction? tx) { CurrentTx = tx; _currentTxTracer = _otherTracer.StartNewTxTrace(tx); + _logsTxTracer = _currentTxTracer as ILogsTxTracer; + return _currentTxTracer; } @@ -270,4 +275,17 @@ public void Dispose() { _currentTxTracer.Dispose(); } + + public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, + ExecutionType callType, bool isPrecompileCall = false) + { + if (_logsTxTracer != null) + { + return _logsTxTracer.ReportActionAndAddResultsToState(gas, value, from, to, input, callType, + isPrecompileCall); + } + + return Enumerable.Empty(); + + } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs index af2fed7b7c2..5117c5deef2 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs @@ -4,13 +4,14 @@ using System; using System.Collections.Generic; using System.Threading; +using System.Linq; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Int256; namespace Nethermind.Evm.Tracing; -public class CancellationTxTracer : ITxTracer, ITxTracerWrapper +public class CancellationTxTracer : ITxTracer, ITxTracerWrapper, ILogsTxTracer { private readonly ITxTracer _innerTracer; private readonly CancellationToken _token; @@ -27,12 +28,14 @@ public class CancellationTxTracer : ITxTracer, ITxTracerWrapper private readonly bool _isTracingBlockHash; private readonly bool _isTracingBlockAccess; private readonly bool _isTracingFees; + private readonly bool _isTracingLogs; public ITxTracer InnerTracer => _innerTracer; - + private ILogsTxTracer? _logsTxTracer; public CancellationTxTracer(ITxTracer innerTracer, CancellationToken token = default) { _innerTracer = innerTracer; + _logsTxTracer = InnerTracer as ILogsTxTracer; _token = token; } @@ -113,6 +116,12 @@ public bool IsTracingFees get => _isTracingFees || _innerTracer.IsTracingFees; init => _isTracingFees = value; } + public bool IsTracingLogs + { + get => _isTracingLogs || (_logsTxTracer != null && _logsTxTracer!.IsTracingLogs); + init => _isTracingLogs = value; + } + public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) { @@ -442,4 +451,17 @@ public void Dispose() { _innerTracer.Dispose(); } + + + public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, + ExecutionType callType, bool isPrecompileCall = false) + { + if (_logsTxTracer == null) + { + return Enumerable.Empty(); + } + + return _logsTxTracer.ReportActionAndAddResultsToState(gas, value, from, to, input, callType, + isPrecompileCall); + } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index a875a22237c..bc73ceadb11 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -436,5 +436,5 @@ public interface ILogsTxTracer /// /// Created logs to be added, only when is true /// Depends on - IEnumerable ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); + IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 45351bf0824..75d1bcede48 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -219,7 +219,7 @@ public TransactionSubstate Run(EvmState state, IWorldState worl { if (_txTracer is ILogsTxTracer { IsTracingLogs: true } logsTxTracer) { - IEnumerable logs = logsTxTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, + IEnumerable logs = logsTxTracer.ReportActionAndAddResultsToState(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, currentState.ExecutionType); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Error.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Error.cs index b9a9b3b2aca..a53bdd9a9e5 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Error.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Error.cs @@ -5,7 +5,7 @@ namespace Nethermind.Facade.Proxy.Models.Simulate; public class Error { - public byte[] Code { get; set; } + public int Code { get; set; } public string Message { get; set; } public string Data { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Log.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Log.cs index 080e358cd3f..1e0f05d12c3 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Log.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/Log.cs @@ -8,10 +8,14 @@ namespace Nethermind.Facade.Proxy.Models.Simulate; public class Log { - public ulong LogIndex { get; set; } - public Hash256 BlockHash { get; set; } - public ulong BlockNumber { get; set; } public Address Address { get; set; } - public byte[] Data { get; set; } public Hash256[] Topics { get; set; } + public byte[] Data { get; set; } + public ulong BlockNumber { get; set; } + public Hash256 TransactionHash { get; set; } + public ulong TransactionIndex { get; set; } + public Hash256 BlockHash { get; set; } + + public ulong LogIndex { get; set; } + public bool Removed { get; set; } = false; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 37ae55a56ca..5240a65aca4 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -8,6 +8,7 @@ using Nethermind.Core.Collections; using Nethermind.Evm; using Nethermind.Evm.Tracing; +using Nethermind.Evm.Tracing.GethStyle.Custom.JavaScript; using Nethermind.Facade.Proxy.Models.Simulate; using ResultType = Nethermind.Facade.Proxy.Models.Simulate.ResultType; @@ -29,9 +30,11 @@ public override void StartNewBlockTrace(Block block) public override ITxTracer StartNewTxTrace(Transaction? tx) { + if (tx?.Hash is not null) { - SimulateTxTracer result = new(isTracingLogs); + ulong txIndex = (ulong)_txTracers.Count; + SimulateTxTracer result = new(isTracingLogs, tx.Hash, (ulong)_currentBlock.Number, _currentBlock.Hash, txIndex); _txTracers.Add(result); return result; } @@ -58,19 +61,6 @@ public override void EndBlockTrace() Withdrawals = _currentBlock.Withdrawals ?? Array.Empty() }; - result.Calls.ForEach(callResult => - { - if (callResult.Type == (ulong)ResultType.Success) - { - callResult.Logs?.ForEach(log => - { - log.BlockHash = _currentBlock.Hash!; - log.BlockNumber = (ulong)_currentBlock.Number; - }); - } - }); - - //TODO: We could potentially improve performance, through streaming through enumerable and yield return rather than accumulating huge result list in memory. Results.Add(result); } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs index 080eb974c95..fc47d87a96a 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs @@ -16,12 +16,23 @@ namespace Nethermind.Facade.Simulate; internal sealed class SimulateTxTracer : TxTracer, ILogsTxTracer { + private readonly Hash256 _txHash; + private readonly ulong _currentBlockNumber; + private readonly Hash256 _currentBlockHash; + private readonly ulong _txIndex; private static readonly Hash256[] _topics = [Keccak.Zero]; + private readonly bool _isTracingTransfers; - public SimulateTxTracer(bool isTracingTransfers) + public SimulateTxTracer(bool isTracingTransfers, Hash256 txHash, ulong currentBlockNumber, Hash256 currentBlockHash, + ulong txIndex) { - IsTracingLogs = isTracingTransfers; + _txHash = txHash; + _currentBlockNumber = currentBlockNumber; + _currentBlockHash = currentBlockHash; + _txIndex = txIndex; IsTracingReceipt = true; + + _isTracingTransfers = isTracingTransfers; } public SimulateCallResult? TraceResult { get; set; } @@ -35,10 +46,15 @@ public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] outp Status = StatusCode.Success, Logs = logs.Select((entry, i) => new Log { - Data = entry.Data, Address = entry.LoggersAddress, Topics = entry.Topics, - LogIndex = (ulong)i + Data = entry.Data, + LogIndex = (ulong)i, + TransactionHash = _txHash, + TransactionIndex = _txIndex, + BlockHash = _currentBlockHash, + BlockNumber = _currentBlockNumber + }) }; } @@ -50,17 +66,17 @@ public override void MarkAsFailed(Address recipient, long gasSpent, byte[] outpu GasUsed = (ulong)gasSpent, Error = new Error { - Code = StatusCode.FailureBytes.ToArray(), + Code = -32015, // revert error code stub Message = error }, - ReturnData = output, + ReturnData = null, Status = StatusCode.Failure }; } - public bool IsTracingLogs { get; } + public bool IsTracingLogs => _isTracingTransfers; - IEnumerable ILogsTxTracer.ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall) + public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); byte[] data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, From 2dc5513c423d63d96e01147f70d4381cad8454d5 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 29 Apr 2024 12:41:49 +0100 Subject: [PATCH 164/213] Minor fixes --- .../Models/Simulate/SimulateCallResult.cs | 8 - .../Simulate/SimulateBridgeHelper.cs | 13 +- .../Simulate/SimulateOutput.cs | 1 + .../EthSimulateTestsBlocksAndTransactions.cs | 23 +- .../Eth/Simulate/EthSimulateTestsHiveBase.cs | 254 +----------------- .../Nethermind.JsonRpc/ErrorType.cs | 10 +- .../SimulateTxExecutor.MultiCallTxExecutor.cs | 54 +++- 7 files changed, 80 insertions(+), 283 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs index 78f75a5ac04..97a649e5729 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs @@ -10,14 +10,6 @@ namespace Nethermind.Facade.Proxy.Models.Simulate; public class SimulateCallResult { - public ulong Type => - (ulong)(Status switch - { - StatusCode.Success => ResultType.Success, - StatusCode.Failure when ReturnData is not null => ResultType.Failure, - _ => ResultType.Invalid, - }); - public ulong Status { get; set; } public byte[]? ReturnData { get; set; } public ulong? GasUsed { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index f8642c94d55..350c5cc81b6 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -75,7 +75,6 @@ private void UpdateStateByModifyingAccounts( parent = latestBlock?.Header ?? env.BlockTree.Head!.Header; } - BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); ulong lastKnown = (ulong)latestBlockNumber; @@ -182,16 +181,14 @@ private void UpdateStateByModifyingAccounts( if (processedBlock is not null) { - //var res = env.BlockTree.SuggestBlock(processedBlock, BlockTreeSuggestOptions.ForceSetAsMain); - //env.BlockTree.UpdateMainChain(new[] { processedBlock }, true, true); - //env. - ////env.BlockTree.UpdateHeadBlock(processedBlock.Hash!); parent = processedBlock.Header; stateProvider.StateRoot = processedBlock.StateRoot; env.StateProvider.StateRoot = processedBlock.StateRoot; - //env.StateProvider.Commit(currentSpec); - //env.StateProvider.RecalculateStateRoot(); - //env.StateProvider.CommitTree(currentBlock.Number); + var currentSpec = env.SpecProvider.GetSpec(processedBlock.Header); + env.StateProvider.Commit(currentSpec); + env.StateProvider.CommitTree(currentBlock.Number); + env.BlockTree.SuggestBlock(processedBlock, BlockTreeSuggestOptions.ForceSetAsMain); + env.BlockTree.UpdateHeadBlock(processedBlock.Hash!); } } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs index 7cf0474407d..448147f8566 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs @@ -9,6 +9,7 @@ namespace Nethermind.Facade.Simulate; public class SimulateOutput { public string? Error { get; set; } + public int? ErrorCode { get; set; } public IReadOnlyList Items { get; set; } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index d0216f5e8dd..0387345b874 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -57,7 +57,7 @@ public async Task Test_eth_simulate_serialisation() [ new() { - BlockOverrides = new BlockOverride { Number = 18000000 }, + BlockOverrides = new BlockOverride { Number = 10 }, Calls = [new TransactionForRpc(txToFail), new TransactionForRpc(tx)], StateOverrides = new Dictionary { @@ -77,12 +77,11 @@ public async Task Test_eth_simulate_serialisation() SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; - Assert.That(data.Count, Is.EqualTo(1)); + Assert.That(data.Count, Is.EqualTo(7)); + + SimulateBlockResult blockResult = data.Last(); + blockResult.Calls.Select(c => c.Status).Should().BeEquivalentTo(new[] { (ulong)ResultType.Success, (ulong)ResultType.Success }); - foreach (SimulateBlockResult blockResult in data) - { - blockResult.Calls.Select(c => c.Type).Should().BeEquivalentTo(new[] { (ulong)ResultType.Success, (ulong)ResultType.Success }); - } } @@ -124,7 +123,7 @@ public async Task Test_eth_simulate_eth_moved() BlockOverrides = new BlockOverride { - Number = (ulong)checked(chain.Bridge.HeadBlock.Number + 10000), + Number = (ulong)checked(chain.Bridge.HeadBlock.Number + 10), GasLimit = 5_000_000, FeeRecipient = TestItem.AddressC, BaseFeePerGas = 0 @@ -153,12 +152,12 @@ public async Task Test_eth_simulate_eth_moved() executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; - Assert.That(data.Count, Is.EqualTo(2)); + Assert.That(data.Count, Is.EqualTo(9)); - foreach (SimulateBlockResult blockResult in data) - { - Assert.That(blockResult.Calls.Count(), Is.EqualTo(2)); - } + SimulateBlockResult blockResult = data[0]; + Assert.That(blockResult.Calls.Count(), Is.EqualTo(2)); + blockResult = data.Last(); + Assert.That(blockResult.Calls.Count(), Is.EqualTo(2)); } /// diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs index 1fef9cdcb81..a14d5e48adf 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs @@ -98,18 +98,7 @@ public async Task TestsimulateBlockOverrideReflectedInContractSimple() Assert.IsNotNull(result.Data); } - [Test] - public async Task TestsimulateBlockOverrideReflectedInContract() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\",\"time\":\"0x64\",\"gasLimit\":\"0xa\",\"feeRecipient\":\"0xc000000000000000000000000000000000000000\",\"prevRandao\":\"0x0000000000000000000000000000000000000000000000000000000000000012\",\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x14\",\"time\":\"0xc8\",\"gasLimit\":\"0x14\",\"feeRecipient\":\"0xc100000000000000000000000000000000000000\",\"prevRandao\":\"0x0000000000000000000000000000000000000000000000000000000000001234\",\"baseFeePerGas\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x15\",\"time\":\"0x12c\",\"gasLimit\":\"0x15\",\"feeRecipient\":\"0xc200000000000000000000000000000000000000\",\"prevRandao\":\"0x0000000000000000000000000000000000000000000000000000000000001234\",\"baseFeePerGas\":\"0x1e\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBlockOverrideReflectedInContract"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } + [Test] public async Task TestsimulateBlockTimestampAutoIncrement() @@ -124,31 +113,6 @@ public async Task TestsimulateBlockTimestampAutoIncrement() Assert.That(result.Result.Error!.Contains("Block timestamp out of order")); } - [Test] - public async Task TestsimulateBlockTimestampNonIncrement() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xc\"}},{\"blockOverrides\":{\"time\":\"0xc\"}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBlockTimestampNonIncrement"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateBlockTimestampOrder38021() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xc\"}},{\"blockOverrides\":{\"time\":\"0xb\"}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBlockTimestampOrder38021"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } [Test] public async Task TestsimulateBlockTimestampsIncrementing() @@ -202,18 +166,6 @@ public async Task TestsimulateBlockhashStartBeforeHead() Assert.IsNotNull(result.Data); } - [Test] - public async Task TestsimulateCheckInvalidNonce() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x4e20\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc000000000000000000000000000000000000000\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x1\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x0\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateCheckInvalidNonce"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } [Test] public async Task TestsimulateCheckThatBalanceIsThereAfterNewBlock() @@ -228,18 +180,7 @@ public async Task TestsimulateCheckThatBalanceIsThereAfterNewBlock() Assert.IsNotNull(result.Data); } - [Test] - public async Task TestsimulateCheckThatNonceIncreases() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x4e20\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc000000000000000000000000000000000000000\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x1\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x2\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateCheckThatNonceIncreases"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } + [Test] public async Task TestsimulateEmptyCallsAndOverrides() @@ -319,44 +260,10 @@ public async Task TestsimulateEthSendShouldProduceNoLogsOnForwardRevert() Assert.IsNotNull(result.Data); } - [Test] - public async Task TestsimulateFeeRecipientReceivingFunds() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\",\"feeRecipient\":\"0xc200000000000000000000000000000000000000\",\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0xa\",\"maxPriorityFeePerGas\":\"0xa\",\"nonce\":\"0x0\",\"input\":\"0x\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x1\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x2\",\"input\":\"0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000\"}]}],\"traceTransfers\":true,\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateFeeRecipientReceivingFunds"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - [Test] - public async Task TestsimulateGasFeesAndValueError38014WithValidation() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateGasFeesAndValueError38014WithValidation"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - [Test] - public async Task TestsimulateGasFeesAndValueError38014() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000123\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateGasFeesAndValueError38014"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } + + [Test] public async Task TestsimulateGetBlockProperties() @@ -371,18 +278,6 @@ public async Task TestsimulateGetBlockProperties() Assert.IsNotNull(result.Data); } - [Test] - public async Task TestsimulateInstrictGas38013() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"gas\":\"0x0\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateInstrictGas38013"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } [Test] public async Task TestsimulateLogs() @@ -475,18 +370,7 @@ public async Task TestsimulateOverrideAddressTwiceInSeparateBlockStateCalls() Assert.IsNotNull(result.Data); } - [Test] - public async Task TestsimulateOverrideAddressTwice() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateOverrideAddressTwice"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } + [Test] public async Task TestsimulateOverrideAllInBlockStateCalls() @@ -605,83 +489,6 @@ public async Task TestsimulateSetReadStorage() Assert.IsNotNull(result.Data); } - [Test] - public async Task TestsimulateSimpleNoFundsWithBalanceQuerying() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateSimpleNoFundsWithBalanceQuerying"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateSimpleNoFundsWithValidationWithoutNonces() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateSimpleNoFundsWithValidationWithoutNonces"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateSimpleNoFundsWithValidation() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"nonce\":\"0x1\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateSimpleNoFundsWithValidation"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateSimpleNoFunds() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateSimpleNoFunds"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateSimpleSendFromContractNoBalance() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateSimpleSendFromContractNoBalance"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateSimpleSendFromContractWithValidation() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\",\"balance\":\"0x3e8\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true,\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateSimpleSendFromContractWithValidation"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } [Test] public async Task TestsimulateSimpleSendFromContract() @@ -696,45 +503,6 @@ public async Task TestsimulateSimpleSendFromContract() Assert.IsNotNull(result.Data); } - [Test] - public async Task TestsimulateSimple() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x3e8\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateSimple"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateTransactionTooHighNonce() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x64\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateTransactionTooHighNonce"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateTransactionTooLowNonce38010() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"nonce\":\"0xa\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x0\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateTransactionTooLowNonce38010"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - [Test] public async Task TestsimulateTransferOverBlockStateCalls() { @@ -747,16 +515,4 @@ public async Task TestsimulateTransferOverBlockStateCalls() Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); } - [Test] - public async Task TestsimulateTryToMoveNonPrecompile() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"nonce\":\"0x5\"}}},{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc100000000000000000000000000000000000000\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc000000000000000000000000000000000000000\",\"nonce\":\"0x0\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"nonce\":\"0x5\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateTryToMoveNonPrecompile"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } } diff --git a/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs b/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs index e43f55e95ca..6b2d8f2e47a 100644 --- a/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs +++ b/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs @@ -87,11 +87,6 @@ public static class ErrorCodes /// public const int UnknownBlockError = -39001; - /// - /// Unsupported fork error - /// - public const int UnsupportedFork = -38005; - /// /// Invalid RPC simulate call block number out of order /// @@ -101,5 +96,10 @@ public static class ErrorCodes /// Invalid RPC simulate call containing too many blocks /// public const int InvalidInputTooManyBlocks = -38026; + + /// + /// Invalid RPC simulate call transaction + /// + public const int InvalidTransaction = -38014; } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs index 5f3e23873dc..49d4b39069c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs @@ -76,6 +76,12 @@ public override ResultWrapper> Execute( SimulatePayload call, BlockParameter? blockParameter) { + + if (call.BlockStateCalls == null) + { + return ResultWrapper>.Fail($"Must contain BlockStateCalls", ErrorCodes.InvalidParams); + } + if (call.BlockStateCalls!.Length > _rpcConfig.MaxSimulateBlocksCap) { return ResultWrapper>.Fail($"This node is configured to support only {_rpcConfig.MaxSimulateBlocksCap} blocks", ErrorCodes.InvalidInputTooManyBlocks); @@ -128,6 +134,14 @@ public override ResultWrapper> Execute( return ResultWrapper>.Fail($"Block number out of order {givenNumber}!", ErrorCodes.InvalidInputBlocksOutOfOrder); } + if (blockToSimulate.BlockOverrides == null) + { + blockToSimulate.BlockOverrides = new BlockOverride(); + } + + blockToSimulate.BlockOverrides!.Number = givenNumber; + + var givenTime = blockToSimulate.BlockOverrides?.Time ?? (lastBlockTime == 0 ? header.Timestamp + 1 : lastBlockTime + 1); if (givenTime > lastBlockTime) @@ -138,9 +152,39 @@ public override ResultWrapper> Execute( { return ResultWrapper>.Fail($"Block timestamp out of order {givenTime}!", ErrorCodes.InvalidInputBlocksOutOfOrder); } + blockToSimulate.BlockOverrides!.Time = givenTime; + } + var minBlockNumber = Math.Min( + call.BlockStateCalls.Min(b => + (long)(b.BlockOverrides?.Number ?? ulong.MaxValue)), + header.Number + 1); + + long maxBlockNumber = Math.Max( + call.BlockStateCalls.Max(b => + (long)(b.BlockOverrides?.Number ?? ulong.MinValue)), + minBlockNumber); + HashSet existingBlockNumbers = new(call.BlockStateCalls.Select(b => + (long)(b.BlockOverrides?.Number ?? ulong.MinValue))); + + var completeBlockStateCalls = call.BlockStateCalls!.ToList(); + + for (long blockNumber = minBlockNumber; blockNumber <= maxBlockNumber; blockNumber++) + { + if (!existingBlockNumbers.Contains(blockNumber)) + { + completeBlockStateCalls.Add(new BlockStateCall + { + BlockOverrides = new BlockOverride { Number = (ulong)blockNumber }, + StateOverrides = null, + Calls = Array.Empty() + }); + } + } + + call.BlockStateCalls = completeBlockStateCalls.OrderBy(b => b.BlockOverrides!.Number!).ToArray(); } using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); //TODO remove! @@ -152,9 +196,17 @@ protected override ResultWrapper> Execute(Blo { SimulateOutput results = _blockchainBridge.Simulate(header, tx, token); + if (results.Error != null && results.Error.Contains("invalid transaction")) + { + results.ErrorCode = ErrorCodes.InvalidTransaction; + } + return results.Error is null ? ResultWrapper>.Success(results.Items) - : ResultWrapper>.Fail(results.Error, results.Items); + : results.ErrorCode != null + ? ResultWrapper>.Fail(results.Error!, results.ErrorCode!.Value, + results.Items) + : ResultWrapper>.Fail(results.Error, results.Items); } } From 11d0e6a1d1a4fad441d691a0014501f0aadbb150 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 29 Apr 2024 13:16:14 +0100 Subject: [PATCH 165/213] Extra transfer Logs use eEE address --- .../Simulate/SimulateTxTracer.cs | 4 +- .../EthSimulateTestsBlocksAndTransactions.cs | 43 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs index fc47d87a96a..134c5a229ed 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs @@ -22,7 +22,7 @@ internal sealed class SimulateTxTracer : TxTracer, ILogsTxTracer private readonly ulong _txIndex; private static readonly Hash256[] _topics = [Keccak.Zero]; private readonly bool _isTracingTransfers; - + private static Address Erc20Sender = new("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"); public SimulateTxTracer(bool isTracingTransfers, Hash256 txHash, ulong currentBlockNumber, Hash256 currentBlockHash, ulong txIndex) { @@ -81,6 +81,6 @@ public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); byte[] data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256), from, to, value); - yield return new LogEntry(Address.Zero, data, _topics); + yield return new LogEntry(Erc20Sender, data, _topics); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 0387345b874..164a54e59b1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -233,4 +233,47 @@ public async Task Test_eth_simulate_transactions_forced_fail() executor.Execute(payload, BlockParameter.Latest); Assert.IsTrue(result.Result!.Error!.Contains("higher than sender balance")); } + + + [Test] + public async Task TestTransferLogsAddress() + { + EthereumJsonSerializer serializer = new(); + string input = """ + { + "traceTransfers": true, + "blockStateCalls": [ + { + "blockOverrides": { + "baseFeePerGas": "0xa" + }, + "stateOverrides": { + "0xc000000000000000000000000000000000000000": { + "balance": "0x35a4ece8" + } + }, + "calls": [ + { + "from": "0xc000000000000000000000000000000000000000", + "to": "0xc100000000000000000000000000000000000000", + "gas": "0x5208", + "maxFeePerGas": "0x14", + "maxPriorityFeePerGas": "0x1", + "maxFeePerBlobGas": "0x0", + "value": "0x65", + "nonce": "0x0", + "input": "0x" + } + ] + } + ] + } + """; + var payload = serializer.Deserialize>(input); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine("current test: simulateTransferOverBlockStateCalls"); + var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); + var logs = result.Data.First().Calls.First().Logs.ToArray(); + Assert.That(logs.First().Address == new Address("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE")); + } } From 706aacf21eb8b9fee9d89b0c0ce22f0f9ab91042 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 29 Apr 2024 14:53:01 +0100 Subject: [PATCH 166/213] manual diff merge with maser using araxis --- .../TestBlockhashProvider.cs | 8 +- ...sts.TestAccountAbstractionRpcBlockchain.cs | 13 +- .../Contract/TxPriorityContractTests.cs | 2 +- .../BlockchainProcessorTests.cs | 2 +- .../BlockhashProviderTests.cs | 24 +- .../FullPruning/FullPruningDiskTest.cs | 3 +- .../Validators/TestBlockValidator.cs | 2 +- .../Nethermind.Blockchain/BlockTree.cs | 3 +- .../BlockhashProvider.cs | 39 +-- .../ReadOnlyBlockTree.cs | 96 +++--- .../Nethermind.Cli/Modules/EthCliModule.cs | 205 ++++++++---- .../Validators/PendingValidators.cs | 2 +- .../Validators/ValidatorInfo.cs | 2 +- .../Processing/BlockProcessor.cs | 2 +- .../Processing/IBlockProcessor.cs | 5 +- .../Processing/NullBlockProcessor.cs | 3 +- .../Processing/ProcessingStats.cs | 5 +- .../Validators/AlwaysValid.cs | 2 +- .../Validators/BlockValidator.cs | 15 +- .../Validators/IBlockValidator.cs | 2 +- .../Validators/NeverValidBlockValidator.cs | 2 +- .../Validators/SimulateBlockValidatorProxy.cs | 10 +- .../Blockchain/TestBlockchain.cs | 8 +- .../Nethermind.Core/BlockchainIds.cs | 2 - .../Nethermind.Core/ByteArrayConverter.cs | 3 +- .../Nethermind.Core/Extensions/Bytes.cs | 72 ++++- .../Extensions/SpanExtensions.cs | 5 +- src/Nethermind/Nethermind.Db/Metrics.cs | 180 +---------- .../Nethermind.Evm.Benchmark/EvmBenchmarks.cs | 8 +- .../StaticCallBenchmarks.cs | 8 +- .../TestBlockhashProvider.cs | 6 +- .../Nethermind.Evm/ByteCodeBuilder.cs | 2 +- .../Nethermind.Evm/CodeAnalysis/CodeInfo.cs | 8 +- .../Nethermind.Evm/IBlockhashProvider.cs | 2 +- .../Nethermind.Evm/IntrinsicGasCalculator.cs | 24 +- .../BlockchainBridgeTests.cs | 22 +- .../Simulate/SimulateBridgeHelper.cs | 2 +- .../Nethermind.Init/Steps/StartMonitoring.cs | 93 ------ .../Modules/Eth/EthRpcSimulateTestsBase.cs | 2 +- .../Modules/TestRpcBlockchain.cs | 10 +- .../EngineModuleTests.Setup.cs | 4 +- .../InvalidBlockInterceptorTest.cs | 8 +- .../Handlers/NewPayloadHandler.cs | 4 +- .../InvalidBlockInterceptor.cs | 8 +- .../Synchronization/BeaconHeadersSyncFeed.cs | 7 - .../MevRpcModuleTests.TestMevRpcBlockchain.cs | 2 +- .../P2P/SessionTests.cs | 17 +- .../AuthEip8MessageSerializerTests.cs | 1 - .../Handshake/AuthMessageSerializerTests.cs | 1 - src/Nethermind/Nethermind.Network/Metrics.cs | 300 ------------------ .../Nethermind.Network/NetworkNodeDecoder.cs | 2 +- .../Analyzers/MetricsDisconnectsAnalyzer.cs | 98 +----- .../ProtocolHandlers/P2PProtocolHandler.cs | 2 - .../SyncPeerProtocolHandlerBase.cs | 5 - .../Subprotocols/Eth/PooledTxsRequestor.cs | 2 - .../Eth/V62/Eth62ProtocolHandler.cs | 5 - .../Eth/V63/Eth63ProtocolHandler.cs | 3 - .../Eth/V65/Eth65ProtocolHandler.cs | 6 - .../Eth/V66/Eth66ProtocolHandler.cs | 10 - .../Eth/V68/Eth68ProtocolHandler.cs | 2 - .../Subprotocols/Les/LesProtocolHandler.cs | 4 - .../NodeData/NodeDataProtocolHandler.cs | 2 - .../Subprotocols/Snap/SnapProtocolHandler.cs | 16 - .../Ethereum/ContextWithMocks.cs | 1 - .../Nethermind.Runner.csproj | 7 +- .../Properties/launchSettings.json | 7 - .../Nethermind.Runner/configs/chiado.cfg | 4 +- .../Nethermind.Runner/configs/energyweb.cfg | 6 +- .../Nethermind.Runner/configs/exosama.cfg | 6 +- .../Nethermind.Runner/configs/gnosis.cfg | 4 +- .../Nethermind.Runner/configs/joc-mainnet.cfg | 6 +- .../Nethermind.Runner/configs/joc-testnet.cfg | 6 +- .../Nethermind.Runner/configs/kovan.cfg | 33 -- .../configs/kovan_archive.cfg | 34 -- .../Nethermind.Runner/configs/mainnet.cfg | 4 +- .../Nethermind.Runner/configs/sepolia.cfg | 4 +- .../Nethermind.Runner/configs/volta.cfg | 6 +- .../DictionaryAddressKey.cs | 3 +- .../DoubleConverter.cs | 1 - .../EthereumJsonSerializer.cs | 12 +- .../ULongConverter.cs | 1 + .../BlockInfoDecoder.cs | 2 + .../ReceiptMessageDecoder.cs | 7 +- .../ReceiptStorageDecoder.cs | 10 +- .../Nethermind.Serialization.Rlp/Rlp.cs | 93 ++++-- .../Nethermind.Serialization.Rlp/TxDecoder.cs | 3 +- .../ValueRlpStream.cs | 2 +- .../BlockDownloaderTests.cs | 2 +- .../FastBlocks/FastHeadersSyncFeed.cs | 17 - .../Nethermind.Trie/PatriciaTree.cs | 6 +- .../Pruning/ITrieNodeResolver.cs | 1 - .../Nethermind.Trie/TrieNode.Decoder.cs | 180 +++++++---- .../Nethermind.Trie/TrieNode.Visitor.cs | 2 +- src/Nethermind/Nethermind.Trie/TrieNode.cs | 39 ++- .../TrieNodeResolverWithReadFlags.cs | 1 - src/Nethermind/Nethermind.TxPool/TxPool.cs | 4 +- 96 files changed, 683 insertions(+), 1244 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Runner/configs/kovan.cfg delete mode 100644 src/Nethermind/Nethermind.Runner/configs/kovan_archive.cfg diff --git a/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs b/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs index fbc91fd2459..786ddde0b16 100644 --- a/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs +++ b/src/Nethermind/Ethereum.Test.Base/TestBlockhashProvider.cs @@ -9,7 +9,11 @@ namespace Ethereum.Test.Base { public class TestBlockhashProvider : IBlockhashProvider { - public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) => - number != 0 ? Keccak.Zero : Keccak.Compute(number.ToString()); + public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) + { + if (number != 0) + return Keccak.Zero; + return Keccak.Compute(number.ToString()); + } } } diff --git a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs index e56fb9f1c0a..c56265edd8a 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.TestAccountAbstractionRpcBlockchain.cs @@ -251,17 +251,22 @@ protected override BlockProcessor CreateBlockProcessor() } protected override async Task Build(ISpecProvider? specProvider = null, - UInt256? initialValues = null, bool addBlockOnStart = true, bool pruning = false) + UInt256? initialValues = null, bool addBlockOnStart = true) { TestBlockchain chain = await base.Build(specProvider, initialValues); IList
entryPointContractAddresses = new List
(); - foreach (string addressString in _accountAbstractionConfig.GetEntryPointAddresses()) + IList _entryPointContractAddressesString = + _accountAbstractionConfig.GetEntryPointAddresses().ToList(); + foreach (string _addressString in _entryPointContractAddressesString) { - Address.TryParse(addressString, out Address? entryPointContractAddress); + bool parsed = Address.TryParse( + _addressString, + out Address? entryPointContractAddress); entryPointContractAddresses.Add(entryPointContractAddress!); } - AccountAbstractionRpcModule = new AccountAbstractionRpcModule(UserOperationPool, entryPointContractAddresses.ToArray()); + AccountAbstractionRpcModule = + new AccountAbstractionRpcModule(UserOperationPool, entryPointContractAddresses.ToArray()); return chain; } diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs index e8f087fa105..276671dab2a 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs @@ -354,7 +354,7 @@ protected override ILocalDataSource> GetWhitelistLocalDataS protected override ILocalDataSource> GetMinGasPricesLocalDataStore() => LocalDataSource.GetMinGasPricesLocalDataSource(); - protected override Task Build(ISpecProvider specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool pruning = false) + protected override Task Build(ISpecProvider specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true) { TempFile = TempPath.GetTempFile(); LocalDataSource = new TxPriorityContract.LocalDataSource(TempFile.Path, new EthereumJsonSerializer(), new FileSystem(), LimboLogs.Instance, Interval); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs index 225480a1ba4..a5dc4884c80 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs @@ -73,7 +73,7 @@ public void AllowToFail(Hash256 hash) _allowedToFail.Add(hash); } - public Block[] Process(Hash256 newBranchStateRoot, IReadOnlyList suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer) + public Block[] Process(Hash256 newBranchStateRoot, List suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer) { if (blockTracer != NullBlockTracer.Instance) { diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs index 2113a984395..9728dfb5475 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockhashProviderTests.cs @@ -24,7 +24,7 @@ public void Can_get_parent_only_headers() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader? head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None); Block current = Build.A.Block.WithParent(head!).TestObject; - Hash256? result = provider.GetBlockhash(current.Header, chainLength - 1); + Hash256 result = provider.GetBlockhash(current.Header, chainLength - 1); Assert.That(result, Is.EqualTo(head?.Hash)); } @@ -39,7 +39,7 @@ public void Can_lookup_up_to_256_before_with_headers_only() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockhash(current.Header, chainLength - 256); + Hash256 result = provider.GetBlockhash(current.Header, chainLength - 256); Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash)); } @@ -54,7 +54,7 @@ public void Can_lookup_up_to_256_before_with_headers_only_and_competing_branches BlockhashProvider provider = new(tree, LimboLogs.Instance); Block current = Build.A.Block.WithParent(headBlock).TestObject; long lookupNumber = chainLength - 256; - Hash256? result = provider.GetBlockhash(current.Header, lookupNumber); + Hash256 result = provider.GetBlockhash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -71,7 +71,7 @@ public void Can_lookup_up_to_256_before_soon_after_fast_sync() tree.SuggestBlock(current); tree.UpdateMainChain(current); long lookupNumber = chainLength - 256; - Hash256? result = provider.GetBlockhash(current.Header, lookupNumber); + Hash256 result = provider.GetBlockhash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -94,7 +94,7 @@ public void Can_lookup_up_to_256_before_some_blocks_after_fast_sync() } long lookupNumber = current.Number - 256; - Hash256? result = provider.GetBlockhash(current.Header, lookupNumber); + Hash256 result = provider.GetBlockhash(current.Header, lookupNumber); Assert.NotNull(result); } @@ -115,7 +115,7 @@ public void Can_handle_non_main_chain_in_fast_sync() BlockhashProvider provider = new(tree, LimboLogs.Instance); - Hash256? result = provider.GetBlockhash(current.Header, 509); + Hash256 result = provider.GetBlockhash(current.Header, 509); Assert.NotNull(result); } @@ -131,7 +131,7 @@ public void Can_get_parent_hash() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockhash(current.Header, chainLength - 1); + Hash256 result = provider.GetBlockhash(current.Header, chainLength - 1); Assert.That(result, Is.EqualTo(head.Hash)); } @@ -146,7 +146,7 @@ public void Cannot_ask_for_self() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockhash(current.Header, chainLength); + Hash256 result = provider.GetBlockhash(current.Header, chainLength); Assert.Null(result); } @@ -161,7 +161,7 @@ public void Cannot_ask_about_future() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockhash(current.Header, chainLength + 1); + Hash256 result = provider.GetBlockhash(current.Header, chainLength + 1); Assert.Null(result); } @@ -176,7 +176,7 @@ public void Can_lookup_up_to_256_before() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockhash(current.Header, chainLength - 256); + Hash256 result = provider.GetBlockhash(current.Header, chainLength - 256); Assert.That(result, Is.EqualTo(tree.FindHeader(256, BlockTreeLookupOptions.None)!.Hash)); } @@ -191,7 +191,7 @@ public void No_lookup_more_than_256_before() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockhash(current.Header, chainLength - 257); + Hash256 result = provider.GetBlockhash(current.Header, chainLength - 257); Assert.Null(result); } @@ -206,7 +206,7 @@ public void UInt_256_overflow() BlockhashProvider provider = new(tree, LimboLogs.Instance); BlockHeader head = tree.FindHeader(chainLength - 1, BlockTreeLookupOptions.None)!; Block current = Build.A.Block.WithParent(head).TestObject; - Hash256? result = provider.GetBlockhash(current.Header, 127); + Hash256 result = provider.GetBlockhash(current.Header, 127); Assert.That(result, Is.EqualTo(head.Hash)); } } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs index 56cb8a99945..08a83248f7a 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs @@ -53,8 +53,7 @@ public PruningTestBlockchain() protected override async Task Build( ISpecProvider? specProvider = null, UInt256? initialValues = null, - bool addBlockOnStart = true, - bool pruning = false + bool addBlockOnStart = true ) { TestBlockchain chain = await base.Build(specProvider, initialValues, addBlockOnStart); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Validators/TestBlockValidator.cs b/src/Nethermind/Nethermind.Blockchain.Test/Validators/TestBlockValidator.cs index a9bfd109efb..23a4fb9dd26 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Validators/TestBlockValidator.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Validators/TestBlockValidator.cs @@ -56,7 +56,7 @@ public bool ValidateSuggestedBlock(Block block) { return _alwaysSameResultForSuggested ?? _suggestedValidationResults.Dequeue(); } - public bool ValidateSuggestedBlock(Block block, [NotNullWhen(false)] out string? error) + public bool ValidateSuggestedBlock(Block block, [NotNullWhen(false)] out string? error, bool validateHashes = true) { error = null; return _alwaysSameResultForSuggested ?? _suggestedValidationResults.Dequeue(); diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index 6d9a52c65c3..c54011a78e8 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -129,7 +129,8 @@ public BlockTree( _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); _bloomStorage = bloomStorage ?? throw new ArgumentNullException(nameof(bloomStorage)); _syncConfig = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig)); - _chainLevelInfoRepository = chainLevelInfoRepository ?? throw new ArgumentNullException(nameof(chainLevelInfoRepository)); + _chainLevelInfoRepository = chainLevelInfoRepository ?? + throw new ArgumentNullException(nameof(chainLevelInfoRepository)); byte[]? deletePointer = _blockInfoDb.Get(DeletePointerAddressInDb); if (deletePointer is not null) diff --git a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs index a376c944962..065211ac7a2 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockhashProvider.cs @@ -2,8 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.IO; using Nethermind.Blockchain.Find; using Nethermind.Core; @@ -13,14 +11,19 @@ namespace Nethermind.Blockchain { - public sealed class BlockhashProvider(IBlockTree blockTree, ILogManager? logManager) - : IBlockhashProvider + public class BlockhashProvider : IBlockhashProvider { private static readonly int _maxDepth = 256; - private readonly IBlockTree _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); - private readonly ILogger _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); + private readonly IBlockTree _blockTree; + private readonly ILogger _logger; - public Hash256? GetBlockhash(BlockHeader currentBlock, in long number) + public BlockhashProvider(IBlockTree blockTree, ILogManager? logManager) + { + _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); + _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); + } + + public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) { long current = currentBlock.Number; if (number >= current || number < current - Math.Min(current, _maxDepth)) @@ -30,15 +33,15 @@ public sealed class BlockhashProvider(IBlockTree blockTree, ILogManager? logMana bool isFastSyncSearch = false; - BlockHeader? header = _blockTree.FindParentHeader(currentBlock, BlockTreeLookupOptions.TotalDifficultyNotNeeded); + BlockHeader header = _blockTree.FindParentHeader(currentBlock, BlockTreeLookupOptions.TotalDifficultyNotNeeded); if (header is null) { - ThrowInvalidDataException(); + throw new InvalidDataException("Parent header cannot be found when executing BLOCKHASH operation"); } for (var i = 0; i < _maxDepth; i++) { - if (number == header!.Number) + if (number == header.Number) { if (_logger.IsTrace) _logger.Trace($"BLOCKHASH opcode returning {header.Number},{header.Hash} for {currentBlock.Number} -> {number}"); return header.Hash; @@ -47,10 +50,10 @@ public sealed class BlockhashProvider(IBlockTree blockTree, ILogManager? logMana header = _blockTree.FindParentHeader(header, BlockTreeLookupOptions.TotalDifficultyNotNeeded); if (header is null) { - ThrowInvalidDataException(); + throw new InvalidDataException("Parent header cannot be found when executing BLOCKHASH operation"); } - if (_blockTree.IsMainChain(header.Hash!) && !isFastSyncSearch) + if (_blockTree.IsMainChain(header.Hash) && !isFastSyncSearch) { try { @@ -66,7 +69,7 @@ public sealed class BlockhashProvider(IBlockTree blockTree, ILogManager? logMana if (!_blockTree.IsMainChain(header)) { header = currentHeader; - ThrowInvalidOperationException(); + throw new InvalidOperationException("Invoke fast blocks chain search"); } } } @@ -80,15 +83,5 @@ public sealed class BlockhashProvider(IBlockTree blockTree, ILogManager? logMana if (_logger.IsTrace) _logger.Trace($"BLOCKHASH opcode returning null for {currentBlock.Number} -> {number}"); return null; } - - [DoesNotReturn] - [StackTraceHidden] - private static void ThrowInvalidDataException() => - throw new InvalidDataException("Parent header cannot be found when executing BLOCKHASH operation"); - - [DoesNotReturn] - [StackTraceHidden] - private static void ThrowInvalidOperationException() => - throw new InvalidOperationException("Invoke fast blocks chain search"); } } diff --git a/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs b/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs index 0f4635229fc..962705967e4 100644 --- a/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs @@ -10,55 +10,63 @@ using Nethermind.Core; using Nethermind.Core.Collections; using Nethermind.Core.Crypto; +using Nethermind.Int256; namespace Nethermind.Blockchain { /// /// Safe to be reused for all classes reading the same wrapped block tree. /// - public class ReadOnlyBlockTree(IBlockTree wrapped) : IReadOnlyBlockTree + public class ReadOnlyBlockTree : IReadOnlyBlockTree { - public ulong NetworkId => wrapped.NetworkId; - public ulong ChainId => wrapped.ChainId; - public BlockHeader? Genesis => wrapped.Genesis; - public BlockHeader? BestSuggestedHeader => wrapped.BestSuggestedHeader; - public BlockHeader? BestSuggestedBeaconHeader => wrapped.BestSuggestedBeaconHeader; - public BlockHeader? LowestInsertedHeader => wrapped.LowestInsertedHeader; + private readonly IBlockTree _wrapped; + + public ReadOnlyBlockTree(IBlockTree wrapped) + { + _wrapped = wrapped; + } + + public ulong NetworkId => _wrapped.NetworkId; + public ulong ChainId => _wrapped.ChainId; + public BlockHeader Genesis => _wrapped.Genesis; + public BlockHeader BestSuggestedHeader => _wrapped.BestSuggestedHeader; + public BlockHeader BestSuggestedBeaconHeader => _wrapped.BestSuggestedBeaconHeader; + public BlockHeader LowestInsertedHeader => _wrapped.LowestInsertedHeader; public long? LowestInsertedBodyNumber { - get => wrapped.LowestInsertedBodyNumber; - set => wrapped.LowestInsertedBodyNumber = value; + get => _wrapped.LowestInsertedBodyNumber; + set => _wrapped.LowestInsertedBodyNumber = value; } public long? BestPersistedState { - get => wrapped.BestPersistedState; - set => wrapped.BestPersistedState = value; + get => _wrapped.BestPersistedState; + set => _wrapped.BestPersistedState = value; } public BlockHeader? LowestInsertedBeaconHeader { - get => wrapped.LowestInsertedBeaconHeader; - set => wrapped.LowestInsertedBeaconHeader = value; + get => _wrapped.LowestInsertedBeaconHeader; + set => _wrapped.LowestInsertedBeaconHeader = value; } - public Block? BestSuggestedBody => wrapped.BestSuggestedBody; - public long BestKnownNumber => wrapped.BestKnownNumber; - public long BestKnownBeaconNumber => wrapped.BestKnownBeaconNumber; - public Block? Head => wrapped.Head; + public Block BestSuggestedBody => _wrapped.BestSuggestedBody; + public long BestKnownNumber => _wrapped.BestKnownNumber; + public long BestKnownBeaconNumber => _wrapped.BestKnownBeaconNumber; + public Block Head => _wrapped.Head; public void MarkChainAsProcessed(IReadOnlyList blocks) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(MarkChainAsProcessed)} calls"); - public (BlockInfo Info, ChainLevelInfo Level) GetInfo(long number, Hash256 blockHash) => wrapped.GetInfo(number, blockHash); + public (BlockInfo Info, ChainLevelInfo Level) GetInfo(long number, Hash256 blockHash) => _wrapped.GetInfo(number, blockHash); public bool CanAcceptNewBlocks { get; } = false; public async Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken) { - await wrapped.Accept(blockTreeVisitor, cancellationToken); + await _wrapped.Accept(blockTreeVisitor, cancellationToken); } - public ChainLevelInfo? FindLevel(long number) => wrapped.FindLevel(number); - public BlockInfo FindCanonicalBlockInfo(long blockNumber) => wrapped.FindCanonicalBlockInfo(blockNumber); + public ChainLevelInfo FindLevel(long number) => _wrapped.FindLevel(number); + public BlockInfo FindCanonicalBlockInfo(long blockNumber) => _wrapped.FindCanonicalBlockInfo(blockNumber); public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOptions = BlockTreeInsertBlockOptions.None, BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None, WriteFlags blockWriteFlags = WriteFlags.None) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(Insert)} calls"); @@ -68,7 +76,7 @@ public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBloc public void UpdateHeadBlock(Hash256 blockHash) { // hacky while there is not special tree for RPC - wrapped.UpdateHeadBlock(blockHash); + _wrapped.UpdateHeadBlock(blockHash); } public AddBlockResult SuggestBlock(Block block, BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(SuggestBlock)} calls"); @@ -79,40 +87,40 @@ public void UpdateHeadBlock(Hash256 blockHash) public AddBlockResult SuggestHeader(BlockHeader header) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(SuggestHeader)} calls"); - public Hash256 HeadHash => wrapped.HeadHash; - public Hash256 GenesisHash => wrapped.GenesisHash; - public Hash256? PendingHash => wrapped.PendingHash; - public Hash256? FinalizedHash => wrapped.FinalizedHash; - public Hash256? SafeHash => wrapped.SafeHash; + public Hash256 HeadHash => _wrapped.HeadHash; + public Hash256 GenesisHash => _wrapped.GenesisHash; + public Hash256 PendingHash => _wrapped.PendingHash; + public Hash256 FinalizedHash => _wrapped.FinalizedHash; + public Hash256 SafeHash => _wrapped.SafeHash; - public Block? FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => wrapped.FindBlock(blockHash, options, blockNumber); + public Block FindBlock(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => _wrapped.FindBlock(blockHash, options, blockNumber); - public BlockHeader? FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => wrapped.FindHeader(blockHash, options, blockNumber: blockNumber); + public BlockHeader FindHeader(Hash256 blockHash, BlockTreeLookupOptions options, long? blockNumber = null) => _wrapped.FindHeader(blockHash, options, blockNumber: blockNumber); - public BlockHeader? FindHeader(long blockNumber, BlockTreeLookupOptions options) => wrapped.FindHeader(blockNumber, options); - public Hash256? FindBlockHash(long blockNumber) => wrapped.FindBlockHash(blockNumber); + public BlockHeader FindHeader(long blockNumber, BlockTreeLookupOptions options) => _wrapped.FindHeader(blockNumber, options); + public Hash256 FindBlockHash(long blockNumber) => _wrapped.FindBlockHash(blockNumber); - public bool IsMainChain(BlockHeader blockHeader) => wrapped.IsMainChain(blockHeader); + public bool IsMainChain(BlockHeader blockHeader) => _wrapped.IsMainChain(blockHeader); - public Hash256 FindHash(long blockNumber) => wrapped.FindHash(blockNumber); + public Hash256 FindHash(long blockNumber) => _wrapped.FindHash(blockNumber); - public IOwnedReadOnlyList FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) => wrapped.FindHeaders(hash, numberOfBlocks, skip, reverse); + public IOwnedReadOnlyList FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse) => _wrapped.FindHeaders(hash, numberOfBlocks, skip, reverse); - public BlockHeader FindLowestCommonAncestor(BlockHeader firstDescendant, BlockHeader secondDescendant, long maxSearchDepth) => wrapped.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth); + public BlockHeader FindLowestCommonAncestor(BlockHeader firstDescendant, BlockHeader secondDescendant, long maxSearchDepth) => _wrapped.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth); - public Block? FindBlock(long blockNumber, BlockTreeLookupOptions options) => wrapped.FindBlock(blockNumber, options); + public Block FindBlock(long blockNumber, BlockTreeLookupOptions options) => _wrapped.FindBlock(blockNumber, options); public void DeleteInvalidBlock(Block invalidBlock) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(DeleteInvalidBlock)} calls"); - public bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true) => wrapped.IsMainChain(blockHash, throwOnMissingHash); + public bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true) => _wrapped.IsMainChain(blockHash, throwOnMissingHash); - public BlockHeader FindBestSuggestedHeader() => wrapped.FindBestSuggestedHeader(); + public BlockHeader FindBestSuggestedHeader() => _wrapped.FindBestSuggestedHeader(); - public bool IsKnownBlock(long number, Hash256 blockHash) => wrapped.IsKnownBlock(number, blockHash); + public bool IsKnownBlock(long number, Hash256 blockHash) => _wrapped.IsKnownBlock(number, blockHash); - public bool IsKnownBeaconBlock(long number, Hash256 blockHash) => wrapped.IsKnownBeaconBlock(number, blockHash); + public bool IsKnownBeaconBlock(long number, Hash256 blockHash) => _wrapped.IsKnownBeaconBlock(number, blockHash); - public bool WasProcessed(long number, Hash256 blockHash) => wrapped.WasProcessed(number, blockHash); + public bool WasProcessed(long number, Hash256 blockHash) => _wrapped.WasProcessed(number, blockHash); public event EventHandler NewBestSuggestedBlock { @@ -160,13 +168,13 @@ public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool fo { for (long i = start; i <= endSearch; i++) { - yield return wrapped.FindHeader(i, BlockTreeLookupOptions.None); + yield return _wrapped.FindHeader(i, BlockTreeLookupOptions.None); } } if (force || GetPotentiallyCorruptedBlocks(startNumber).Any(b => b is null)) { - return wrapped.DeleteChainSlice(startNumber, endNumber, force); + return _wrapped.DeleteChainSlice(startNumber, endNumber, force); } throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} cannot {nameof(DeleteChainSlice)} if searched blocks [{startNumber}, {endSearch}] are not corrupted."); @@ -182,7 +190,7 @@ public int DeleteChainSlice(in long startNumber, long? endNumber = null, bool fo } - public bool IsBetterThanHead(BlockHeader? header) => wrapped.IsBetterThanHead(header); + public bool IsBetterThanHead(BlockHeader? header) => _wrapped.IsBetterThanHead(header); public void UpdateBeaconMainChain(BlockInfo[]? blockInfos, long clearBeaconMainChainStartPoint) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(UpdateBeaconMainChain)} calls"); public void RecalculateTreeLevels() => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(RecalculateTreeLevels)} calls"); diff --git a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs index 426f605340f..bc002797513 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs @@ -13,110 +13,173 @@ namespace Nethermind.Cli.Modules { [CliModule("eth")] - public class EthCliModule(ICliEngine cliEngine, INodeManager nodeManager) : CliModuleBase(cliEngine, nodeManager) + public class EthCliModule : CliModuleBase { private string? SendEth(Address from, Address address, in UInt256 amountInWei) { long blockNumber = NodeManager.Post("eth_blockNumber").Result; - TransactionForRpc tx = new() - { - Value = amountInWei, - Gas = Transaction.BaseTxGasCost, - GasPrice = (UInt256)Engine.JintEngine.GetValue("gasPrice").AsNumber(), - To = address, - Nonce = (ulong)NodeManager.Post("eth_getTransactionCount", from, blockNumber).Result, - From = from - }; + TransactionForRpc tx = new(); + tx.Value = amountInWei; + tx.Gas = Transaction.BaseTxGasCost; + tx.GasPrice = (UInt256)Engine.JintEngine.GetValue("gasPrice").AsNumber(); + tx.To = address; + tx.Nonce = (ulong)NodeManager.Post("eth_getTransactionCount", from, blockNumber).Result; + tx.From = from; Hash256? keccak = NodeManager.Post("eth_sendTransaction", tx).Result; return keccak?.Bytes.ToHexString(); } [CliFunction("eth", "syncing")] - public JsValue Syncing() => NodeManager.PostJint("eth_syncing").Result; + public JsValue Syncing() + { + return NodeManager.PostJint("eth_syncing").Result; + } [CliFunction("eth", "getProof")] - public JsValue GetProof(string address, string[] storageKeys, string? blockParameter = null) => - NodeManager.PostJint("eth_getProof", CliParseAddress(address), storageKeys.Select(CliParseHash), blockParameter ?? "latest").Result; + public JsValue GetProof(string address, string[] storageKeys, string? blockParameter = null) + { + return NodeManager.PostJint("eth_getProof", CliParseAddress(address), storageKeys.Select(CliParseHash), blockParameter ?? "latest").Result; + } [CliFunction("eth", "call")] - public string? Call(object tx, string? blockParameter = null) => - NodeManager.Post("eth_call", tx, blockParameter ?? "latest").Result; + public string? Call(object tx, string? blockParameter = null) + { + return NodeManager.Post("eth_call", tx, blockParameter ?? "latest").Result; + } [CliFunction("eth", "simulateV1")] public JsValue SimulateV1(ulong version, object[] blockCalls, string? blockParameter = null, bool traceTransfers = true) => NodeManager.PostJint("eth_simulateV1", 1, blockCalls, blockParameter ?? "latest", traceTransfers).Result; [CliFunction("eth", "getBlockByHash")] - public JsValue GetBlockByHash(string hash, bool returnFullTransactionObjects) => - NodeManager.PostJint("eth_getBlockByHash", CliParseHash(hash), returnFullTransactionObjects).Result; + public JsValue GetBlockByHash(string hash, bool returnFullTransactionObjects) + { + return NodeManager.PostJint("eth_getBlockByHash", CliParseHash(hash), returnFullTransactionObjects).Result; + } [CliFunction("eth", "getTransactionCount")] - public string? GetTransactionCount(string address, string? blockParameter = null) => - NodeManager.Post("eth_getTransactionCount", CliParseAddress(address), blockParameter ?? "latest").Result; + public string? GetTransactionCount(string address, string? blockParameter = null) + { + return NodeManager.Post("eth_getTransactionCount", CliParseAddress(address), blockParameter ?? "latest").Result; + } [CliFunction("eth", "getStorageAt")] - public string? GetStorageAt(string address, string positionIndex, string? blockParameter = null) => - NodeManager.Post("eth_getStorageAt", CliParseAddress(address), positionIndex, blockParameter ?? "latest").Result; + public string? GetStorageAt(string address, string positionIndex, string? blockParameter = null) + { + return NodeManager.Post("eth_getStorageAt", CliParseAddress(address), positionIndex, blockParameter ?? "latest").Result; + } [CliFunction("eth", "getBlockByNumber")] - public JsValue GetBlockByNumber(string blockParameter, bool returnFullTransactionObjects = false) => - NodeManager.PostJint("eth_getBlockByNumber", blockParameter, returnFullTransactionObjects).Result; + public JsValue GetBlockByNumber(string blockParameter, bool returnFullTransactionObjects = false) + { + return NodeManager.PostJint("eth_getBlockByNumber", blockParameter, returnFullTransactionObjects).Result; + } [CliFunction("eth", "sendEth")] - public string? SendEth(string from, string to, decimal amountInEth) => - SendEth(CliParseAddress(from), CliParseAddress(to), (UInt256)(amountInEth * (decimal)1.Ether())); + public string? SendEth(string from, string to, decimal amountInEth) + { + return SendEth(CliParseAddress(from), CliParseAddress(to), (UInt256)(amountInEth * (decimal)1.Ether())); + } [CliFunction("eth", "estimateGas")] - public string? EstimateGas(object json, string? blockParameter = null) => - NodeManager.Post("eth_estimateGas", json, blockParameter ?? "latest").Result; + public string? EstimateGas(object json, string? blockParameter = null) + { + return NodeManager.Post("eth_estimateGas", json, blockParameter ?? "latest").Result; + } [CliFunction("eth", "createAccessList")] - public JsValue CreateAccessList(object tx, string? blockParameter = null, bool optimize = true) => - optimize ? + public JsValue CreateAccessList(object tx, string? blockParameter = null, bool optimize = true) + { + if (optimize) + { // to support Geth - NodeManager.PostJint("eth_createAccessList", tx, blockParameter ?? "latest").Result - : NodeManager.PostJint("eth_createAccessList", tx, blockParameter ?? "latest", optimize).Result; + return NodeManager.PostJint("eth_createAccessList", tx, blockParameter ?? "latest").Result; + } + else + { + return NodeManager.PostJint("eth_createAccessList", tx, blockParameter ?? "latest", optimize).Result; + } + } [CliFunction("eth", "sendWei")] - public string? SendWei(string from, string to, BigInteger amountInWei) => SendEth(CliParseAddress(from), CliParseAddress(to), (UInt256)amountInWei); + public string? SendWei(string from, string to, BigInteger amountInWei) + { + return SendEth(CliParseAddress(from), CliParseAddress(to), (UInt256)amountInWei); + } [CliFunction("eth", "sendRawTransaction")] - public string? SendRawTransaction(string txRlp) => NodeManager.Post("eth_sendRawTransaction", txRlp).Result; + public string? SendRawTransaction(string txRlp) + { + return NodeManager.Post("eth_sendRawTransaction", txRlp).Result; + } [CliFunction("eth", "sendTransaction")] - public string? SendTransaction(object tx) => NodeManager.Post("eth_sendTransaction", tx).Result; + public string? SendTransaction(object tx) + { + return NodeManager.Post("eth_sendTransaction", tx).Result; + } [CliProperty("eth", "blockNumber")] - public long BlockNumber() => NodeManager.Post("eth_blockNumber").Result; + public long BlockNumber() + { + return NodeManager.Post("eth_blockNumber").Result; + } [CliFunction("eth", "getCode")] - public string? GetCode(string address, string? blockParameter = null) => NodeManager.Post("eth_getCode", CliParseAddress(address), blockParameter ?? "latest").Result; + public string? GetCode(string address, string? blockParameter = null) + { + return NodeManager.Post("eth_getCode", CliParseAddress(address), blockParameter ?? "latest").Result; + } [CliFunction("eth", "getBlockTransactionCountByNumber")] - public long GetBlockTransactionCountByNumber(string? blockParameter) => NodeManager.Post("eth_getBlockTransactionCountByNumber", blockParameter).Result; + public long GetBlockTransactionCountByNumber(string? blockParameter) + { + return NodeManager.Post("eth_getBlockTransactionCountByNumber", blockParameter).Result; + } [CliFunction("eth", "getBlockTransactionCountByHash")] - public long GetBlockTransactionCountByHash(string hash) => NodeManager.Post("eth_getBlockTransactionCountByHash", CliParseHash(hash)).Result; + public long GetBlockTransactionCountByHash(string hash) + { + return NodeManager.Post("eth_getBlockTransactionCountByHash", CliParseHash(hash)).Result; + } [CliFunction("eth", "getUncleCountByBlockNumber")] - public long GetUncleCountByBlockNumber(string blockParameter) => NodeManager.Post("eth_getUncleCountByBlockNumber", blockParameter).Result; + public long GetUncleCountByBlockNumber(string blockParameter) + { + return NodeManager.Post("eth_getUncleCountByBlockNumber", blockParameter).Result; + } [CliFunction("eth", "getUncleByBlockNumberAndIndex")] - public JsValue GetUncleByBlockNumberAndIndex(string blockParameter, int index) => NodeManager.PostJint("eth_getUncleByBlockNumberAndIndex", blockParameter, index).Result; + public JsValue GetUncleByBlockNumberAndIndex(string blockParameter, int index) + { + return NodeManager.PostJint("eth_getUncleByBlockNumberAndIndex", blockParameter, index).Result; + } [CliFunction("eth", "getUncleByBlockHashAndIndex")] - public JsValue GetUncleByBlockHashAndIndex(string hash, int index) => NodeManager.PostJint("eth_getUncleByBlockHashAndIndex", CliParseHash(hash), index).Result; + public JsValue GetUncleByBlockHashAndIndex(string hash, int index) + { + return NodeManager.PostJint("eth_getUncleByBlockHashAndIndex", CliParseHash(hash), index).Result; + } [CliFunction("eth", "getTransactionByBlockNumberAndIndex")] - public JsValue GetTransactionByBlockNumberAndIndex(string blockParameter, string index) => NodeManager.PostJint("eth_getTransactionByBlockNumberAndIndex", blockParameter, index).Result; + public JsValue GetTransactionByBlockNumberAndIndex(string blockParameter, string index) + { + return NodeManager.PostJint("eth_getTransactionByBlockNumberAndIndex", blockParameter, index).Result; + } [CliFunction("eth", "getTransactionByHash")] - public JsValue GetTransactionByHash(string txHash) => NodeManager.PostJint("eth_getTransactionByHash", CliParseHash(txHash)).Result; + public JsValue GetTransactionByHash(string txHash) + { + return NodeManager.PostJint("eth_getTransactionByHash", CliParseHash(txHash)).Result; + } [CliProperty("eth", "pendingTransactions")] - public JsValue PendingTransactions() => NodeManager.PostJint("eth_pendingTransactions").Result; + public JsValue PendingTransactions() + { + return NodeManager.PostJint("eth_pendingTransactions").Result; + } [CliFunction("eth", "getTransactionReceipt")] public JsValue GetTransactionReceipt(string txHash) @@ -125,33 +188,67 @@ public JsValue GetTransactionReceipt(string txHash) } [CliFunction("eth", "getBalance")] - public BigInteger GetBalance(string address, string? blockParameter = null) => NodeManager.Post("eth_getBalance", CliParseAddress(address), blockParameter ?? "latest").Result; + public BigInteger GetBalance(string address, string? blockParameter = null) + { + return NodeManager.Post("eth_getBalance", CliParseAddress(address), blockParameter ?? "latest").Result; + } [CliProperty("eth", "chainId")] - public string? ChainId() => NodeManager.Post("eth_chainId").Result; + public string? ChainId() + { + return NodeManager.Post("eth_chainId").Result; + } [CliProperty("eth", "protocolVersion")] - public JsValue ProtocolVersion() => NodeManager.PostJint("eth_protocolVersion").Result; + public JsValue ProtocolVersion() + { + return NodeManager.PostJint("eth_protocolVersion").Result; + } [CliFunction("eth", "getLogs")] - public JsValue GetLogs(object filter) => NodeManager.PostJint("eth_getLogs", filter).Result; + public JsValue GetLogs(object filter) + { + return NodeManager.PostJint("eth_getLogs", filter).Result; + } [CliFunction("eth", "getFilterChanges")] - public JsValue GetFilterChanges(long filterId) => NodeManager.PostJint("eth_getFilterChanges", filterId).Result; + public JsValue GetFilterChanges(long filterId) + { + return NodeManager.PostJint("eth_getFilterChanges", filterId).Result; + } [CliFunction("eth", "newPendingTransactionFilter")] - public long NewPendingTransactionFilter() => NodeManager.Post("eth_newPendingTransactionFilter").Result; + public long NewPendingTransactionFilter() + { + return NodeManager.Post("eth_newPendingTransactionFilter").Result; + } [CliFunction("eth", "feeHistory")] - public JsValue FeeHistory(long blockCount, string newestBlock, double[]? rewardPercentiles = null) => NodeManager.PostJint("eth_feeHistory", blockCount, newestBlock, rewardPercentiles!).Result; + public JsValue FeeHistory(long blockCount, string newestBlock, double[]? rewardPercentiles = null) + { + return NodeManager.PostJint("eth_feeHistory", blockCount, newestBlock, rewardPercentiles!).Result; + } [CliFunction("eth", "gasPrice")] - public JsValue GasPrice() => NodeManager.PostJint("eth_gasPrice").Result; + public JsValue GasPrice() + { + return NodeManager.PostJint("eth_gasPrice").Result; + } [CliFunction("eth", "maxPriorityFeePerGas")] - public JsValue MaxPriorityFeePerGas() => NodeManager.PostJint("eth_maxPriorityFeePerGas").Result; + public JsValue MaxPriorityFeePerGas() + { + return NodeManager.PostJint("eth_maxPriorityFeePerGas").Result; + } [CliFunction("eth", "getAccount")] - public JsValue GetAccount(Address accountAddress, string? blockParam = null) => NodeManager.PostJint("eth_getAccount", accountAddress, blockParam ?? "latest").Result; + public JsValue GetAccount(Address accountAddress, string? blockParam = null) + { + return NodeManager.PostJint("eth_getAccount", accountAddress, blockParam ?? "latest").Result; + } + + public EthCliModule(ICliEngine cliEngine, INodeManager nodeManager) : base(cliEngine, nodeManager) + { + } } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidators.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidators.cs index d116f5179d6..ee2a0c429f4 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidators.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/PendingValidators.cs @@ -11,7 +11,7 @@ public class PendingValidators { static PendingValidators() { - Rlp.Decoders[typeof(PendingValidators)] = new PendingValidatorsDecoder(); + Rlp.RegisterDecoder(typeof(PendingValidators), new PendingValidatorsDecoder()); } public PendingValidators(long blockNumber, Hash256 blockHash, Address[] addresses) diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfo.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfo.cs index 90d6a25c8c9..92af2d99efa 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfo.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorInfo.cs @@ -10,7 +10,7 @@ public class ValidatorInfo { static ValidatorInfo() { - Rlp.Decoders[typeof(ValidatorInfo)] = new ValidatorInfoDecoder(); + Rlp.RegisterDecoder(typeof(ValidatorInfo), new ValidatorInfoDecoder()); } public ValidatorInfo(long finalizingBlockNumber, long previousFinalizingBlockNumber, Address[] validators) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index bd2bdeb1ddf..b812599e2ff 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -85,7 +85,7 @@ public event EventHandler TransactionProcessed } // TODO: move to branch processor - public Block[] Process(Hash256 newBranchStateRoot, IReadOnlyList suggestedBlocks, ProcessingOptions options, IBlockTracer blockTracer) + public Block[] Process(Hash256 newBranchStateRoot, List suggestedBlocks, ProcessingOptions options, IBlockTracer blockTracer) { if (suggestedBlocks.Count == 0) return Array.Empty(); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs index ec6473ef6d4..3dad052417f 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs @@ -22,8 +22,9 @@ public interface IBlockProcessor /// Block tracer to use. By default either or /// /// List of processed blocks. - Block[] Process(Hash256 newBranchStateRoot, - IReadOnlyList suggestedBlocks, + Block[] Process( + Hash256 newBranchStateRoot, + List suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/NullBlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/NullBlockProcessor.cs index 979aad8c506..ad47599ff84 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/NullBlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/NullBlockProcessor.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Evm.Tracing; @@ -16,7 +15,7 @@ private NullBlockProcessor() { } public static IBlockProcessor Instance { get; } = new NullBlockProcessor(); - public Block[] Process(Hash256 newBranchStateRoot, IReadOnlyList suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer) + public Block[] Process(Hash256 newBranchStateRoot, List suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer) { return suggestedBlocks.ToArray(); } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs index ee77182b03a..f292d5bfff7 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Generic; using System.Diagnostics; using Nethermind.Blockchain; using Nethermind.Core; @@ -97,8 +98,8 @@ public void UpdateStats(Block? block, IBlockTree blockTreeCtx, int recoveryQueue long reportMs = Environment.TickCount64; if (reportMs - _lastReportMs > 1000) { - long currentStateDbReads = Db.Metrics.StateDbReads; - long currentStateDbWrites = Db.Metrics.StateDbWrites; + long currentStateDbReads = Db.Metrics.DbReads.GetValueOrDefault("StateDb"); + long currentStateDbWrites = Db.Metrics.DbWrites.GetValueOrDefault("StateDb"); long currentTreeNodeRlp = Trie.Metrics.TreeNodeRlpEncodings + Trie.Metrics.TreeNodeRlpDecodings; long evmExceptions = Evm.Metrics.EvmExceptions; long currentSelfDestructs = Evm.Metrics.SelfDestructs; diff --git a/src/Nethermind/Nethermind.Consensus/Validators/AlwaysValid.cs b/src/Nethermind/Nethermind.Consensus/Validators/AlwaysValid.cs index 85abab721b0..92ec5b749bf 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/AlwaysValid.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/AlwaysValid.cs @@ -102,7 +102,7 @@ public bool ValidateOrphanedBlock(Block block, out string? error) return _result; } - public bool ValidateSuggestedBlock(Block block, out string? error) + public bool ValidateSuggestedBlock(Block block, out string? error, bool validateHashes = true) { error = null; return _result; diff --git a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs index 902bf829380..58562b9b536 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs @@ -88,15 +88,17 @@ public bool ValidateSuggestedBlock(Block block) { return ValidateSuggestedBlock(block, out _); } + /// /// Suggested block validation runs basic checks that can be executed before going through the expensive EVM processing. /// /// A block to validate /// Message detailing a validation failure. + /// /// /// true if the is valid; otherwise, false. /// - public bool ValidateSuggestedBlock(Block block, out string? errorMessage) + public bool ValidateSuggestedBlock(Block block, out string? errorMessage, bool validateHashes = true) { IReleaseSpec spec = _specProvider.GetSpec(block.Header); @@ -113,14 +115,14 @@ public bool ValidateSuggestedBlock(Block block, out string? errorMessage) return false; } - if (!ValidateUnclesHashMatches(block, out Hash256 unclesHash)) + if (validateHashes && !ValidateUnclesHashMatches(block, out Hash256 unclesHash)) { if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} Uncles hash mismatch: expected {block.Header.UnclesHash}, got {unclesHash}"); errorMessage = BlockErrorMessages.InvalidUnclesHash; return false; } - if (!_unclesValidator.Validate(block.Header, block.Uncles)) + if (block.Uncles.Length > 0 && !_unclesValidator.Validate(block.Header, block.Uncles)) { if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} Invalid uncles"); errorMessage = BlockErrorMessages.InvalidUncle; @@ -134,15 +136,20 @@ public bool ValidateSuggestedBlock(Block block, out string? errorMessage) return false; } + if (validateHashes) + { if (!ValidateTxRootMatchesTxs(block, out Hash256 txRoot)) { if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} Transaction root hash mismatch: expected {block.Header.TxRoot}, got {txRoot}"); - errorMessage = BlockErrorMessages.InvalidTxRoot(block.Header.TxRoot, txRoot); + errorMessage = BlockErrorMessages.InvalidTxRoot(block.Header.TxRoot!, txRoot); return false; } if (!ValidateWithdrawals(block, spec, out errorMessage)) + { return false; + } + } return true; } diff --git a/src/Nethermind/Nethermind.Consensus/Validators/IBlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/IBlockValidator.cs index efc9d858277..e31754c8870 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/IBlockValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/IBlockValidator.cs @@ -9,6 +9,6 @@ namespace Nethermind.Consensus.Validators; public interface IBlockValidator : IHeaderValidator, IWithdrawalValidator { bool ValidateOrphanedBlock(Block block, [NotNullWhen(false)] out string? error); - bool ValidateSuggestedBlock(Block block, [NotNullWhen(false)] out string? error); + bool ValidateSuggestedBlock(Block block, [NotNullWhen(false)] out string? error, bool validateHashes = true); bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock, [NotNullWhen(false)] out string? error); } diff --git a/src/Nethermind/Nethermind.Consensus/Validators/NeverValidBlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/NeverValidBlockValidator.cs index 9982dea2e4c..de1a3fa77bf 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/NeverValidBlockValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/NeverValidBlockValidator.cs @@ -55,7 +55,7 @@ public bool ValidateOrphanedBlock(Block block, out string? error) return false; } - public bool ValidateSuggestedBlock(Block block, out string? error) + public bool ValidateSuggestedBlock(Block block, out string? error, bool validateHashes = true) { error = null; return false; diff --git a/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs b/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs index 80401f518f1..34801deef76 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs @@ -7,21 +7,15 @@ namespace Nethermind.Consensus.Validators; public class SimulateBlockValidatorProxy(IBlockValidator baseBlockValidator) : IBlockValidator { - public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle = false) => - baseBlockValidator.Validate(header, parent, isUncle); - - public bool Validate(BlockHeader header, bool isUncle = false) => - baseBlockValidator.Validate(header, isUncle); - public bool ValidateWithdrawals(Block block, out string? error) => baseBlockValidator.ValidateWithdrawals(block, out error); public bool ValidateOrphanedBlock(Block block, out string? error) => baseBlockValidator.ValidateOrphanedBlock(block, out error); - public bool ValidateSuggestedBlock(Block block, out string? error) + public bool ValidateSuggestedBlock(Block block, out string? error, bool validateHashes = true) { - return baseBlockValidator.ValidateSuggestedBlock(block, out error); + return baseBlockValidator.ValidateSuggestedBlock(block, out error, validateHashes); } public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock, out string? error) diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index 06332a6663d..efa49593a59 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -121,18 +121,14 @@ protected TestBlockchain() protected virtual async Task Build( ISpecProvider? specProvider = null, UInt256? initialValues = null, - bool addBlockOnStart = true, - bool pruning = false) + bool addBlockOnStart = true) { Timestamper = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc)); JsonSerializer = new EthereumJsonSerializer(); SpecProvider = CreateSpecProvider(specProvider ?? MainnetSpecProvider.Instance); EthereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId, LogManager); DbProvider = await CreateDbProvider(); - TrieStore = pruning - ? new TrieStore(StateDb, new MemoryLimit(10.KB()), new ConstantInterval(10), LogManager) - : new TrieStore(StateDb, LogManager); - + TrieStore = new TrieStore(StateDb, LogManager); State = new WorldState(TrieStore, DbProvider.CodeDb, LogManager); // Eip4788 precompile state account diff --git a/src/Nethermind/Nethermind.Core/BlockchainIds.cs b/src/Nethermind/Nethermind.Core/BlockchainIds.cs index 7ec21bfa62b..d2ec8c54276 100644 --- a/src/Nethermind/Nethermind.Core/BlockchainIds.cs +++ b/src/Nethermind/Nethermind.Core/BlockchainIds.cs @@ -8,7 +8,6 @@ namespace Nethermind.Core /// 0: Olympic, Ethereum public pre-release PoW testnet /// 1: Expanse, an alternative Ethereum implementation, chain ID 2 /// 2: Morden Classic, the public Ethereum Classic PoW testnet - /// 42: Kovan, the public Parity-only PoA testnet /// 60: GoChain, the GoChain networks mainnet /// 99: Core, the public POA Network main network /// 100: Gnosis, the public Gnosis main network @@ -49,7 +48,6 @@ public static string GetBlockchainName(ulong networkId) Goerli => nameof(Goerli), RootstockMainnet => nameof(RootstockMainnet), RootstockTestnet => nameof(RootstockTestnet), - Kovan => nameof(Kovan), EthereumClassicMainnet => nameof(EthereumClassicMainnet), EthereumClassicTestnet => nameof(EthereumClassicTestnet), DefaultGethPrivateChain => nameof(DefaultGethPrivateChain), diff --git a/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs b/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs index 67ba0bad755..9e5c9b2cd3c 100644 --- a/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs +++ b/src/Nethermind/Nethermind.Core/ByteArrayConverter.cs @@ -81,6 +81,7 @@ public override void Write( Convert(writer, bytes, skipLeadingZeros: false); } + [SkipLocalsInit] public static void Convert(Utf8JsonWriter writer, ReadOnlySpan bytes, bool skipLeadingZeros = true) { Convert(writer, @@ -101,7 +102,7 @@ public static void Convert( const int maxStackLength = 128; const int stackLength = 256; - int leadingNibbleZeros = skipLeadingZeros ? bytes.CountLeadingZeros() : 0; + int leadingNibbleZeros = skipLeadingZeros ? bytes.CountLeadingNibbleZeros() : 0; int length = bytes.Length * 2 - leadingNibbleZeros + 2 + (addQuotations ? 2 : 0); byte[]? array = null; diff --git a/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs b/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs index 85b1bd8c7cb..b6a6936d599 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs @@ -649,7 +649,7 @@ public static string ByteArrayToHexViaLookup32Safe(byte[] bytes, bool withZeroX) private static string ByteArrayToHexViaLookup32(byte[] bytes, bool withZeroX, bool skipLeadingZeros, bool withEip55Checksum) { - int leadingZerosFirstCheck = skipLeadingZeros ? CountLeadingZeros(bytes) : 0; + int leadingZerosFirstCheck = skipLeadingZeros ? CountLeadingNibbleZeros(bytes) : 0; int length = bytes.Length * 2 + (withZeroX ? 2 : 0) - leadingZerosFirstCheck; if (skipLeadingZeros && length == (withZeroX ? 2 : 0)) { @@ -943,30 +943,78 @@ private static uint[] CreateLookup32(string format) return result; } - public static int CountLeadingZeros(this ReadOnlySpan bytes) + public static int CountLeadingNibbleZeros(this ReadOnlySpan bytes) { - int leadingZeros = 0; - for (int i = 0; i < bytes.Length; i++) + int firstNonZero = bytes.IndexOfAnyExcept((byte)0); + if (firstNonZero < 0) { - if ((bytes[i] & 0b1111_0000) == 0) + return bytes.Length * 2; + } + + int leadingZeros = firstNonZero * 2; + if ((bytes[firstNonZero] & 0b1111_0000) == 0) { leadingZeros++; - if ((bytes[i] & 0b1111) == 0) + } + + return leadingZeros; + } + + public static int CountZeros(this Span data) + => CountZeros((ReadOnlySpan)data); + + public static int CountZeros(this ReadOnlySpan data) { - leadingZeros++; + int totalZeros = 0; + if (Vector512.IsHardwareAccelerated && data.Length >= Vector512.Count) + { + ref byte bytes = ref MemoryMarshal.GetReference(data); + int i = 0; + for (; i < data.Length - Vector512.Count; i += Vector512.Count) + { + Vector512 dataVector = Unsafe.ReadUnaligned>(ref Unsafe.Add(ref bytes, i)); + ulong flags = Vector512.Equals(dataVector, default).ExtractMostSignificantBits(); + totalZeros += BitOperations.PopCount(flags); } - else + + data = data[i..]; + } + if (Vector256.IsHardwareAccelerated && data.Length >= Vector256.Count) + { + ref byte bytes = ref MemoryMarshal.GetReference(data); + int i = 0; + for (; i < data.Length - Vector256.Count; i += Vector256.Count) { - break; + Vector256 dataVector = Unsafe.ReadUnaligned>(ref Unsafe.Add(ref bytes, i)); + uint flags = Vector256.Equals(dataVector, default).ExtractMostSignificantBits(); + totalZeros += BitOperations.PopCount(flags); } + + data = data[i..]; } - else + if (Vector128.IsHardwareAccelerated && data.Length >= Vector128.Count) + { + ref byte bytes = ref MemoryMarshal.GetReference(data); + int i = 0; + for (; i < data.Length - Vector128.Count; i += Vector128.Count) { - break; + Vector128 dataVector = Unsafe.ReadUnaligned>(ref Unsafe.Add(ref MemoryMarshal.GetReference(data), i)); + uint flags = Vector128.Equals(dataVector, default).ExtractMostSignificantBits(); + totalZeros += BitOperations.PopCount(flags); } + + data = data[i..]; } - return leadingZeros; + for (int i = 0; i < data.Length; i++) + { + if (data[i] == 0) + { + totalZeros++; + } + } + + return totalZeros; } [DebuggerStepThrough] diff --git a/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs b/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs index 0ba94c59549..99b4b7645fe 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/SpanExtensions.cs @@ -57,7 +57,7 @@ private unsafe static string ToHexViaLookup(ReadOnlySpan bytes, bool withZ } if (bytes.Length == 0) return ""; - int leadingZeros = skipLeadingZeros ? Bytes.CountLeadingZeros(bytes) : 0; + int leadingZeros = skipLeadingZeros ? Bytes.CountLeadingNibbleZeros(bytes) : 0; int length = bytes.Length * 2 + (withZeroX ? 2 : 0) - leadingZeros; if (skipLeadingZeros && length == (withZeroX ? 2 : 0)) @@ -90,7 +90,7 @@ private static string ToHexStringWithEip55Checksum(ReadOnlySpan bytes, boo { string hashHex = Keccak.Compute(bytes.ToHexString(false)).ToString(false); - int leadingZeros = skipLeadingZeros ? Bytes.CountLeadingZeros(bytes) : 0; + int leadingZeros = skipLeadingZeros ? Bytes.CountLeadingNibbleZeros(bytes) : 0; int length = bytes.Length * 2 + (withZeroX ? 2 : 0) - leadingZeros; if (leadingZeros >= 2) { @@ -154,6 +154,7 @@ public static ReadOnlySpan TakeAndMove(this ref ReadOnlySpan span, i span = span[length..]; return s; } + public static bool IsNullOrEmpty(this in Span span) => span.Length == 0; public static bool IsNull(this in Span span) => Unsafe.IsNullRef(ref MemoryMarshal.GetReference(span)); public static bool IsNullOrEmpty(this in ReadOnlySpan span) => span.Length == 0; diff --git a/src/Nethermind/Nethermind.Db/Metrics.cs b/src/Nethermind/Nethermind.Db/Metrics.cs index 64c5fb306e4..2d9a7c5ad0e 100644 --- a/src/Nethermind/Nethermind.Db/Metrics.cs +++ b/src/Nethermind/Nethermind.Db/Metrics.cs @@ -11,201 +11,33 @@ namespace Nethermind.Db public static class Metrics { [CounterMetric] - [Description("_Deprecated._ Number of Bloom DB reads.")] - public static long BloomDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Bloom DB writes.")] - public static long BloomDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of CHT DB reads.")] - public static long CHTDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of CHT DB writes.")] - public static long CHTDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Blocks DB reads.")] - public static long BlocksDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Blocks DB writes.")] - public static long BlocksDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Code DB cache reads.")] + [Description("Number of Code DB cache reads.")] public static long CodeDbCache { get; set; } [CounterMetric] - [Description("_Deprecated._ Number of Code DB reads.")] - public static long CodeDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Code DB writes.")] - public static long CodeDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Receipts DB reads.")] - public static long ReceiptsDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Receipts DB writes.")] - public static long ReceiptsDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Block Infos DB reads.")] - public static long BlockInfosDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Block Infos DB writes.")] - public static long BlockInfosDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of State Trie reads.")] + [Description("Number of State Trie reads.")] public static long StateTreeReads { get; set; } [CounterMetric] - [Description("_Deprecated._ Number of Blocks Trie writes.")] + [Description("Number of Blocks Trie writes.")] public static long StateTreeWrites { get; set; } - [CounterMetric] - [Description("_Deprecated._ Number of State DB reads.")] - public static long StateDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of State DB writes.")] - public static long StateDbWrites { get; set; } - [CounterMetric] [Description("Number of State DB duplicate writes during full pruning.")] public static int StateDbInPruningWrites; [CounterMetric] - [Description("_Deprecated._ Number of storage trie reads.")] + [Description("Number of storage trie reads.")] public static long StorageTreeReads { get; set; } [CounterMetric] - [Description("_Deprecated._ Number of storage trie writes.")] + [Description("Number of storage trie writes.")] public static long StorageTreeWrites { get; set; } - [CounterMetric] - [Description("_Deprecated._ Number of other DB reads.")] - public static long OtherDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of other DB writes.")] - public static long OtherDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Headers DB reads.")] - public static long HeaderDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Headers DB writes.")] - public static long HeaderDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of BlockNumbers DB reads.")] - public static long BlockNumberDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of BlockNumbers DB writes.")] - public static long BlockNumberDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Witness DB reads.")] - public static long WitnessDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Witness DB writes.")] - public static long WitnessDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Metadata DB reads.")] - public static long MetadataDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of Metadata DB writes.")] - public static long MetadataDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of BadBlocks DB writes.")] - public static long BadBlocksDbWrites { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of BadBlocks DB reads.")] - public static long BadBlocksDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of BlobTransactions DB reads.")] - public static long BlobTransactionsDbReads { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of BlobTransactions DB writes.")] - public static long BlobTransactionsDbWrites { get; set; } - [GaugeMetric] - [Description("_Deprecated._ Indicator if StadeDb is being pruned.")] + [Description("Indicator if StadeDb is being pruned.")] public static int StateDbPruning { get; set; } - [GaugeMetric] - [Description("_Deprecated._ Size of state DB in bytes")] - public static long StateDbSize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of receipts DB in bytes")] - public static long ReceiptsDbSize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of headers DB in bytes")] - public static long HeadersDbSize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of blocks DB in bytes")] - public static long BlocksDbSize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of bloom DB in bytes")] - public static long BloomDbSize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of code DB in bytes")] - public static long CodeDbSize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of blockInfos DB in bytes")] - public static long BlockInfosDbSize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of cht DB in bytes")] - public static long ChtDbSize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of metadata DB in bytes")] - public static long MetadataDbSize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of witness DB in bytes")] - public static long WitnessDbSize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of unmanaged memory for DB block caches in bytes")] - public static long DbBlockCacheMemorySize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of unmanaged memory for DB indexes and filters in bytes")] - public static long DbIndexFilterMemorySize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of unmanaged memory for DB memtables in bytes")] - public static long DbMemtableMemorySize { get; set; } - - [GaugeMetric] - [Description("_Deprecated._ Size of total unmanaged memory for DB in bytes")] - public static long DbTotalMemorySize { get; set; } - [GaugeMetric] [Description("Database reads per database")] [KeyIsLabel("db")] diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs index 076a597ab8c..9d8e167b7a7 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs @@ -23,12 +23,12 @@ public class EvmBenchmarks { public static byte[] ByteCode { get; set; } - private readonly IReleaseSpec _spec = MainnetSpecProvider.Instance.GetSpec((ForkActivation)MainnetSpecProvider.IstanbulBlockNumber); - private readonly ITxTracer _txTracer = NullTxTracer.Instance; + private IReleaseSpec _spec = MainnetSpecProvider.Instance.GetSpec((ForkActivation)MainnetSpecProvider.IstanbulBlockNumber); + private ITxTracer _txTracer = NullTxTracer.Instance; private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; - private readonly BlockHeader _header = new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.IstanbulBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private readonly IBlockhashProvider _blockhashProvider = new TestBlockhashProvider(); + private BlockHeader _header = new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.IstanbulBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); + private IBlockhashProvider _blockhashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs index 15f21963011..b4d3792de3e 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs @@ -23,12 +23,12 @@ namespace Nethermind.Evm.Benchmark [MemoryDiagnoser] public class StaticCallBenchmarks { - private readonly IReleaseSpec _spec = MainnetSpecProvider.Instance.GetSpec((ForkActivation)MainnetSpecProvider.IstanbulBlockNumber); - private readonly ITxTracer _txTracer = NullTxTracer.Instance; + private IReleaseSpec _spec = MainnetSpecProvider.Instance.GetSpec((ForkActivation)MainnetSpecProvider.IstanbulBlockNumber); + private ITxTracer _txTracer = NullTxTracer.Instance; private ExecutionEnvironment _environment; private IVirtualMachine _virtualMachine; - private readonly BlockHeader _header = new(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.MuirGlacierBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); - private readonly IBlockhashProvider _blockhashProvider = new TestBlockhashProvider(); + private BlockHeader _header = new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.One, MainnetSpecProvider.MuirGlacierBlockNumber, Int64.MaxValue, 1UL, Bytes.Empty); + private IBlockhashProvider _blockhashProvider = new TestBlockhashProvider(); private EvmState _evmState; private WorldState _stateProvider; diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs index d53a1cf96f0..c95162989f5 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/TestBlockhashProvider.cs @@ -8,7 +8,9 @@ namespace Nethermind.Evm.Benchmark { public class TestBlockhashProvider : IBlockhashProvider { - public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) => - Keccak.Compute(number.ToString()); + public Hash256 GetBlockhash(BlockHeader currentBlock, in long number) + { + return Keccak.Compute(number.ToString()); + } } } diff --git a/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs b/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs index 526ef98db21..7054c8f3ec1 100644 --- a/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs +++ b/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs @@ -262,7 +262,7 @@ public Prepare PushData(ReadOnlyMemory data) public Prepare PushData(byte data) { - PushData([data]); + PushData(new[] { data }); return this; } diff --git a/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs b/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs index 8cf6358c051..6d167abac09 100644 --- a/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs +++ b/src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs @@ -14,7 +14,13 @@ public class CodeInfo : IThreadPoolWorkItem public IPrecompile? Precompile { get; set; } private readonly JumpDestinationAnalyzer _analyzer; private static readonly JumpDestinationAnalyzer _emptyAnalyzer = new(Array.Empty()); - public static CodeInfo Empty { get; } = new(Array.Empty()); + public static CodeInfo Empty { get; } = new CodeInfo(Array.Empty()); + + public CodeInfo(byte[] code) + { + MachineCode = code; + _analyzer = code.Length == 0 ? _emptyAnalyzer : new JumpDestinationAnalyzer(code); + } public CodeInfo(ReadOnlyMemory code) { diff --git a/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs b/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs index ff225c7790d..3cbc1b9335d 100644 --- a/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Evm/IBlockhashProvider.cs @@ -8,6 +8,6 @@ namespace Nethermind.Evm { public interface IBlockhashProvider { - Hash256? GetBlockhash(BlockHeader currentBlock, in long number); + Hash256 GetBlockhash(BlockHeader currentBlock, in long number); } } diff --git a/src/Nethermind/Nethermind.Evm/IntrinsicGasCalculator.cs b/src/Nethermind/Nethermind.Evm/IntrinsicGasCalculator.cs index f3e54899438..7742bcfc5ba 100644 --- a/src/Nethermind/Nethermind.Evm/IntrinsicGasCalculator.cs +++ b/src/Nethermind/Nethermind.Evm/IntrinsicGasCalculator.cs @@ -2,12 +2,16 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Collections.Generic; using System.IO; +using System.Numerics; using Nethermind.Core; using Nethermind.Core.Eip2930; using Nethermind.Core.Specs; using Nethermind.Int256; +using System.Runtime.Intrinsics; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using Nethermind.Core.Extensions; namespace Nethermind.Evm; @@ -37,19 +41,17 @@ private static long DataCost(Transaction transaction, IReleaseSpec releaseSpec) { long txDataNonZeroGasCost = releaseSpec.IsEip2028Enabled ? GasCostOf.TxDataNonZeroEip2028 : GasCostOf.TxDataNonZero; - long dataCost = 0; Span data = transaction.Data.GetValueOrDefault().Span; - for (int i = 0; i < data.Length; i++) - { - dataCost += data[i] == 0 ? GasCostOf.TxDataZero : txDataNonZeroGasCost; - } - if (transaction.IsContractCreation && releaseSpec.IsEip3860Enabled) - { - dataCost += EvmPooledMemory.Div32Ceiling((UInt256)data.Length) * GasCostOf.InitCodeWord; - } + int totalZeros = data.CountZeros(); + + var baseDataCost = (transaction.IsContractCreation && releaseSpec.IsEip3860Enabled + ? EvmPooledMemory.Div32Ceiling((UInt256)data.Length) * GasCostOf.InitCodeWord + : 0); - return dataCost; + return baseDataCost + + totalZeros * GasCostOf.TxDataZero + + (data.Length - totalZeros) * txDataNonZeroGasCost; } private static long AccessListCost(Transaction transaction, IReleaseSpec releaseSpec) diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index 960d573f408..f3e3a2d8022 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -36,17 +36,17 @@ namespace Nethermind.Facade.Test { public class BlockchainBridgeTests { - private BlockchainBridge _blockchainBridge = null!; - private IBlockTree _blockTree = null!; - private ITxPool _txPool = null!; - private IReceiptStorage _receiptStorage = null!; - private IFilterStore _filterStore = null!; - private IFilterManager _filterManager = null!; - private ITransactionProcessor _transactionProcessor = null!; - private IEthereumEcdsa _ethereumEcdsa = null!; - private ManualTimestamper _timestamper = null!; - private ISpecProvider _specProvider = null!; - private IDbProvider _dbProvider = null!; + private BlockchainBridge _blockchainBridge; + private IBlockTree _blockTree; + private ITxPool _txPool; + private IReceiptStorage _receiptStorage; + private IFilterStore _filterStore; + private IFilterManager _filterManager; + private ITransactionProcessor _transactionProcessor; + private IEthereumEcdsa _ethereumEcdsa; + private ManualTimestamper _timestamper; + private ISpecProvider _specProvider; + private IDbProvider _dbProvider; [SetUp] public async Task SetUp() diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 350c5cc81b6..48281e945e2 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -169,7 +169,7 @@ private void UpdateStateByModifyingAccounts( //try { IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!); - currentBlocks = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer); + currentBlocks = processor.Process(stateProvider.StateRoot, suggestedBlocks.ToList(), processingFlags, tracer); } //catch (Exception) diff --git a/src/Nethermind/Nethermind.Init/Steps/StartMonitoring.cs b/src/Nethermind/Nethermind.Init/Steps/StartMonitoring.cs index 097f6ce9463..f919a010c1a 100644 --- a/src/Nethermind/Nethermind.Init/Steps/StartMonitoring.cs +++ b/src/Nethermind/Nethermind.Init/Steps/StartMonitoring.cs @@ -92,10 +92,6 @@ private void SetupMetrics(IMonitoringService monitoringService) return; } - long totalBlockCacheMemorySize = 0; - long totalIndexAndFilterMemorySize = 0; - long totalMemtableMemorySize = 0; - foreach (KeyValuePair kv in dbProvider.GetAllDbMeta()) { // Note: At the moment, the metric for a columns db is combined across column. @@ -106,96 +102,7 @@ private void SetupMetrics(IMonitoringService monitoringService) Db.Metrics.DbIndexFilterSize[kv.Key] = dbMetric.IndexSize; Db.Metrics.DbReads[kv.Key] = dbMetric.TotalReads; Db.Metrics.DbWrites[kv.Key] = dbMetric.TotalWrites; - - totalBlockCacheMemorySize += dbMetric.CacheSize; - totalIndexAndFilterMemorySize += dbMetric.IndexSize; - totalMemtableMemorySize += dbMetric.MemtableSize; - } - - // You dont need this, just use `sum` in prometheus, this is what happen when you don't use label. - Db.Metrics.DbBlockCacheMemorySize = totalBlockCacheMemorySize; - Db.Metrics.DbIndexFilterMemorySize = totalIndexAndFilterMemorySize; - Db.Metrics.DbMemtableMemorySize = totalMemtableMemorySize; - Db.Metrics.DbTotalMemorySize = Db.Metrics.DbBlockCacheMemorySize - + Db.Metrics.DbIndexFilterMemorySize - + Db.Metrics.DbMemtableMemorySize; - - - // Please don't use these anymore. Just use label... I'm just adding it here to not break existing dashboard. - // TODO: Remove this... please - IDbMeta.DbMetric stateDbMetric = dbProvider.StateDb.GatherMetric(includeSharedCache: true); - IDbMeta.DbMetric receiptDbMetric = dbProvider.ReceiptsDb.GatherMetric(); - IDbMeta.DbMetric headerDbMetric = dbProvider.HeadersDb.GatherMetric(); - IDbMeta.DbMetric blocksDbMetric = dbProvider.BlocksDb.GatherMetric(); - IDbMeta.DbMetric blockNumberDbMetric = dbProvider.BlockNumbersDb.GatherMetric(); - IDbMeta.DbMetric badBlockDbMetric = dbProvider.BadBlocksDb.GatherMetric(); - IDbMeta.DbMetric bloomDbMetric = dbProvider.BloomDb.GatherMetric(); - IDbMeta.DbMetric codeDbMetric = dbProvider.CodeDb.GatherMetric(); - IDbMeta.DbMetric blockInfoDbMetric = dbProvider.BlockInfosDb.GatherMetric(); - IDbMeta.DbMetric chtDbMetric = dbProvider.ChtDb.GatherMetric(); - IDbMeta.DbMetric metadataDbMetric = dbProvider.MetadataDb.GatherMetric(); - IDbMeta.DbMetric witnessDbMetric = dbProvider.WitnessDb.GatherMetric(); - IDbMeta.DbMetric blobTransactionDbMetric = new IDbMeta.DbMetric(); - try - { - blobTransactionDbMetric = dbProvider.BlobTransactionsDb.GatherMetric(); } - catch (ArgumentException) - { - // Sometime its not registered. - } - - Db.Metrics.StateDbSize = stateDbMetric.Size; - Db.Metrics.StateDbReads = stateDbMetric.TotalReads; - Db.Metrics.StateDbWrites = stateDbMetric.TotalWrites; - - Db.Metrics.ReceiptsDbSize = receiptDbMetric.Size; - Db.Metrics.ReceiptsDbReads = receiptDbMetric.TotalReads; - Db.Metrics.ReceiptsDbWrites = receiptDbMetric.TotalWrites; - - // Look at what just happen, one metric have `s`, two other dont. Just use label. - Db.Metrics.HeadersDbSize = headerDbMetric.Size; - Db.Metrics.HeaderDbReads = headerDbMetric.TotalReads; - Db.Metrics.HeaderDbWrites = headerDbMetric.TotalWrites; - - Db.Metrics.BlocksDbSize = blocksDbMetric.Size; - Db.Metrics.BlocksDbReads = blocksDbMetric.TotalReads; - Db.Metrics.BlocksDbWrites = blocksDbMetric.TotalWrites; - - // Guess what? this one does not have db size and stuff. - Db.Metrics.BlockNumberDbReads = blockNumberDbMetric.TotalReads; - Db.Metrics.BlockNumberDbReads = blockNumberDbMetric.TotalWrites; - - Db.Metrics.BadBlocksDbReads = badBlockDbMetric.TotalReads; - Db.Metrics.BadBlocksDbWrites = badBlockDbMetric.TotalWrites; - - Db.Metrics.BloomDbSize = bloomDbMetric.Size; - Db.Metrics.BloomDbReads = bloomDbMetric.TotalReads; - Db.Metrics.BloomDbWrites = bloomDbMetric.TotalWrites; - - Db.Metrics.CodeDbSize = codeDbMetric.Size; - Db.Metrics.CodeDbReads = codeDbMetric.TotalReads; - Db.Metrics.CodeDbWrites = codeDbMetric.TotalWrites; - - Db.Metrics.BlockInfosDbSize = blockInfoDbMetric.Size; - Db.Metrics.BlockInfosDbReads = blockInfoDbMetric.TotalReads; - Db.Metrics.BlockInfosDbWrites = blockInfoDbMetric.TotalWrites; - - // Ooo look! One is capitalized differently. **snap a picture like in a zoo** - Db.Metrics.ChtDbSize = chtDbMetric.Size; - Db.Metrics.CHTDbReads = chtDbMetric.TotalReads; - Db.Metrics.CHTDbWrites = chtDbMetric.TotalWrites; - - Db.Metrics.MetadataDbSize = metadataDbMetric.Size; - Db.Metrics.MetadataDbReads = metadataDbMetric.TotalReads; - Db.Metrics.MetadataDbWrites = metadataDbMetric.TotalWrites; - - Db.Metrics.WitnessDbSize = witnessDbMetric.Size; - Db.Metrics.WitnessDbReads = witnessDbMetric.TotalReads; - Db.Metrics.WitnessDbReads = witnessDbMetric.TotalWrites; - - Db.Metrics.BlobTransactionsDbReads = blobTransactionDbMetric.TotalReads; - Db.Metrics.BlobTransactionsDbWrites = blobTransactionDbMetric.TotalWrites; }); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs index a303132ab20..8bbb7bad3ad 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs @@ -37,7 +37,7 @@ public static Task CreateChain(IReleaseSpec? releaseSpec = nu TestSpecProvider testSpecProvider = releaseSpec is not null ? new TestSpecProvider(releaseSpec) : new TestSpecProvider(London.Instance); - return TestRpcBlockchain.ForTest(testMevRpcBlockchain).Build(testSpecProvider, null, true); + return TestRpcBlockchain.ForTest(testMevRpcBlockchain).Build(testSpecProvider, null); } private static string GetEcRecoverContractJsonAbi(string name = "recover") diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 433242b3d80..18e85f49476 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -107,19 +107,17 @@ public Builder WithConfig(IJsonRpcConfig config) public async Task Build( ISpecProvider? specProvider = null, - UInt256? initialValues = null, - bool pruning = false) => - (T)(await _blockchain.Build(specProvider, initialValues, true, pruning)); + UInt256? initialValues = null) => + (T)(await _blockchain.Build(specProvider, initialValues, true)); } protected override async Task Build( ISpecProvider? specProvider = null, UInt256? initialValues = null, - bool addBlockOnStart = true, - bool pruning = false) + bool addBlockOnStart = true) { specProvider ??= new TestSpecProvider(Berlin.Instance); - await base.Build(specProvider, initialValues, addBlockOnStart, pruning); + await base.Build(specProvider, initialValues, addBlockOnStart); IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = new FilterManager(filterStore, BlockProcessor, TxPool, LimboLogs.Instance); var dbProvider = new ReadOnlyDbProvider(DbProvider, false); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs index cf58cb863c1..cd10b95848b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs @@ -259,7 +259,7 @@ protected IBlockValidator CreateBlockValidator() public IManualBlockFinalizationManager BlockFinalizationManager { get; } = new ManualBlockFinalizationManager(); - protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true, bool pruning = false) + protected override async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true) { TestBlockchain chain = await base.Build(specProvider, initialValues); return chain; @@ -282,7 +282,7 @@ public TestBlockProcessorInterceptor(IBlockProcessor baseBlockProcessor, int del DelayMs = delayMs; } - public Block[] Process(Hash256 newBranchStateRoot, IReadOnlyList suggestedBlocks, ProcessingOptions processingOptions, + public Block[] Process(Hash256 newBranchStateRoot, List suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer) { if (DelayMs > 0) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/InvalidChainTracker/InvalidBlockInterceptorTest.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/InvalidChainTracker/InvalidBlockInterceptorTest.cs index 7483159ddbd..2d7f6226b01 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/InvalidChainTracker/InvalidBlockInterceptorTest.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/InvalidChainTracker/InvalidBlockInterceptorTest.cs @@ -43,8 +43,8 @@ public void Setup() public void TestValidateSuggestedBlock(bool baseReturnValue, bool isInvalidBlockReported) { Block block = Build.A.Block.TestObject; - _baseValidator.ValidateSuggestedBlock(block, out string? error).Returns(baseReturnValue); - _invalidBlockInterceptor.ValidateSuggestedBlock(block); + _baseValidator.ValidateSuggestedBlock(block, out _).Returns(baseReturnValue); + _invalidBlockInterceptor.ValidateSuggestedBlock(block, out _); _tracker.Received().SetChildParent(block.GetOrCalculateHash(), block.ParentHash!); if (isInvalidBlockReported) @@ -103,7 +103,7 @@ public void TestBlockWithNotMatchingTxShouldNotGetTracked() )); _baseValidator.ValidateSuggestedBlock(block, out _).Returns(false); - _invalidBlockInterceptor.ValidateSuggestedBlock(block); + _invalidBlockInterceptor.ValidateSuggestedBlock(block, out _); _tracker.DidNotReceive().SetChildParent(block.GetOrCalculateHash(), block.ParentHash!); _tracker.DidNotReceive().OnInvalidBlock(block.GetOrCalculateHash(), block.ParentHash); @@ -121,7 +121,7 @@ public void TestBlockWithIncorrectWithdrawalsShouldNotGetTracked() )); _baseValidator.ValidateSuggestedBlock(block, out _).Returns(false); - _invalidBlockInterceptor.ValidateSuggestedBlock(block); + _invalidBlockInterceptor.ValidateSuggestedBlock(block, out _); _tracker.DidNotReceive().SetChildParent(block.GetOrCalculateHash(), block.ParentHash!); _tracker.DidNotReceive().OnInvalidBlock(block.GetOrCalculateHash(), block.ParentHash); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs index 7e7d9f1b17b..d418492d139 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/NewPayloadHandler.cs @@ -154,7 +154,7 @@ public async Task> HandleAsync(ExecutionPayload r if (!ShouldProcessBlock(block, parentHeader, out ProcessingOptions processingOptions)) // we shouldn't process block { - if (!_blockValidator.ValidateSuggestedBlock(block, out string? error)) + if (!_blockValidator.ValidateSuggestedBlock(block, out string? error, validateHashes: false)) { if (_logger.IsInfo) _logger.Info($"Rejecting invalid block received during the sync, block: {block}"); return NewPayloadV1Result.Invalid(error); @@ -394,7 +394,7 @@ private bool ValidateWithBlockValidator(Block block, BlockHeader parent, out str { block.Header.TotalDifficulty ??= parent.TotalDifficulty + block.Difficulty; block.Header.IsPostMerge = true; // I think we don't need to set it again here. - bool isValid = _blockValidator.ValidateSuggestedBlock(block, out error); + bool isValid = _blockValidator.ValidateSuggestedBlock(block, out error, validateHashes: false); if (!isValid && _logger.IsWarn) _logger.Warn($"Block validator rejected the block {block.ToString(Block.Format.FullHashAndNumber)}."); return isValid; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/InvalidChainTracker/InvalidBlockInterceptor.cs b/src/Nethermind/Nethermind.Merge.Plugin/InvalidChainTracker/InvalidBlockInterceptor.cs index 2a3c9dd350e..87cbb58f650 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/InvalidChainTracker/InvalidBlockInterceptor.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/InvalidChainTracker/InvalidBlockInterceptor.cs @@ -69,13 +69,9 @@ public bool Validate(BlockHeader header, bool isUncle, [NotNullWhen(false)] out return result; } - public bool ValidateSuggestedBlock(Block block) + public bool ValidateSuggestedBlock(Block block, [NotNullWhen(false)] out string? error, bool validateHashes = true) { - return ValidateSuggestedBlock(block, out _); - } - public bool ValidateSuggestedBlock(Block block, [NotNullWhen(false)] out string? error) - { - bool result = _baseValidator.ValidateSuggestedBlock(block, out error); + bool result = _baseValidator.ValidateSuggestedBlock(block, out error, validateHashes); if (!result) { if (_logger.IsTrace) _logger.Trace($"Intercepted a bad block {block}"); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs index a82e764f4b0..2bb5ee7f4dd 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs @@ -188,17 +188,10 @@ protected override AddBlockResult InsertToBlockTree(BlockHeader header) if (insertOutcome == AddBlockResult.Added || insertOutcome == AddBlockResult.AlreadyKnown) { _nextHeaderHash = header.ParentHash!; - if (_expectedDifficultyOverride?.TryGetValue(header.Number, out ulong nextHeaderDiff) == true) - { - _nextHeaderDiff = nextHeaderDiff; - } - else - { _nextHeaderDiff = header.TotalDifficulty is not null && header.TotalDifficulty >= header.Difficulty ? header.TotalDifficulty - header.Difficulty : null; } - } if (_logger.IsTrace) _logger.Trace( diff --git a/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs b/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs index b544ef31d0a..c0a3b4b1168 100644 --- a/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.Mev.Test/MevRpcModuleTests.TestMevRpcBlockchain.cs @@ -220,7 +220,7 @@ protected override BlockProcessor CreateBlockProcessor() } protected override async Task Build(ISpecProvider? specProvider = null, - UInt256? initialValues = null, bool addBlockOnStart = true, bool pruning = false) + UInt256? initialValues = null, bool addBlockOnStart = true) { TestBlockchain chain = await base.Build(specProvider, initialValues); MevRpcModule = new MevRpcModule(new JsonRpcConfig(), diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/SessionTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/SessionTests.cs index 0a4c63b9d6b..3a9a3401b14 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/SessionTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/SessionTests.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Generic; using System.Threading.Tasks; using DotNetty.Transport.Channels; using FluentAssertions; @@ -598,11 +599,11 @@ public void Updates_local_and_remote_metrics_on_disconnects() IProtocolHandler p2p = BuildHandler("p2p", 10); session.AddProtocolHandler(p2p); - long beforeLocal = Network.Metrics.LocalOtherDisconnects; - long beforeRemote = Network.Metrics.OtherDisconnects; + long beforeLocal = Network.Metrics.LocalDisconnectsTotal.GetValueOrDefault(DisconnectReason.Other); + long beforeRemote = Network.Metrics.RemoteDisconnectsTotal.GetValueOrDefault(DisconnectReason.Other); session.MarkDisconnected(DisconnectReason.Other, DisconnectType.Local, string.Empty); - long afterLocal = Network.Metrics.LocalOtherDisconnects; - long afterRemote = Network.Metrics.OtherDisconnects; + long afterLocal = Network.Metrics.LocalDisconnectsTotal.GetValueOrDefault(DisconnectReason.Other); + long afterRemote = Network.Metrics.RemoteDisconnectsTotal.GetValueOrDefault(DisconnectReason.Other); Assert.That(afterLocal, Is.EqualTo(beforeLocal + 1)); Assert.That(afterRemote, Is.EqualTo(beforeRemote)); @@ -612,11 +613,11 @@ public void Updates_local_and_remote_metrics_on_disconnects() p2p = BuildHandler("p2p", 10); session.AddProtocolHandler(p2p); - beforeLocal = Network.Metrics.LocalOtherDisconnects; - beforeRemote = Network.Metrics.OtherDisconnects; + beforeLocal = Network.Metrics.LocalDisconnectsTotal.GetValueOrDefault(DisconnectReason.Other); + beforeRemote = Network.Metrics.RemoteDisconnectsTotal.GetValueOrDefault(DisconnectReason.Other); session.MarkDisconnected(DisconnectReason.Other, DisconnectType.Remote, string.Empty); - afterLocal = Network.Metrics.LocalOtherDisconnects; - afterRemote = Network.Metrics.OtherDisconnects; + afterLocal = Network.Metrics.LocalDisconnectsTotal.GetValueOrDefault(DisconnectReason.Other); + afterRemote = Network.Metrics.RemoteDisconnectsTotal.GetValueOrDefault(DisconnectReason.Other); Assert.That(afterLocal, Is.EqualTo(beforeLocal)); Assert.That(afterRemote, Is.EqualTo(beforeRemote + 1)); } diff --git a/src/Nethermind/Nethermind.Network.Test/Rlpx/Handshake/AuthEip8MessageSerializerTests.cs b/src/Nethermind/Nethermind.Network.Test/Rlpx/Handshake/AuthEip8MessageSerializerTests.cs index 88bfed8755a..7d155359e69 100644 --- a/src/Nethermind/Nethermind.Network.Test/Rlpx/Handshake/AuthEip8MessageSerializerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/Rlpx/Handshake/AuthEip8MessageSerializerTests.cs @@ -56,7 +56,6 @@ public void Encode_decode_before_eip155(int chainId) [TestCase(BlockchainIds.Mainnet)] [TestCase(BlockchainIds.Sepolia)] - [TestCase(BlockchainIds.Kovan)] public void Encode_decode_with_eip155(int chainId) { EthereumEcdsa ecdsa = new(BlockchainIds.Olympic, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Network.Test/Rlpx/Handshake/AuthMessageSerializerTests.cs b/src/Nethermind/Nethermind.Network.Test/Rlpx/Handshake/AuthMessageSerializerTests.cs index 5619d8f55ea..3b6626bb38c 100644 --- a/src/Nethermind/Nethermind.Network.Test/Rlpx/Handshake/AuthMessageSerializerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/Rlpx/Handshake/AuthMessageSerializerTests.cs @@ -58,7 +58,6 @@ public void Encode_decode_before_eip155(int chainId) [TestCase(BlockchainIds.Mainnet)] [TestCase(BlockchainIds.Sepolia)] - [TestCase(BlockchainIds.Kovan)] public void Encode_decode_with_eip155(int chainId) { EthereumEcdsa ecdsa = new(BlockchainIds.Olympic, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Network/Metrics.cs b/src/Nethermind/Nethermind.Network/Metrics.cs index d3a0ab87b64..c8d7f1c84fa 100644 --- a/src/Nethermind/Nethermind.Network/Metrics.cs +++ b/src/Nethermind/Nethermind.Network/Metrics.cs @@ -51,306 +51,6 @@ public static class Metrics [Description("Number of devp2p handshake timeouts")] public static long HandshakeTimeouts { get; set; } - [CounterMetric] - [Description("_Deprecated._ Number of devp2p hello messages received")] - public static long HellosReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of devp2p hello messages sent")] - public static long HellosSent { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth status messages received")] - public static long StatusesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth status messages sent")] - public static long StatusesSent { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of les status messages received")] - public static long LesStatusesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of les status messages sent")] - public static long LesStatusesSent { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to breach of protocol")] - public static long BreachOfProtocolDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to useless peer")] - public static long UselessPeerDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to too many peers")] - public static long TooManyPeersDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to already connected")] - public static long AlreadyConnectedDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to incompatible devp2p version")] - public static long IncompatibleP2PDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to request timeouts")] - public static long ReceiveMessageTimeoutDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to peer identity information mismatch")] - public static long UnexpectedIdentityDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to missing peer identity")] - public static long NullNodeIdentityDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to client quitting")] - public static long ClientQuittingDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to other reasons")] - public static long OtherDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to disconnect requested")] - public static long DisconnectRequestedDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of received disconnects due to connecting to self")] - public static long SameAsSelfDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of disconnects due to TCP error")] - public static long TcpSubsystemErrorDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of sent disconnects due to breach of protocol")] - public static long LocalBreachOfProtocolDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of sent disconnects due to useless peer")] - public static long LocalUselessPeerDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to breach of protocol")] - public static long LocalTooManyPeersDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to already connected")] - public static long LocalAlreadyConnectedDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to incompatible devp2p")] - public static long LocalIncompatibleP2PDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to request timeout")] - public static long LocalReceiveMessageTimeoutDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to node identity info mismatch")] - public static long LocalUnexpectedIdentityDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to missing node identity")] - public static long LocalNullNodeIdentityDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to client quitting")] - public static long LocalClientQuittingDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to other reason")] - public static long LocalOtherDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to disconnect requested")] - public static long LocalDisconnectRequestedDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to connection to self")] - public static long LocalSameAsSelfDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of initiated disconnects due to TCP error")] - public static long LocalTcpSubsystemErrorDisconnects { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.62 NewBlockHashes messages received")] - public static long Eth62NewBlockHashesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.62 Transactions messages received")] - public static long Eth62TransactionsReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.62 GetBlockHeaders messages received")] - public static long Eth62GetBlockHeadersReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.62 BlockHeaders messages received")] - public static long Eth62BlockHeadersReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.62 GetBlockBodies messages received")] - public static long Eth62GetBlockBodiesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.62 BlockBodies messages received")] - public static long Eth62BlockBodiesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.62 NewBlock messages received")] - public static long Eth62NewBlockReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.63 GetReceipts messages received")] - public static long Eth63GetReceiptsReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.63 Receipts messages received")] - public static long Eth63ReceiptsReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.63 GetNodeData messages received")] - public static long Eth63GetNodeDataReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.63 NodeData messages received")] - public static long Eth63NodeDataReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.65 NewPooledTransactionHashes messages received")] - public static long Eth65NewPooledTransactionHashesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.65 NewPooledTransactionHashes messages sent")] - public static long Eth65NewPooledTransactionHashesSent { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.68 NewPooledTransactionHashes messages received")] - public static long Eth68NewPooledTransactionHashesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.68 NewPooledTransactionHashes messages sent")] - public static long Eth68NewPooledTransactionHashesSent { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.65 GetPooledTransactions messages received")] - public static long Eth65GetPooledTransactionsReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.65 GetPooledTransactions messages sent")] - public static long Eth65GetPooledTransactionsRequested { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.65 PooledTransactions messages received")] - public static long Eth65PooledTransactionsReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 GetBlockHeaders messages received")] - public static long Eth66GetBlockHeadersReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 BlockHeaders messages received")] - public static long Eth66BlockHeadersReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 GetBlockBodies messages received")] - public static long Eth66GetBlockBodiesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 BlockBodies messages received")] - public static long Eth66BlockBodiesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 GetNodeData messages received")] - public static long Eth66GetNodeDataReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 NodeData messages received")] - public static long Eth66NodeDataReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 GetReceipts messages received")] - public static long Eth66GetReceiptsReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 Receipts messages received")] - public static long Eth66ReceiptsReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 GetPooledTransactions messages received")] - public static long Eth66GetPooledTransactionsReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 GetPooledTransactions messages sent")] - public static long Eth66GetPooledTransactionsRequested { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of eth.66 PooledTransactions messages received")] - public static long Eth66PooledTransactionsReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP GetAccountRange messages received")] - public static long SnapGetAccountRangeReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP GetAccountRange messages sent")] - public static long SnapGetAccountRangeSent { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP AccountRange messages received")] - public static long SnapAccountRangeReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP GetStorageRanges messages received")] - public static long SnapGetStorageRangesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP GetStorageRanges messages sent")] - public static long SnapGetStorageRangesSent { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP StorageRanges messages received")] - public static long SnapStorageRangesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP GetByteCodes messages received")] - public static long SnapGetByteCodesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP GetByteCodes messages sent")] - public static long SnapGetByteCodesSent { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP ByteCodes messages received")] - public static long SnapByteCodesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP GetTrieNodes messages received")] - public static long SnapGetTrieNodesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP GetTrieNodes messages sent")] - public static long SnapGetTrieNodesSent { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of SNAP TrieNodes messages received")] - public static long SnapTrieNodesReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of GetNodeData messages received via NodeData protocol")] - public static long GetNodeDataReceived { get; set; } - - [CounterMetric] - [Description("_Deprecated._ Number of NodeData messages received via NodeData protocol")] - public static long NodeDataReceived { get; set; } - [CounterMetric] [Description("_Deprecated._ Number of bytes sent through P2P (TCP).")] public static long P2PBytesSent; diff --git a/src/Nethermind/Nethermind.Network/NetworkNodeDecoder.cs b/src/Nethermind/Nethermind.Network/NetworkNodeDecoder.cs index eb252b50e03..641d0657188 100644 --- a/src/Nethermind/Nethermind.Network/NetworkNodeDecoder.cs +++ b/src/Nethermind/Nethermind.Network/NetworkNodeDecoder.cs @@ -14,7 +14,7 @@ public class NetworkNodeDecoder : IRlpStreamDecoder, IRlpObjectDeco { static NetworkNodeDecoder() { - Rlp.Decoders[typeof(NetworkNode)] = new NetworkNodeDecoder(); + Rlp.RegisterDecoder(typeof(NetworkNode), new NetworkNodeDecoder()); } public NetworkNode Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) diff --git a/src/Nethermind/Nethermind.Network/P2P/Analyzers/MetricsDisconnectsAnalyzer.cs b/src/Nethermind/Nethermind.Network/P2P/Analyzers/MetricsDisconnectsAnalyzer.cs index 0f69e5a8261..5f7d063bb95 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Analyzers/MetricsDisconnectsAnalyzer.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Analyzers/MetricsDisconnectsAnalyzer.cs @@ -10,103 +10,7 @@ public class MetricsDisconnectsAnalyzer : IDisconnectsAnalyzer { public void ReportDisconnect(DisconnectReason reason, DisconnectType type, string details) { - EthDisconnectReason ethReason = reason.ToEthDisconnectReason(); - - if (type == DisconnectType.Remote) - { - Metrics.RemoteDisconnectsTotal.Increment(reason); - - switch (ethReason) - { - case EthDisconnectReason.BreachOfProtocol: - Metrics.BreachOfProtocolDisconnects++; - break; - case EthDisconnectReason.UselessPeer: - Metrics.UselessPeerDisconnects++; - break; - case EthDisconnectReason.TooManyPeers: - Metrics.TooManyPeersDisconnects++; - break; - case EthDisconnectReason.AlreadyConnected: - Metrics.AlreadyConnectedDisconnects++; - break; - case EthDisconnectReason.IncompatibleP2PVersion: - Metrics.IncompatibleP2PDisconnects++; - break; - case EthDisconnectReason.NullNodeIdentityReceived: - Metrics.NullNodeIdentityDisconnects++; - break; - case EthDisconnectReason.ClientQuitting: - Metrics.ClientQuittingDisconnects++; - break; - case EthDisconnectReason.UnexpectedIdentity: - Metrics.UnexpectedIdentityDisconnects++; - break; - case EthDisconnectReason.ReceiveMessageTimeout: - Metrics.ReceiveMessageTimeoutDisconnects++; - break; - case EthDisconnectReason.DisconnectRequested: - Metrics.DisconnectRequestedDisconnects++; - break; - case EthDisconnectReason.IdentitySameAsSelf: - Metrics.SameAsSelfDisconnects++; - break; - case EthDisconnectReason.TcpSubSystemError: - Metrics.TcpSubsystemErrorDisconnects++; - break; - default: - Metrics.OtherDisconnects++; - break; - } - } - - if (type == DisconnectType.Local) - { - Metrics.LocalDisconnectsTotal.Increment(reason); - - switch (ethReason) - { - case EthDisconnectReason.BreachOfProtocol: - Metrics.LocalBreachOfProtocolDisconnects++; - break; - case EthDisconnectReason.UselessPeer: - Metrics.LocalUselessPeerDisconnects++; - break; - case EthDisconnectReason.TooManyPeers: - Metrics.LocalTooManyPeersDisconnects++; - break; - case EthDisconnectReason.AlreadyConnected: - Metrics.LocalAlreadyConnectedDisconnects++; - break; - case EthDisconnectReason.IncompatibleP2PVersion: - Metrics.LocalIncompatibleP2PDisconnects++; - break; - case EthDisconnectReason.NullNodeIdentityReceived: - Metrics.LocalNullNodeIdentityDisconnects++; - break; - case EthDisconnectReason.ClientQuitting: - Metrics.LocalClientQuittingDisconnects++; - break; - case EthDisconnectReason.UnexpectedIdentity: - Metrics.LocalUnexpectedIdentityDisconnects++; - break; - case EthDisconnectReason.ReceiveMessageTimeout: - Metrics.LocalReceiveMessageTimeoutDisconnects++; - break; - case EthDisconnectReason.DisconnectRequested: - Metrics.LocalDisconnectRequestedDisconnects++; - break; - case EthDisconnectReason.IdentitySameAsSelf: - Metrics.LocalSameAsSelfDisconnects++; - break; - case EthDisconnectReason.TcpSubSystemError: - Metrics.LocalTcpSubsystemErrorDisconnects++; - break; - default: - Metrics.LocalOtherDisconnects++; - break; - } - } + (type == DisconnectType.Remote ? Metrics.RemoteDisconnectsTotal : Metrics.LocalDisconnectsTotal).Increment(reason); } } } diff --git a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/P2PProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/P2PProtocolHandler.cs index 728d3adac17..e5a3db6b9d6 100644 --- a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/P2PProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/P2PProtocolHandler.cs @@ -104,7 +104,6 @@ public override void HandleMessage(Packet msg) { case P2PMessageCode.Hello: { - Metrics.HellosReceived++; using HelloMessage helloMessage = Deserialize(msg.Data); HandleHello(helloMessage); ReportIn(helloMessage, size); @@ -328,7 +327,6 @@ private void SendHello() _sentHello = true; Send(helloMessage); - Metrics.HellosSent++; } private void HandlePing() diff --git a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs index d2aa29eb951..f65e44e8122 100644 --- a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs +++ b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/SyncPeerProtocolHandlerBase.cs @@ -282,7 +282,6 @@ private void SendMessage(IOwnedReadOnlyList txsToSend) protected async Task Handle(GetBlockHeadersMessage getBlockHeadersMessage, CancellationToken cancellationToken) { using GetBlockHeadersMessage message = getBlockHeadersMessage; - Metrics.Eth62GetBlockHeadersReceived++; Stopwatch stopwatch = Stopwatch.StartNew(); if (Logger.IsTrace) { @@ -338,7 +337,6 @@ startingHash is null protected async Task Handle(GetBlockBodiesMessage request, CancellationToken cancellationToken) { using GetBlockBodiesMessage message = request; - Metrics.Eth62GetBlockBodiesReceived++; if (Logger.IsTrace) { Logger.Trace($"Received bodies request of length {message.BlockHashes.Count} from {Session.Node:c}:"); @@ -376,20 +374,17 @@ protected Task FulfillBlockBodiesRequest(GetBlockBodiesMessa protected void Handle(BlockHeadersMessage message, long size) { - Metrics.Eth62BlockHeadersReceived++; _headersRequests.Handle(message.BlockHeaders, size); } protected void HandleBodies(BlockBodiesMessage blockBodiesMessage, long size) { - Metrics.Eth62BlockBodiesReceived++; _bodiesRequests.Handle((blockBodiesMessage.Bodies, size), size); } protected async Task Handle(GetReceiptsMessage msg, CancellationToken cancellationToken) { using var message = msg; - Metrics.Eth63GetReceiptsReceived++; if (message.Hashes.Count > 512) { throw new EthSyncException("Incoming receipts request for more than 512 blocks"); diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/PooledTxsRequestor.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/PooledTxsRequestor.cs index 0181aa0c9cd..05c9805e9d0 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/PooledTxsRequestor.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/PooledTxsRequestor.cs @@ -140,14 +140,12 @@ private ArrayPoolList AddMarkUnknownHashes(IReadOnlyList hashe private static void RequestPooledTransactions(Action send, IOwnedReadOnlyList hashesToRequest) { send(new GetPooledTransactionsMessage(hashesToRequest)); - Metrics.Eth65GetPooledTransactionsRequested++; } private static void RequestPooledTransactionsEth66(Action send, IOwnedReadOnlyList hashesToRequest) { GetPooledTransactionsMessage msg65 = new(hashesToRequest); send(new V66.Messages.GetPooledTransactionsMessage { EthMessage = msg65 }); - Metrics.Eth66GetPooledTransactionsRequested++; } } } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs index d800738904b..783c85e47d9 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs @@ -97,7 +97,6 @@ public override void Init() EnrichStatusMessage(statusMessage); - Metrics.StatusesSent++; Send(statusMessage); CheckProtocolInitTimeout().ContinueWith(x => @@ -149,7 +148,6 @@ bool CanAcceptBlockGossip() break; } case Eth62MessageCode.NewBlockHashes: - Metrics.Eth62NewBlockHashesReceived++; if (CanAcceptBlockGossip()) { using NewBlockHashesMessage newBlockHashesMessage = Deserialize(message.Content); @@ -158,7 +156,6 @@ bool CanAcceptBlockGossip() } break; case Eth62MessageCode.Transactions: - Metrics.Eth62TransactionsReceived++; if (CanReceiveTransactions) { if (_floodController.IsAllowed()) @@ -201,7 +198,6 @@ bool CanAcceptBlockGossip() HandleBodies(bodiesMsg, size); break; case Eth62MessageCode.NewBlock: - Metrics.Eth62NewBlockReceived++; if (CanAcceptBlockGossip()) { using NewBlockMessage newBlockMsg = Deserialize(message.Content); @@ -227,7 +223,6 @@ private bool EnsureGossipPolicy() private void Handle(StatusMessage status) { - Metrics.StatusesReceived++; if (_statusReceived) { throw new SubprotocolException($"{nameof(StatusMessage)} has already been received in the past"); diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Eth63ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Eth63ProtocolHandler.cs index 23e5885bf3b..be1d225effb 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Eth63ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V63/Eth63ProtocolHandler.cs @@ -99,14 +99,12 @@ public override void HandleMessage(ZeroPacket message) protected virtual void Handle(ReceiptsMessage msg, long size) { - Metrics.Eth63ReceiptsReceived++; _receiptsRequests.Handle((msg.TxReceipts, size), size); } private async Task Handle(GetNodeDataMessage msg, CancellationToken cancellationToken) { using var message = msg; - Metrics.Eth63GetNodeDataReceived++; Stopwatch stopwatch = Stopwatch.StartNew(); NodeDataMessage response = await FulfillNodeDataRequest(message, cancellationToken); @@ -130,7 +128,6 @@ protected Task FulfillNodeDataRequest(GetNodeDataMessage msg, C protected virtual void Handle(NodeDataMessage msg, int size) { - Metrics.Eth63NodeDataReceived++; _nodeDataRequests.Handle(msg.Data, size); } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandler.cs index ebd1d3620f1..59f36e2ddfb 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V65/Eth65ProtocolHandler.cs @@ -60,7 +60,6 @@ public override void HandleMessage(ZeroPacket message) if (CanReceiveTransactions) { PooledTransactionsMessage pooledTxMsg = Deserialize(message.Content); - Metrics.Eth65PooledTransactionsReceived++; ReportIn(pooledTxMsg, size); Handle(pooledTxMsg); } @@ -95,8 +94,6 @@ public override void HandleMessage(ZeroPacket message) protected virtual void Handle(NewPooledTransactionHashesMessage msg) { - Metrics.Eth65NewPooledTransactionHashesReceived++; - AddNotifiedTransactions(msg.Hashes); Stopwatch stopwatch = Stopwatch.StartNew(); @@ -121,8 +118,6 @@ protected void AddNotifiedTransactions(IReadOnlyList hashes) private async ValueTask Handle(GetPooledTransactionsMessage msg, CancellationToken cancellationToken) { using var message = msg; - Metrics.Eth65GetPooledTransactionsReceived++; - var stopwatch = Stopwatch.StartNew(); Send(await FulfillPooledTransactionsRequest(message, cancellationToken)); stopwatch.Stop(); @@ -197,7 +192,6 @@ private void SendNewPooledTransactionMessage(IOwnedReadOnlyList hashes) { NewPooledTransactionHashesMessage msg = new(hashes); Send(msg); - Metrics.Eth65NewPooledTransactionHashesSent++; } } } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V66/Eth66ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V66/Eth66ProtocolHandler.cs index 125fecabeca..95595b3b5c0 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V66/Eth66ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V66/Eth66ProtocolHandler.cs @@ -70,32 +70,27 @@ public override void HandleMessage(ZeroPacket message) { case Eth66MessageCode.GetBlockHeaders: GetBlockHeadersMessage getBlockHeadersMessage = Deserialize(message.Content); - Metrics.Eth66GetBlockHeadersReceived++; ReportIn(getBlockHeadersMessage, size); BackgroundTaskScheduler.ScheduleSyncServe(getBlockHeadersMessage, Handle); break; case Eth66MessageCode.BlockHeaders: BlockHeadersMessage headersMsg = Deserialize(message.Content); - Metrics.Eth66BlockHeadersReceived++; ReportIn(headersMsg, size); Handle(headersMsg, size); break; case Eth66MessageCode.GetBlockBodies: GetBlockBodiesMessage getBodiesMsg = Deserialize(message.Content); - Metrics.Eth66GetBlockBodiesReceived++; ReportIn(getBodiesMsg, size); BackgroundTaskScheduler.ScheduleSyncServe(getBodiesMsg, Handle); break; case Eth66MessageCode.BlockBodies: BlockBodiesMessage bodiesMsg = Deserialize(message.Content); - Metrics.Eth66BlockBodiesReceived++; ReportIn(bodiesMsg, size); HandleBodies(bodiesMsg, size); break; case Eth66MessageCode.GetPooledTransactions: GetPooledTransactionsMessage getPooledTxMsg = Deserialize(message.Content); - Metrics.Eth66GetPooledTransactionsReceived++; ReportIn(getPooledTxMsg, size); BackgroundTaskScheduler.ScheduleSyncServe(getPooledTxMsg, Handle); break; @@ -104,7 +99,6 @@ GetPooledTransactionsMessage getPooledTxMsg { PooledTransactionsMessage pooledTxMsg = Deserialize(message.Content); - Metrics.Eth66PooledTransactionsReceived++; ReportIn(pooledTxMsg, size); Handle(pooledTxMsg.EthMessage); } @@ -117,25 +111,21 @@ PooledTransactionsMessage pooledTxMsg break; case Eth66MessageCode.GetReceipts: GetReceiptsMessage getReceiptsMessage = Deserialize(message.Content); - Metrics.Eth66GetReceiptsReceived++; ReportIn(getReceiptsMessage, size); BackgroundTaskScheduler.ScheduleSyncServe(getReceiptsMessage, Handle); break; case Eth66MessageCode.Receipts: ReceiptsMessage receiptsMessage = Deserialize(message.Content); - Metrics.Eth66ReceiptsReceived++; ReportIn(receiptsMessage, size); Handle(receiptsMessage, size); break; case Eth66MessageCode.GetNodeData: GetNodeDataMessage getNodeDataMessage = Deserialize(message.Content); - Metrics.Eth66GetNodeDataReceived++; ReportIn(getNodeDataMessage, size); BackgroundTaskScheduler.ScheduleSyncServe(getNodeDataMessage, Handle); break; case Eth66MessageCode.NodeData: NodeDataMessage nodeDataMessage = Deserialize(message.Content); - Metrics.Eth66NodeDataReceived++; ReportIn(nodeDataMessage, size); Handle(nodeDataMessage, size); break; diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandler.cs index 0bd40e6fe08..15c0ace7a19 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V68/Eth68ProtocolHandler.cs @@ -90,7 +90,6 @@ private void Handle(NewPooledTransactionHashesMessage68 msg) throw new SubprotocolException(errorMessage); } - Metrics.Eth68NewPooledTransactionHashesReceived++; TxPool.Metrics.PendingTransactionsHashesReceived += message.Hashes.Count; AddNotifiedTransactions(message.Hashes); @@ -166,7 +165,6 @@ protected override void SendNewTransactionsCore(IEnumerable txs, bo private void SendMessage(IOwnedReadOnlyList types, IOwnedReadOnlyList sizes, IOwnedReadOnlyList hashes) { NewPooledTransactionHashesMessage68 message = new(types, sizes, hashes); - Metrics.Eth68NewPooledTransactionHashesSent++; Send(message); } } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Les/LesProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Les/LesProtocolHandler.cs index 963da8db843..d1d71d1f40a 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Les/LesProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Les/LesProtocolHandler.cs @@ -76,8 +76,6 @@ public override void Init() }; Send(statusMessage); - Metrics.LesStatusesSent++; - CheckProtocolInitTimeout().ContinueWith(x => { if (x.IsFaulted && Logger.IsError) @@ -154,8 +152,6 @@ public override void HandleMessage(ZeroPacket message) public void Handle(StatusMessage status) { - Metrics.LesStatusesReceived++; - // set defaults if (!status.AnnounceType.HasValue) status.AnnounceType = 1; diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/NodeData/NodeDataProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/NodeData/NodeDataProtocolHandler.cs index 5357626835d..5341cdc4af5 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/NodeData/NodeDataProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/NodeData/NodeDataProtocolHandler.cs @@ -77,7 +77,6 @@ public override void HandleMessage(ZeroPacket message) case NodeDataMessageCode.GetNodeData: { GetNodeDataMessage getNodeDataMessage = Deserialize(message.Content); - Metrics.GetNodeDataReceived++; ReportIn(getNodeDataMessage, size); _backgroundTaskScheduler.ScheduleSyncServe(getNodeDataMessage, Handle); break; @@ -85,7 +84,6 @@ public override void HandleMessage(ZeroPacket message) case NodeDataMessageCode.NodeData: { NodeDataMessage nodeDataMessage = Deserialize(message.Content); - Metrics.NodeDataReceived++; ReportIn(nodeDataMessage, size); Handle(nodeDataMessage, size); break; diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Snap/SnapProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Snap/SnapProtocolHandler.cs index bc253ce2a32..ce55da7d775 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Snap/SnapProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Snap/SnapProtocolHandler.cs @@ -170,32 +170,27 @@ private bool ShouldServeSnap(string messageName) private void Handle(AccountRangeMessage msg, long size) { - Metrics.SnapAccountRangeReceived++; _getAccountRangeRequests.Handle(msg.RequestId, msg, size); } private void Handle(StorageRangeMessage msg, long size) { - Metrics.SnapStorageRangesReceived++; _getStorageRangeRequests.Handle(msg.RequestId, msg, size); } private void Handle(ByteCodesMessage msg, long size) { - Metrics.SnapByteCodesReceived++; _getByteCodesRequests.Handle(msg.RequestId, msg, size); } private void Handle(TrieNodesMessage msg, long size) { - Metrics.SnapTrieNodesReceived++; _getTrieNodesRequests.Handle(msg.RequestId, msg, size); } private ValueTask Handle(GetAccountRangeMessage getAccountRangeMessage, CancellationToken cancellationToken) { using GetAccountRangeMessage message = getAccountRangeMessage; - Metrics.SnapGetAccountRangeReceived++; AccountRangeMessage? response = FulfillAccountRangeMessage(message, cancellationToken); response.RequestId = message.RequestId; return new ValueTask(response); @@ -204,7 +199,6 @@ private ValueTask Handle(GetAccountRangeMessage getAccountR private ValueTask Handle(GetStorageRangeMessage getStorageRangesMessage, CancellationToken cancellationToken) { using GetStorageRangeMessage message = getStorageRangesMessage; - Metrics.SnapGetStorageRangesReceived++; StorageRangeMessage? response = FulfillStorageRangeMessage(message, cancellationToken); response.RequestId = message.RequestId; return new ValueTask(response); @@ -213,7 +207,6 @@ private ValueTask Handle(GetStorageRangeMessage getStorageR private ValueTask Handle(GetByteCodesMessage getByteCodesMessage, CancellationToken cancellationToken) { using GetByteCodesMessage message = getByteCodesMessage; - Metrics.SnapGetByteCodesReceived++; ByteCodesMessage? response = FulfillByteCodesMessage(message, cancellationToken); response.RequestId = message.RequestId; return new ValueTask(response); @@ -222,7 +215,6 @@ private ValueTask Handle(GetByteCodesMessage getByteCodesMessa private ValueTask Handle(GetTrieNodesMessage getTrieNodesMessage, CancellationToken cancellationToken) { using GetTrieNodesMessage message = getTrieNodesMessage; - Metrics.SnapGetTrieNodesReceived++; TrieNodesMessage? response = FulfillTrieNodesMessage(message, cancellationToken); response.RequestId = message.RequestId; return new ValueTask(response); @@ -284,8 +276,6 @@ public async Task GetAccountRange(AccountRange range, Cancell ResponseBytes = bytesLimit }, _getAccountRangeRequests, token)); - Metrics.SnapGetAccountRangeSent++; - return new AccountsAndProofs { PathAndAccounts = response.PathsWithAccounts, Proofs = response.Proofs }; } @@ -298,8 +288,6 @@ public async Task GetStorageRange(StorageRange range, Cancellati ResponseBytes = bytesLimit }, _getStorageRangeRequests, token)); - Metrics.SnapGetStorageRangesSent++; - return new SlotsAndProofs { PathsAndSlots = response.Slots, Proofs = response.Proofs }; } @@ -312,8 +300,6 @@ public async Task> GetByteCodes(IReadOnlyList> GetTrieNodes(ValueHash256 rootHas Bytes = bytesLimit }, _getTrieNodesRequests, token)); - Metrics.SnapGetTrieNodesSent++; - return response.Nodes; } diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index bfa05f34749..4224aca2f0d 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -15,7 +15,6 @@ using Nethermind.Consensus.Producers; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; -using Nethermind.Core; using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Db; diff --git a/src/Nethermind/Nethermind.Runner/Nethermind.Runner.csproj b/src/Nethermind/Nethermind.Runner/Nethermind.Runner.csproj index 0865f7469a5..c033683318c 100644 --- a/src/Nethermind/Nethermind.Runner/Nethermind.Runner.csproj +++ b/src/Nethermind/Nethermind.Runner/Nethermind.Runner.csproj @@ -19,10 +19,6 @@ 03db39d0-4200-473e-9ff8-4a48d496381f - - $(NoWarn);AD0001 - - @@ -82,6 +78,7 @@ true + Always @@ -123,7 +120,7 @@ - + diff --git a/src/Nethermind/Nethermind.Runner/Properties/launchSettings.json b/src/Nethermind/Nethermind.Runner/Properties/launchSettings.json index ffd9f258b2d..df5dc1e011f 100644 --- a/src/Nethermind/Nethermind.Runner/Properties/launchSettings.json +++ b/src/Nethermind/Nethermind.Runner/Properties/launchSettings.json @@ -98,13 +98,6 @@ "ASPNETCORE_ENVIRONMENT": "Development" } }, - "Kovan": { - "commandName": "Project", - "commandLineArgs": "-c kovan -dd .data --JsonRpc.Enabled true", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "Mainnet": { "commandName": "Project", "commandLineArgs": "-c mainnet -dd .data", diff --git a/src/Nethermind/Nethermind.Runner/configs/chiado.cfg b/src/Nethermind/Nethermind.Runner/configs/chiado.cfg index 3db7f2f5fac..213f9f13d2a 100644 --- a/src/Nethermind/Nethermind.Runner/configs/chiado.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/chiado.cfg @@ -15,8 +15,8 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 9360000, - "PivotHash": "0xb46aeb7df63c23e42381e17e0f5421532b54eed0e1c00a6b97d90ca8d3db5815", + "PivotNumber": 9480000, + "PivotHash": "0x999c4be9d80941fb2b34b7f4224353b63ba480488914e0d7223b1f6d7cf993b2", "PivotTotalDifficulty": "231708131825107706987652208063906496124457284", "FastSyncCatchUpHeightDelta": "10000000000", "UseGethLimitsInFastBlocks": false diff --git a/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg b/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg index 2a0c784d896..7be846349b3 100644 --- a/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/energyweb.cfg @@ -11,9 +11,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 29530000, - "PivotHash": "0x4df667ffa3ef5dca146c06188dcdcfd7b8e065c18ef79a365708dfdb248a2b92", - "PivotTotalDifficulty": "10048538295175312826073452157460115283923567545", + "PivotNumber": 29640000, + "PivotHash": "0x6f963fe178e1dee1b53c5af9fdfb8ab18e3c3d22f812c358fd1bc2b5d05b939b", + "PivotTotalDifficulty": "10085969355536616057054423364277609787183497422", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/exosama.cfg b/src/Nethermind/Nethermind.Runner/configs/exosama.cfg index b48b7bdef96..bdfb3465aee 100644 --- a/src/Nethermind/Nethermind.Runner/configs/exosama.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/exosama.cfg @@ -11,9 +11,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 9440000, - "PivotHash": "0x8e9c02a024a08fee6b4cfd33d7fb3ff3fbb970e816682894af876ef6588d46dc", - "PivotTotalDifficulty": "3212265543733659095094256294155891915792613287", + "PivotNumber": 9560000, + "PivotHash": "0x82a64ac409ba411a81521d583310eb7b3d321d8fb3293dfb30bc04829393c3cb", + "PivotTotalDifficulty": "3253099427764171710709861247047704101167093286", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg b/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg index 1d2269af173..8013f8484bd 100644 --- a/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/gnosis.cfg @@ -12,8 +12,8 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 33530000, - "PivotHash": "0x2744fc800e9f14e6a66a8177a312fd3a0bcd80f213ef650f9fff1f1d57c31a72", + "PivotNumber": 33650000, + "PivotHash": "0xdc51b3f7be1a1631fe6e9fc6b47c25eab2799584c9aae5acd5d72667bcdeb0c5", "PivotTotalDifficulty": "8626000110427538733349499292577475819600160930", "FastBlocks": true, "UseGethLimitsInFastBlocks": false, diff --git a/src/Nethermind/Nethermind.Runner/configs/joc-mainnet.cfg b/src/Nethermind/Nethermind.Runner/configs/joc-mainnet.cfg index 06afd39e536..9251f7a4553 100644 --- a/src/Nethermind/Nethermind.Runner/configs/joc-mainnet.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/joc-mainnet.cfg @@ -12,9 +12,9 @@ "FastSync": true, "SnapSync": true, "FastBlocks": true, - "PivotNumber": 10800000, - "PivotHash": "0x34d3a3a29e428a46b0736de107d829d34b4d4621dc4df87a5589e16c510b7c64", - "PivotTotalDifficulty": "21576853" + "PivotNumber": 10920000, + "PivotHash": "0x7d1c8aac54b6219147dfba90686b8ec408d22417fa8b6292184a82523b5c652e", + "PivotTotalDifficulty": "21816851" }, "Metrics": { "NodeName": "JOC-Mainnet" diff --git a/src/Nethermind/Nethermind.Runner/configs/joc-testnet.cfg b/src/Nethermind/Nethermind.Runner/configs/joc-testnet.cfg index 9016111e1ff..ef6e810a5d3 100644 --- a/src/Nethermind/Nethermind.Runner/configs/joc-testnet.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/joc-testnet.cfg @@ -11,9 +11,9 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 4410000, - "PivotHash": "0x62b9930c5d83dd874f45fdc8e158668bb42de6689ddba3158ce1ed115666f0b1", - "PivotTotalDifficulty": "8819445" + "PivotNumber": 4530000, + "PivotHash": "0xab972522fea93c1d4c1bb23de1df280bbe6282704f22751479ea1dd1e994397a", + "PivotTotalDifficulty": "9059445" }, "Metrics": { "NodeName": "JOC-Testnet" diff --git a/src/Nethermind/Nethermind.Runner/configs/kovan.cfg b/src/Nethermind/Nethermind.Runner/configs/kovan.cfg deleted file mode 100644 index af44032f832..00000000000 --- a/src/Nethermind/Nethermind.Runner/configs/kovan.cfg +++ /dev/null @@ -1,33 +0,0 @@ -{ - "Init": { - "ChainSpecPath": "chainspec/kovan.json", - "GenesisHash": "0xa3c565fc15c7478862d50ccd6561e3c06b24cc509bf388941c25ea985ce32cb9", - "BaseDbPath": "nethermind_db/kovan", - "LogFileName": "kovan.logs.txt", - "MemoryHint": 768000000 - }, - "TxPool": { - "Size": 1024 - }, - "Sync": { - "FastSync": true, - "PivotNumber": 34000000, - "PivotHash": "0xaace54dd10cada02c236bd8182489cc7f9520dedceb1795f9f716e66d86921cb", - "PivotTotalDifficulty": "11519157357521914760869389464249041320958641825", - "UseGethLimitsInFastBlocks": false, - "FastSyncCatchUpHeightDelta": 10000000000 - }, - "EthStats": { - "Name": "Nethermind kovan" - }, - "Metrics": { - "NodeName": "kovan" - }, - "Bloom": { - "IndexLevelBucketSizes": [ - 16, - 16, - 16 - ] - } -} diff --git a/src/Nethermind/Nethermind.Runner/configs/kovan_archive.cfg b/src/Nethermind/Nethermind.Runner/configs/kovan_archive.cfg deleted file mode 100644 index 7ca449a06e8..00000000000 --- a/src/Nethermind/Nethermind.Runner/configs/kovan_archive.cfg +++ /dev/null @@ -1,34 +0,0 @@ -{ - "Init": { - "ChainSpecPath": "chainspec/kovan.json", - "GenesisHash": "0xa3c565fc15c7478862d50ccd6561e3c06b24cc509bf388941c25ea985ce32cb9", - "BaseDbPath": "nethermind_db/kovan", - "LogFileName": "kovan.logs.txt", - "MemoryHint": 768000000 - }, - "TxPool": { - "Size": 1024 - }, - "Sync": { - "TotalDifficultyOverrides": [148240, 19430113280] - }, - "Receipt": { - "TxLookupLimit": 0 - }, - "EthStats": { - "Name": "Nethermind kovan" - }, - "Metrics": { - "NodeName": "kovan" - }, - "Bloom": { - "IndexLevelBucketSizes": [ - 16, - 16, - 16 - ] - }, - "Pruning": { - "Mode": "None" - } -} diff --git a/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg b/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg index 8b7a3f81afb..4fac25aa6c2 100644 --- a/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/mainnet.cfg @@ -9,8 +9,8 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 19699000, - "PivotHash": "0xba621f0936f2feaf1ff1017af5b9c483f2f00bc9dd083c31baa305c1643ae185", + "PivotNumber": 19749000, + "PivotHash": "0xc8dc518cca2572321f18be673e012239f7a01aaf3d2f38395f33dcab14bc8abd", "PivotTotalDifficulty": "58750003716598352816469", "FastBlocks": true, "FastSyncCatchUpHeightDelta": "10000000000" diff --git a/src/Nethermind/Nethermind.Runner/configs/sepolia.cfg b/src/Nethermind/Nethermind.Runner/configs/sepolia.cfg index 6eebd43a5f7..146693533cd 100644 --- a/src/Nethermind/Nethermind.Runner/configs/sepolia.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/sepolia.cfg @@ -17,8 +17,8 @@ "FastSync": true, "SnapSync": true, "UseGethLimitsInFastBlocks": true, - "PivotNumber": 5741000, - "PivotHash": "0x060fa3e4b7cf2f519814aa524ea5a0a258f7a7a79a7fa895191285659dec4fe4", + "PivotNumber": 5790000, + "PivotHash": "0x2e686ac4d3ddb7a6c81d2afdb6b1dd9675e80ed70dfb93acb52e021750fd6fec", "PivotTotalDifficulty": "17000018015853232", "FastSyncCatchUpHeightDelta": "10000000000" }, diff --git a/src/Nethermind/Nethermind.Runner/configs/volta.cfg b/src/Nethermind/Nethermind.Runner/configs/volta.cfg index f46cfdd6384..d421cc4bc6c 100644 --- a/src/Nethermind/Nethermind.Runner/configs/volta.cfg +++ b/src/Nethermind/Nethermind.Runner/configs/volta.cfg @@ -15,9 +15,9 @@ }, "Sync": { "FastSync": true, - "PivotNumber": 27460000, - "PivotHash": "0x63676c08951ead77b88cbe164197d5b9fc24a1071a5160d0b38260c7e0687447", - "PivotTotalDifficulty": "9344153795648970206704266720076355086211719168", + "PivotNumber": 27540000, + "PivotHash": "0x0328d6a8eaaf2a46594ff390eb1e3b113679791c7ed2eda0f7b7cfbbd130058a", + "PivotTotalDifficulty": "9371376385002645283781336688670896543128001703", "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 }, diff --git a/src/Nethermind/Nethermind.Serialization.Json/DictionaryAddressKey.cs b/src/Nethermind/Nethermind.Serialization.Json/DictionaryAddressKey.cs index 6bbcb7cf266..aee76ac021a 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/DictionaryAddressKey.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/DictionaryAddressKey.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using Nethermind.Core; #nullable enable @@ -13,6 +12,8 @@ namespace Nethermind.Serialization.Json using System.Text.Json; using System.Text.Json.Serialization; + using Nethermind.Core; + public class DictionaryAddressKeyConverter : JsonConverterFactory { public override bool CanConvert(Type typeToConvert) diff --git a/src/Nethermind/Nethermind.Serialization.Json/DoubleConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/DoubleConverter.cs index 259b928186e..d1f2890f62b 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/DoubleConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/DoubleConverter.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using Nethermind.Core.Collections; namespace Nethermind.Serialization.Json { diff --git a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs index d501614269f..df3ae54609c 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs @@ -51,7 +51,7 @@ public T Deserialize(ref Utf8JsonReader json) public string Serialize(T value, bool indented = false) { - return JsonSerializer.Serialize(value, indented ? JsonOptionsIndented : _jsonOptions); + return JsonSerializer.Serialize(value, indented ? JsonOptionsIndented : _jsonOptions); } public static JsonSerializerOptions CreateOptions(bool indented, IEnumerable converters = null, int maxDepth = 64) @@ -86,7 +86,7 @@ public static JsonSerializerOptions CreateOptions(bool indented, IEnumerable.Shared, minimumBufferSize: 4096, leaveOpen: true); - private static readonly StreamPipeWriterOptions _options = new(pool: MemoryPool.Shared, minimumBufferSize: 4096, leaveOpen: false); + private static readonly StreamPipeWriterOptions optionsLeaveOpen = new(pool: MemoryPool.Shared, minimumBufferSize: 4096, leaveOpen: true); + private static readonly StreamPipeWriterOptions options = new(pool: MemoryPool.Shared, minimumBufferSize: 4096, leaveOpen: false); private static CountingStreamPipeWriter GetPipeWriter(Stream stream, bool leaveOpen) { - return new CountingStreamPipeWriter(stream, leaveOpen ? _optionsLeaveOpen : _options); + return new CountingStreamPipeWriter(stream, leaveOpen ? optionsLeaveOpen : options); } public long Serialize(Stream stream, T value, bool indented = false, bool leaveOpen = true) @@ -137,7 +137,7 @@ private JsonWriterOptions CreateWriterOptions(bool indented) public async ValueTask SerializeAsync(Stream stream, T value, bool indented = false, bool leaveOpen = true) { - CountingStreamPipeWriter writer = GetPipeWriter(stream, leaveOpen); + var writer = GetPipeWriter(stream, leaveOpen); Serialize(writer, value, indented); await writer.CompleteAsync(); diff --git a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs index 282a542221a..1db75c2a7a7 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/ULongConverter.cs @@ -12,6 +12,7 @@ namespace Nethermind.Serialization.Json using System.Runtime.CompilerServices; using System.Text.Json; using System.Text.Json.Serialization; + using Nethermind.Int256; public class ULongConverter : JsonConverter { diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/BlockInfoDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/BlockInfoDecoder.cs index eea5c4a73b9..69ee52db06c 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/BlockInfoDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/BlockInfoDecoder.cs @@ -9,6 +9,8 @@ namespace Nethermind.Serialization.Rlp { public class BlockInfoDecoder : IRlpStreamDecoder, IRlpValueDecoder { + public static BlockInfoDecoder Instance { get; } = new(); + public BlockInfo? Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (rlpStream.IsNextItemNull()) diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs index 52923b4831f..2453a91d1db 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptMessageDecoder.cs @@ -13,7 +13,7 @@ public class ReceiptMessageDecoder : IRlpStreamDecoder static ReceiptMessageDecoder() { - Rlp.Decoders[typeof(TxReceipt)] = new ReceiptMessageDecoder(); + Rlp.RegisterDecoder(typeof(TxReceipt), new ReceiptMessageDecoder()); } public TxReceipt Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) @@ -171,9 +171,10 @@ public void Encode(RlpStream rlpStream, TxReceipt item, RlpBehaviors rlpBehavior rlpStream.Encode(item.Bloom); rlpStream.StartSequence(logsLength); - for (var i = 0; i < item.Logs.Length; i++) + LogEntry[] logs = item.Logs; + for (var i = 0; i < logs.Length; i++) { - rlpStream.Encode(item.Logs[i]); + rlpStream.Encode(logs[i]); } } } diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptStorageDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptStorageDecoder.cs index 2d27f141112..f9a9c4bfccd 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptStorageDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/ReceiptStorageDecoder.cs @@ -226,9 +226,10 @@ public void Encode(RlpStream rlpStream, TxReceipt? item, RlpBehaviors rlpBehavio rlpStream.StartSequence(logsLength); - for (int i = 0; i < item.Logs.Length; i++) + LogEntry[] logs = item.Logs; + for (int i = 0; i < logs.Length; i++) { - rlpStream.Encode(item.Logs[i]); + rlpStream.Encode(logs[i]); } if (_supportTxHash) @@ -246,9 +247,10 @@ public void Encode(RlpStream rlpStream, TxReceipt? item, RlpBehaviors rlpBehavio rlpStream.StartSequence(logsLength); - for (int i = 0; i < item.Logs.Length; i++) + LogEntry[] logs = item.Logs; + for (int i = 0; i < logs.Length; i++) { - rlpStream.Encode(item.Logs[i]); + rlpStream.Encode(logs[i]); } rlpStream.Encode(item.Error); diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs b/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs index 306eaa6e15b..923cb54f74f 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs @@ -3,12 +3,14 @@ using System; using System.Buffers.Binary; +using System.Collections.Frozen; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; using Nethermind.Core; using Nethermind.Core.Collections; @@ -73,7 +75,28 @@ public Rlp(byte[] bytes) public int Length => Bytes.Length; - public static readonly Dictionary Decoders = new(); + private static Dictionary _decoderBuilder = new(); + private static FrozenDictionary? _decoders; + public static FrozenDictionary Decoders => _decoders ??= _decoderBuilder.ToFrozenDictionary(); + + public struct TypeAsKey(Type key) : IEquatable + { + private readonly Type _key = key; + public Type Value => _key; + + public static implicit operator Type(TypeAsKey key) => key._key; + public static implicit operator TypeAsKey(Type key) => new(key); + + public bool Equals(TypeAsKey other) => _key.Equals(other._key); + public override int GetHashCode() => _key.GetHashCode(); + } + + public static void RegisterDecoder(Type type, IRlpDecoder decoder) + { + _decoderBuilder[type] = decoder; + // Mark FrozenDictionary as null to force re-creation + _decoders = null; + } public static void RegisterDecoders(Assembly assembly) { @@ -107,13 +130,16 @@ public static void RegisterDecoders(Assembly assembly) } Type key = implementedInterface.GenericTypeArguments[0]; - if (!Decoders.ContainsKey(key)) + if (!_decoderBuilder.ContainsKey(key)) { - Decoders[key] = (IRlpDecoder)Activator.CreateInstance(type); + _decoderBuilder[key] = (IRlpDecoder)Activator.CreateInstance(type); } } } } + + // Mark FrozenDictionary as null to force re-creation + _decoders = null; } public static T Decode(Rlp oldRlp, RlpBehaviors rlpBehaviors = RlpBehaviors.None) @@ -132,17 +158,6 @@ public static T Decode(Span bytes, RlpBehaviors rlpBehaviors = RlpBehav return Decode(ref valueContext, rlpBehaviors); } - public static T[] DecodeArray(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) - { - IRlpStreamDecoder? rlpDecoder = GetStreamDecoder(); - if (rlpDecoder is not null) - { - return DecodeArray(rlpStream, rlpDecoder, rlpBehaviors); - } - - throw new RlpException($"{nameof(Rlp)} does not support decoding {typeof(T).Name}"); - } - public static T[] DecodeArray(RlpStream rlpStream, IRlpStreamDecoder? rlpDecoder, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { int checkPosition = rlpStream.ReadSequenceLength() + rlpStream.Position; @@ -246,6 +261,12 @@ public static T Decode(ref ValueDecoderContext decoderContext, RlpBehaviors r return result; } + public static Rlp Encode(Account item, RlpBehaviors behaviors = RlpBehaviors.None) + => AccountDecoder.Instance.Encode(item, behaviors); + + public static Rlp Encode(LogEntry item, RlpBehaviors behaviors = RlpBehaviors.None) + => LogEntryDecoder.Instance.Encode(item, behaviors); + public static Rlp Encode(T item, RlpBehaviors behaviors = RlpBehaviors.None) { if (item is Rlp rlp) @@ -314,8 +335,7 @@ public static Rlp Encode( bool isEip155Enabled = false, ulong chainId = 0) { - TxDecoder txDecoder = new TxDecoder(); - return txDecoder.EncodeTx(transaction, RlpBehaviors.SkipTypedWrapping, forSigning, isEip155Enabled, + return TxDecoder.Instance.EncodeTx(transaction, RlpBehaviors.SkipTypedWrapping, forSigning, isEip155Enabled, chainId); } @@ -366,18 +386,6 @@ public static Rlp Encode(in UInt256 value, int length = -1) } } - - public static int Encode(Span buffer, int position, byte[]? input) - { - if (input is null || input.Length == 0) - { - buffer[position++] = OfEmptyByteArray.Bytes[0]; - return position; - } - - return Encode(buffer, position, input.AsSpan()); - } - public static int Encode(Span buffer, int position, ReadOnlySpan input) { if (input.Length == 1 && input[0] < 128) @@ -405,6 +413,27 @@ public static int Encode(Span buffer, int position, ReadOnlySpan inp return position; } + public static int Encode(Span buffer, int position, Hash256 hash) + { + Debug.Assert(hash is not null); + var newPosition = position + LengthOfKeccakRlp; + if ((uint)newPosition > (uint)buffer.Length) + { + ThrowArgumentOutOfRangeException(); + } + + Unsafe.Add(ref MemoryMarshal.GetReference(buffer), position) = 160; + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetReference(buffer), position + 1)) = hash.ValueHash256; + return newPosition; + + [DoesNotReturn] + [StackTraceHidden] + static void ThrowArgumentOutOfRangeException() + { + throw new ArgumentOutOfRangeException(nameof(buffer)); + } + } + public static Rlp Encode(ReadOnlySpan input) { if (input.Length == 0) @@ -528,7 +557,7 @@ public static Rlp Encode(Hash256? keccak) byte[] result = new byte[LengthOfKeccakRlp]; result[0] = 160; - keccak.Bytes.CopyTo(result.AsSpan()[1..]); + Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(result), 1)) = keccak.ValueHash256; return new Rlp(result); } @@ -1830,14 +1859,12 @@ public static int LengthOf(bool value) public static int LengthOf(LogEntry item) { - IRlpDecoder? rlpDecoder = GetDecoder(); - return rlpDecoder?.GetLength(item, RlpBehaviors.None) ?? throw new RlpException($"{nameof(Rlp)} does not support length of {nameof(LogEntry)}"); + return LogEntryDecoder.Instance.GetLength(item, RlpBehaviors.None); } public static int LengthOf(BlockInfo item) { - IRlpDecoder? rlpDecoder = GetDecoder(); - return rlpDecoder?.GetLength(item, RlpBehaviors.None) ?? throw new RlpException($"{nameof(Rlp)} does not support length of {nameof(BlockInfo)}"); + return BlockInfoDecoder.Instance.GetLength(item, RlpBehaviors.None); } public class SkipGlobalRegistration : Attribute diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoder.cs index ba1172a0b2d..66059c44de4 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/TxDecoder.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using FastEnumUtility; using Microsoft.Extensions.ObjectPool; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -11,7 +10,7 @@ namespace Nethermind.Serialization.Rlp { - public class TxDecoder : TxDecoder + public sealed class TxDecoder : TxDecoder { public const int MaxDelayedHashTxnSize = 32768; public static TxDecoder Instance = new TxDecoder(); diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/ValueRlpStream.cs b/src/Nethermind/Nethermind.Serialization.Rlp/ValueRlpStream.cs index 5297463cbdf..d762dd566a3 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/ValueRlpStream.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/ValueRlpStream.cs @@ -279,7 +279,7 @@ public readonly byte PeekByte() return Data![_position]; } - private void SkipBytes(int length) + public void SkipBytes(int length) { _position += length; } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs index a903d3137a2..709607c9a41 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/BlockDownloaderTests.cs @@ -489,7 +489,7 @@ public bool ValidateOrphanedBlock(Block block, [NotNullWhen(false)] out string? return true; } - public bool ValidateSuggestedBlock(Block block, [NotNullWhen(false)] out string? error) + public bool ValidateSuggestedBlock(Block block, [NotNullWhen(false)] out string? error, bool validateHashes = true) { Thread.Sleep(1000); error = null; diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs index 46736a78e01..fc414e65f12 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs @@ -26,12 +26,6 @@ namespace Nethermind.Synchronization.FastBlocks { public class HeadersSyncFeed : ActivatedSyncFeed { - private readonly Dictionary> _historicalOverrides = new Dictionary>() - { - // Kovan has some wrong difficulty in early blocks before using proper AuRa difficulty calculation - // In order to support that we need to support another pivot - { BlockchainIds.Kovan, new Dictionary { {148240, 19430113280} } } - }; private readonly ILogger _logger; private readonly ISyncPeerPool _syncPeerPool; @@ -184,8 +178,6 @@ public HeadersSyncFeed( { throw new InvalidOperationException("Entered fast headers mode without fast sync enabled in configuration."); } - - _historicalOverrides.TryGetValue(_blockTree.NetworkId, out _expectedDifficultyOverride); } public override void InitializeFeed() @@ -691,8 +683,6 @@ private void MarkDirty() Volatile.Write(ref _memoryEstimate, ulong.MaxValue); } - protected readonly IDictionary? _expectedDifficultyOverride; - private AddBlockResult InsertHeader(BlockHeader header) { if (header.IsGenesis) @@ -717,14 +707,7 @@ protected virtual AddBlockResult InsertToBlockTree(BlockHeader header) protected void SetExpectedNextHeaderToParent(BlockHeader header) { _nextHeaderHash = header.ParentHash!; - if (_expectedDifficultyOverride?.TryGetValue(header.Number, out ulong nextHeaderDiff) == true) - { - _nextHeaderDiff = nextHeaderDiff; - } - else - { _nextHeaderDiff = (header.TotalDifficulty ?? 0) - header.Difficulty; } } - } } diff --git a/src/Nethermind/Nethermind.Trie/PatriciaTree.cs b/src/Nethermind/Nethermind.Trie/PatriciaTree.cs index c12bcbf0cc7..79e2c05cd41 100644 --- a/src/Nethermind/Nethermind.Trie/PatriciaTree.cs +++ b/src/Nethermind/Nethermind.Trie/PatriciaTree.cs @@ -347,7 +347,7 @@ void TraceSkipInlineNode(TrieNode node) public void UpdateRootHash() { TreePath path = TreePath.Empty; - RootRef?.ResolveKey(TrieStore, ref path, true, bufferPool: _bufferPool); + RootRef?.ResolveKey(TrieStore, ref path, isRoot: true, bufferPool: _bufferPool); SetRootHash(RootRef?.Keccak ?? EmptyTreeHash, false); } @@ -730,7 +730,7 @@ L X - - - - - - - - - - - - - - */ } } - node.AppendChildPathBranch(ref path, childNodeIndex); + path.AppendMut(childNodeIndex); TrieNode childNode = node.GetChildWithChildPath(TrieStore, ref path, childNodeIndex); if (childNode is null) { @@ -926,7 +926,7 @@ which is not possible within the Ethereum protocol which has keys of the same le } int childIdx = traverseContext.UpdatePath[traverseContext.CurrentIndex]; - node.AppendChildPathBranch(ref path, childIdx); + path.AppendMut(childIdx); TrieNode childNode = node.GetChildWithChildPath(TrieStore, ref path, childIdx); if (traverseContext.IsUpdate) { diff --git a/src/Nethermind/Nethermind.Trie/Pruning/ITrieNodeResolver.cs b/src/Nethermind/Nethermind.Trie/Pruning/ITrieNodeResolver.cs index 6b40d7d2601..5b2dbe205a3 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/ITrieNodeResolver.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/ITrieNodeResolver.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using Nethermind.Core; using Nethermind.Core.Attributes; using Nethermind.Core.Crypto; diff --git a/src/Nethermind/Nethermind.Trie/TrieNode.Decoder.cs b/src/Nethermind/Nethermind.Trie/TrieNode.Decoder.cs index 8e019862037..55b522e38d1 100644 --- a/src/Nethermind/Nethermind.Trie/TrieNode.Decoder.cs +++ b/src/Nethermind/Nethermind.Trie/TrieNode.Decoder.cs @@ -4,8 +4,6 @@ using System; using System.Buffers; using System.Diagnostics; -using System.IO; -using System.Linq; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Nethermind.Core.Buffers; @@ -25,41 +23,11 @@ public partial class TrieNode private class TrieNodeDecoder { - public static CappedArray Encode(ITrieNodeResolver tree, ref TreePath path, TrieNode? item, ICappedArrayPool? bufferPool) + [SkipLocalsInit] + public static CappedArray EncodeExtension(TrieNode item, ITrieNodeResolver tree, ref TreePath path, ICappedArrayPool? bufferPool) { Metrics.TreeNodeRlpEncodings++; - if (item is null) - { - ThrowNullNode(); - } - - return item.NodeType switch - { - NodeType.Branch => RlpEncodeBranch(tree, ref path, item, bufferPool), - NodeType.Extension => EncodeExtension(tree, ref path, item, bufferPool), - NodeType.Leaf => EncodeLeaf(item, bufferPool), - _ => ThrowUnhandledNodeType(item) - }; - - [DoesNotReturn] - [StackTraceHidden] - static void ThrowNullNode() - { - throw new TrieException("An attempt was made to RLP encode a null node."); - } - - [DoesNotReturn] - [StackTraceHidden] - static CappedArray ThrowUnhandledNodeType(TrieNode item) - { - throw new TrieException($"An attempt was made to encode a trie node of type {item.NodeType}"); - } - } - - [SkipLocalsInit] - private static CappedArray EncodeExtension(ITrieNodeResolver tree, ref TreePath path, TrieNode item, ICappedArrayPool? bufferPool) - { Debug.Assert(item.NodeType == NodeType.Extension, $"Node passed to {nameof(EncodeExtension)} is {item.NodeType}"); Debug.Assert(item.Key is not null, @@ -115,8 +83,10 @@ private static CappedArray EncodeExtension(ITrieNodeResolver tree, ref Tre } [SkipLocalsInit] - private static CappedArray EncodeLeaf(TrieNode node, ICappedArrayPool? pool) + public static CappedArray EncodeLeaf(TrieNode node, ICappedArrayPool? pool) { + Metrics.TreeNodeRlpEncodings++; + if (node.Key is null) { ThrowNullKey(node); @@ -155,8 +125,10 @@ private static void ThrowNullKey(TrieNode node) throw new TrieException($"Hex prefix of a leaf node is null at node {node.Keccak}"); } - private static CappedArray RlpEncodeBranch(ITrieNodeResolver tree, ref TreePath path, TrieNode item, ICappedArrayPool? pool) + public static CappedArray RlpEncodeBranch(TrieNode item, ITrieNodeResolver tree, ref TreePath path, ICappedArrayPool? pool) { + Metrics.TreeNodeRlpEncodings++; + int valueRlpLength = AllowBranchValues ? Rlp.LengthOf(item.Value.AsSpan()) : 1; int contentLength = valueRlpLength + GetChildrenRlpLengthForBranch(tree, ref path, item, pool); int sequenceLength = Rlp.LengthOfSequence(contentLength); @@ -179,18 +151,57 @@ private static CappedArray RlpEncodeBranch(ITrieNodeResolver tree, ref Tre private static int GetChildrenRlpLengthForBranch(ITrieNodeResolver tree, ref TreePath path, TrieNode item, ICappedArrayPool? bufferPool) { - int totalLength = 0; item.EnsureInitialized(); + // Tail call optimized. + if (item.HasRlp) + { + return GetChildrenRlpLengthForBranchRlp(tree, ref path, item, bufferPool); + } + else + { + return GetChildrenRlpLengthForBranchNonRlp(tree, ref path, item, bufferPool); + } + } + + private static int GetChildrenRlpLengthForBranchNonRlp(ITrieNodeResolver tree, ref TreePath path, TrieNode item, ICappedArrayPool bufferPool) + { + int totalLength = 0; + for (int i = 0; i < BranchesCount; i++) + { + object data = item._data[i]; + if (ReferenceEquals(data, _nullNode) || data is null) + { + totalLength++; + } + else if (data is Hash256) + { + totalLength += Rlp.LengthOfKeccakRlp; + } + else + { + path.AppendMut(i); + TrieNode childNode = (TrieNode)data; + childNode.ResolveKey(tree, ref path, isRoot: false, bufferPool: bufferPool); + path.TruncateOne(); + totalLength += childNode.Keccak is null ? childNode.FullRlp.Length : Rlp.LengthOfKeccakRlp; + } + } + return totalLength; + } + + private static int GetChildrenRlpLengthForBranchRlp(ITrieNodeResolver tree, ref TreePath path, TrieNode item, ICappedArrayPool? bufferPool) + { + int totalLength = 0; ValueRlpStream rlpStream = item.RlpStream; item.SeekChild(ref rlpStream, 0); for (int i = 0; i < BranchesCount; i++) { - bool isRlp = rlpStream.IsNotNull; object data = item._data[i]; - if (rlpStream.IsNotNull && data is null) + if (data is null) { - (int prefixLength, int contentLength) = rlpStream.PeekPrefixAndContentLength(); - totalLength += prefixLength + contentLength; + int length = rlpStream.PeekNextRlpLength(); + totalLength += length; + rlpStream.SkipBytes(length); } else { @@ -204,15 +215,16 @@ private static int GetChildrenRlpLengthForBranch(ITrieNodeResolver tree, ref Tre } else { - TrieNode childNode = (TrieNode)data; - item.AppendChildPathBranch(ref path, i); - childNode!.ResolveKey(tree, ref path, false, bufferPool: bufferPool); + path.AppendMut(i); + Debug.Assert(data is TrieNode, "Data is not TrieNode"); + TrieNode childNode = Unsafe.As(data); + childNode.ResolveKey(tree, ref path, isRoot: false, bufferPool: bufferPool); path.TruncateOne(); totalLength += childNode.Keccak is null ? childNode.FullRlp.Length : Rlp.LengthOfKeccakRlp; } - } - if (isRlp) rlpStream.SkipItem(); + rlpStream.SkipItem(); + } } return totalLength; @@ -220,41 +232,91 @@ private static int GetChildrenRlpLengthForBranch(ITrieNodeResolver tree, ref Tre private static void WriteChildrenRlpBranch(ITrieNodeResolver tree, ref TreePath path, TrieNode item, Span destination, ICappedArrayPool? bufferPool) { - int position = 0; item.EnsureInitialized(); + // Tail call optimized. + if (item.HasRlp) + { + WriteChildrenRlpBranchRlp(tree, ref path, item, destination, bufferPool); + } + else + { + WriteChildrenRlpBranchNonRlp(tree, ref path, item, destination, bufferPool); + } + } + + private static void WriteChildrenRlpBranchNonRlp(ITrieNodeResolver tree, ref TreePath path, TrieNode item, Span destination, ICappedArrayPool? bufferPool) + { + int position = 0; + for (int i = 0; i < BranchesCount; i++) + { + object data = item._data[i]; + if (ReferenceEquals(data, _nullNode) || data is null) + { + destination[position++] = 128; + } + else if (data is Hash256 hash) + { + position = Rlp.Encode(destination, position, hash); + } + else + { + path.AppendMut(i); + Debug.Assert(data is TrieNode, "Data is not TrieNode"); + TrieNode childNode = Unsafe.As(data); + childNode!.ResolveKey(tree, ref path, isRoot: false, bufferPool: bufferPool); + path.TruncateOne(); + + hash = childNode.Keccak; + if (hash is null) + { + Span fullRlp = childNode.FullRlp!.AsSpan(); + fullRlp.CopyTo(destination.Slice(position, fullRlp.Length)); + position += fullRlp.Length; + } + else + { + position = Rlp.Encode(destination, position, hash); + } + } + } + } + + private static void WriteChildrenRlpBranchRlp(ITrieNodeResolver tree, ref TreePath path, TrieNode item, Span destination, ICappedArrayPool? bufferPool) + { ValueRlpStream rlpStream = item.RlpStream; item.SeekChild(ref rlpStream, 0); + int position = 0; for (int i = 0; i < BranchesCount; i++) { - bool isRlp = rlpStream.IsNotNull; object data = item._data[i]; - if (isRlp && data is null) + if (data is null) { int length = rlpStream.PeekNextRlpLength(); Span nextItem = rlpStream.Data.AsSpan(rlpStream.Position, length); nextItem.CopyTo(destination.Slice(position, nextItem.Length)); position += nextItem.Length; - rlpStream.SkipItem(); + rlpStream.SkipBytes(length); } else { - if (isRlp) rlpStream.SkipItem(); if (ReferenceEquals(data, _nullNode) || data is null) { destination[position++] = 128; } - else if (data is Hash256) + else if (data is Hash256 hash) { - position = Rlp.Encode(destination, position, (data as Hash256)!.Bytes); + position = Rlp.Encode(destination, position, hash); } else { - TrieNode childNode = (TrieNode)data; - item.AppendChildPathBranch(ref path, i); - childNode!.ResolveKey(tree, ref path, false, bufferPool: bufferPool); + path.AppendMut(i); + Debug.Assert(data is TrieNode, "Data is not TrieNode"); + TrieNode childNode = Unsafe.As(data); + childNode!.ResolveKey(tree, ref path, isRoot: false, bufferPool: bufferPool); path.TruncateOne(); - if (childNode.Keccak is null) + hash = childNode.Keccak; + if (hash is null) { Span fullRlp = childNode.FullRlp!.AsSpan(); fullRlp.CopyTo(destination.Slice(position, fullRlp.Length)); @@ -262,9 +324,11 @@ private static void WriteChildrenRlpBranch(ITrieNodeResolver tree, ref TreePath } else { - position = Rlp.Encode(destination, position, childNode.Keccak.Bytes); + position = Rlp.Encode(destination, position, hash); } } + + rlpStream.SkipItem(); } } } diff --git a/src/Nethermind/Nethermind.Trie/TrieNode.Visitor.cs b/src/Nethermind/Nethermind.Trie/TrieNode.Visitor.cs index a5c5aec1cab..67b43655dde 100644 --- a/src/Nethermind/Nethermind.Trie/TrieNode.Visitor.cs +++ b/src/Nethermind/Nethermind.Trie/TrieNode.Visitor.cs @@ -213,7 +213,7 @@ static void VisitAllSingleThread(TrieNode currentNode, ref TreePath path, ITreeV { TrieNode?[] output = new TrieNode?[16]; currentNode.ResolveAllChildBranch(nodeResolver, ref path, output); - currentNode.AppendChildPathBranch(ref path, 0); + path.AppendMut(0); for (int i = 0; i < 16; i++) { if (output[i] == null) continue; diff --git a/src/Nethermind/Nethermind.Trie/TrieNode.cs b/src/Nethermind/Nethermind.Trie/TrieNode.cs index 86ddbd6649e..73f8efc70dc 100644 --- a/src/Nethermind/Nethermind.Trie/TrieNode.cs +++ b/src/Nethermind/Nethermind.Trie/TrieNode.cs @@ -21,7 +21,7 @@ namespace Nethermind.Trie { - public partial class TrieNode + public sealed partial class TrieNode { #if DEBUG private static int _idCounter; @@ -57,6 +57,8 @@ public partial class TrieNode public Hash256? Keccak { get; internal set; } + public bool HasRlp => _rlp != null; + public ref readonly CappedArray FullRlp { get @@ -507,7 +509,10 @@ public void ResolveKey(ITrieNodeResolver tree, ref TreePath path, bool isRoot, I if (rlp is null || IsDirty) { ref readonly CappedArray oldRlp = ref rlp is not null ? ref rlp.Data : ref CappedArray.Empty; - CappedArray fullRlp = RlpEncode(tree, ref path, bufferPool); + CappedArray fullRlp = NodeType == NodeType.Branch ? + TrieNodeDecoder.RlpEncodeBranch(this, tree, ref path, bufferPool) : + RlpEncode(tree, ref path, bufferPool); + if (fullRlp.IsNotNullOrEmpty) { bufferPool.SafeReturnBuffer(oldRlp); @@ -529,15 +534,20 @@ public void ResolveKey(ITrieNodeResolver tree, ref TreePath path, bool isRoot, I internal CappedArray RlpEncode(ITrieNodeResolver tree, ref TreePath path, ICappedArrayPool? bufferPool = null) { - CappedArray rlp = TrieNodeDecoder.Encode(tree, ref path, this, bufferPool); - // just included here to improve the class reading - // after some analysis I believe that any non-test Ethereum cases of a trie ever have nodes with RLP shorter than 32 bytes - // if (rlp.Bytes.Length < 32) - // { - // throw new InvalidDataException("Unexpected less than 32"); - // } + return NodeType switch + { + NodeType.Branch => TrieNodeDecoder.RlpEncodeBranch(this, tree, ref path, bufferPool), + NodeType.Extension => TrieNodeDecoder.EncodeExtension(this, tree, ref path, bufferPool), + NodeType.Leaf => TrieNodeDecoder.EncodeLeaf(this, bufferPool), + _ => ThrowUnhandledNodeType(this) + }; - return rlp; + [DoesNotReturn] + [StackTraceHidden] + static CappedArray ThrowUnhandledNodeType(TrieNode item) + { + throw new TrieException($"An attempt was made to encode a trie node of type {item.NodeType}"); + } } public object GetData(int index) @@ -662,11 +672,6 @@ public int AppendChildPath(ref TreePath currentPath, int childIndex) return previousLength; } - public void AppendChildPathBranch(ref TreePath currentPath, int childIndex) - { - currentPath.AppendMut(childIndex); - } - public TrieNode? GetChild(ITrieNodeResolver tree, ref TreePath path, int childIndex) { int originalLength = path.Length; @@ -1159,7 +1164,7 @@ private void ResolveAllChildBranch(ITrieNodeResolver tree, ref TreePath path, Tr RlpFactory rlp = _rlp; if (rlp is null) { - AppendChildPathBranch(ref path, 0); + path.AppendMut(0); for (int i = 0; i < 16; i++) { path.SetLast(i); @@ -1173,7 +1178,7 @@ private void ResolveAllChildBranch(ITrieNodeResolver tree, ref TreePath path, Tr rlpStream.Reset(); rlpStream.SkipLength(); - AppendChildPathBranch(ref path, 0); + path.AppendMut(0); for (int i = 0; i < 16; i++) { int prefix = rlpStream.PeekByte(); diff --git a/src/Nethermind/Nethermind.Trie/TrieNodeResolverWithReadFlags.cs b/src/Nethermind/Nethermind.Trie/TrieNodeResolverWithReadFlags.cs index 50418b7fcd8..27035114192 100644 --- a/src/Nethermind/Nethermind.Trie/TrieNodeResolverWithReadFlags.cs +++ b/src/Nethermind/Nethermind.Trie/TrieNodeResolverWithReadFlags.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Trie.Pruning; diff --git a/src/Nethermind/Nethermind.TxPool/TxPool.cs b/src/Nethermind/Nethermind.TxPool/TxPool.cs index 7841ea39993..306f0470626 100644 --- a/src/Nethermind/Nethermind.TxPool/TxPool.cs +++ b/src/Nethermind/Nethermind.TxPool/TxPool.cs @@ -804,8 +804,8 @@ private static void WriteTxPoolReport(in ILogger logger) * Blobs: {Metrics.BlobsInBlock,24:N0} ------------------------------------------------ Db usage: -* BlobDb writes: {Db.Metrics.BlobTransactionsDbWrites,24:N0} -* BlobDb reads: {Db.Metrics.BlobTransactionsDbReads,24:N0} +* BlobDb writes: {Db.Metrics.DbWrites.GetValueOrDefault("BlobTransactions"),24:N0} +* BlobDb reads: {Db.Metrics.DbReads.GetValueOrDefault("BlobTransactions"),24:N0} ------------------------------------------------ "); } From 3a3e115689a8065869ffab11dbab6882cf612b60 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 29 Apr 2024 14:54:11 +0100 Subject: [PATCH 167/213] fix formatting --- .../Validators/BlockValidator.cs | 14 +++++++------- src/Nethermind/Nethermind.Core/Extensions/Bytes.cs | 14 +++++++------- .../Synchronization/BeaconHeadersSyncFeed.cs | 8 ++++---- .../FastBlocks/FastHeadersSyncFeed.cs | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs index 58562b9b536..04e0ca08f68 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs @@ -138,16 +138,16 @@ public bool ValidateSuggestedBlock(Block block, out string? errorMessage, bool v if (validateHashes) { - if (!ValidateTxRootMatchesTxs(block, out Hash256 txRoot)) - { - if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} Transaction root hash mismatch: expected {block.Header.TxRoot}, got {txRoot}"); + if (!ValidateTxRootMatchesTxs(block, out Hash256 txRoot)) + { + if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} Transaction root hash mismatch: expected {block.Header.TxRoot}, got {txRoot}"); errorMessage = BlockErrorMessages.InvalidTxRoot(block.Header.TxRoot!, txRoot); - return false; - } + return false; + } - if (!ValidateWithdrawals(block, spec, out errorMessage)) + if (!ValidateWithdrawals(block, spec, out errorMessage)) { - return false; + return false; } } diff --git a/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs b/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs index b6a6936d599..cdbdd104a4a 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs @@ -953,8 +953,8 @@ public static int CountLeadingNibbleZeros(this ReadOnlySpan bytes) int leadingZeros = firstNonZero * 2; if ((bytes[firstNonZero] & 0b1111_0000) == 0) - { - leadingZeros++; + { + leadingZeros++; } return leadingZeros; @@ -964,7 +964,7 @@ public static int CountZeros(this Span data) => CountZeros((ReadOnlySpan)data); public static int CountZeros(this ReadOnlySpan data) - { + { int totalZeros = 0; if (Vector512.IsHardwareAccelerated && data.Length >= Vector512.Count) { @@ -975,7 +975,7 @@ public static int CountZeros(this ReadOnlySpan data) Vector512 dataVector = Unsafe.ReadUnaligned>(ref Unsafe.Add(ref bytes, i)); ulong flags = Vector512.Equals(dataVector, default).ExtractMostSignificantBits(); totalZeros += BitOperations.PopCount(flags); - } + } data = data[i..]; } @@ -984,14 +984,14 @@ public static int CountZeros(this ReadOnlySpan data) ref byte bytes = ref MemoryMarshal.GetReference(data); int i = 0; for (; i < data.Length - Vector256.Count; i += Vector256.Count) - { + { Vector256 dataVector = Unsafe.ReadUnaligned>(ref Unsafe.Add(ref bytes, i)); uint flags = Vector256.Equals(dataVector, default).ExtractMostSignificantBits(); totalZeros += BitOperations.PopCount(flags); - } + } data = data[i..]; - } + } if (Vector128.IsHardwareAccelerated && data.Length >= Vector128.Count) { ref byte bytes = ref MemoryMarshal.GetReference(data); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs index 2bb5ee7f4dd..4820f52be48 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconHeadersSyncFeed.cs @@ -188,10 +188,10 @@ protected override AddBlockResult InsertToBlockTree(BlockHeader header) if (insertOutcome == AddBlockResult.Added || insertOutcome == AddBlockResult.AlreadyKnown) { _nextHeaderHash = header.ParentHash!; - _nextHeaderDiff = header.TotalDifficulty is not null && header.TotalDifficulty >= header.Difficulty - ? header.TotalDifficulty - header.Difficulty - : null; - } + _nextHeaderDiff = header.TotalDifficulty is not null && header.TotalDifficulty >= header.Difficulty + ? header.TotalDifficulty - header.Difficulty + : null; + } if (_logger.IsTrace) _logger.Trace( diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs index fc414e65f12..a5b175233c7 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/FastHeadersSyncFeed.cs @@ -707,7 +707,7 @@ protected virtual AddBlockResult InsertToBlockTree(BlockHeader header) protected void SetExpectedNextHeaderToParent(BlockHeader header) { _nextHeaderHash = header.ParentHash!; - _nextHeaderDiff = (header.TotalDifficulty ?? 0) - header.Difficulty; - } + _nextHeaderDiff = (header.TotalDifficulty ?? 0) - header.Difficulty; } + } } From 5b717b68573962439e5f539a27ffd1c594b88e58 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 3 May 2024 15:41:21 +0200 Subject: [PATCH 168/213] fix test --- .../Modules/Eth/EthRpcModuleTests.EthCall.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs index 37c45f61978..14fabc863e3 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs @@ -242,7 +242,7 @@ public async Task Eth_call_without_gas_pricing_after_1559_new_type_of_transactio } [Test] - public async Task Eth_call_with_base_fee_opcode_should_return_0() + public async Task Eth_call_with_base_fee_opcode_should_return_block_base_fee() { using Context ctx = await Context.CreateWithLondonEnabled(); @@ -260,7 +260,7 @@ public async Task Eth_call_with_base_fee_opcode_should_return_0() $"{{\"from\": \"0x32e4e4c7c5d1cea5db5f9202a9e4d99e56c91a24\", \"type\": \"0x2\", \"data\": \"{dataStr}\"}}"); string serialized = await ctx.Test.TestEthRpc("eth_call", ctx.Test.JsonSerializer.Serialize(transaction)); Assert.That( - serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"result\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"id\":67}")); + serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"result\":\"0x000000000000000000000000000000000000000000000000000000002da282a8\",\"id\":67}")); } [Test] From 26654464235875f5360669682ce39bc2155a9a3a Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 3 May 2024 15:45:33 +0200 Subject: [PATCH 169/213] Revert "fix test" This reverts commit 5b717b68573962439e5f539a27ffd1c594b88e58. --- .../Modules/Eth/EthRpcModuleTests.EthCall.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs index 14fabc863e3..37c45f61978 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs @@ -242,7 +242,7 @@ public async Task Eth_call_without_gas_pricing_after_1559_new_type_of_transactio } [Test] - public async Task Eth_call_with_base_fee_opcode_should_return_block_base_fee() + public async Task Eth_call_with_base_fee_opcode_should_return_0() { using Context ctx = await Context.CreateWithLondonEnabled(); @@ -260,7 +260,7 @@ public async Task Eth_call_with_base_fee_opcode_should_return_block_base_fee() $"{{\"from\": \"0x32e4e4c7c5d1cea5db5f9202a9e4d99e56c91a24\", \"type\": \"0x2\", \"data\": \"{dataStr}\"}}"); string serialized = await ctx.Test.TestEthRpc("eth_call", ctx.Test.JsonSerializer.Serialize(transaction)); Assert.That( - serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"result\":\"0x000000000000000000000000000000000000000000000000000000002da282a8\",\"id\":67}")); + serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"result\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"id\":67}")); } [Test] From 1a99a298edaefd43606f054491afec6c8253be80 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 7 May 2024 20:18:10 +0100 Subject: [PATCH 170/213] pre review fixes --- .../Blockchain/TestBlockchain.cs | 5 +--- .../Nethermind.Facade/BlockchainBridge.cs | 6 +---- .../Simulate/SimulateBridgeHelper.cs | 5 ++++ .../Simulate/SimulateTxTracer.cs | 15 +++++++++--- .../Modules/Eth/EthRpcModuleTests.EthCall.cs | 2 +- .../Eth/EthRpcModule.TransactionExecutor.cs | 24 ++++++++++++++++++- .../SimulateTxExecutor.MultiCallTxExecutor.cs | 5 +++- 7 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index efa49593a59..1a2f2ae59a5 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -118,10 +118,7 @@ protected TestBlockchain() public static TransactionBuilder BuildSimpleTransaction => Builders.Build.A.Transaction.SignedAndResolved(TestItem.PrivateKeyA).To(AccountB); - protected virtual async Task Build( - ISpecProvider? specProvider = null, - UInt256? initialValues = null, - bool addBlockOnStart = true) + protected virtual async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true) { Timestamper = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc)); JsonSerializer = new EthereumJsonSerializer(); diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 07188586863..db1733964cb 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -249,11 +249,7 @@ private TransactionResult CallAndRestore( if (transaction.Nonce == 0) { - try - { - transaction.Nonce = _processingEnv.StateReader.GetNonce(stateRoot, transaction.SenderAddress); - } - catch (TrieException) { } + transaction.Nonce = GetNonce(stateRoot, transaction.SenderAddress); } BlockHeader callHeader = treatBlockHeaderAsParentBlock diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 48281e945e2..83916a63109 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -119,6 +119,11 @@ private void UpdateStateByModifyingAccounts( } } + if (!payload.Validation) + { + callHeader.BaseFeePerGas = 0; + } + Transaction[] transactions = callInputBlock.Calls?.Select(t => CreateTransaction(t, callHeader, env, nonceCache, payload.Validation)).ToArray() ?? Array.Empty(); diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs index 134c5a229ed..652d87cfcd6 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs @@ -9,8 +9,10 @@ using Nethermind.Core.Crypto; using Nethermind.Evm; using Nethermind.Evm.Tracing; +using Nethermind.Evm.Tracing.GethStyle.Custom.JavaScript; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; +using Log = Nethermind.Facade.Proxy.Models.Simulate.Log; namespace Nethermind.Facade.Simulate; @@ -20,7 +22,7 @@ internal sealed class SimulateTxTracer : TxTracer, ILogsTxTracer private readonly ulong _currentBlockNumber; private readonly Hash256 _currentBlockHash; private readonly ulong _txIndex; - private static readonly Hash256[] _topics = [Keccak.Zero]; + private static readonly Hash256 transferSignature = new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256).Hash; private readonly bool _isTracingTransfers; private static Address Erc20Sender = new("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"); public SimulateTxTracer(bool isTracingTransfers, Hash256 txHash, ulong currentBlockNumber, Hash256 currentBlockHash, @@ -76,11 +78,18 @@ public override void MarkAsFailed(Address recipient, long gasSpent, byte[] outpu public bool IsTracingLogs => _isTracingTransfers; + private Hash256 AddressToHash256(Address input) + { + byte[] addressBytes = new byte[32]; + Array.Copy(input.Bytes, 0, addressBytes, 32 - Address.Size, Address.Size); + return new Hash256(addressBytes); + } + public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); byte[] data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, - new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256), from, to, value); - yield return new LogEntry(Erc20Sender, data, _topics); + new AbiSignature("", AbiType.UInt256), value); + yield return new LogEntry(Erc20Sender, data, [transferSignature, AddressToHash256(from), AddressToHash256(to)]); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs index 37c45f61978..cd7fb615ec8 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs @@ -160,7 +160,7 @@ public async Task Eth_call_create_tx_with_empty_data() string serialized = await ctx.Test.TestEthRpc("eth_call", ctx.Test.JsonSerializer.Serialize(transaction), "latest"); - serialized.Should().BeEquivalentTo("{\"jsonrpc\":\"2.0\",\"result\":\"0x\",\"id\":67}"); + serialized.Should().BeEquivalentTo("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"Contract creation without any data provided.\"},\"id\":67}"); } [Test] diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index b0f136b5dcd..63416d5917f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -24,17 +24,39 @@ public partial class EthRpcModule // Single call executor private abstract class TxExecutor : ExecutorBase { + protected bool NoBaseFee { get; set; } protected TxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : base(blockchainBridge, blockFinder, rpcConfig) { } protected override Transaction Prepare(TransactionForRpc call) => call.ToTransaction(_blockchainBridge.GetChainId()); - protected override ResultWrapper Execute(BlockHeader header, Transaction tx, CancellationToken token) => ExecuteTx(header, tx, token); + protected override ResultWrapper Execute(BlockHeader header, Transaction tx, CancellationToken token) + { + BlockHeader clonedHeader = header.Clone(); + if (NoBaseFee) + { + clonedHeader.BaseFeePerGas = 0; + } + if (tx.IsContractCreation && tx.DataLength == 0) + { + return ResultWrapper.Fail("Contract creation without any data provided.", + ErrorCodes.InvalidInput); + } + return ExecuteTx(clonedHeader, tx, token); + } + + private static bool ShouldSetBaseFee(TransactionForRpc t) + { + return (t.GasPrice.HasValue && t.GasPrice.Value > 0) || + (t.MaxFeePerGas.HasValue && t.MaxFeePerGas.Value > 0) || + (t.MaxPriorityFeePerGas.HasValue && t.MaxPriorityFeePerGas.Value > 0); + } public override ResultWrapper Execute( TransactionForRpc transactionCall, BlockParameter? blockParameter) { + NoBaseFee = !ShouldSetBaseFee(transactionCall); transactionCall.EnsureDefaults(_rpcConfig.GasCap); return base.Execute(transactionCall, blockParameter); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs index 49d4b39069c..f3cfe3b480e 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs @@ -12,16 +12,19 @@ using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.JsonRpc.Data; using Newtonsoft.Json.Linq; +using Nethermind.Config; namespace Nethermind.JsonRpc.Modules.Eth; public class SimulateTxExecutor : ExecutorBase, SimulatePayload, SimulatePayload> { + private readonly ulong _interBlocksTimings; private long gasCapBudget; private long blocksLimit; public SimulateTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : base(blockchainBridge, blockFinder, rpcConfig) { + _interBlocksTimings = new BlocksConfig().SecondsPerSlot; gasCapBudget = rpcConfig.GasCap ?? long.MaxValue; blocksLimit = rpcConfig.MaxSimulateBlocksCap ?? 256; } @@ -142,7 +145,7 @@ public override ResultWrapper> Execute( blockToSimulate.BlockOverrides!.Number = givenNumber; - var givenTime = blockToSimulate.BlockOverrides?.Time ?? (lastBlockTime == 0 ? header.Timestamp + 1 : lastBlockTime + 1); + var givenTime = blockToSimulate.BlockOverrides?.Time ?? (lastBlockTime == 0 ? header.Timestamp + _interBlocksTimings : lastBlockTime + _interBlocksTimings); if (givenTime > lastBlockTime) { From c007a4ee2d3ce082469956a9e2fae9076d5d3d71 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 7 May 2024 23:58:37 +0100 Subject: [PATCH 171/213] post merge tests fixes --- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 7 ++++++- .../Json/UInt256DictionaryKeyConverterTests.cs | 2 +- .../Tracing/GasEstimationTests.cs | 2 +- .../VirtualMachineTestsBase.cs | 2 +- .../Tracing/BlockReceiptsTracer.cs | 3 +-- .../Tracing/CancellationTxTracer.cs | 10 +++++++++- .../Nethermind.Evm/Tracing/ITxTracer.cs | 4 ++-- src/Nethermind/Nethermind.Evm/VirtualMachine.cs | 6 ++++-- .../Nethermind.Facade/BlockchainBridge.cs | 8 ++------ .../SimulateReadOnlyBlocksProcessingEnv.cs | 6 ++++-- .../Simulate/SimulateTxTracer.cs | 17 ++++++++++------- 11 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index e9a6bc181c4..21e43ca6e1e 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -3,6 +3,7 @@ using System; using Nethermind.Blockchain; +using Nethermind.Core.Specs; using Nethermind.Db; using Nethermind.Evm; using Nethermind.Logging; @@ -21,12 +22,16 @@ public class ReadOnlyTxProcessingEnvBase protected ReadOnlyTxProcessingEnvBase( IWorldStateManager worldStateManager, IBlockTree readOnlyBlockTree, + ISpecProvider? specProvider, ILogManager? logManager ) { + ArgumentNullException.ThrowIfNull(specProvider); + ArgumentNullException.ThrowIfNull(worldStateManager); + StateReader = worldStateManager.GlobalStateReader; StateProvider = worldStateManager.CreateResettableWorldState(); BlockTree = readOnlyBlockTree ?? throw new ArgumentNullException(nameof(readOnlyBlockTree)); - BlockhashProvider = new BlockhashProvider(BlockTree, logManager); + BlockhashProvider = new BlockhashProvider(BlockTree, specProvider, StateProvider, logManager); } } diff --git a/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs index 533e777f8af..2f37bd6b572 100644 --- a/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Json/UInt256DictionaryKeyConverterTests.cs @@ -115,7 +115,7 @@ public void WriteJson_Dictionary_SerializedCorrectly() { new UInt256(1), new UInt256(12345) } }; string serialised = JsonSerializer.Serialize(dictionary, Options); - + serialised = serialised.Replace("\r\n", "\n"); string expected = """ { "0x1": "0x3039" diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs index 75e210ddec0..def68b3ca1d 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs @@ -363,7 +363,7 @@ public TestEnvironment() _stateProvider.CommitTree(0); CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, codeInfoRepository, LimboLogs.Instance); + VirtualMachine virtualMachine = new(new TestBlockhashProvider(_specProvider), _specProvider, codeInfoRepository, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); diff --git a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs index 2b548a53f0e..dcddc35cfec 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs @@ -67,7 +67,7 @@ public virtual void Setup() ITrieStore trieStore = new TrieStore(_stateDb, logManager); TestState = new WorldState(trieStore, codeDb, logManager); _ethereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId, logManager); - IBlockhashProvider blockhashProvider = new TestBlockhashProvider(_specProvider); + IBlockhashProvider blockhashProvider = new TestBlockhashProvider(SpecProvider); CodeInfoRepository = new CodeInfoRepository(); Machine = new VirtualMachine(blockhashProvider, SpecProvider, CodeInfoRepository, logManager); _processor = new TransactionProcessor(SpecProvider, TestState, Machine, CodeInfoRepository, logManager); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index c8235af4271..6f7d84009f7 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -28,8 +28,7 @@ public class BlockReceiptsTracer : IBlockTracer, ITxTracer, IJournal, ITxTr public bool IsTracingAccess => _currentTxTracer.IsTracingAccess; public bool IsTracingFees => _currentTxTracer.IsTracingFees; public bool IsTracingLogs => _currentTxTracer.IsTracingLogs; - - public bool IsTracingLogs => _logsTxTracer != null && _logsTxTracer!.IsTracingLogs; + public bool IsTracingEvmActionLogs => (_logsTxTracer != null && _logsTxTracer!.IsTracingEvmActionLogs); private ILogsTxTracer? _logsTxTracer; private IBlockTracer _otherTracer = NullBlockTracer.Instance; diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs index dd52ea5aa9f..779ce49ed8d 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs @@ -29,6 +29,7 @@ public class CancellationTxTracer : ITxTracer, ITxTracerWrapper, ILogsTxTracer private readonly bool _isTracingBlockAccess; private readonly bool _isTracingFees; private readonly bool _isTracingOpLevelLogs; + private readonly bool _isTracingEvmActionLogs; public ITxTracer InnerTracer => _innerTracer; private ILogsTxTracer? _logsTxTracer; @@ -54,6 +55,12 @@ public bool IsTracingActions init => _isTracingActions = value; } + public bool IsTracingEvmActionLogs + { + get => _isTracingEvmActionLogs || (_logsTxTracer != null && _logsTxTracer!.IsTracingEvmActionLogs); + init => _isTracingEvmActionLogs = value; + } + public bool IsTracingOpLevelStorage { get => _isTracingOpLevelStorage || _innerTracer.IsTracingOpLevelStorage; @@ -119,12 +126,14 @@ public bool IsTracingFees get => _isTracingFees || _innerTracer.IsTracingFees; init => _isTracingFees = value; } + public bool IsTracingLogs { get => _isTracingOpLevelLogs || _innerTracer.IsTracingLogs; init => _isTracingOpLevelLogs = value; } + public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) { _token.ThrowIfCancellationRequested(); @@ -463,7 +472,6 @@ public void Dispose() _innerTracer.Dispose(); } - public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index 01612a352a1..46d489a7ba0 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -441,7 +441,7 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn public interface ILogsTxTracer { - bool IsTracingLogs { get; } + bool IsTracingEvmActionLogs { get; } /// /// @@ -454,6 +454,6 @@ public interface ILogsTxTracer /// /// /// Created logs to be added, only when is true - /// Depends on + /// Depends on IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 910a724408b..82436ac6979 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -214,9 +214,11 @@ public TransactionSubstate Run(EvmState state, IWorldState worl } else { - if (typeof(TTracingActions) == typeof(IsTracing) && !currentState.IsContinuation) + var hereIsTracing = typeof(TTracingActions) == typeof(IsTracing); + + if (hereIsTracing && !currentState.IsContinuation) { - if (_txTracer is ILogsTxTracer { IsTracingLogs: true } logsTxTracer) + if (_txTracer is ILogsTxTracer { IsTracingEvmActionLogs: true } logsTxTracer) { IEnumerable logs = logsTxTracer.ReportActionAndAddResultsToState(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index db1733964cb..a3f089c2bf3 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -26,12 +26,8 @@ using Nethermind.Core.Extensions; using Nethermind.Config; using Nethermind.Facade.Proxy.Models.Simulate; -using System.Transactions; -using Microsoft.CSharp.RuntimeBinder; using Nethermind.Facade.Simulate; using Transaction = Nethermind.Core.Transaction; -using Nethermind.Specs; -using MathNet.Numerics.RootFinding; namespace Nethermind.Facade { @@ -156,12 +152,12 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can public SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, CancellationToken cancellationToken) { SimulateBlockTracer simulateOutputTracer = new(payload.TraceTransfers); - BlockReceiptsTracer tracer = new BlockReceiptsTracer(); + BlockReceiptsTracer tracer = new(); tracer.SetOtherTracer(simulateOutputTracer); SimulateOutput result = new(); try { - (bool success, string error) = _simulateBridgeHelper.TrySimulateTrace(header, payload, tracer.WithCancellation(cancellationToken)); + (bool success, string error) = _simulateBridgeHelper.TrySimulateTrace(header, payload, new CancellationBlockTracer(tracer, cancellationToken)); if (!success) { result.Error = error; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 63d2dbf9106..ecf752bcec3 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -3,6 +3,7 @@ using System; using Nethermind.Blockchain; +using Nethermind.Blockchain.Blocks; using Nethermind.Blockchain.Receipts; using Nethermind.Consensus.Processing; using Nethermind.Consensus.Rewards; @@ -40,7 +41,7 @@ public SimulateReadOnlyBlocksProcessingEnv( ISpecProvider specProvider, ILogManager? logManager = null, bool doValidation = false) - : base(worldStateManager, blockTree, logManager) + : base(worldStateManager, blockTree, specProvider, logManager) { ReadOnlyBlockTree = baseBlockTree; DbProvider = readOnlyDbProvider; @@ -49,7 +50,7 @@ public SimulateReadOnlyBlocksProcessingEnv( SpecProvider = specProvider; BlockTree = new BlockTreeOverlay(ReadOnlyBlockTree, blockTree); - BlockhashProvider = new SimulateBlockhashProvider(new BlockhashProvider(BlockTree, logManager), BlockTree); + BlockhashProvider = new SimulateBlockhashProvider(new BlockhashProvider(BlockTree, specProvider, StateProvider, logManager), BlockTree); StateProvider = WorldStateManager.GlobalWorldState; StateReader = WorldStateManager.GlobalStateReader; CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); @@ -87,6 +88,7 @@ public IBlockProcessor GetProcessor(Hash256 stateRoot) StateProvider, NullReceiptStorage.Instance, NullWitnessCollector.Instance, + new BlockhashStore(BlockTree, SpecProvider, StateProvider), _logManager); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs index 652d87cfcd6..42eae05db2b 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs @@ -9,7 +9,6 @@ using Nethermind.Core.Crypto; using Nethermind.Evm; using Nethermind.Evm.Tracing; -using Nethermind.Evm.Tracing.GethStyle.Custom.JavaScript; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; using Log = Nethermind.Facade.Proxy.Models.Simulate.Log; @@ -23,8 +22,10 @@ internal sealed class SimulateTxTracer : TxTracer, ILogsTxTracer private readonly Hash256 _currentBlockHash; private readonly ulong _txIndex; private static readonly Hash256 transferSignature = new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256).Hash; - private readonly bool _isTracingTransfers; private static Address Erc20Sender = new("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"); + + public bool IsTracingEvmActionLogs { get; } + public SimulateTxTracer(bool isTracingTransfers, Hash256 txHash, ulong currentBlockNumber, Hash256 currentBlockHash, ulong txIndex) { @@ -33,10 +34,14 @@ public SimulateTxTracer(bool isTracingTransfers, Hash256 txHash, ulong currentBl _currentBlockHash = currentBlockHash; _txIndex = txIndex; IsTracingReceipt = true; - - _isTracingTransfers = isTracingTransfers; + IsTracingEvmActionLogs = isTracingTransfers; + if (isTracingTransfers) + { + IsTracingActions = true; + } } + public SimulateCallResult? TraceResult { get; set; } public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Hash256? stateRoot = null) @@ -57,7 +62,7 @@ public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] outp BlockHash = _currentBlockHash, BlockNumber = _currentBlockNumber - }) + }).ToList() }; } @@ -76,8 +81,6 @@ public override void MarkAsFailed(Address recipient, long gasSpent, byte[] outpu }; } - public bool IsTracingLogs => _isTracingTransfers; - private Hash256 AddressToHash256(Address input) { byte[] addressBytes = new byte[32]; From bf575566d780a945f74a0d3ebbcf220daa97c3ae Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Wed, 8 May 2024 01:40:43 +0100 Subject: [PATCH 172/213] automated cleanup of new files --- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 2 - .../Nethermind.Evm/VirtualMachine.cs | 2 +- .../BlockchainBridgeExtensions.cs | 1 - .../OverridableCodeInfoRepository.cs | 31 ++--- .../Proxy/Models/AccountOverride.cs | 4 +- .../Proxy/Models/Simulate/BlockOverride.cs | 1 - .../Models/Simulate/SimulateBlockResult.cs | 3 - .../Models/Simulate/SimulateCallResult.cs | 2 - .../Proxy/Models/Simulate/SimulatePayload.cs | 7 +- .../Simulate/TransactionWithSourceDetails.cs | 2 +- .../Simulate/SimulateBlockTracer.cs | 6 +- .../Simulate/SimulateBlockhashProvider.cs | 1 - .../Simulate/SimulateBridgeHelper.cs | 2 - .../SimulateReadOnlyBlocksProcessingEnv.cs | 36 +++--- .../Simulate/SimulateTxTracer.cs | 49 ++++---- .../Modules/Eth/EthRpcSimulateTestsBase.cs | 9 +- ...SimulateTestsPrecompilesWithRedirection.cs | 8 +- .../Modules/Eth/SecureStringWrapper.cs | 52 --------- .../Eth/Simulate/EthSimulateTestsHiveBase.cs | 13 +-- .../EthSimulateTestsSimplePrecompiles.cs | 5 +- .../Modules/Eth/ExecutorBase.cs | 18 ++- .../SimulateTxExecutor.MultiCallTxExecutor.cs | 109 +++++++----------- .../OverlayWorldStateManager.cs | 11 +- 23 files changed, 141 insertions(+), 233 deletions(-) delete mode 100644 src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/SecureStringWrapper.cs diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index 21e43ca6e1e..51210ade60b 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -4,11 +4,9 @@ using System; using Nethermind.Blockchain; using Nethermind.Core.Specs; -using Nethermind.Db; using Nethermind.Evm; using Nethermind.Logging; using Nethermind.State; -using Nethermind.Trie.Pruning; namespace Nethermind.Consensus.Processing; diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 82436ac6979..28d8c15f71d 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -216,7 +216,7 @@ public TransactionSubstate Run(EvmState state, IWorldState worl { var hereIsTracing = typeof(TTracingActions) == typeof(IsTracing); - if (hereIsTracing && !currentState.IsContinuation) + if (hereIsTracing && !currentState.IsContinuation) { if (_txTracer is ILogsTxTracer { IsTracingEvmActionLogs: true } logsTxTracer) { diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs index 8114aa6ad22..bd523ef8517 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core; -using Nethermind.Trie; namespace Nethermind.Facade; diff --git a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs index 312080cf5d1..6163641fe05 100644 --- a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs @@ -16,6 +16,23 @@ public class OverridableCodeInfoRepository(ICodeInfoRepository codeInfoRepositor { private readonly Dictionary _codeOverwrites = new(); + public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) + { + return _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) + ? result + : codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, vmSpec); + } + + public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) + { + return codeInfoRepository.GetOrAdd(codeHash, initCode); + } + + public void InsertCode(IWorldState state, ReadOnlyMemory code, Address codeOwner, IReleaseSpec spec) + { + codeInfoRepository.InsertCode(state, code, codeOwner, spec); + } + public void SetCodeOverwrite( IWorldState worldState, IReleaseSpec vmSpec, @@ -23,20 +40,8 @@ public void SetCodeOverwrite( CodeInfo value, Address? redirectAddress = null) { - if (redirectAddress is not null) - { - _codeOverwrites[redirectAddress] = GetCachedCodeInfo(worldState, key, vmSpec); - } + if (redirectAddress is not null) _codeOverwrites[redirectAddress] = GetCachedCodeInfo(worldState, key, vmSpec); _codeOverwrites[key] = value; } - - public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) => - _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) ? result : codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, vmSpec); - - public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) => - codeInfoRepository.GetOrAdd(codeHash, initCode); - - public void InsertCode(IWorldState state, ReadOnlyMemory code, Address codeOwner, IReleaseSpec spec) => - codeInfoRepository.InsertCode(state, code, codeOwner, spec); } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs index c50fe6d1b2d..5b8a26ab431 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/AccountOverride.cs @@ -16,12 +16,12 @@ public class AccountOverride public Address? MovePrecompileToAddress { get; set; } /// - /// Storage for AccountOverrideState + /// Storage for AccountOverrideState /// public Dictionary? State { get; set; } /// - /// Storage difference for AccountOverrideStateDiff + /// Storage difference for AccountOverrideStateDiff /// public Dictionary? StateDiff { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs index 7f833aaedfc..ad017bec29e 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/BlockOverride.cs @@ -3,7 +3,6 @@ using System; using Nethermind.Config; -using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs index 4eea0fd2cf2..25b7257f5e3 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs @@ -1,9 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using System.Collections.Generic; -using System.Linq; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Int256; @@ -26,5 +24,4 @@ public class SimulateBlockResult public ulong BlobGasUsed { get; set; } public UInt256 ExcessBlobGas { get; set; } public UInt256 BlobBaseFee { get; set; } - } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs index 97a649e5729..e07ec128b4d 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs @@ -1,10 +1,8 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using System.Collections.Generic; using System.Linq; -using Nethermind.Evm; namespace Nethermind.Facade.Proxy.Models.Simulate; diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs index 820a8dece1e..6bc19755870 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs @@ -6,17 +6,18 @@ namespace Nethermind.Facade.Proxy.Models.Simulate; public class SimulatePayload { /// - /// Definition of blocks that can contain calls and overrides + /// Definition of blocks that can contain calls and overrides /// public BlockStateCall[]? BlockStateCalls { get; set; } /// - /// Should trace ETH Transfers + /// Should trace ETH Transfers /// public bool TraceTransfers { get; set; } /// - /// When true, the simulate does all validations that a normal EVM would do, except contract sender and signature checks. When false, multicall behaves like eth_call. + /// When true, the simulate does all validations that a normal EVM would do, except contract sender and signature + /// checks. When false, multicall behaves like eth_call. /// public bool Validation { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/TransactionWithSourceDetails.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/TransactionWithSourceDetails.cs index 2fce8df871a..b3fed70ba7c 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/TransactionWithSourceDetails.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/TransactionWithSourceDetails.cs @@ -7,7 +7,7 @@ namespace Nethermind.Facade.Proxy.Models.Simulate; public class TransactionWithSourceDetails { - public bool HadNonceInRequest; public bool HadGasLimitInRequest; + public bool HadNonceInRequest; public Transaction Transaction { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 5240a65aca4..0d746c5f119 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -5,22 +5,18 @@ using System.Collections.Generic; using System.Linq; using Nethermind.Core; -using Nethermind.Core.Collections; using Nethermind.Evm; using Nethermind.Evm.Tracing; -using Nethermind.Evm.Tracing.GethStyle.Custom.JavaScript; using Nethermind.Facade.Proxy.Models.Simulate; -using ResultType = Nethermind.Facade.Proxy.Models.Simulate.ResultType; namespace Nethermind.Facade.Simulate; public class SimulateBlockTracer(bool isTracingLogs) : BlockTracer { - public List Results { get; } = new(); - private readonly List _txTracers = new(); private Block _currentBlock = null!; + public List Results { get; } = new(); public override void StartNewBlockTrace(Block block) { diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs index 1ace83cf3a4..0af6761cb53 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs @@ -5,7 +5,6 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Evm; -using Nethermind.Logging; namespace Nethermind.Facade.Simulate; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 83916a63109..a30df63ddfb 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -10,10 +10,8 @@ using Nethermind.Core; using Nethermind.Core.Collections; using Nethermind.Core.Crypto; -using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Crypto; -using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade.Proxy.Models.Simulate; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index ecf752bcec3..156361f130c 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -21,16 +21,9 @@ namespace Nethermind.Facade.Simulate; public class SimulateReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IDisposable { - private readonly ILogManager? _logManager; private readonly IBlockValidator _blockValidator; + private readonly ILogManager? _logManager; private readonly TransactionProcessor _transactionProcessor; - public ISpecProvider SpecProvider { get; } - public IWorldStateManager WorldStateManager { get; } - public IVirtualMachine VirtualMachine { get; } - public IReadOnlyDbProvider DbProvider { get; } - public IReadOnlyBlockTree ReadOnlyBlockTree { get; set; } - public OverridableCodeInfoRepository CodeInfoRepository { get; } - public BlockProductionTransactionPicker BlockTransactionPicker { get; } public SimulateReadOnlyBlocksProcessingEnv( bool traceTransfers, @@ -50,15 +43,30 @@ public SimulateReadOnlyBlocksProcessingEnv( SpecProvider = specProvider; BlockTree = new BlockTreeOverlay(ReadOnlyBlockTree, blockTree); - BlockhashProvider = new SimulateBlockhashProvider(new BlockhashProvider(BlockTree, specProvider, StateProvider, logManager), BlockTree); + BlockhashProvider = + new SimulateBlockhashProvider(new BlockhashProvider(BlockTree, specProvider, StateProvider, logManager), + BlockTree); StateProvider = WorldStateManager.GlobalWorldState; StateReader = WorldStateManager.GlobalStateReader; CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); VirtualMachine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); - _transactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !doValidation); + _transactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, + CodeInfoRepository, _logManager, !doValidation); _blockValidator = CreateValidator(); BlockTransactionPicker = new BlockProductionTransactionPicker(specProvider, true); + } + + public ISpecProvider SpecProvider { get; } + public IWorldStateManager WorldStateManager { get; } + public IVirtualMachine VirtualMachine { get; } + public IReadOnlyDbProvider DbProvider { get; } + public IReadOnlyBlockTree ReadOnlyBlockTree { get; set; } + public OverridableCodeInfoRepository CodeInfoRepository { get; } + public BlockProductionTransactionPicker BlockTransactionPicker { get; } + public void Dispose() + { + DbProvider.Dispose(); } private SimulateBlockValidatorProxy CreateValidator() @@ -84,7 +92,7 @@ public IBlockProcessor GetProcessor(Hash256 stateRoot) return new BlockProcessor(SpecProvider, _blockValidator, NoBlockRewards.Instance, - new BlockProcessor.BlockValidationTransactionsExecutor(_transactionProcessor, StateProvider), + new BlockValidationTransactionsExecutor(_transactionProcessor, StateProvider), StateProvider, NullReceiptStorage.Instance, NullWitnessCollector.Instance, @@ -92,10 +100,8 @@ public IBlockProcessor GetProcessor(Hash256 stateRoot) _logManager); } - public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) => new ReadOnlyTransactionProcessor(_transactionProcessor, StateProvider, stateRoot); - - public void Dispose() + public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) { - DbProvider.Dispose(); + return new ReadOnlyTransactionProcessor(_transactionProcessor, StateProvider, stateRoot); } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs index 42eae05db2b..861e11bd39e 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs @@ -17,14 +17,14 @@ namespace Nethermind.Facade.Simulate; internal sealed class SimulateTxTracer : TxTracer, ILogsTxTracer { - private readonly Hash256 _txHash; - private readonly ulong _currentBlockNumber; + private static readonly Hash256 transferSignature = + new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256).Hash; + + private static readonly Address Erc20Sender = new("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"); private readonly Hash256 _currentBlockHash; + private readonly ulong _currentBlockNumber; + private readonly Hash256 _txHash; private readonly ulong _txIndex; - private static readonly Hash256 transferSignature = new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256).Hash; - private static Address Erc20Sender = new("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"); - - public bool IsTracingEvmActionLogs { get; } public SimulateTxTracer(bool isTracingTransfers, Hash256 txHash, ulong currentBlockNumber, Hash256 currentBlockHash, ulong txIndex) @@ -35,18 +35,27 @@ public SimulateTxTracer(bool isTracingTransfers, Hash256 txHash, ulong currentBl _txIndex = txIndex; IsTracingReceipt = true; IsTracingEvmActionLogs = isTracingTransfers; - if (isTracingTransfers) - { - IsTracingActions = true; - } + if (isTracingTransfers) IsTracingActions = true; } public SimulateCallResult? TraceResult { get; set; } - public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Hash256? stateRoot = null) + public bool IsTracingEvmActionLogs { get; } + + public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, + ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { - TraceResult = new SimulateCallResult() + ReportAction(gas, value, from, to, input, callType, isPrecompileCall); + var data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, + new AbiSignature("", AbiType.UInt256), value); + yield return new LogEntry(Erc20Sender, data, [transferSignature, AddressToHash256(from), AddressToHash256(to)]); + } + + public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, + Hash256? stateRoot = null) + { + TraceResult = new SimulateCallResult { GasUsed = (ulong)gasSpent, ReturnData = output, @@ -61,14 +70,14 @@ public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] outp TransactionIndex = _txIndex, BlockHash = _currentBlockHash, BlockNumber = _currentBlockNumber - }).ToList() }; } - public override void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Hash256? stateRoot = null) + public override void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, + Hash256? stateRoot = null) { - TraceResult = new SimulateCallResult() + TraceResult = new SimulateCallResult { GasUsed = (ulong)gasSpent, Error = new Error @@ -83,16 +92,8 @@ public override void MarkAsFailed(Address recipient, long gasSpent, byte[] outpu private Hash256 AddressToHash256(Address input) { - byte[] addressBytes = new byte[32]; + var addressBytes = new byte[32]; Array.Copy(input.Bytes, 0, addressBytes, 32 - Address.Size, Address.Size); return new Hash256(addressBytes); } - - public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) - { - base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); - byte[] data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, - new AbiSignature("", AbiType.UInt256), value); - yield return new LogEntry(Erc20Sender, data, [transferSignature, AddressToHash256(from), AddressToHash256(to)]); - } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs index 8bbb7bad3ad..58c84bcef64 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using System.Linq; using System.Threading.Tasks; using FluentAssertions; @@ -13,19 +12,13 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; -using Nethermind.Core.Test.IO; using Nethermind.Crypto; using Nethermind.Int256; using Nethermind.JsonRpc.Data; -using Nethermind.KeyStore; -using Nethermind.KeyStore.Config; using Nethermind.Logging; -using Nethermind.Serialization.Json; using Nethermind.Specs; using Nethermind.Specs.Forks; using Nethermind.TxPool; -using Nethermind.Wallet; -using Org.BouncyCastle.Asn1.X509; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -37,7 +30,7 @@ public static Task CreateChain(IReleaseSpec? releaseSpec = nu TestSpecProvider testSpecProvider = releaseSpec is not null ? new TestSpecProvider(releaseSpec) : new TestSpecProvider(London.Instance); - return TestRpcBlockchain.ForTest(testMevRpcBlockchain).Build(testSpecProvider, null); + return TestRpcBlockchain.ForTest(testMevRpcBlockchain).Build(testSpecProvider); } private static string GetEcRecoverContractJsonAbi(string name = "recover") diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs index 4da303b977e..734d3518209 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -34,8 +33,7 @@ public async Task Test_eth_simulate_create() Data = Bytes.FromHexString("0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001"), To = TestItem.AddressA, GasLimit = 3_500_000, - GasPrice = 20.GWei(), - + GasPrice = 20.GWei() }; TransactionForRpc transactionForRpc = new(systemTransactionForModifiedVm) { Nonce = null }; @@ -168,9 +166,9 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( new AccountOverride { Code = code, - MovePrecompileToAddress = TestItem.AddressB, + MovePrecompileToAddress = TestItem.AddressB } - }, + } }, Calls = [transactionForRpc] } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/SecureStringWrapper.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/SecureStringWrapper.cs deleted file mode 100644 index 537650a69a7..00000000000 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/SecureStringWrapper.cs +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Security; - -namespace Nethermind.JsonRpc.Test.Modules.Eth; - -internal sealed class SecureStringWrapper : IDisposable -{ - private bool _disposed = false; - public SecureString SecureData { get; private set; } - - public SecureStringWrapper(string data) - { - SecureData = CreateSecureString(data); - } - - private SecureString CreateSecureString(string regularString) - { - var secureString = new SecureString(); - foreach (char c in regularString) - { - secureString.AppendChar(c); - } - secureString.MakeReadOnly(); - return secureString; - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - SecureData.Dispose(); - } - _disposed = true; - } - } - - ~SecureStringWrapper() - { - Dispose(false); - } -} diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs index a14d5e48adf..14cad67e745 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs @@ -2,14 +2,12 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Linq; +using System.Collections.Generic; using System.Threading.Tasks; using Nethermind.Blockchain.Find; -using Nethermind.Core.Crypto; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.JsonRpc.Data; using Nethermind.Serialization.Json; -using Newtonsoft.Json; using NUnit.Framework; using ResultType = Nethermind.Core.ResultType; @@ -17,16 +15,17 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; public class EthSimulateTestsHiveBase { - [Test] public async Task TestsimulateAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit() { EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; - var payload = serializer.Deserialize>(input); + var input = + "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; + SimulatePayload? payload = serializer.Deserialize>(input); TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine("current test: simulateAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); + ResultWrapper> result = + chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs index 3386db3c88f..b362a5439fd 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Collections.Generic; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Nethermind.Core; @@ -12,17 +11,15 @@ using Nethermind.Crypto; using Nethermind.Evm; using Nethermind.Evm.Precompiles; -using Nethermind.Facade; -using Nethermind.Facade.Simulate; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.Simulate; +using Nethermind.Facade.Simulate; using NUnit.Framework; namespace Nethermind.JsonRpc.Test.Modules.Eth; public class EthSimulateTestsSimplePrecompiles : EthRpcSimulateTestsBase { - /* Compiled contract * Call example for TestItem.AddressA * recover 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 28 0x7b8b1991eb44757bc688016d27940df8fb971d7c87f77a6bc4e938e3202c4403 0x7e9267b0aeaa82fa765361918f2d8abd9cdd86e64aa6f2b81d3c4e0b69a7b055 diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs index 723fea171dc..2e04d10b455 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/ExecutorBase.cs @@ -10,8 +10,8 @@ namespace Nethermind.JsonRpc.Modules.Eth; public abstract class ExecutorBase { - protected readonly IBlockFinder _blockFinder; protected readonly IBlockchainBridge _blockchainBridge; + protected readonly IBlockFinder _blockFinder; protected readonly IJsonRpcConfig _rpcConfig; protected ExecutorBase(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) @@ -26,16 +26,12 @@ public virtual ResultWrapper Execute( BlockParameter? blockParameter) { SearchResult searchResult = _blockFinder.SearchForHeader(blockParameter); - if (searchResult.IsError) - { - return ResultWrapper.Fail(searchResult); - } + if (searchResult.IsError) return ResultWrapper.Fail(searchResult); BlockHeader header = searchResult.Object; if (!_blockchainBridge.HasStateForBlock(header!)) - { - return ResultWrapper.Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable); - } + return ResultWrapper.Fail($"No state available for block {header.Hash}", + ErrorCodes.ResourceUnavailable); using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); TProcessing? toProcess = Prepare(call); @@ -46,6 +42,8 @@ public virtual ResultWrapper Execute( protected abstract ResultWrapper Execute(BlockHeader header, TProcessing tx, CancellationToken token); - protected ResultWrapper? TryGetInputError(CallOutput result) => - result.InputError ? ResultWrapper.Fail(result.Error!, ErrorCodes.InvalidInput) : null; + protected ResultWrapper? TryGetInputError(CallOutput result) + { + return result.InputError ? ResultWrapper.Fail(result.Error!, ErrorCodes.InvalidInput) : null; + } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs index f3cfe3b480e..69abc7babb8 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs @@ -6,21 +6,22 @@ using System.Linq; using System.Threading; using Nethermind.Blockchain.Find; +using Nethermind.Config; using Nethermind.Core; using Nethermind.Facade; -using Nethermind.Facade.Simulate; using Nethermind.Facade.Proxy.Models.Simulate; +using Nethermind.Facade.Simulate; using Nethermind.JsonRpc.Data; -using Newtonsoft.Json.Linq; -using Nethermind.Config; namespace Nethermind.JsonRpc.Modules.Eth; -public class SimulateTxExecutor : ExecutorBase, SimulatePayload, SimulatePayload> +public class SimulateTxExecutor : ExecutorBase, SimulatePayload, + SimulatePayload> { private readonly ulong _interBlocksTimings; + private readonly long blocksLimit; private long gasCapBudget; - private long blocksLimit; + public SimulateTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : base(blockchainBridge, blockFinder, rpcConfig) { @@ -38,9 +39,8 @@ protected override SimulatePayload Prepare(Simulat BlockStateCalls = call.BlockStateCalls?.Select(blockStateCall => { if (blockStateCall.BlockOverrides?.GasLimit != null) - { - blockStateCall.BlockOverrides.GasLimit = (ulong)Math.Min((long)blockStateCall.BlockOverrides.GasLimit!.Value, gasCapBudget); - } + blockStateCall.BlockOverrides.GasLimit = + (ulong)Math.Min((long)blockStateCall.BlockOverrides.GasLimit!.Value, gasCapBudget); return new BlockStateCall { @@ -48,17 +48,14 @@ protected override SimulatePayload Prepare(Simulat StateOverrides = blockStateCall.StateOverrides, Calls = blockStateCall.Calls?.Select(callTransactionModel => { - if (callTransactionModel.Type == TxType.Legacy) - { - callTransactionModel.Type = TxType.EIP1559; - } + if (callTransactionModel.Type == TxType.Legacy) callTransactionModel.Type = TxType.EIP1559; bool hadGasLimitInRequest = callTransactionModel.Gas.HasValue; bool hadNonceInRequest = callTransactionModel.Nonce.HasValue; callTransactionModel.EnsureDefaults(gasCapBudget); gasCapBudget -= callTransactionModel.Gas!.Value; - var tx = callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()); + Transaction tx = callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()); TransactionWithSourceDetails? result = new() { @@ -75,43 +72,36 @@ protected override SimulatePayload Prepare(Simulat return result; } + public override ResultWrapper> Execute( SimulatePayload call, BlockParameter? blockParameter) { - if (call.BlockStateCalls == null) - { - return ResultWrapper>.Fail($"Must contain BlockStateCalls", ErrorCodes.InvalidParams); - } + return ResultWrapper>.Fail("Must contain BlockStateCalls", + ErrorCodes.InvalidParams); if (call.BlockStateCalls!.Length > _rpcConfig.MaxSimulateBlocksCap) - { - return ResultWrapper>.Fail($"This node is configured to support only {_rpcConfig.MaxSimulateBlocksCap} blocks", ErrorCodes.InvalidInputTooManyBlocks); - } + return ResultWrapper>.Fail( + $"This node is configured to support only {_rpcConfig.MaxSimulateBlocksCap} blocks", + ErrorCodes.InvalidInputTooManyBlocks); SearchResult searchResult = _blockFinder.SearchForBlock(blockParameter); if (searchResult.IsError || searchResult.Object == null) - { return ResultWrapper>.Fail(searchResult); - } BlockHeader header = searchResult.Object.Header; - if (blockParameter.Type == BlockParameterType.Latest) - { - header = _blockFinder.FindLatestBlock().Header; - } + if (blockParameter.Type == BlockParameterType.Latest) header = _blockFinder.FindLatestBlock().Header; if (!_blockchainBridge.HasStateForBlock(header!)) - { - return ResultWrapper>.Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable); - } + return ResultWrapper>.Fail($"No state available for block {header.Hash}", + ErrorCodes.ResourceUnavailable); if (call.BlockStateCalls?.Length > blocksLimit) - { - return ResultWrapper>.Fail($"Too many blocks provided, node is configured to simulate up to {blocksLimit} while {call.BlockStateCalls?.Length} were given", ErrorCodes.InvalidParams); - } + return ResultWrapper>.Fail( + $"Too many blocks provided, node is configured to simulate up to {blocksLimit} while {call.BlockStateCalls?.Length} were given", + ErrorCodes.InvalidParams); if (call.BlockStateCalls != null) { @@ -120,49 +110,41 @@ public override ResultWrapper> Execute( foreach (BlockStateCall? blockToSimulate in call.BlockStateCalls!) { - var givenNumber = blockToSimulate.BlockOverrides?.Number ?? (lastBlockNumber == -1 ? (ulong)header.Number + 1 : (ulong)lastBlockNumber + 1); + ulong givenNumber = blockToSimulate.BlockOverrides?.Number ?? + (lastBlockNumber == -1 ? (ulong)header.Number + 1 : (ulong)lastBlockNumber + 1); if (givenNumber > long.MaxValue) - { - return ResultWrapper>.Fail($"Block number too big {givenNumber}!", ErrorCodes.InvalidParams); - } + return ResultWrapper>.Fail( + $"Block number too big {givenNumber}!", ErrorCodes.InvalidParams); - var given = (long)givenNumber; + long given = (long)givenNumber; if (given > lastBlockNumber) - { lastBlockNumber = given; - } else - { - return ResultWrapper>.Fail($"Block number out of order {givenNumber}!", ErrorCodes.InvalidInputBlocksOutOfOrder); - } + return ResultWrapper>.Fail( + $"Block number out of order {givenNumber}!", ErrorCodes.InvalidInputBlocksOutOfOrder); - if (blockToSimulate.BlockOverrides == null) - { - blockToSimulate.BlockOverrides = new BlockOverride(); - } + if (blockToSimulate.BlockOverrides == null) blockToSimulate.BlockOverrides = new BlockOverride(); blockToSimulate.BlockOverrides!.Number = givenNumber; - var givenTime = blockToSimulate.BlockOverrides?.Time ?? (lastBlockTime == 0 ? header.Timestamp + _interBlocksTimings : lastBlockTime + _interBlocksTimings); + ulong givenTime = blockToSimulate.BlockOverrides?.Time ?? (lastBlockTime == 0 + ? header.Timestamp + _interBlocksTimings + : lastBlockTime + _interBlocksTimings); if (givenTime > lastBlockTime) - { lastBlockTime = givenTime; - } else - { - return ResultWrapper>.Fail($"Block timestamp out of order {givenTime}!", ErrorCodes.InvalidInputBlocksOutOfOrder); - } + return ResultWrapper>.Fail( + $"Block timestamp out of order {givenTime}!", ErrorCodes.InvalidInputBlocksOutOfOrder); blockToSimulate.BlockOverrides!.Time = givenTime; - } - var minBlockNumber = Math.Min( - call.BlockStateCalls.Min(b => - (long)(b.BlockOverrides?.Number ?? ulong.MaxValue)), - header.Number + 1); + long minBlockNumber = Math.Min( + call.BlockStateCalls.Min(b => + (long)(b.BlockOverrides?.Number ?? ulong.MaxValue)), + header.Number + 1); long maxBlockNumber = Math.Max( call.BlockStateCalls.Max(b => @@ -172,20 +154,16 @@ public override ResultWrapper> Execute( HashSet existingBlockNumbers = new(call.BlockStateCalls.Select(b => (long)(b.BlockOverrides?.Number ?? ulong.MinValue))); - var completeBlockStateCalls = call.BlockStateCalls!.ToList(); + List> completeBlockStateCalls = call.BlockStateCalls!.ToList(); for (long blockNumber = minBlockNumber; blockNumber <= maxBlockNumber; blockNumber++) - { if (!existingBlockNumbers.Contains(blockNumber)) - { completeBlockStateCalls.Add(new BlockStateCall { BlockOverrides = new BlockOverride { Number = (ulong)blockNumber }, StateOverrides = null, Calls = Array.Empty() }); - } - } call.BlockStateCalls = completeBlockStateCalls.OrderBy(b => b.BlockOverrides!.Number!).ToArray(); } @@ -195,14 +173,13 @@ public override ResultWrapper> Execute( return Execute(header.Clone(), toProcess, cancellationTokenSource.Token); } - protected override ResultWrapper> Execute(BlockHeader header, SimulatePayload tx, CancellationToken token) + protected override ResultWrapper> Execute(BlockHeader header, + SimulatePayload tx, CancellationToken token) { SimulateOutput results = _blockchainBridge.Simulate(header, tx, token); if (results.Error != null && results.Error.Contains("invalid transaction")) - { results.ErrorCode = ErrorCodes.InvalidTransaction; - } return results.Error is null ? ResultWrapper>.Success(results.Items) @@ -212,5 +189,3 @@ protected override ResultWrapper> Execute(Blo : ResultWrapper>.Fail(results.Error, results.Items); } } - - diff --git a/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs b/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs index 13dd8372627..01b528a3b83 100644 --- a/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs +++ b/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs @@ -9,16 +9,16 @@ namespace Nethermind.State; public class OverlayWorldStateManager( - IReadOnlyDbProvider dbProvider, + IReadOnlyDbProvider dbProvider, OverlayTrieStore overlayTrieStore, ILogManager? logManager) : IWorldStateManager { private readonly IDb _codeDb = dbProvider.GetDb(DbNames.Code); - private readonly WorldState _state = new WorldState(overlayTrieStore, dbProvider.GetDb(DbNames.Code), logManager); + private readonly StateReader _reader = new(overlayTrieStore, dbProvider.GetDb(DbNames.Code), logManager); - private readonly StateReader _reader = new StateReader(overlayTrieStore, dbProvider.GetDb(DbNames.Code), logManager); + private readonly WorldState _state = new(overlayTrieStore, dbProvider.GetDb(DbNames.Code), logManager); public IWorldState GlobalWorldState => _state; @@ -26,7 +26,10 @@ public class OverlayWorldStateManager( public IReadOnlyTrieStore TrieStore { get; } = overlayTrieStore.AsReadOnly(); - public IWorldState CreateResettableWorldState() => new WorldState(overlayTrieStore, _codeDb, logManager); + public IWorldState CreateResettableWorldState() + { + return new WorldState(overlayTrieStore, _codeDb, logManager); + } public event EventHandler? ReorgBoundaryReached { From 918e9fd8ed4dd8240069ea6b40be8392fba0850a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 13 May 2024 14:04:05 +0100 Subject: [PATCH 173/213] Minor bug fixes --- ...sor.BlockValidationTransactionsExecutor.cs | 2 +- .../Simulate/SimulateBridgeHelper.cs | 9 +++++-- .../SimulateReadOnlyBlocksProcessingEnv.cs | 26 +++++++++++++++++-- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs index e2e7eb42592..56fbe6a607e 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs @@ -48,7 +48,7 @@ public TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processing return receiptsTracer.TxReceipts.ToArray(); } - private void ProcessTransaction(in BlockExecutionContext blkCtx, Transaction currentTx, int index, BlockReceiptsTracer receiptsTracer, ProcessingOptions processingOptions) + protected virtual void ProcessTransaction(in BlockExecutionContext blkCtx, Transaction currentTx, int index, BlockReceiptsTracer receiptsTracer, ProcessingOptions processingOptions) { TransactionResult result = _transactionProcessor.ProcessTransaction(in blkCtx, currentTx, receiptsTracer, processingOptions, _stateProvider); if (!result) ThrowInvalidBlockException(result, blkCtx.Header, currentTx, index); diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index a30df63ddfb..4acc81d19a6 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -122,6 +122,11 @@ private void UpdateStateByModifyingAccounts( callHeader.BaseFeePerGas = 0; } + if (callInputBlock.BlockOverrides is { BaseFeePerGas: not null }) + { + callHeader.BaseFeePerGas = callInputBlock.BlockOverrides.BaseFeePerGas.Value; + } + Transaction[] transactions = callInputBlock.Calls?.Select(t => CreateTransaction(t, callHeader, env, nonceCache, payload.Validation)).ToArray() ?? Array.Empty(); @@ -141,7 +146,7 @@ private void UpdateStateByModifyingAccounts( testedTxs, stateProvider); - if (args.Action is BlockProcessor.TxAction.Stop or BlockProcessor.TxAction.Skip) + if (args.Action is BlockProcessor.TxAction.Stop or BlockProcessor.TxAction.Skip && payload.Validation) { return (false, $"invalid transaction index: {index} at block number: {callHeader.Number}, Reason: {args.Reason}"); } @@ -171,7 +176,7 @@ private void UpdateStateByModifyingAccounts( Block[] currentBlocks; //try { - IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!); + IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!, payload.Validation); currentBlocks = processor.Process(stateProvider.StateRoot, suggestedBlocks.ToList(), processingFlags, tracer); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 156361f130c..5ffaa8fcabc 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -8,10 +8,12 @@ using Nethermind.Consensus.Processing; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; +using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Db; using Nethermind.Evm; +using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; using Nethermind.Logging; using Nethermind.State; @@ -19,6 +21,26 @@ namespace Nethermind.Facade.Simulate; + + +public class SimulateBlockValidationTransactionsExecutor : BlockProcessor.BlockValidationTransactionsExecutor +{ + public SimulateBlockValidationTransactionsExecutor(ITransactionProcessor transactionProcessor, IWorldState stateProvider) : base(transactionProcessor, stateProvider) + { + } + + public SimulateBlockValidationTransactionsExecutor(ITransactionProcessorAdapter transactionProcessor, IWorldState stateProvider) : base(transactionProcessor, stateProvider) + { + } + + protected override void ProcessTransaction(in BlockExecutionContext blkCtx, Transaction currentTx, int index, + BlockReceiptsTracer receiptsTracer, ProcessingOptions processingOptions) + { + processingOptions |= ProcessingOptions.DoNotVerifyNonce; + base.ProcessTransaction(in blkCtx, currentTx, index, receiptsTracer, processingOptions); + } +} + public class SimulateReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, IDisposable { private readonly IBlockValidator _blockValidator; @@ -87,12 +109,12 @@ private SimulateBlockValidatorProxy CreateValidator() return new SimulateBlockValidatorProxy(blockValidator); } - public IBlockProcessor GetProcessor(Hash256 stateRoot) + public IBlockProcessor GetProcessor(Hash256 stateRoot, bool validate) { return new BlockProcessor(SpecProvider, _blockValidator, NoBlockRewards.Instance, - new BlockValidationTransactionsExecutor(_transactionProcessor, StateProvider), + validate ? new BlockValidationTransactionsExecutor(_transactionProcessor, StateProvider) : new SimulateBlockValidationTransactionsExecutor(_transactionProcessor, StateProvider), StateProvider, NullReceiptStorage.Instance, NullWitnessCollector.Instance, From 37b52bb4247ef2af20a66b563b123e06e44d3228 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 11:35:09 +0200 Subject: [PATCH 174/213] refactors --- .../TransactionSelectorTests.cs | 2 +- .../TransactionsExecutorTests.cs | 2 +- .../Processing/IBlockProcessor.cs | 4 +- .../Processing/ReadOnlyTxProcessingEnv.cs | 1 - .../Validators/SimulateBlockValidatorProxy.cs | 18 +++---- src/Nethermind/Nethermind.Db/ReadOnlyDb.cs | 52 ++++++------------- .../TransactionSubstateTests.cs | 13 +++-- .../Nethermind.Evm/ByteCodeBuilder.cs | 7 --- .../Tracing/BlockReceiptsTracer.cs | 11 ++-- .../Tracing/CancellationTxTracer.cs | 11 ++-- .../StateProviderTests.cs | 4 +- src/Nethermind/Nethermind.State/WorldState.cs | 9 ---- .../Nethermind.Trie.Test/TrieTests.cs | 4 +- .../Nethermind.Trie/Pruning/TrieStore.cs | 5 +- 14 files changed, 46 insertions(+), 97 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs index bb730fa4b20..6b833e60048 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionSelectorTests.cs @@ -195,7 +195,7 @@ public void Proper_transactions_selected(ProperTransactionsSelectedTestCase test MemDb stateDb = new(); MemDb codeDb = new(); TrieStore trieStore = new(stateDb, LimboLogs.Instance); - WorldState stateProvider = new(trieStore, codeDb, LimboLogs.Instance); + IWorldState stateProvider = new WorldState(trieStore, codeDb, LimboLogs.Instance); StateReader _ = new(new TrieStore(stateDb, LimboLogs.Instance), codeDb, LimboLogs.Instance); ISpecProvider specProvider = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs index f43d92ead95..8799490191a 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionsExecutorTests.cs @@ -262,7 +262,7 @@ public void Proper_transactions_selected(TransactionSelectorTests.ProperTransact MemDb stateDb = new(); MemDb codeDb = new(); TrieStore trieStore = new(stateDb, LimboLogs.Instance); - WorldState stateProvider = new(trieStore, codeDb, LimboLogs.Instance); + IWorldState stateProvider = new WorldState(trieStore, codeDb, LimboLogs.Instance); ISpecProvider specProvider = Substitute.For(); IReleaseSpec spec = testCase.ReleaseSpec; diff --git a/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs index 3dad052417f..88aba737926 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/IBlockProcessor.cs @@ -18,9 +18,7 @@ public interface IBlockProcessor /// Initial state for the processed branch. /// List of blocks to be processed. /// Options to use for processor and transaction processor. - /// - /// Block tracer to use. By default either or - /// + /// Block tracer to use. By default either or /// List of processed blocks. Block[] Process( Hash256 newBranchStateRoot, diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index 9dbb1e5ab18..0d7ad95afcf 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -10,7 +10,6 @@ using Nethermind.Logging; using Nethermind.State; - // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedAutoPropertyAccessor.Global namespace Nethermind.Consensus.Processing diff --git a/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs b/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs index 34801deef76..83381ed2271 100644 --- a/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs +++ b/src/Nethermind/Nethermind.Consensus/Validators/SimulateBlockValidatorProxy.cs @@ -13,10 +13,8 @@ public bool ValidateWithdrawals(Block block, out string? error) => public bool ValidateOrphanedBlock(Block block, out string? error) => baseBlockValidator.ValidateOrphanedBlock(block, out error); - public bool ValidateSuggestedBlock(Block block, out string? error, bool validateHashes = true) - { - return baseBlockValidator.ValidateSuggestedBlock(block, out error, validateHashes); - } + public bool ValidateSuggestedBlock(Block block, out string? error, bool validateHashes = true) => + baseBlockValidator.ValidateSuggestedBlock(block, out error, validateHashes); public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock, out string? error) { @@ -24,13 +22,9 @@ public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, B return true; } - public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle, out string? error) - { - return baseBlockValidator.Validate(header, parent, isUncle, out error); - } + public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle, out string? error) => + baseBlockValidator.Validate(header, parent, isUncle, out error); - public bool Validate(BlockHeader header, bool isUncle, out string? error) - { - return baseBlockValidator.Validate(header, isUncle, out error); - } + public bool Validate(BlockHeader header, bool isUncle, out string? error) => + baseBlockValidator.Validate(header, isUncle, out error); } diff --git a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs index aeb1bbcd8ba..495a51fbe5e 100644 --- a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs +++ b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs @@ -8,34 +8,25 @@ namespace Nethermind.Db { - public class ReadOnlyDb : IReadOnlyDb + public class ReadOnlyDb(IDb wrappedDb, bool createInMemWriteStore) : IReadOnlyDb { private readonly MemDb _memDb = new(); - private readonly IDb _wrappedDb; - private readonly bool _createInMemWriteStore; - - public ReadOnlyDb(IDb wrappedDb, bool createInMemWriteStore) - { - _wrappedDb = wrappedDb; - _createInMemWriteStore = createInMemWriteStore; - } - public void Dispose() { _memDb.Dispose(); } - public string Name { get => _wrappedDb.Name; } + public string Name { get => wrappedDb.Name; } public byte[]? Get(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) { - return _memDb.Get(key, flags) ?? _wrappedDb.Get(key, flags); + return _memDb.Get(key, flags) ?? wrappedDb.Get(key, flags); } public void Set(ReadOnlySpan key, byte[]? value, WriteFlags flags = WriteFlags.None) { - if (!_createInMemWriteStore) + if (!createInMemWriteStore) { throw new InvalidOperationException($"This {nameof(ReadOnlyDb)} did not expect any writes."); } @@ -47,7 +38,7 @@ public KeyValuePair[] this[byte[][] keys] { get { - var result = _wrappedDb[keys]; + var result = wrappedDb[keys]; var memResult = _memDb[keys]; for (int i = 0; i < memResult.Length; i++) { @@ -62,47 +53,34 @@ public KeyValuePair[] this[byte[][] keys] } } - public IEnumerable> GetAll(bool ordered = false) => _memDb.GetAll().Union(_wrappedDb.GetAll()); + public IEnumerable> GetAll(bool ordered = false) => _memDb.GetAll().Union(wrappedDb.GetAll()); - public IEnumerable GetAllKeys(bool ordered = false) => _memDb.GetAllKeys().Union(_wrappedDb.GetAllKeys()); + public IEnumerable GetAllKeys(bool ordered = false) => _memDb.GetAllKeys().Union(wrappedDb.GetAllKeys()); - public IEnumerable GetAllValues(bool ordered = false) => _memDb.GetAllValues().Union(_wrappedDb.GetAllValues()); + public IEnumerable GetAllValues(bool ordered = false) => _memDb.GetAllValues().Union(wrappedDb.GetAllValues()); - public IWriteBatch StartWriteBatch() - { - return this.LikeABatch(); - } + public IWriteBatch StartWriteBatch() => this.LikeABatch(); - //public long GetSize() => _memDb.GetSize() + _wrappedDb.GetSize(); - //public long GetCacheSize() => _memDb.GetCacheSize() + _wrappedDb.GetCacheSize(); - //public long GetIndexSize() => _memDb.GetIndexSize() + _wrappedDb.GetIndexSize(); - //public long GetMemtableSize() => _memDb.GetMemtableSize() + _wrappedDb.GetMemtableSize(); - public IDbMeta.DbMetric GatherMetric(bool includeSharedCache = false) => _wrappedDb.GatherMetric(includeSharedCache); + public IDbMeta.DbMetric GatherMetric(bool includeSharedCache = false) => wrappedDb.GatherMetric(includeSharedCache); public void Remove(ReadOnlySpan key) { } - public bool KeyExists(ReadOnlySpan key) - { - return _memDb.KeyExists(key) || _wrappedDb.KeyExists(key); - } + public bool KeyExists(ReadOnlySpan key) => _memDb.KeyExists(key) || wrappedDb.KeyExists(key); public void Flush() { - _wrappedDb.Flush(); + wrappedDb.Flush(); _memDb.Flush(); } - public void Clear() { throw new InvalidOperationException(); } + public void Clear() => throw new InvalidOperationException(); - public virtual void ClearTempChanges() - { - _memDb.Clear(); - } + public virtual void ClearTempChanges() => _memDb.Clear(); public Span GetSpan(ReadOnlySpan key) => Get(key).AsSpan(); public void PutSpan(ReadOnlySpan keyBytes, ReadOnlySpan value, WriteFlags writeFlags = WriteFlags.None) { - if (!_createInMemWriteStore) + if (!createInMemWriteStore) { throw new InvalidOperationException($"This {nameof(ReadOnlyDb)} did not expect any writes."); } diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs index 30a6e0dd9f6..b067d7539a0 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs @@ -16,12 +16,15 @@ public class TransactionSubstateTests [Test] public void should_return_proper_revert_error_when_there_is_no_exception() { - byte[] data = {0, 0, 0, 0, + byte[] data = + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5, - 0x05, 0x06, 0x07, 0x08, 0x09}; + 0x05, 0x06, 0x07, 0x08, 0x09 + ]; ReadOnlyMemory readOnlyMemory = new(data); TransactionSubstate transactionSubstate = new(readOnlyMemory, 0, @@ -158,12 +161,14 @@ public void should_return_proper_revert_error_when_using_special_functions((byte [Ignore("Badly implemented")] public void should_return_proper_revert_error_when_revert_custom_error() { - byte[] data = { + byte[] data = + [ 0x22, 0x02, 0x66, 0xb6, // Keccak of `FailedOp(uint256,string)` == 0x220266b6 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x41, 0x41, 0x32, 0x31, 0x20, 0x64, 0x69, 0x64, 0x6e, 0x27, 0x74, 0x20, 0x70, 0x61, 0x79, 0x20, 0x70, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, // "AA21 didn't pay prefund" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + ]; ReadOnlyMemory readOnlyMemory = new(data); TransactionSubstate transactionSubstate = new( readOnlyMemory, diff --git a/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs b/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs index 740306180e5..b05d9b77825 100644 --- a/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs +++ b/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs @@ -274,13 +274,6 @@ public Prepare PushData(string data) return this; } - public Prepare PushData(byte[] data) - { - _byteCode.Add((byte)(Instruction.PUSH1 + (byte)data.Length - 1)); - _byteCode.AddRange(data); - return this; - } - public Prepare PushData(ReadOnlyMemory data) { _byteCode.Add((byte)(Instruction.PUSH1 + (byte)data.Length - 1)); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index 6f7d84009f7..ec24a910e00 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -281,13 +281,8 @@ public void Dispose() public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { - if (_logsTxTracer != null) - { - return _logsTxTracer.ReportActionAndAddResultsToState(gas, value, from, to, input, callType, - isPrecompileCall); - } - - return Enumerable.Empty(); - + return _logsTxTracer is not null + ? _logsTxTracer.ReportActionAndAddResultsToState(gas, value, from, to, input, callType, isPrecompileCall) + : Enumerable.Empty(); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs index 779ce49ed8d..fa8e1eff2f1 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs @@ -475,12 +475,9 @@ public void Dispose() public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { - if (_logsTxTracer == null) - { - return Enumerable.Empty(); - } - - return _logsTxTracer.ReportActionAndAddResultsToState(gas, value, from, to, input, callType, - isPrecompileCall); + return _logsTxTracer is null + ? Enumerable.Empty() + : _logsTxTracer.ReportActionAndAddResultsToState(gas, value, from, to, input, callType, + isPrecompileCall); } } diff --git a/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs b/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs index cc0f1e4496c..ee924de5b4e 100644 --- a/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StateProviderTests.cs @@ -176,9 +176,9 @@ public void Keep_in_cache() [Test] public void Restore_in_the_middle() { - byte[] code = new byte[] { 1 }; + byte[] code = [1]; - WorldState provider = new(new TrieStore(new MemDb(), Logger), _codeDb, Logger); + IWorldState provider = new WorldState(new TrieStore(new MemDb(), Logger), _codeDb, Logger); provider.CreateAccount(_address1, 1); provider.AddToBalance(_address1, 1, Frontier.Instance); provider.IncrementNonce(_address1); diff --git a/src/Nethermind/Nethermind.State/WorldState.cs b/src/Nethermind/Nethermind.State/WorldState.cs index 979e8fdc52b..548596784c8 100644 --- a/src/Nethermind/Nethermind.State/WorldState.cs +++ b/src/Nethermind/Nethermind.State/WorldState.cs @@ -145,15 +145,6 @@ public void DecrementNonce(Address address, UInt256 delta) _stateProvider.DecrementNonce(address, delta); } - public void IncrementNonce(Address address) - { - _stateProvider.IncrementNonce(address, 1); - } - public void DecrementNonce(Address address) - { - _stateProvider.DecrementNonce(address, 1); - } - public void CommitTree(long blockNumber) { _persistentStorageProvider.CommitTrees(blockNumber); diff --git a/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs b/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs index 47953a99e84..0d9e05c1e1f 100644 --- a/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/TrieTests.cs @@ -1013,7 +1013,7 @@ public void Fuzz_accounts_with_storage( MemDb memDb = new(); using TrieStore trieStore = new(memDb, Prune.WhenCacheReaches(1.MB()), Persist.IfBlockOlderThan(lookupLimit), _logManager); - WorldState stateProvider = new(trieStore, new MemDb(), _logManager); + WorldState stateProvider = new WorldState(trieStore, new MemDb(), _logManager); Account[] accounts = new Account[accountsCount]; Address[] addresses = new Address[accountsCount]; @@ -1062,7 +1062,7 @@ public void Fuzz_accounts_with_storage( address, existing.Balance - account.Balance, MuirGlacier.Instance); } - stateProvider.IncrementNonce(address); + stateProvider.IncrementNonce(address, UInt256.One); } byte[] storage = new byte[1]; diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs index e556fd7b7f3..699d3305f34 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs @@ -52,7 +52,7 @@ public void SaveInCache(in Key key, TrieNode node) } } - public virtual TrieNode FindCachedOrUnknown(in Key key) + public TrieNode FindCachedOrUnknown(in Key key) { if (TryGetValue(key, out TrieNode trieNode)) { @@ -609,7 +609,6 @@ public IReadOnlyTrieStore AsReadOnly(INodeStorage? store) => new ReadOnlyTrieStore(this, store); public bool IsNodeCached(Hash256? address, in TreePath path, Hash256? hash) => _dirtyNodes.IsNodeCached(new DirtyNodesCache.Key(address, path, hash)); - private bool IsNodeCached(DirtyNodesCache.Key key) => _dirtyNodes.IsNodeCached(key); public virtual TrieNode FindCachedOrUnknown(Hash256? address, in TreePath path, Hash256? hash) => FindCachedOrUnknown(address, path, hash, false); @@ -1276,7 +1275,7 @@ void PersistNode(TrieNode n, Hash256? address, TreePath path) } // Used to serve node by hash - public virtual byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) + public byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) { Hash256 asHash = new Hash256(key); return _pruningStrategy.PruningEnabled From 5e7be691545cce749a8a0ab677fc0ce397d259e2 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 12:24:31 +0200 Subject: [PATCH 175/213] Refactor ITxLogsTracer to ITxLogsMutator and introduce SimulateVirtualMachine --- .../Tracing/BlockReceiptsTracer.cs | 17 +- .../Tracing/CancellationBlockTracer.cs | 32 +- .../Tracing/CancellationTxTracer.cs | 283 ++++++++---------- .../Nethermind.Evm/Tracing/ITxLogsMutator.cs | 14 + .../Nethermind.Evm/Tracing/ITxTracer.cs | 19 -- .../Nethermind.Evm/VirtualMachine.cs | 21 +- .../Simulate/SimulateBlockTracer.cs | 4 +- .../SimulateReadOnlyBlocksProcessingEnv.cs | 14 +- .../Simulate/SimulateTxTracer.cs | 23 +- .../Simulate/SimulateVirtualMachine.cs | 37 +++ 10 files changed, 216 insertions(+), 248 deletions(-) create mode 100644 src/Nethermind/Nethermind.Evm/Tracing/ITxLogsMutator.cs create mode 100644 src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index ec24a910e00..4a8587a7690 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -10,8 +10,9 @@ namespace Nethermind.Evm.Tracing; -public class BlockReceiptsTracer : IBlockTracer, ITxTracer, IJournal, ITxTracerWrapper, ILogsTxTracer +public class BlockReceiptsTracer : IBlockTracer, ITxTracer, IJournal, ITxTracerWrapper { + private IBlockTracer _otherTracer = NullBlockTracer.Instance; protected Block Block = null!; public bool IsTracingReceipt => true; public bool IsTracingActions => _currentTxTracer.IsTracingActions; @@ -28,10 +29,6 @@ public class BlockReceiptsTracer : IBlockTracer, ITxTracer, IJournal, ITxTr public bool IsTracingAccess => _currentTxTracer.IsTracingAccess; public bool IsTracingFees => _currentTxTracer.IsTracingFees; public bool IsTracingLogs => _currentTxTracer.IsTracingLogs; - public bool IsTracingEvmActionLogs => (_logsTxTracer != null && _logsTxTracer!.IsTracingEvmActionLogs); - - private ILogsTxTracer? _logsTxTracer; - private IBlockTracer _otherTracer = NullBlockTracer.Instance; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Hash256? stateRoot = null) { @@ -242,8 +239,6 @@ public ITxTracer StartNewTxTrace(Transaction? tx) { CurrentTx = tx; _currentTxTracer = _otherTracer.StartNewTxTrace(tx); - _logsTxTracer = _currentTxTracer as ILogsTxTracer; - return _currentTxTracer; } @@ -277,12 +272,4 @@ public void Dispose() { _currentTxTracer.Dispose(); } - - public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, - ExecutionType callType, bool isPrecompileCall = false) - { - return _logsTxTracer is not null - ? _logsTxTracer.ReportActionAndAddResultsToState(gas, value, from, to, input, callType, isPrecompileCall) - : Enumerable.Empty(); - } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CancellationBlockTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CancellationBlockTracer.cs index 2fabb220ca2..311a2fedd26 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CancellationBlockTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CancellationBlockTracer.cs @@ -7,54 +7,46 @@ namespace Nethermind.Evm.Tracing { - public class CancellationBlockTracer : IBlockTracer + public class CancellationBlockTracer(IBlockTracer innerTracer, CancellationToken token = default) : IBlockTracer { - private readonly IBlockTracer _innerTracer; - private readonly CancellationToken _token; private bool _isTracingRewards; - public CancellationBlockTracer(IBlockTracer innerTracer, CancellationToken token = default) - { - _innerTracer = innerTracer; - _token = token; - } - public bool IsTracingRewards { - get => _isTracingRewards || _innerTracer.IsTracingRewards; + get => _isTracingRewards || innerTracer.IsTracingRewards; set => _isTracingRewards = value; } public void ReportReward(Address author, string rewardType, UInt256 rewardValue) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingRewards) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingRewards) { - _innerTracer.ReportReward(author, rewardType, rewardValue); + innerTracer.ReportReward(author, rewardType, rewardValue); } } public void StartNewBlockTrace(Block block) { - _token.ThrowIfCancellationRequested(); - _innerTracer.StartNewBlockTrace(block); + token.ThrowIfCancellationRequested(); + innerTracer.StartNewBlockTrace(block); } public ITxTracer StartNewTxTrace(Transaction? tx) { - _token.ThrowIfCancellationRequested(); - return _innerTracer.StartNewTxTrace(tx).WithCancellation(_token); + token.ThrowIfCancellationRequested(); + return innerTracer.StartNewTxTrace(tx).WithCancellation(token); } public void EndTxTrace() { - _token.ThrowIfCancellationRequested(); - _innerTracer.EndTxTrace(); + token.ThrowIfCancellationRequested(); + innerTracer.EndTxTrace(); } public void EndBlockTrace() { - _innerTracer.EndBlockTrace(); + innerTracer.EndBlockTrace(); } } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs index fa8e1eff2f1..5bfd05b9d4a 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs @@ -11,10 +11,8 @@ namespace Nethermind.Evm.Tracing; -public class CancellationTxTracer : ITxTracer, ITxTracerWrapper, ILogsTxTracer +public class CancellationTxTracer(ITxTracer innerTracer, CancellationToken token = default) : ITxTracer, ITxTracerWrapper { - private readonly ITxTracer _innerTracer; - private readonly CancellationToken _token; private readonly bool _isTracingReceipt; private readonly bool _isTracingActions; private readonly bool _isTracingOpLevelStorage; @@ -29,455 +27,432 @@ public class CancellationTxTracer : ITxTracer, ITxTracerWrapper, ILogsTxTracer private readonly bool _isTracingBlockAccess; private readonly bool _isTracingFees; private readonly bool _isTracingOpLevelLogs; - private readonly bool _isTracingEvmActionLogs; - public ITxTracer InnerTracer => _innerTracer; - private ILogsTxTracer? _logsTxTracer; - public CancellationTxTracer(ITxTracer innerTracer, CancellationToken token = default) - { - _innerTracer = innerTracer; - _logsTxTracer = InnerTracer as ILogsTxTracer; - _token = token; - } + public ITxTracer InnerTracer => innerTracer; public bool IsCancelable => true; - public bool IsCancelled => _token.IsCancellationRequested; + public bool IsCancelled => token.IsCancellationRequested; public bool IsTracingReceipt { - get => _isTracingReceipt || _innerTracer.IsTracingReceipt; + get => _isTracingReceipt || innerTracer.IsTracingReceipt; init => _isTracingReceipt = value; } public bool IsTracingActions { - get => _isTracingActions || _innerTracer.IsTracingActions; + get => _isTracingActions || innerTracer.IsTracingActions; init => _isTracingActions = value; } - public bool IsTracingEvmActionLogs - { - get => _isTracingEvmActionLogs || (_logsTxTracer != null && _logsTxTracer!.IsTracingEvmActionLogs); - init => _isTracingEvmActionLogs = value; - } - public bool IsTracingOpLevelStorage { - get => _isTracingOpLevelStorage || _innerTracer.IsTracingOpLevelStorage; + get => _isTracingOpLevelStorage || innerTracer.IsTracingOpLevelStorage; init => _isTracingOpLevelStorage = value; } public bool IsTracingMemory { - get => _isTracingMemory || _innerTracer.IsTracingMemory; + get => _isTracingMemory || innerTracer.IsTracingMemory; init => _isTracingMemory = value; } public bool IsTracingInstructions { - get => _isTracingInstructions || _innerTracer.IsTracingInstructions; + get => _isTracingInstructions || innerTracer.IsTracingInstructions; init => _isTracingInstructions = value; } public bool IsTracingRefunds { - get => _isTracingRefunds || _innerTracer.IsTracingRefunds; + get => _isTracingRefunds || innerTracer.IsTracingRefunds; init => _isTracingRefunds = value; } public bool IsTracingCode { - get => _isTracingCode || _innerTracer.IsTracingCode; + get => _isTracingCode || innerTracer.IsTracingCode; init => _isTracingCode = value; } public bool IsTracingStack { - get => _isTracingStack || _innerTracer.IsTracingStack; + get => _isTracingStack || innerTracer.IsTracingStack; init => _isTracingStack = value; } public bool IsTracingState { - get => _isTracingState || _innerTracer.IsTracingState; + get => _isTracingState || innerTracer.IsTracingState; init => _isTracingState = value; } public bool IsTracingStorage { - get => _isTracingStorage || _innerTracer.IsTracingStorage; + get => _isTracingStorage || innerTracer.IsTracingStorage; init => _isTracingStorage = value; } public bool IsTracingBlockHash { - get => _isTracingBlockHash || _innerTracer.IsTracingBlockHash; + get => _isTracingBlockHash || innerTracer.IsTracingBlockHash; init => _isTracingBlockHash = value; } public bool IsTracingAccess { - get => _isTracingBlockAccess || _innerTracer.IsTracingAccess; + get => _isTracingBlockAccess || innerTracer.IsTracingAccess; init => _isTracingBlockAccess = value; } public bool IsTracingFees { - get => _isTracingFees || _innerTracer.IsTracingFees; + get => _isTracingFees || innerTracer.IsTracingFees; init => _isTracingFees = value; } public bool IsTracingLogs { - get => _isTracingOpLevelLogs || _innerTracer.IsTracingLogs; + get => _isTracingOpLevelLogs || innerTracer.IsTracingLogs; init => _isTracingOpLevelLogs = value; } public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingState) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingState) { - _innerTracer.ReportBalanceChange(address, before, after); + innerTracer.ReportBalanceChange(address, before, after); } } public void ReportCodeChange(Address address, byte[] before, byte[] after) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingState) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingState) { - _innerTracer.ReportCodeChange(address, before, after); + innerTracer.ReportCodeChange(address, before, after); } } public void ReportNonceChange(Address address, UInt256? before, UInt256? after) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingState) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingState) { - _innerTracer.ReportNonceChange(address, before, after); + innerTracer.ReportNonceChange(address, before, after); } } public void ReportAccountRead(Address address) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingState) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingState) { - _innerTracer.ReportAccountRead(address); + innerTracer.ReportAccountRead(address); } } public void ReportStorageChange(in StorageCell storageCell, byte[] before, byte[] after) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingStorage) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingStorage) { - _innerTracer.ReportStorageChange(storageCell, before, after); + innerTracer.ReportStorageChange(storageCell, before, after); } } public void ReportStorageRead(in StorageCell storageCell) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingStorage) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingStorage) { - _innerTracer.ReportStorageRead(storageCell); + innerTracer.ReportStorageRead(storageCell); } } public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Hash256? stateRoot = null) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingReceipt) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingReceipt) { - _innerTracer.MarkAsSuccess(recipient, gasSpent, output, logs, stateRoot); + innerTracer.MarkAsSuccess(recipient, gasSpent, output, logs, stateRoot); } } public void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Hash256? stateRoot = null) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingReceipt) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingReceipt) { - _innerTracer.MarkAsFailed(recipient, gasSpent, output, error, stateRoot); + innerTracer.MarkAsFailed(recipient, gasSpent, output, error, stateRoot); } } public void StartOperation(int pc, Instruction opcode, long gas, in ExecutionEnvironment env) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.StartOperation(pc, opcode, gas, env); + innerTracer.StartOperation(pc, opcode, gas, env); } } public void ReportOperationError(EvmExceptionType error) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.ReportOperationError(error); + innerTracer.ReportOperationError(error); } } public void ReportOperationRemainingGas(long gas) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.ReportOperationRemainingGas(gas); + innerTracer.ReportOperationRemainingGas(gas); } } public void ReportLog(LogEntry log) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingLogs) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingLogs) { - _innerTracer.ReportLog(log); + innerTracer.ReportLog(log); } } public void SetOperationStack(TraceStack stack) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingStack) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingStack) { - _innerTracer.SetOperationStack(stack); + innerTracer.SetOperationStack(stack); } } public void ReportStackPush(in ReadOnlySpan stackItem) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.ReportStackPush(stackItem); + innerTracer.ReportStackPush(stackItem); } } public void ReportStackPush(in ZeroPaddedSpan stackItem) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.ReportStackPush(stackItem); + innerTracer.ReportStackPush(stackItem); } } public void ReportStackPush(byte stackItem) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.ReportStackPush(stackItem); + innerTracer.ReportStackPush(stackItem); } } public void SetOperationMemory(TraceMemory memoryTrace) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingMemory) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingMemory) { - _innerTracer.SetOperationMemory(memoryTrace); + innerTracer.SetOperationMemory(memoryTrace); } } public void SetOperationMemorySize(ulong newSize) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingMemory) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingMemory) { - _innerTracer.SetOperationMemorySize(newSize); + innerTracer.SetOperationMemorySize(newSize); } } public void ReportMemoryChange(long offset, in ReadOnlySpan data) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.ReportMemoryChange(offset, data); + innerTracer.ReportMemoryChange(offset, data); } } public void ReportMemoryChange(long offset, in ZeroPaddedSpan data) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.ReportMemoryChange(offset, data); + innerTracer.ReportMemoryChange(offset, data); } } public void ReportMemoryChange(long offset, byte data) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.ReportMemoryChange(offset, data); + innerTracer.ReportMemoryChange(offset, data); } } public void ReportStorageChange(in ReadOnlySpan key, in ReadOnlySpan value) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.ReportStorageChange(key, value); + innerTracer.ReportStorageChange(key, value); } } public void SetOperationStorage(Address address, UInt256 storageIndex, ReadOnlySpan newValue, ReadOnlySpan currentValue) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingOpLevelStorage) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingOpLevelStorage) { - _innerTracer.SetOperationStorage(address, storageIndex, newValue, currentValue); + innerTracer.SetOperationStorage(address, storageIndex, newValue, currentValue); } } public void LoadOperationStorage(Address address, UInt256 storageIndex, ReadOnlySpan value) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingOpLevelStorage) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingOpLevelStorage) { - _innerTracer.LoadOperationStorage(address, storageIndex, value); + innerTracer.LoadOperationStorage(address, storageIndex, value); } } public void ReportSelfDestruct(Address address, UInt256 balance, Address refundAddress) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingActions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingActions) { - _innerTracer.ReportSelfDestruct(address, balance, refundAddress); + innerTracer.ReportSelfDestruct(address, balance, refundAddress); } } public void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingActions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingActions) { - _innerTracer.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); + innerTracer.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); } } public void ReportActionEnd(long gas, ReadOnlyMemory output) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingActions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingActions) { - _innerTracer.ReportActionEnd(gas, output); + innerTracer.ReportActionEnd(gas, output); } } public void ReportActionError(EvmExceptionType evmExceptionType) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingActions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingActions) { - _innerTracer.ReportActionError(evmExceptionType); + innerTracer.ReportActionError(evmExceptionType); } } public void ReportActionRevert(long gasLeft, ReadOnlyMemory output) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingActions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingActions) { - _innerTracer.ReportActionRevert(gasLeft, output); + innerTracer.ReportActionRevert(gasLeft, output); } } public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingActions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingActions) { - _innerTracer.ReportActionEnd(gas, deploymentAddress, deployedCode); + innerTracer.ReportActionEnd(gas, deploymentAddress, deployedCode); } } public void ReportBlockHash(Hash256 blockHash) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingBlockHash) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingBlockHash) { - _innerTracer.ReportBlockHash(blockHash); + innerTracer.ReportBlockHash(blockHash); } } public void ReportByteCode(ReadOnlyMemory byteCode) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingCode) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingCode) { - _innerTracer.ReportByteCode(byteCode); + innerTracer.ReportByteCode(byteCode); } } public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingInstructions) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingInstructions) { - _innerTracer.ReportGasUpdateForVmTrace(refund, gasAvailable); + innerTracer.ReportGasUpdateForVmTrace(refund, gasAvailable); } } public void ReportRefund(long refund) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingRefunds) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingRefunds) { - _innerTracer.ReportRefund(refund); + innerTracer.ReportRefund(refund); } } public void ReportExtraGasPressure(long extraGasPressure) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingRefunds) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingRefunds) { - _innerTracer.ReportExtraGasPressure(extraGasPressure); + innerTracer.ReportExtraGasPressure(extraGasPressure); } } public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingAccess) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingAccess) { - _innerTracer.ReportAccess(accessedAddresses, accessedStorageCells); + innerTracer.ReportAccess(accessedAddresses, accessedStorageCells); } } public void ReportFees(UInt256 fees, UInt256 burntFees) { - _token.ThrowIfCancellationRequested(); - if (_innerTracer.IsTracingFees) + token.ThrowIfCancellationRequested(); + if (innerTracer.IsTracingFees) { - _innerTracer.ReportFees(fees, burntFees); + innerTracer.ReportFees(fees, burntFees); } } public void Dispose() { - _innerTracer.Dispose(); - } - - public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, - ExecutionType callType, bool isPrecompileCall = false) - { - return _logsTxTracer is null - ? Enumerable.Empty() - : _logsTxTracer.ReportActionAndAddResultsToState(gas, value, from, to, input, callType, - isPrecompileCall); + innerTracer.Dispose(); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxLogsMutator.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxLogsMutator.cs new file mode 100644 index 00000000000..fad85dc3b1f --- /dev/null +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxLogsMutator.cs @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using Nethermind.Core; + +namespace Nethermind.Evm.Tracing; + +public interface ITxLogsMutator +{ + bool IsMutatingLogs { get; } + + void SetLogsToMutate(ICollection logsToMutate); +} diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index 46d489a7ba0..4552b43b2d1 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -438,22 +438,3 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn /// Depends on void ReportFees(UInt256 fees, UInt256 burntFees); } - -public interface ILogsTxTracer -{ - bool IsTracingEvmActionLogs { get; } - - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Created logs to be added, only when is true - /// Depends on - IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false); -} diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 28d8c15f71d..872f6cf2a70 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -214,24 +214,11 @@ public TransactionSubstate Run(EvmState state, IWorldState worl } else { - var hereIsTracing = typeof(TTracingActions) == typeof(IsTracing); - - if (hereIsTracing && !currentState.IsContinuation) + if (typeof(TTracingActions) == typeof(IsTracing) && !currentState.IsContinuation) { - if (_txTracer is ILogsTxTracer { IsTracingEvmActionLogs: true } logsTxTracer) - { - IEnumerable logs = logsTxTracer.ReportActionAndAddResultsToState(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, - currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, - currentState.ExecutionType); - - currentState.Logs.AddRange(logs); - } - else - { - _txTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, - currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, - currentState.ExecutionType); - } + _txTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, + currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, + currentState.ExecutionType); if (_txTracer.IsTracingCode) _txTracer.ReportByteCode(currentState.Env.CodeInfo.MachineCode); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 0d746c5f119..cbbcb2f2f3a 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -13,7 +13,7 @@ namespace Nethermind.Facade.Simulate; public class SimulateBlockTracer(bool isTracingLogs) : BlockTracer { - private readonly List _txTracers = new(); + private readonly List _txTracers = new(); private Block _currentBlock = null!; public List Results { get; } = new(); @@ -30,7 +30,7 @@ public override ITxTracer StartNewTxTrace(Transaction? tx) if (tx?.Hash is not null) { ulong txIndex = (ulong)_txTracers.Count; - SimulateTxTracer result = new(isTracingLogs, tx.Hash, (ulong)_currentBlock.Number, _currentBlock.Hash, txIndex); + SimulateTxMutatorTracer result = new(isTracingLogs, tx.Hash, (ulong)_currentBlock.Number, _currentBlock.Hash, txIndex); _txTracers.Add(result); return result; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 156361f130c..63bbd2a4abd 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -49,7 +49,7 @@ public SimulateReadOnlyBlocksProcessingEnv( StateProvider = WorldStateManager.GlobalWorldState; StateReader = WorldStateManager.GlobalStateReader; CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); - VirtualMachine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); + VirtualMachine = new SimulateVirtualMachine(new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager)); _transactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, !doValidation); _blockValidator = CreateValidator(); @@ -87,9 +87,8 @@ private SimulateBlockValidatorProxy CreateValidator() return new SimulateBlockValidatorProxy(blockValidator); } - public IBlockProcessor GetProcessor(Hash256 stateRoot) - { - return new BlockProcessor(SpecProvider, + public IBlockProcessor GetProcessor(Hash256 stateRoot) => + new BlockProcessor(SpecProvider, _blockValidator, NoBlockRewards.Instance, new BlockValidationTransactionsExecutor(_transactionProcessor, StateProvider), @@ -98,10 +97,7 @@ public IBlockProcessor GetProcessor(Hash256 stateRoot) NullWitnessCollector.Instance, new BlockhashStore(BlockTree, SpecProvider, StateProvider), _logManager); - } - public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) - { - return new ReadOnlyTransactionProcessor(_transactionProcessor, StateProvider, stateRoot); - } + public IReadOnlyTransactionProcessor Build(Hash256 stateRoot) => + new ReadOnlyTransactionProcessor(_transactionProcessor, StateProvider, stateRoot); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs index 861e11bd39e..83a20d6cade 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs @@ -15,7 +15,7 @@ namespace Nethermind.Facade.Simulate; -internal sealed class SimulateTxTracer : TxTracer, ILogsTxTracer +internal sealed class SimulateTxMutatorTracer : TxTracer, ITxLogsMutator { private static readonly Hash256 transferSignature = new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256).Hash; @@ -25,8 +25,9 @@ internal sealed class SimulateTxTracer : TxTracer, ILogsTxTracer private readonly ulong _currentBlockNumber; private readonly Hash256 _txHash; private readonly ulong _txIndex; + private ICollection? _logsToMutate; - public SimulateTxTracer(bool isTracingTransfers, Hash256 txHash, ulong currentBlockNumber, Hash256 currentBlockHash, + public SimulateTxMutatorTracer(bool isTracingTransfers, Hash256 txHash, ulong currentBlockNumber, Hash256 currentBlockHash, ulong txIndex) { _txHash = txHash; @@ -34,22 +35,20 @@ public SimulateTxTracer(bool isTracingTransfers, Hash256 txHash, ulong currentBl _currentBlockHash = currentBlockHash; _txIndex = txIndex; IsTracingReceipt = true; - IsTracingEvmActionLogs = isTracingTransfers; - if (isTracingTransfers) IsTracingActions = true; + IsTracingActions = IsMutatingLogs = isTracingTransfers; } - public SimulateCallResult? TraceResult { get; set; } - public bool IsTracingEvmActionLogs { get; } + public bool IsMutatingLogs { get; } + + public void SetLogsToMutate(ICollection logsToMutate) => _logsToMutate = logsToMutate; - public IEnumerable ReportActionAndAddResultsToState(long gas, UInt256 value, Address from, Address to, - ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { - ReportAction(gas, value, from, to, input, callType, isPrecompileCall); - var data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, - new AbiSignature("", AbiType.UInt256), value); - yield return new LogEntry(Erc20Sender, data, [transferSignature, AddressToHash256(from), AddressToHash256(to)]); + base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); + var data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, new AbiSignature("", AbiType.UInt256), value); + _logsToMutate?.Add(new LogEntry(Erc20Sender, data, [transferSignature, AddressToHash256(from), AddressToHash256(to)])); } public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs new file mode 100644 index 00000000000..654d814464f --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Diagnostics.CodeAnalysis; +using Nethermind.Evm; +using Nethermind.Evm.Tracing; +using Nethermind.State; + +namespace Nethermind.Facade.Simulate; + +public class SimulateVirtualMachine(IVirtualMachine virtualMachine) : IVirtualMachine +{ + public TransactionSubstate Run(EvmState state, IWorldState worldState, ITxTracer txTracer) where TTracingActions : struct, VirtualMachine.IIsTracing + { + if (typeof(TTracingActions)== typeof(VirtualMachine.IsTracing) && TryGetLogsMutator(txTracer, out ITxLogsMutator logsMutator)) + { + logsMutator.SetLogsToMutate(state.Logs); + } + + return virtualMachine.Run(state, worldState, txTracer); + } + + private static bool TryGetLogsMutator(ITxTracer txTracer, [NotNullWhen(true)] out ITxLogsMutator? txLogsMutator) + { + switch (txTracer) + { + case ITxLogsMutator { IsMutatingLogs: true } logsMutator: + txLogsMutator = logsMutator; + return true; + case ITxTracerWrapper txTracerWrapper: + return TryGetLogsMutator(txTracerWrapper.InnerTracer, out txLogsMutator); + default: + txLogsMutator = null; + return false; + } + } +} From b9be04d7536fedc01b8cb1567030c2a4fbd6cb7b Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 12:37:13 +0200 Subject: [PATCH 176/213] Revert TxHashCalculator changes --- .../Processing/BlockProcessor.cs | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index 19ddbc1a421..d13588b765c 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -79,7 +79,7 @@ public BlockProcessor( ReceiptsTracer = new BlockReceiptsTracer(); } - public event EventHandler BlockProcessed; + public event EventHandler? BlockProcessed; public event EventHandler TransactionProcessed { @@ -92,8 +92,7 @@ public Block[] Process(Hash256 newBranchStateRoot, List suggestedBlocks, { if (suggestedBlocks.Count == 0) return Array.Empty(); - using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); - TxHashCalculator.CalculateInBackground(suggestedBlocks, cancellationTokenSource.Token); + TxHashCalculator.CalculateInBackground(suggestedBlocks); BlocksProcessing?.Invoke(this, new BlocksProcessingEventArgs(suggestedBlocks)); @@ -155,10 +154,6 @@ the previous head state.*/ RestoreBranch(previousBranchStateRoot); throw; } - finally - { - cancellationTokenSource.Cancel(); - } } public event EventHandler? BlocksProcessing; @@ -387,21 +382,17 @@ private void ApplyDaoTransition(Block block) } } - private class TxHashCalculator(IReadOnlyList suggestedBlocks, CancellationToken cancellationToken) : IThreadPoolWorkItem + private class TxHashCalculator(List suggestedBlocks) : IThreadPoolWorkItem { - public static void CalculateInBackground(IReadOnlyList suggestedBlocks, CancellationToken cancellationToken) + public static void CalculateInBackground(List suggestedBlocks) { // Memory has been reserved on the transactions to delay calculate the hashes // We calculate the hashes in the background to release that memory - ThreadPool.UnsafeQueueUserWorkItem(new TxHashCalculator(suggestedBlocks, cancellationToken), preferLocal: false); + ThreadPool.UnsafeQueueUserWorkItem(new TxHashCalculator(suggestedBlocks), preferLocal: false); } void IThreadPoolWorkItem.Execute() { - if (cancellationToken.IsCancellationRequested) - { - return; - } // Hashes will be required for PersistentReceiptStorage in UpdateMainChain ForkchoiceUpdatedHandler // Which occurs after the block has been processed; however the block is stored in cache and picked up // from there so we can calculate the hashes now for that later use. @@ -409,10 +400,6 @@ void IThreadPoolWorkItem.Execute() { foreach (Transaction tx in block.Transactions) { - if (cancellationToken.IsCancellationRequested) - { - return; - } // Calculate the hashes to release the memory from the transactionSequence tx.CalculateHashInternal(); } From 57805bdca601ae213aff4ee7817a418594c2a495 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 13:08:04 +0200 Subject: [PATCH 177/213] Move ErrorCodes, Add AddressToHash256 --- .../CliqueRpcModule.cs | 1 + .../Processing/BlockProcessor.cs | 3 +-- src/Nethermind/Nethermind.Core/Address.cs | 12 +++++++++-- .../Nethermind.Core/Crypto/Hash256.cs | 2 +- .../Nethermind.Evm/ByteCodeBuilder.cs | 1 - .../Nethermind.Evm/VirtualMachine.cs | 9 ++++++-- .../BlockchainBridgeExtensions.cs | 6 ++---- .../ErrorCodes.cs} | 4 ++-- .../OverridableCodeInfoRepository.cs | 21 ++++++++----------- .../Simulate/SimulateBlockhashProvider.cs | 2 +- .../Simulate/SimulateBridgeHelper.cs | 11 +++++----- ...TxTracer.cs => SimulateTxMutatorTracer.cs} | 12 +++-------- .../JsonRpcServiceTests.cs | 1 + .../Modules/DebugModuleTests.cs | 1 + .../Modules/FeeHistoryOracleTests.cs | 1 + .../Modules/Proof/ProofRpcModuleTests.cs | 1 + .../Nethermind.JsonRpc/JsonRpcProcessor.cs | 1 + .../Nethermind.JsonRpc/JsonRpcService.cs | 1 + .../Modules/BlockFinderExtensions.cs | 1 + .../Modules/DebugModule/DebugRpcModule.cs | 1 + .../Modules/Eth/EthRpcModule.cs | 9 ++------ .../Eth/FeeHistory/FeeHistoryOracle.cs | 1 + .../Modules/Proof/ProofRpcModule.cs | 1 + .../Modules/ReceiptFinderExtensions.cs | 1 + .../Modules/Subscribe/SubscribeRpcModule.cs | 1 + .../Modules/Witness/WitnessRpcModule.cs | 1 + .../Nethermind.JsonRpc/ResultWrapper.cs | 1 + .../EngineModuleTests.V2.cs | 1 + .../EngineModuleTests.V3.cs | 1 + .../EngineRpcModule.Paris.cs | 1 + .../Handlers/ForkchoiceUpdatedHandler.cs | 1 + .../GetPayloadBodiesByRangeV1Handler.cs | 1 + src/Nethermind/Nethermind.Mev/MevRpcModule.cs | 1 + .../JsonRpc/JsonRpcClient.cs | 1 + .../Nethermind.Runner/JsonRpc/Startup.cs | 1 + 35 files changed, 67 insertions(+), 48 deletions(-) rename src/Nethermind/{Nethermind.JsonRpc/ErrorType.cs => Nethermind.Facade/ErrorCodes.cs} (98%) rename src/Nethermind/Nethermind.Facade/Simulate/{SimulateTxTracer.cs => SimulateTxMutatorTracer.cs} (90%) diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs index 82581295402..8fa0257ed1b 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs @@ -7,6 +7,7 @@ using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Facade; using Nethermind.JsonRpc; namespace Nethermind.Consensus.Clique diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index d13588b765c..216c8b55f20 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -93,7 +93,6 @@ public Block[] Process(Hash256 newBranchStateRoot, List suggestedBlocks, if (suggestedBlocks.Count == 0) return Array.Empty(); TxHashCalculator.CalculateInBackground(suggestedBlocks); - BlocksProcessing?.Invoke(this, new BlocksProcessingEventArgs(suggestedBlocks)); /* We need to save the snapshot state root before reorganization in case the new branch has invalid blocks. @@ -396,7 +395,7 @@ void IThreadPoolWorkItem.Execute() // Hashes will be required for PersistentReceiptStorage in UpdateMainChain ForkchoiceUpdatedHandler // Which occurs after the block has been processed; however the block is stored in cache and picked up // from there so we can calculate the hashes now for that later use. - foreach (Block block in suggestedBlocks) + foreach (Block block in CollectionsMarshal.AsSpan(suggestedBlocks)) { foreach (Transaction tx in block.Transactions) { diff --git a/src/Nethermind/Nethermind.Core/Address.cs b/src/Nethermind/Nethermind.Core/Address.cs index d56cda23269..79acbe7d5ff 100644 --- a/src/Nethermind/Nethermind.Core/Address.cs +++ b/src/Nethermind/Nethermind.Core/Address.cs @@ -35,9 +35,9 @@ public class Address : IEquatable
, IComparable
public byte[] Bytes { get; } - public Address(Hash256 keccak) : this(keccak.Bytes.Slice(12, Size).ToArray()) { } + public Address(Hash256 hash) : this(hash.Bytes.Slice(12, Size).ToArray()) { } - public Address(in ValueHash256 keccak) : this(keccak.BytesAsSpan.Slice(12, Size).ToArray()) { } + public Address(in ValueHash256 hash) : this(hash.BytesAsSpan.Slice(12, Size).ToArray()) { } public byte this[int index] => Bytes[index]; @@ -235,6 +235,14 @@ public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destina } public Hash256 ToAccountPath => Keccak.Compute(Bytes); + + [SkipLocalsInit] + public ValueHash256 ToHash() + { + Span addressBytes = stackalloc byte[Hash256.Size]; + Bytes.CopyTo(addressBytes.Slice(Hash256.Size - Address.Size)); + return new ValueHash256(addressBytes); + } } public readonly struct AddressAsKey(Address key) : IEquatable diff --git a/src/Nethermind/Nethermind.Core/Crypto/Hash256.cs b/src/Nethermind/Nethermind.Core/Crypto/Hash256.cs index b2002f8936f..6b123e45158 100644 --- a/src/Nethermind/Nethermind.Core/Crypto/Hash256.cs +++ b/src/Nethermind/Nethermind.Core/Crypto/Hash256.cs @@ -117,12 +117,12 @@ public Hash256 ToCommitment() } public static bool operator ==(in ValueHash256 left, in ValueHash256 right) => left.Equals(in right); - public static bool operator !=(in ValueHash256 left, in ValueHash256 right) => !(left == right); public static bool operator >(in ValueHash256 left, in ValueHash256 right) => left.CompareTo(in right) > 0; public static bool operator <(in ValueHash256 left, in ValueHash256 right) => left.CompareTo(in right) < 0; public static bool operator >=(in ValueHash256 left, in ValueHash256 right) => left.CompareTo(in right) >= 0; public static bool operator <=(in ValueHash256 left, in ValueHash256 right) => left.CompareTo(in right) <= 0; + public static implicit operator Hash256(in ValueHash256 keccak) => new(keccak); } public readonly struct Hash256AsKey(Hash256 key) : IEquatable diff --git a/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs b/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs index b05d9b77825..a44ab9dae90 100644 --- a/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs +++ b/src/Nethermind/Nethermind.Evm/ByteCodeBuilder.cs @@ -281,7 +281,6 @@ public Prepare PushData(ReadOnlyMemory data) return this; } - public Prepare PushData(byte data) { PushData(new[] { data }); diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index a50caac96f9..7ea1d0ace7b 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -217,8 +217,13 @@ public TransactionSubstate Run(EvmState state, IWorldState worl { if (typeof(TTracingActions) == typeof(IsTracing) && !currentState.IsContinuation) { - _txTracer.ReportAction(currentState.GasAvailable, currentState.Env.Value, currentState.From, currentState.To, - currentState.ExecutionType.IsAnyCreate() ? currentState.Env.CodeInfo.MachineCode : currentState.Env.InputData, + _txTracer.ReportAction(currentState.GasAvailable, + currentState.Env.Value, + currentState.From, + currentState.To, + currentState.ExecutionType.IsAnyCreate() + ? currentState.Env.CodeInfo.MachineCode + : currentState.Env.InputData, currentState.ExecutionType); if (_txTracer.IsTracingCode) _txTracer.ReportByteCode(currentState.Env.CodeInfo.MachineCode); diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs index bd523ef8517..a5af9f8b625 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridgeExtensions.cs @@ -7,8 +7,6 @@ namespace Nethermind.Facade; public static class BlockchainBridgeExtensions { - public static bool HasStateForBlock(this IBlockchainBridge blockchainBridge, BlockHeader header) - { - return blockchainBridge.HasStateForRoot(header.StateRoot!); - } + public static bool HasStateForBlock(this IBlockchainBridge blockchainBridge, BlockHeader header) => + blockchainBridge.HasStateForRoot(header.StateRoot!); } diff --git a/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs b/src/Nethermind/Nethermind.Facade/ErrorCodes.cs similarity index 98% rename from src/Nethermind/Nethermind.JsonRpc/ErrorType.cs rename to src/Nethermind/Nethermind.Facade/ErrorCodes.cs index 6b2d8f2e47a..a58696a5a2c 100644 --- a/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs +++ b/src/Nethermind/Nethermind.Facade/ErrorCodes.cs @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -namespace Nethermind.JsonRpc +namespace Nethermind.Facade { public static class ErrorCodes { @@ -68,7 +68,7 @@ public static class ErrorCodes public const int LimitExceeded = -32005; /// - /// + /// /// public const int ExecutionError = -32015; diff --git a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs index 6163641fe05..dbe43ddddc7 100644 --- a/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Facade/OverridableCodeInfoRepository.cs @@ -16,22 +16,16 @@ public class OverridableCodeInfoRepository(ICodeInfoRepository codeInfoRepositor { private readonly Dictionary _codeOverwrites = new(); - public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) - { - return _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) + public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec vmSpec) => + _codeOverwrites.TryGetValue(codeSource, out CodeInfo result) ? result : codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, vmSpec); - } - public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) - { - return codeInfoRepository.GetOrAdd(codeHash, initCode); - } + public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) => codeInfoRepository.GetOrAdd(codeHash, initCode); - public void InsertCode(IWorldState state, ReadOnlyMemory code, Address codeOwner, IReleaseSpec spec) - { + public void InsertCode(IWorldState state, ReadOnlyMemory code, Address codeOwner, IReleaseSpec spec) => codeInfoRepository.InsertCode(state, code, codeOwner, spec); - } + public void SetCodeOverwrite( IWorldState worldState, @@ -40,7 +34,10 @@ public void SetCodeOverwrite( CodeInfo value, Address? redirectAddress = null) { - if (redirectAddress is not null) _codeOverwrites[redirectAddress] = GetCachedCodeInfo(worldState, key, vmSpec); + if (redirectAddress is not null) + { + _codeOverwrites[redirectAddress] = GetCachedCodeInfo(worldState, key, vmSpec); + } _codeOverwrites[key] = value; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs index 0af6761cb53..8f054a809ca 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockhashProvider.cs @@ -13,7 +13,7 @@ public sealed class SimulateBlockhashProvider(IBlockhashProvider blockhashProvid { public Hash256? GetBlockhash(BlockHeader currentBlock, in long number) { - var bestKnown = blockTree.BestKnownNumber; + long bestKnown = blockTree.BestKnownNumber; return bestKnown < number && blockTree.BestSuggestedHeader is not null ? blockhashProvider.GetBlockhash(blockTree.BestSuggestedHeader!, in bestKnown) : blockhashProvider.GetBlockhash(currentBlock, in number); diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 4acc81d19a6..c4ddda58631 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -26,10 +26,11 @@ public class SimulateBridgeHelper( ISpecProvider specProvider, IBlocksConfig blocksConfig) { - private static readonly ProcessingOptions _simulateProcessingOptions = ProcessingOptions.ForceProcessing | - ProcessingOptions.IgnoreParentNotOnMainChain | - ProcessingOptions.MarkAsProcessed | - ProcessingOptions.StoreReceipts; + private const ProcessingOptions SimulateProcessingOptions = + ProcessingOptions.ForceProcessing + | ProcessingOptions.IgnoreParentNotOnMainChain + | ProcessingOptions.MarkAsProcessed + | ProcessingOptions.StoreReceipts; private void UpdateStateByModifyingAccounts( BlockHeader blockHeader, @@ -162,7 +163,7 @@ private void UpdateStateByModifyingAccounts( currentBlock.WithReplacedBody(currentBlock.Body.WithChangedTransactions(testedTxs.ToArray())); - ProcessingOptions processingFlags = _simulateProcessingOptions; + ProcessingOptions processingFlags = SimulateProcessingOptions; if (!payload.Validation) { diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs similarity index 90% rename from src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs rename to src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs index 83a20d6cade..5c0c0547c01 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs @@ -7,6 +7,7 @@ using Nethermind.Abi; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.Simulate; @@ -48,7 +49,7 @@ public override void ReportAction(long gas, UInt256 value, Address from, Address { base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); var data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, new AbiSignature("", AbiType.UInt256), value); - _logsToMutate?.Add(new LogEntry(Erc20Sender, data, [transferSignature, AddressToHash256(from), AddressToHash256(to)])); + _logsToMutate?.Add(new LogEntry(Erc20Sender, data, [transferSignature, from.ToHash(), to.ToHash()])); } public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, @@ -81,18 +82,11 @@ public override void MarkAsFailed(Address recipient, long gasSpent, byte[] outpu GasUsed = (ulong)gasSpent, Error = new Error { - Code = -32015, // revert error code stub + Code = ErrorCodes.ExecutionError, // revert error code stub Message = error }, ReturnData = null, Status = StatusCode.Failure }; } - - private Hash256 AddressToHash256(Address input) - { - var addressBytes = new byte[32]; - Array.Copy(input.Bytes, 0, addressBytes, 32 - Address.Size, Address.Size); - return new Hash256(addressBytes); - } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 88a3746af1b..85619b26b80 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -16,6 +16,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; +using Nethermind.Facade; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; using Nethermind.JsonRpc.Data; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs index 064fff4e886..838b6d8bf8e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs @@ -19,6 +19,7 @@ using Nethermind.Db; using Nethermind.Evm.Tracing.GethStyle; using Nethermind.Evm.Tracing.GethStyle.Custom; +using Nethermind.Facade; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.DebugModule; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs index 230ea5a6dbd..730eb17222d 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs @@ -10,6 +10,7 @@ using Nethermind.Core.Collections; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; +using Nethermind.Facade; using Nethermind.Int256; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.JsonRpc.Modules.Eth.FeeHistory; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs index 31a16936028..b773cb16636 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs @@ -29,6 +29,7 @@ using FluentAssertions; using Nethermind.Consensus.Processing; using Nethermind.Core.Buffers; +using Nethermind.Facade; using Nethermind.State.Tracing; using NSubstitute; diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs index 99f81d57751..5046fef8d8b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs @@ -17,6 +17,7 @@ using Nethermind.Core.Collections; using Nethermind.Core.Extensions; using Nethermind.Core.Resettables; +using Nethermind.Facade; using Nethermind.Logging; using Nethermind.Serialization.Json; diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs index d66c226b494..e0dac052d03 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs @@ -11,6 +11,7 @@ using System.Threading.Tasks; using Nethermind.Core; +using Nethermind.Facade; using Nethermind.JsonRpc.Exceptions; using Nethermind.JsonRpc.Modules; using Nethermind.Logging; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs index 277c77dc501..8251d8ce5b1 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs @@ -6,6 +6,7 @@ using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Facade; namespace Nethermind.JsonRpc.Modules { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs index 2c8813c7dbd..c6de68af67b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs @@ -18,6 +18,7 @@ using System.Collections.Generic; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Core.Specs; +using Nethermind.Facade; namespace Nethermind.JsonRpc.Modules.DebugModule; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 0c0719fd9bf..9b49572026e 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -57,11 +57,6 @@ public partial class EthRpcModule : IEthRpcModule private readonly IFeeHistoryOracle _feeHistoryOracle; - private static bool HasStateForBlock(IBlockchainBridge blockchainBridge, BlockHeader header) - { - return blockchainBridge.HasStateForRoot(header.StateRoot!); - } - public EthRpcModule( IJsonRpcConfig rpcConfig, IBlockchainBridge blockchainBridge, @@ -265,7 +260,7 @@ public ResultWrapper eth_getCode(Address address, BlockParameter? blockP } BlockHeader header = searchResult.Object; - return !HasStateForBlock(_blockchainBridge, header!) + return !_blockchainBridge.HasStateForBlock(header!) ? GetStateFailureResult(header) : ResultWrapper.Success( _stateReader.TryGetAccount(header!.StateRoot!, address, out AccountStruct account) @@ -721,7 +716,7 @@ private static IEnumerable GetLogs(IEnumerable logs, Cance } BlockHeader header = searchResult.Object; - return !HasStateForBlock(_blockchainBridge, header!) + return !_blockchainBridge.HasStateForBlock(header!) ? GetStateFailureResult(header) : ResultWrapper.Success( _stateReader.TryGetAccount(header!.StateRoot!, accountAddress, out AccountStruct account) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs index f1ee8593978..463e0936921 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs @@ -15,6 +15,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Evm; +using Nethermind.Facade; using Nethermind.Int256; using NonBlocking; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs index d4885d1c608..cfd72d41187 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs @@ -14,6 +14,7 @@ using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Evm.Tracing.Proofs; +using Nethermind.Facade; using Nethermind.JsonRpc.Data; using Nethermind.Logging; using Nethermind.Serialization.Rlp; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs index 7ebf603cfcc..18591fe63a4 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs @@ -10,6 +10,7 @@ using Nethermind.Core.Specs; using Nethermind.JsonRpc.Data; using Nethermind.Evm; +using Nethermind.Facade; namespace Nethermind.JsonRpc.Modules { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SubscribeRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SubscribeRpcModule.cs index eea2daff894..2ecdaae5fd7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SubscribeRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SubscribeRpcModule.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; +using Nethermind.Facade; namespace Nethermind.JsonRpc.Modules.Subscribe { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Witness/WitnessRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Witness/WitnessRpcModule.cs index 9438b40f0ec..afdd7a4c92f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Witness/WitnessRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Witness/WitnessRpcModule.cs @@ -5,6 +5,7 @@ using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Facade; using Nethermind.State; namespace Nethermind.JsonRpc.Modules.Witness diff --git a/src/Nethermind/Nethermind.JsonRpc/ResultWrapper.cs b/src/Nethermind/Nethermind.JsonRpc/ResultWrapper.cs index 80d69d2ae4d..0dc9ffa9251 100644 --- a/src/Nethermind/Nethermind.JsonRpc/ResultWrapper.cs +++ b/src/Nethermind/Nethermind.JsonRpc/ResultWrapper.cs @@ -4,6 +4,7 @@ using System; using System.Threading.Tasks; using Nethermind.Core; +using Nethermind.Facade; using Nethermind.Facade.Proxy; using Nethermind.JsonRpc.Modules; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs index 1e8855b494e..273febc09b3 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs @@ -15,6 +15,7 @@ using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; +using Nethermind.Facade; using Nethermind.Int256; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Test; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs index cabce29d34b..46626056fc1 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs @@ -17,6 +17,7 @@ using Nethermind.Core.Test.Builders; using Nethermind.Crypto; using Nethermind.Evm; +using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Test; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs index f5c0616b826..6670e05c128 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs @@ -8,6 +8,7 @@ using Nethermind.Consensus; using Nethermind.Consensus.Producers; using Nethermind.Core.Specs; +using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.Merge.Plugin.Data; using Nethermind.Merge.Plugin.GC; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs index 3360272a11c..073a0ef78fd 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs @@ -16,6 +16,7 @@ using Nethermind.Core.Specs; using Nethermind.Core.Threading; using Nethermind.Crypto; +using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.Logging; using Nethermind.Merge.Plugin.BlockProduction; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs index 0ca3a7e5af7..33b6efb2767 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Nethermind.Blockchain; +using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.Logging; using Nethermind.Merge.Plugin.Data; diff --git a/src/Nethermind/Nethermind.Mev/MevRpcModule.cs b/src/Nethermind/Nethermind.Mev/MevRpcModule.cs index 4ce4b656215..e972c508501 100644 --- a/src/Nethermind/Nethermind.Mev/MevRpcModule.cs +++ b/src/Nethermind/Nethermind.Mev/MevRpcModule.cs @@ -10,6 +10,7 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; +using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; using Nethermind.Mev.Data; diff --git a/src/Nethermind/Nethermind.Overseer.Test/JsonRpc/JsonRpcClient.cs b/src/Nethermind/Nethermind.Overseer.Test/JsonRpc/JsonRpcClient.cs index 2611cf8bbb0..39778bb14e5 100644 --- a/src/Nethermind/Nethermind.Overseer.Test/JsonRpc/JsonRpcClient.cs +++ b/src/Nethermind/Nethermind.Overseer.Test/JsonRpc/JsonRpcClient.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading.Tasks; using DotNetty.Common.Utilities; +using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.Serialization.Json; diff --git a/src/Nethermind/Nethermind.Runner/JsonRpc/Startup.cs b/src/Nethermind/Nethermind.Runner/JsonRpc/Startup.cs index 6625abe7e9a..f60db66fa0e 100644 --- a/src/Nethermind/Nethermind.Runner/JsonRpc/Startup.cs +++ b/src/Nethermind/Nethermind.Runner/JsonRpc/Startup.cs @@ -28,6 +28,7 @@ using Nethermind.Core.Authentication; using Nethermind.Core.Extensions; using Nethermind.Core.Resettables; +using Nethermind.Facade; using Nethermind.HealthChecks; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; From d542546ee336d12911c91a4a39bd8b4fd5ef3e71 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 13:13:22 +0200 Subject: [PATCH 178/213] Revert "Move ErrorCodes," This reverts commit 57805bdca601ae213aff4ee7817a418594c2a495. --- src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs | 1 - src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs | 1 - .../Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs | 1 - .../Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs | 1 - .../Modules/Proof/ProofRpcModuleTests.cs | 1 - .../ErrorCodes.cs => Nethermind.JsonRpc/ErrorType.cs} | 4 ++-- src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs | 1 - src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs | 1 - .../Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs | 1 - .../Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs | 1 - .../Modules/Eth/FeeHistory/FeeHistoryOracle.cs | 1 - .../Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs | 1 - .../Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs | 1 - .../Modules/Subscribe/SubscribeRpcModule.cs | 1 - .../Nethermind.JsonRpc/Modules/Witness/WitnessRpcModule.cs | 1 - src/Nethermind/Nethermind.JsonRpc/ResultWrapper.cs | 1 - .../Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs | 1 - .../Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs | 1 - .../Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs | 1 - .../Handlers/ForkchoiceUpdatedHandler.cs | 1 - .../Handlers/GetPayloadBodiesByRangeV1Handler.cs | 1 - src/Nethermind/Nethermind.Mev/MevRpcModule.cs | 1 - .../Nethermind.Overseer.Test/JsonRpc/JsonRpcClient.cs | 1 - src/Nethermind/Nethermind.Runner/JsonRpc/Startup.cs | 1 - 24 files changed, 2 insertions(+), 25 deletions(-) rename src/Nethermind/{Nethermind.Facade/ErrorCodes.cs => Nethermind.JsonRpc/ErrorType.cs} (98%) diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs index 8fa0257ed1b..82581295402 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliqueRpcModule.cs @@ -7,7 +7,6 @@ using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Facade; using Nethermind.JsonRpc; namespace Nethermind.Consensus.Clique diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 85619b26b80..88a3746af1b 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -16,7 +16,6 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; -using Nethermind.Facade; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; using Nethermind.JsonRpc.Data; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs index 838b6d8bf8e..064fff4e886 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs @@ -19,7 +19,6 @@ using Nethermind.Db; using Nethermind.Evm.Tracing.GethStyle; using Nethermind.Evm.Tracing.GethStyle.Custom; -using Nethermind.Facade; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.DebugModule; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs index 730eb17222d..230ea5a6dbd 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/FeeHistoryOracleTests.cs @@ -10,7 +10,6 @@ using Nethermind.Core.Collections; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; -using Nethermind.Facade; using Nethermind.Int256; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.JsonRpc.Modules.Eth.FeeHistory; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs index b773cb16636..31a16936028 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs @@ -29,7 +29,6 @@ using FluentAssertions; using Nethermind.Consensus.Processing; using Nethermind.Core.Buffers; -using Nethermind.Facade; using Nethermind.State.Tracing; using NSubstitute; diff --git a/src/Nethermind/Nethermind.Facade/ErrorCodes.cs b/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs similarity index 98% rename from src/Nethermind/Nethermind.Facade/ErrorCodes.cs rename to src/Nethermind/Nethermind.JsonRpc/ErrorType.cs index a58696a5a2c..6b2d8f2e47a 100644 --- a/src/Nethermind/Nethermind.Facade/ErrorCodes.cs +++ b/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -namespace Nethermind.Facade +namespace Nethermind.JsonRpc { public static class ErrorCodes { @@ -68,7 +68,7 @@ public static class ErrorCodes public const int LimitExceeded = -32005; /// - /// + /// /// public const int ExecutionError = -32015; diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs index 5046fef8d8b..99f81d57751 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcProcessor.cs @@ -17,7 +17,6 @@ using Nethermind.Core.Collections; using Nethermind.Core.Extensions; using Nethermind.Core.Resettables; -using Nethermind.Facade; using Nethermind.Logging; using Nethermind.Serialization.Json; diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs index e0dac052d03..d66c226b494 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs @@ -11,7 +11,6 @@ using System.Threading.Tasks; using Nethermind.Core; -using Nethermind.Facade; using Nethermind.JsonRpc.Exceptions; using Nethermind.JsonRpc.Modules; using Nethermind.Logging; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs index 8251d8ce5b1..277c77dc501 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs @@ -6,7 +6,6 @@ using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Facade; namespace Nethermind.JsonRpc.Modules { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs index c6de68af67b..2c8813c7dbd 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs @@ -18,7 +18,6 @@ using System.Collections.Generic; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Core.Specs; -using Nethermind.Facade; namespace Nethermind.JsonRpc.Modules.DebugModule; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs index 463e0936921..f1ee8593978 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/FeeHistory/FeeHistoryOracle.cs @@ -15,7 +15,6 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Evm; -using Nethermind.Facade; using Nethermind.Int256; using NonBlocking; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs index cfd72d41187..d4885d1c608 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs @@ -14,7 +14,6 @@ using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Evm.Tracing.Proofs; -using Nethermind.Facade; using Nethermind.JsonRpc.Data; using Nethermind.Logging; using Nethermind.Serialization.Rlp; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs index 18591fe63a4..7ebf603cfcc 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/ReceiptFinderExtensions.cs @@ -10,7 +10,6 @@ using Nethermind.Core.Specs; using Nethermind.JsonRpc.Data; using Nethermind.Evm; -using Nethermind.Facade; namespace Nethermind.JsonRpc.Modules { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SubscribeRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SubscribeRpcModule.cs index 2ecdaae5fd7..eea2daff894 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SubscribeRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/SubscribeRpcModule.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; -using Nethermind.Facade; namespace Nethermind.JsonRpc.Modules.Subscribe { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Witness/WitnessRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Witness/WitnessRpcModule.cs index afdd7a4c92f..9438b40f0ec 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Witness/WitnessRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Witness/WitnessRpcModule.cs @@ -5,7 +5,6 @@ using Nethermind.Blockchain.Find; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Facade; using Nethermind.State; namespace Nethermind.JsonRpc.Modules.Witness diff --git a/src/Nethermind/Nethermind.JsonRpc/ResultWrapper.cs b/src/Nethermind/Nethermind.JsonRpc/ResultWrapper.cs index 0dc9ffa9251..80d69d2ae4d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/ResultWrapper.cs +++ b/src/Nethermind/Nethermind.JsonRpc/ResultWrapper.cs @@ -4,7 +4,6 @@ using System; using System.Threading.Tasks; using Nethermind.Core; -using Nethermind.Facade; using Nethermind.Facade.Proxy; using Nethermind.JsonRpc.Modules; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs index 273febc09b3..1e8855b494e 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs @@ -15,7 +15,6 @@ using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; -using Nethermind.Facade; using Nethermind.Int256; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Test; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs index 46626056fc1..cabce29d34b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V3.cs @@ -17,7 +17,6 @@ using Nethermind.Core.Test.Builders; using Nethermind.Crypto; using Nethermind.Evm; -using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Test; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs index 6670e05c128..f5c0616b826 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs @@ -8,7 +8,6 @@ using Nethermind.Consensus; using Nethermind.Consensus.Producers; using Nethermind.Core.Specs; -using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.Merge.Plugin.Data; using Nethermind.Merge.Plugin.GC; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs index 073a0ef78fd..3360272a11c 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs @@ -16,7 +16,6 @@ using Nethermind.Core.Specs; using Nethermind.Core.Threading; using Nethermind.Crypto; -using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.Logging; using Nethermind.Merge.Plugin.BlockProduction; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs index 33b6efb2767..0ca3a7e5af7 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/GetPayloadBodiesByRangeV1Handler.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Threading.Tasks; using Nethermind.Blockchain; -using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.Logging; using Nethermind.Merge.Plugin.Data; diff --git a/src/Nethermind/Nethermind.Mev/MevRpcModule.cs b/src/Nethermind/Nethermind.Mev/MevRpcModule.cs index e972c508501..4ce4b656215 100644 --- a/src/Nethermind/Nethermind.Mev/MevRpcModule.cs +++ b/src/Nethermind/Nethermind.Mev/MevRpcModule.cs @@ -10,7 +10,6 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; -using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; using Nethermind.Mev.Data; diff --git a/src/Nethermind/Nethermind.Overseer.Test/JsonRpc/JsonRpcClient.cs b/src/Nethermind/Nethermind.Overseer.Test/JsonRpc/JsonRpcClient.cs index 39778bb14e5..2611cf8bbb0 100644 --- a/src/Nethermind/Nethermind.Overseer.Test/JsonRpc/JsonRpcClient.cs +++ b/src/Nethermind/Nethermind.Overseer.Test/JsonRpc/JsonRpcClient.cs @@ -6,7 +6,6 @@ using System.Text; using System.Threading.Tasks; using DotNetty.Common.Utilities; -using Nethermind.Facade; using Nethermind.JsonRpc; using Nethermind.Serialization.Json; diff --git a/src/Nethermind/Nethermind.Runner/JsonRpc/Startup.cs b/src/Nethermind/Nethermind.Runner/JsonRpc/Startup.cs index f60db66fa0e..6625abe7e9a 100644 --- a/src/Nethermind/Nethermind.Runner/JsonRpc/Startup.cs +++ b/src/Nethermind/Nethermind.Runner/JsonRpc/Startup.cs @@ -28,7 +28,6 @@ using Nethermind.Core.Authentication; using Nethermind.Core.Extensions; using Nethermind.Core.Resettables; -using Nethermind.Facade; using Nethermind.HealthChecks; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; From e443f840e11ae4961600e589852e16db0d690d34 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 13:15:20 +0200 Subject: [PATCH 179/213] more refactors --- .../Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs | 5 +++-- .../Nethermind.Serialization.Json/EthereumJsonSerializer.cs | 2 +- src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs index 5c0c0547c01..ce234cc3eed 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs @@ -7,7 +7,6 @@ using Nethermind.Abi; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Core.Extensions; using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.Simulate; @@ -18,6 +17,8 @@ namespace Nethermind.Facade.Simulate; internal sealed class SimulateTxMutatorTracer : TxTracer, ITxLogsMutator { + public const int ExecutionError = -32015; + private static readonly Hash256 transferSignature = new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256).Hash; @@ -82,7 +83,7 @@ public override void MarkAsFailed(Address recipient, long gasSpent, byte[] outpu GasUsed = (ulong)gasSpent, Error = new Error { - Code = ErrorCodes.ExecutionError, // revert error code stub + Code = ExecutionError, // revert error code stub Message = error }, ReturnData = null, diff --git a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs index df3ae54609c..0cbf7c2dd1d 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/EthereumJsonSerializer.cs @@ -54,7 +54,7 @@ public string Serialize(T value, bool indented = false) return JsonSerializer.Serialize(value, indented ? JsonOptionsIndented : _jsonOptions); } - public static JsonSerializerOptions CreateOptions(bool indented, IEnumerable converters = null, int maxDepth = 64) + private static JsonSerializerOptions CreateOptions(bool indented, IEnumerable converters = null, int maxDepth = 64) { var options = new JsonSerializerOptions { diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs index 699d3305f34..586da611f5c 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs @@ -1275,7 +1275,7 @@ void PersistNode(TrieNode n, Hash256? address, TreePath path) } // Used to serve node by hash - public byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) + private byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) { Hash256 asHash = new Hash256(key); return _pruningStrategy.PruningEnabled From fe8783229d1bd6d7a8adce62d5132f9a8eac2440 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 14:43:23 +0200 Subject: [PATCH 180/213] Big SimulateBridgeHelper refactor --- .../Collections/LinkedHashSet.cs | 3 +- .../Nethermind.Facade/BlockchainBridge.cs | 4 +- .../Simulate/SimulateBridgeHelper.cs | 300 +++++++++--------- .../{ErrorType.cs => ErrorCodes.cs} | 0 .../Nethermind.State/StateProvider.cs | 6 +- 5 files changed, 160 insertions(+), 153 deletions(-) rename src/Nethermind/Nethermind.JsonRpc/{ErrorType.cs => ErrorCodes.cs} (100%) diff --git a/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs b/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs index 7ebcb0ad518..864c61a1ec4 100644 --- a/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs +++ b/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs @@ -195,8 +195,7 @@ public void UnionWith(IEnumerable? other) } #endregion - - + #region ICollection public int Count => _dict.Count; diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index a3f089c2bf3..fa46f8d471f 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -77,7 +77,6 @@ public BlockchainBridge(ReadOnlyTxProcessingEnv processingEnv, IsMining = isMining; _simulateBridgeHelper = new SimulateBridgeHelper( simulateProcessingEnvFactory ?? throw new ArgumentNullException(nameof(simulateProcessingEnvFactory)), - _specProvider, _blocksConfig); } @@ -157,8 +156,7 @@ public SimulateOutput Simulate(BlockHeader header, SimulatePayload blockStateCall, - SimulateReadOnlyBlocksProcessingEnv env) + IWorldState stateProvider, + OverridableCodeInfoRepository codeInfoRepository, + IReleaseSpec releaseSpec) { - IReleaseSpec currentSpec = env.SpecProvider.GetSpec(blockHeader); - env.StateProvider.ApplyStateOverrides(env.CodeInfoRepository, blockStateCall.StateOverrides, currentSpec, - blockHeader.Number); - - IEnumerable senders = blockStateCall.Calls?.Select(details => details.Transaction.SenderAddress) ?? Enumerable.Empty(); - IEnumerable targets = blockStateCall.Calls?.Select(details => details.Transaction.To!) ?? Enumerable.Empty(); - var all = senders.Union(targets) - .Where(address => address is not null && !env.StateProvider.AccountExists(address)) - .Distinct() - .ToList(); - - foreach (Address address in all) + stateProvider.StateRoot = parent.StateRoot!; + stateProvider.ApplyStateOverrides(codeInfoRepository, blockStateCall.StateOverrides, releaseSpec, blockHeader.Number); + + IEnumerable
senders = blockStateCall.Calls?.Select(details => details.Transaction.SenderAddress) ?? Enumerable.Empty(); + IEnumerable
targets = blockStateCall.Calls?.Select(details => details.Transaction.To!) ?? Enumerable.Empty(); + foreach (Address address in senders.Union(targets)) { - env.StateProvider.CreateAccountIfNotExists(address, 0, 1); + stateProvider.CreateAccountIfNotExists(address, 0, 1); } - env.StateProvider.Commit(currentSpec); - env.StateProvider.CommitTree(blockHeader.Number - 1); - env.StateProvider.RecalculateStateRoot(); + stateProvider.Commit(releaseSpec); + stateProvider.CommitTree(blockHeader.Number - 1); + stateProvider.RecalculateStateRoot(); - blockHeader.StateRoot = env.StateProvider.StateRoot; + blockHeader.StateRoot = stateProvider.StateRoot; } - public (bool Success, string Error) TrySimulateTrace(BlockHeader parent, SimulatePayload payload, IBlockTracer tracer) => - TrySimulateTrace(parent, payload, tracer, simulateProcessingEnvFactory.Create(payload.TraceTransfers, payload.Validation)); + public bool TrySimulate( + BlockHeader parent, + SimulatePayload payload, + IBlockTracer tracer, + [NotNullWhen(false)] out string? error) => + TrySimulate(parent, payload, tracer, simulateProcessingEnvFactory.Create(payload.TraceTransfers, payload.Validation), out error); - private (bool Success, string Error) TrySimulateTrace(BlockHeader parent, SimulatePayload payload, IBlockTracer tracer, SimulateReadOnlyBlocksProcessingEnv env) + private bool TrySimulate( + BlockHeader parent, + SimulatePayload payload, + IBlockTracer tracer, + SimulateReadOnlyBlocksProcessingEnv env, + [NotNullWhen(false)] out string? error) { - Block? latestBlock = env.BlockTree.FindLatestBlock(); - long latestBlockNumber = latestBlock?.Number ?? 0; - - if (latestBlockNumber < parent.Number) - { - parent = latestBlock?.Header ?? env.BlockTree.Head!.Header; - } - - BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); - - ulong lastKnown = (ulong)latestBlockNumber; - if (firstBlock?.BlockOverrides?.Number > 0 && firstBlock?.BlockOverrides?.Number < lastKnown) - { - Block? searchResult = env.BlockTree.FindBlock((long)firstBlock.BlockOverrides.Number); - if (searchResult is not null) - { - parent = searchResult.Header; - } - } + IBlockTree blockTree = env.BlockTree; IWorldState stateProvider = env.StateProvider; - stateProvider.StateRoot = parent.StateRoot!; + parent = GetParent(parent, payload, blockTree); + IReleaseSpec spec = env.SpecProvider.GetSpec(parent); + if (payload.BlockStateCalls is not null) { Dictionary nonceCache = new(); - using ArrayPoolList suggestedBlocks = new(payload.BlockStateCalls.Length); + List suggestedBlocks = [null]; - foreach (BlockStateCall callInputBlock in payload.BlockStateCalls) + foreach (BlockStateCall blockCall in payload.BlockStateCalls) { - stateProvider.StateRoot = parent.StateRoot!; - - - BlockHeader callHeader = GetCallHeader(callInputBlock, parent); - UpdateStateByModifyingAccounts(callHeader, callInputBlock, env); - stateProvider.StateRoot = env.StateProvider.StateRoot; - - using IReadOnlyTransactionProcessor? readOnlyTransactionProcessor = env.Build(stateProvider.StateRoot!); - - IReleaseSpec spec = specProvider.GetSpec(parent); + nonceCache.Clear(); + BlockHeader callHeader = GetCallHeader(blockCall, parent, payload.Validation, spec); //currentSpec is still parent spec + spec = env.SpecProvider.GetSpec(callHeader); + PrepareState(callHeader, parent, blockCall, env.StateProvider, env.CodeInfoRepository, spec); - var specifiedGasTxs = callInputBlock.Calls.Where(details => details.HadGasLimitInRequest).ToList(); - var notSpecifiedGasTxs = callInputBlock.Calls.Where(details => !details.HadGasLimitInRequest).ToList(); - var gasSpecified = - specifiedGasTxs.Sum(details => details.Transaction.GasLimit); - if (notSpecifiedGasTxs.Any()) + if (blockCall.BlockOverrides is { BaseFeePerGas: not null }) { - var gasPerTx = callHeader.GasLimit - gasSpecified / notSpecifiedGasTxs.Count; - foreach (TransactionWithSourceDetails? call in notSpecifiedGasTxs) - { - call.Transaction.GasLimit = gasPerTx; - } + callHeader.BaseFeePerGas = blockCall.BlockOverrides.BaseFeePerGas.Value; } - - if (!payload.Validation) + else if(!payload.Validation) { callHeader.BaseFeePerGas = 0; } + callHeader.Hash = callHeader.CalculateHash(); - if (callInputBlock.BlockOverrides is { BaseFeePerGas: not null }) + Transaction[] transactions = CreateTransactions(payload, blockCall, callHeader, stateProvider, nonceCache); + if (!TryGetBlock(payload, env, callHeader, transactions, out Block currentBlock, out error)) { - callHeader.BaseFeePerGas = callInputBlock.BlockOverrides.BaseFeePerGas.Value; + return false; } - Transaction[] transactions = callInputBlock.Calls?.Select(t => CreateTransaction(t, callHeader, env, nonceCache, payload.Validation)).ToArray() - ?? Array.Empty(); + ProcessingOptions processingFlags = SimulateProcessingOptions; - nonceCache.Clear(); + if (!payload.Validation) + { + processingFlags |= ProcessingOptions.NoValidation; + } + + suggestedBlocks[0] = currentBlock; + //try + //{ + IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!, payload.Validation); + Block processedBlock = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer)[0]; + //} + //catch (Exception) + //{ + // return (false, $"invalid on block {callHeader.Number}"); + //} + FinalizeStateAndBlock(stateProvider, processedBlock, spec, currentBlock, blockTree); + parent = processedBlock.Header; + } + } - Block currentBlock = new Block(callHeader, Array.Empty(), Array.Empty()); - currentBlock.Header.Hash = currentBlock.Header.CalculateHash(); + error = null; + return true; + } - var shoot = stateProvider.TakeSnapshot(); - var testedTxs = new HashSet(); - for (var index = 0; index < transactions.Length; index++) - { - Transaction transaction = transactions[index]; - BlockProcessor.AddingTxEventArgs? args = env.BlockTransactionPicker.CanAddTransaction(currentBlock, transaction, - testedTxs, - stateProvider); - - if (args.Action is BlockProcessor.TxAction.Stop or BlockProcessor.TxAction.Skip && payload.Validation) - { - return (false, $"invalid transaction index: {index} at block number: {callHeader.Number}, Reason: {args.Reason}"); - } - stateProvider.IncrementNonce(transaction.SenderAddress); - - testedTxs.Add(transaction); - } + private static void FinalizeStateAndBlock(IWorldState stateProvider, Block processedBlock, IReleaseSpec currentSpec, Block currentBlock, IBlockTree blockTree) + { + stateProvider.StateRoot = processedBlock.StateRoot!; + stateProvider.Commit(currentSpec); + stateProvider.CommitTree(currentBlock.Number); + blockTree.SuggestBlock(processedBlock, BlockTreeSuggestOptions.ForceSetAsMain); + blockTree.UpdateHeadBlock(processedBlock.Hash!); + } - stateProvider.Restore(shoot); - stateProvider.RecalculateStateRoot(); + private static BlockHeader GetParent(BlockHeader parent, SimulatePayload payload, IBlockTree blockTree) + { + Block? latestBlock = blockTree.FindLatestBlock(); + long latestBlockNumber = latestBlock?.Number ?? 0; - currentBlock = - currentBlock.WithReplacedBody(currentBlock.Body.WithChangedTransactions(testedTxs.ToArray())); + if (latestBlockNumber < parent.Number) + { + parent = latestBlock?.Header ?? blockTree.Head!.Header; + } + BlockStateCall? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); - ProcessingOptions processingFlags = SimulateProcessingOptions; + ulong lastKnown = (ulong)latestBlockNumber; + if (firstBlock?.BlockOverrides?.Number > 0 && firstBlock?.BlockOverrides?.Number < lastKnown) + { + Block? searchResult = blockTree.FindBlock((long)firstBlock.BlockOverrides.Number); + if (searchResult is not null) + { + parent = searchResult.Header; + } + } - if (!payload.Validation) - { - processingFlags |= ProcessingOptions.NoValidation; - } + return parent; + } - suggestedBlocks.Clear(); - suggestedBlocks.Add(currentBlock); + private static bool TryGetBlock( + SimulatePayload payload, + SimulateReadOnlyBlocksProcessingEnv env, + BlockHeader callHeader, + Transaction[] transactions, + out Block currentBlock, + [NotNullWhen(false)] out string? error) + { + IWorldState stateProvider = env.StateProvider; + Snapshot shoot = stateProvider.TakeSnapshot(); + currentBlock = new Block(callHeader); + LinkedHashSet testedTxs = new(); + for (int index = 0; index < transactions.Length; index++) + { + Transaction transaction = transactions[index]; + BlockProcessor.AddingTxEventArgs? args = env.BlockTransactionPicker.CanAddTransaction(currentBlock, transaction, testedTxs, stateProvider); + if (args.Action is BlockProcessor.TxAction.Stop or BlockProcessor.TxAction.Skip && payload.Validation) + { + error = $"invalid transaction index: {index} at block number: {callHeader.Number}, Reason: {args.Reason}"; + return false; + } - Block[] currentBlocks; - //try - { - IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!, payload.Validation); - currentBlocks = processor.Process(stateProvider.StateRoot, suggestedBlocks.ToList(), processingFlags, tracer); + stateProvider.IncrementNonce(transaction.SenderAddress!); + testedTxs.Add(transaction); + } - } - //catch (Exception) - //{ - // return (false, $"invalid on block {callHeader.Number}"); - //} + stateProvider.Restore(shoot); + stateProvider.RecalculateStateRoot(); - Block processedBlock = currentBlocks[0]; + currentBlock = currentBlock.WithReplacedBody(currentBlock.Body.WithChangedTransactions(testedTxs.ToArray())); + error = null; + return true; + } - if (processedBlock is not null) - { - parent = processedBlock.Header; - stateProvider.StateRoot = processedBlock.StateRoot; - env.StateProvider.StateRoot = processedBlock.StateRoot; - var currentSpec = env.SpecProvider.GetSpec(processedBlock.Header); - env.StateProvider.Commit(currentSpec); - env.StateProvider.CommitTree(currentBlock.Number); - env.BlockTree.SuggestBlock(processedBlock, BlockTreeSuggestOptions.ForceSetAsMain); - env.BlockTree.UpdateHeadBlock(processedBlock.Hash!); - } + private Transaction[] CreateTransactions(SimulatePayload payload, + BlockStateCall callInputBlock, + BlockHeader callHeader, + IWorldState stateProvider, + Dictionary nonceCache) + { + int notSpecifiedGasTxsCount = callInputBlock.Calls?.Count(details => !details.HadGasLimitInRequest) ?? 0; + long gasSpecified = callInputBlock.Calls?.Where(details => details.HadGasLimitInRequest).Sum(details => details.Transaction.GasLimit) ?? 0; + if (notSpecifiedGasTxsCount > 0) + { + long gasPerTx = callHeader.GasLimit - gasSpecified / notSpecifiedGasTxsCount; + IEnumerable notSpecifiedGasTxs = callInputBlock.Calls?.Where(details => !details.HadGasLimitInRequest) ?? Enumerable.Empty(); + foreach (TransactionWithSourceDetails call in notSpecifiedGasTxs) + { + call.Transaction.GasLimit = gasPerTx; } } - return (true, ""); + return callInputBlock.Calls?.Select(t => CreateTransaction(t, callHeader, stateProvider, nonceCache, payload.Validation)).ToArray() ?? Array.Empty(); } - private Transaction CreateTransaction( - TransactionWithSourceDetails transactionDetails, + private Transaction CreateTransaction(TransactionWithSourceDetails transactionDetails, BlockHeader callHeader, - SimulateReadOnlyBlocksProcessingEnv env, + IWorldState stateProvider, Dictionary nonceCache, bool validate) { @@ -219,23 +233,18 @@ private Transaction CreateTransaction( if (!transactionDetails.HadNonceInRequest) { - if (!nonceCache.TryGetValue(transaction.SenderAddress, out UInt256 cachedNonce)) + ref UInt256 cachedNonce = ref CollectionsMarshal.GetValueRefOrAddDefault(nonceCache, transaction.SenderAddress, out bool exist); + if (!exist) { - if (env.StateProvider.TryGetAccount(transaction.SenderAddress, out AccountStruct test)) + if (stateProvider.TryGetAccount(transaction.SenderAddress, out AccountStruct test)) { cachedNonce = test.Nonce; } - else - { - cachedNonce = 0; // Todo think if we shall create account here - } - - nonceCache[transaction.SenderAddress] = cachedNonce; + // else // Todo think if we shall create account here } else { cachedNonce++; - nonceCache[transaction.SenderAddress] = cachedNonce; } transaction.Nonce = cachedNonce; @@ -263,9 +272,9 @@ private Transaction CreateTransaction( return transaction; } - private BlockHeader GetCallHeader(BlockStateCall block, BlockHeader parent) => + private BlockHeader GetCallHeader(BlockStateCall block, BlockHeader parent, bool payloadValidation, IReleaseSpec parentSpec) => block.BlockOverrides is not null - ? block.BlockOverrides.GetBlockHeader(parent, blocksConfig, specProvider.GetSpec(parent)) + ? block.BlockOverrides.GetBlockHeader(parent, blocksConfig, parentSpec) : new BlockHeader( parent.Hash!, Keccak.OfAnEmptySequenceRlp, @@ -273,11 +282,10 @@ block.BlockOverrides is not null UInt256.Zero, parent.Number + 1, parent.GasLimit, - parent.Timestamp + 1, Array.Empty()) { - BaseFeePerGas = BaseFeeCalculator.Calculate(parent, specProvider.GetSpec(parent)), + BaseFeePerGas = !payloadValidation ? 0 : BaseFeeCalculator.Calculate(parent, parentSpec), MixHash = parent.MixHash, IsPostMerge = parent.Difficulty == 0 }; diff --git a/src/Nethermind/Nethermind.JsonRpc/ErrorType.cs b/src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs similarity index 100% rename from src/Nethermind/Nethermind.JsonRpc/ErrorType.cs rename to src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs diff --git a/src/Nethermind/Nethermind.State/StateProvider.cs b/src/Nethermind/Nethermind.State/StateProvider.cs index 945bd11d459..5050caa4f67 100644 --- a/src/Nethermind/Nethermind.State/StateProvider.cs +++ b/src/Nethermind/Nethermind.State/StateProvider.cs @@ -423,8 +423,10 @@ public void CreateAccount(Address address, in UInt256 balance, in UInt256 nonce public void CreateAccountIfNotExists(Address address, in UInt256 balance, in UInt256 nonce = default) { - if (AccountExists(address)) return; - CreateAccount(address, balance, nonce); + if (!AccountExists(address)) + { + CreateAccount(address, balance, nonce); + } } public void AddToBalanceAndCreateIfNotExists(Address address, in UInt256 balance, IReleaseSpec spec) From b408aaf45ea68db60076c51c2dd7158eb4a6c64f Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 14 May 2024 14:15:03 +0100 Subject: [PATCH 181/213] minor issues fix --- .../Nethermind.Facade/Simulate/SimulateBridgeHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index d89ab56ba91..93a1fb5abb5 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -42,7 +42,7 @@ private void PrepareState(BlockHeader blockHeader, IEnumerable
senders = blockStateCall.Calls?.Select(details => details.Transaction.SenderAddress) ?? Enumerable.Empty(); IEnumerable
targets = blockStateCall.Calls?.Select(details => details.Transaction.To!) ?? Enumerable.Empty(); - foreach (Address address in senders.Union(targets)) + foreach (Address address in senders.Union(targets).Where(t=> t != null)) { stateProvider.CreateAccountIfNotExists(address, 0, 1); } From 4740cc1cdbd6ac9b7c912bd738819238b97873be Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 15:57:36 +0200 Subject: [PATCH 182/213] more refactor --- .../Proxy/Models/Simulate/SimulatePayload.cs | 4 +- .../Simulate/SimulateBridgeHelper.cs | 2 +- .../JsonRpcServiceTests.cs | 2 +- .../EthSimulateTestsBlocksAndTransactions.cs | 4 +- .../Eth/EthRpcModule.TransactionExecutor.cs | 50 +++----- ...allTxExecutor.cs => SimulateTxExecutor.cs} | 115 ++++++++++-------- 6 files changed, 83 insertions(+), 94 deletions(-) rename src/Nethermind/Nethermind.JsonRpc/Modules/Eth/{SimulateTxExecutor.MultiCallTxExecutor.cs => SimulateTxExecutor.cs} (64%) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs index 6bc19755870..f549f3c6d20 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.Collections.Generic; + namespace Nethermind.Facade.Proxy.Models.Simulate; public class SimulatePayload @@ -8,7 +10,7 @@ public class SimulatePayload /// /// Definition of blocks that can contain calls and overrides /// - public BlockStateCall[]? BlockStateCalls { get; set; } + public List>? BlockStateCalls { get; set; } /// /// Should trace ETH Transfers diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 93a1fb5abb5..f8577ec5e61 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -152,7 +152,7 @@ private static BlockHeader GetParent(BlockHeader parent, SimulatePayload? firstBlock = payload.BlockStateCalls?.FirstOrDefault(); ulong lastKnown = (ulong)latestBlockNumber; - if (firstBlock?.BlockOverrides?.Number > 0 && firstBlock?.BlockOverrides?.Number < lastKnown) + if (firstBlock?.BlockOverrides?.Number > 0 && firstBlock.BlockOverrides?.Number < lastKnown) { Block? searchResult = blockTree.FindBlock((long)firstBlock.BlockOverrides.Number); if (searchResult is not null) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index 88a3746af1b..2f15419f94c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -92,7 +92,7 @@ public void Eth_module_populates_size_when_returning_block_data() [Test] public void CanRunEthSimulateV1Empty() { - SimulatePayload payload = new() { BlockStateCalls = Array.Empty>() }; + SimulatePayload payload = new() { BlockStateCalls = new List>() }; string serializedCall = new EthereumJsonSerializer().Serialize(payload); IEthRpcModule ethRpcModule = Substitute.For(); ethRpcModule.eth_simulateV1(payload).ReturnsForAnyArgs(_ => diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 164a54e59b1..4f3bb344d17 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -104,7 +104,7 @@ public async Task Test_eth_simulate_eth_moved() SimulatePayload payload = new() { - BlockStateCalls = new BlockStateCall[] + BlockStateCalls = new List> { new() { @@ -183,7 +183,7 @@ public async Task Test_eth_simulate_transactions_forced_fail() TransactionForRpc transactionForRpc2 = new(txAtoB1) { Nonce = null }; SimulatePayload payload = new() { - BlockStateCalls = new BlockStateCall[] + BlockStateCalls = new List> { new() { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 63416d5917f..ae145dbb8d9 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -22,11 +22,10 @@ namespace Nethermind.JsonRpc.Modules.Eth public partial class EthRpcModule { // Single call executor - private abstract class TxExecutor : ExecutorBase + private abstract class TxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) + : ExecutorBase(blockchainBridge, blockFinder, rpcConfig) { - protected bool NoBaseFee { get; set; } - protected TxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) - : base(blockchainBridge, blockFinder, rpcConfig) { } + private bool NoBaseFee { get; set; } protected override Transaction Prepare(TransactionForRpc call) => call.ToTransaction(_blockchainBridge.GetChainId()); @@ -39,18 +38,14 @@ protected override ResultWrapper Execute(BlockHeader header, Transactio } if (tx.IsContractCreation && tx.DataLength == 0) { - return ResultWrapper.Fail("Contract creation without any data provided.", - ErrorCodes.InvalidInput); + return ResultWrapper.Fail("Contract creation without any data provided.", ErrorCodes.InvalidInput); } return ExecuteTx(clonedHeader, tx, token); } - private static bool ShouldSetBaseFee(TransactionForRpc t) - { - return (t.GasPrice.HasValue && t.GasPrice.Value > 0) || - (t.MaxFeePerGas.HasValue && t.MaxFeePerGas.Value > 0) || - (t.MaxPriorityFeePerGas.HasValue && t.MaxPriorityFeePerGas.Value > 0); - } + private static bool ShouldSetBaseFee(TransactionForRpc t) => + // x?.IsZero == false <=> x > 0 + t.GasPrice?.IsZero == false || t.MaxFeePerGas?.IsZero == false || t.MaxPriorityFeePerGas?.IsZero == false; public override ResultWrapper Execute( TransactionForRpc transactionCall, @@ -69,13 +64,9 @@ protected ResultWrapper GetInputError(CallOutput result) => ResultWrapper.Fail(result.Error, ErrorCodes.InvalidInput); } - private class CallTxExecutor : TxExecutor + private class CallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) + : TxExecutor(blockchainBridge, blockFinder, rpcConfig) { - public CallTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) - : base(blockchainBridge, blockFinder, rpcConfig) - { - } - protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token) { CallOutput result = _blockchainBridge.Call(header, tx, token); @@ -87,14 +78,10 @@ protected override ResultWrapper ExecuteTx(BlockHeader header, Transacti } - private class EstimateGasTxExecutor : TxExecutor + private class EstimateGasTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) + : TxExecutor(blockchainBridge, blockFinder, rpcConfig) { - private readonly int _errorMargin; - public EstimateGasTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) - : base(blockchainBridge, blockFinder, rpcConfig) - { - _errorMargin = rpcConfig.EstimateErrorMargin; - } + private readonly int _errorMargin = rpcConfig.EstimateErrorMargin; protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token) { @@ -111,19 +98,12 @@ public EstimateGasTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder bl } } - private class CreateAccessListTxExecutor : TxExecutor + private class CreateAccessListTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig, bool optimize) + : TxExecutor(blockchainBridge, blockFinder, rpcConfig) { - private readonly bool _optimize; - - public CreateAccessListTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig, bool optimize) - : base(blockchainBridge, blockFinder, rpcConfig) - { - _optimize = optimize; - } - protected override ResultWrapper ExecuteTx(BlockHeader header, Transaction tx, CancellationToken token) { - CallOutput result = _blockchainBridge.CreateAccessList(header, tx, token, _optimize); + CallOutput result = _blockchainBridge.CreateAccessList(header, tx, token, optimize); if (result.Error is null) { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs similarity index 64% rename from src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs rename to src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index 69abc7babb8..7444a9818d9 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -15,32 +15,26 @@ namespace Nethermind.JsonRpc.Modules.Eth; -public class SimulateTxExecutor : ExecutorBase, SimulatePayload, - SimulatePayload> +public class SimulateTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig, IBlocksConfig? blocksConfig = null) + : ExecutorBase, SimulatePayload, + SimulatePayload>(blockchainBridge, blockFinder, rpcConfig) { - private readonly ulong _interBlocksTimings; - private readonly long blocksLimit; - private long gasCapBudget; - - public SimulateTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig) : - base(blockchainBridge, blockFinder, rpcConfig) - { - _interBlocksTimings = new BlocksConfig().SecondsPerSlot; - gasCapBudget = rpcConfig.GasCap ?? long.MaxValue; - blocksLimit = rpcConfig.MaxSimulateBlocksCap ?? 256; - } + private readonly ulong _interBlocksTimings = (blocksConfig ?? new BlocksConfig()).SecondsPerSlot; + private readonly long _blocksLimit = rpcConfig.MaxSimulateBlocksCap ?? 256; + private long _gasCapBudget = rpcConfig.GasCap ?? long.MaxValue; protected override SimulatePayload Prepare(SimulatePayload call) { - SimulatePayload? result = new() + SimulatePayload result = new() { TraceTransfers = call.TraceTransfers, Validation = call.Validation, BlockStateCalls = call.BlockStateCalls?.Select(blockStateCall => { - if (blockStateCall.BlockOverrides?.GasLimit != null) - blockStateCall.BlockOverrides.GasLimit = - (ulong)Math.Min((long)blockStateCall.BlockOverrides.GasLimit!.Value, gasCapBudget); + if (blockStateCall.BlockOverrides?.GasLimit is not null) + { + blockStateCall.BlockOverrides.GasLimit = (ulong)Math.Min((long)blockStateCall.BlockOverrides.GasLimit!.Value, _gasCapBudget); + } return new BlockStateCall { @@ -48,12 +42,15 @@ protected override SimulatePayload Prepare(Simulat StateOverrides = blockStateCall.StateOverrides, Calls = blockStateCall.Calls?.Select(callTransactionModel => { - if (callTransactionModel.Type == TxType.Legacy) callTransactionModel.Type = TxType.EIP1559; + if (callTransactionModel.Type == TxType.Legacy) + { + callTransactionModel.Type = TxType.EIP1559; + } bool hadGasLimitInRequest = callTransactionModel.Gas.HasValue; bool hadNonceInRequest = callTransactionModel.Nonce.HasValue; - callTransactionModel.EnsureDefaults(gasCapBudget); - gasCapBudget -= callTransactionModel.Gas!.Value; + callTransactionModel.EnsureDefaults(_gasCapBudget); + _gasCapBudget -= callTransactionModel.Gas!.Value; Transaction tx = callTransactionModel.ToTransaction(_blockchainBridge.GetChainId()); @@ -67,7 +64,7 @@ protected override SimulatePayload Prepare(Simulat return result; }).ToArray() }; - }).ToArray() + }).ToList() }; return result; @@ -77,38 +74,37 @@ public override ResultWrapper> Execute( SimulatePayload call, BlockParameter? blockParameter) { - if (call.BlockStateCalls == null) - return ResultWrapper>.Fail("Must contain BlockStateCalls", - ErrorCodes.InvalidParams); + if (call.BlockStateCalls is null) + return ResultWrapper>.Fail("Must contain BlockStateCalls", ErrorCodes.InvalidParams); - if (call.BlockStateCalls!.Length > _rpcConfig.MaxSimulateBlocksCap) + if (call.BlockStateCalls!.Count > _rpcConfig.MaxSimulateBlocksCap) return ResultWrapper>.Fail( - $"This node is configured to support only {_rpcConfig.MaxSimulateBlocksCap} blocks", - ErrorCodes.InvalidInputTooManyBlocks); + $"This node is configured to support only {_rpcConfig.MaxSimulateBlocksCap} blocks", ErrorCodes.InvalidInputTooManyBlocks); + SearchResult searchResult = _blockFinder.SearchForBlock(blockParameter); - if (searchResult.IsError || searchResult.Object == null) + if (searchResult.IsError || searchResult.Object is null) return ResultWrapper>.Fail(searchResult); BlockHeader header = searchResult.Object.Header; - if (blockParameter.Type == BlockParameterType.Latest) header = _blockFinder.FindLatestBlock().Header; + if (blockParameter?.Type == BlockParameterType.Latest) header = _blockFinder.FindLatestBlock()?.Header; if (!_blockchainBridge.HasStateForBlock(header!)) return ResultWrapper>.Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable); - if (call.BlockStateCalls?.Length > blocksLimit) + if (call.BlockStateCalls?.Count > _blocksLimit) return ResultWrapper>.Fail( - $"Too many blocks provided, node is configured to simulate up to {blocksLimit} while {call.BlockStateCalls?.Length} were given", + $"Too many blocks provided, node is configured to simulate up to {_blocksLimit} while {call.BlockStateCalls?.Count} were given", ErrorCodes.InvalidParams); - if (call.BlockStateCalls != null) + if (call.BlockStateCalls is not null) { long lastBlockNumber = -1; ulong lastBlockTime = 0; - foreach (BlockStateCall? blockToSimulate in call.BlockStateCalls!) + foreach (BlockStateCall? blockToSimulate in call.BlockStateCalls) { ulong givenNumber = blockToSimulate.BlockOverrides?.Number ?? (lastBlockNumber == -1 ? (ulong)header.Number + 1 : (ulong)lastBlockNumber + 1); @@ -119,57 +115,69 @@ public override ResultWrapper> Execute( long given = (long)givenNumber; if (given > lastBlockNumber) + { lastBlockNumber = given; + } else + { return ResultWrapper>.Fail( $"Block number out of order {givenNumber}!", ErrorCodes.InvalidInputBlocksOutOfOrder); + } - if (blockToSimulate.BlockOverrides == null) blockToSimulate.BlockOverrides = new BlockOverride(); + blockToSimulate.BlockOverrides ??= new BlockOverride(); + blockToSimulate.BlockOverrides.Number = givenNumber; - blockToSimulate.BlockOverrides!.Number = givenNumber; - - - ulong givenTime = blockToSimulate.BlockOverrides?.Time ?? (lastBlockTime == 0 - ? header.Timestamp + _interBlocksTimings - : lastBlockTime + _interBlocksTimings); + ulong givenTime = blockToSimulate.BlockOverrides.Time ?? + (lastBlockTime == 0 + ? header.Timestamp + _interBlocksTimings + : lastBlockTime + _interBlocksTimings); if (givenTime > lastBlockTime) + { lastBlockTime = givenTime; + } else + { return ResultWrapper>.Fail( $"Block timestamp out of order {givenTime}!", ErrorCodes.InvalidInputBlocksOutOfOrder); - blockToSimulate.BlockOverrides!.Time = givenTime; + } + + blockToSimulate.BlockOverrides.Time = givenTime; } long minBlockNumber = Math.Min( - call.BlockStateCalls.Min(b => - (long)(b.BlockOverrides?.Number ?? ulong.MaxValue)), + call.BlockStateCalls.Min(b => (long)(b.BlockOverrides?.Number ?? ulong.MaxValue)), header.Number + 1); long maxBlockNumber = Math.Max( - call.BlockStateCalls.Max(b => - (long)(b.BlockOverrides?.Number ?? ulong.MinValue)), + call.BlockStateCalls.Max(b => (long)(b.BlockOverrides?.Number ?? ulong.MinValue)), minBlockNumber); - HashSet existingBlockNumbers = new(call.BlockStateCalls.Select(b => - (long)(b.BlockOverrides?.Number ?? ulong.MinValue))); + HashSet existingBlockNumbers = + [ + ..call.BlockStateCalls.Select(b => (long)(b.BlockOverrides?.Number ?? ulong.MinValue)) + ]; - List> completeBlockStateCalls = call.BlockStateCalls!.ToList(); + List> completeBlockStateCalls = call.BlockStateCalls; for (long blockNumber = minBlockNumber; blockNumber <= maxBlockNumber; blockNumber++) + { if (!existingBlockNumbers.Contains(blockNumber)) + { completeBlockStateCalls.Add(new BlockStateCall { BlockOverrides = new BlockOverride { Number = (ulong)blockNumber }, StateOverrides = null, Calls = Array.Empty() }); + } + } - call.BlockStateCalls = completeBlockStateCalls.OrderBy(b => b.BlockOverrides!.Number!).ToArray(); + call.BlockStateCalls.Sort((b1, b2) => b1.BlockOverrides!.Number!.Value.CompareTo(b2.BlockOverrides!.Number!.Value)); } using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout); //TODO remove! - SimulatePayload? toProcess = Prepare(call); + SimulatePayload toProcess = Prepare(call); return Execute(header.Clone(), toProcess, cancellationTokenSource.Token); } @@ -178,14 +186,13 @@ protected override ResultWrapper> Execute(Blo { SimulateOutput results = _blockchainBridge.Simulate(header, tx, token); - if (results.Error != null && results.Error.Contains("invalid transaction")) + if (results.Error?.Contains("invalid transaction") == true) results.ErrorCode = ErrorCodes.InvalidTransaction; return results.Error is null ? ResultWrapper>.Success(results.Items) - : results.ErrorCode != null - ? ResultWrapper>.Fail(results.Error!, results.ErrorCode!.Value, - results.Items) + : results.ErrorCode is not null + ? ResultWrapper>.Fail(results.Error!, results.ErrorCode!.Value, results.Items) : ResultWrapper>.Fail(results.Error, results.Items); } } From 9701065bd7a85713ba3c0171077667acb1827ef8 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 15:58:45 +0200 Subject: [PATCH 183/213] not null --- .../Nethermind.Facade/Simulate/SimulateBridgeHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index f8577ec5e61..462e6cf89e9 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -42,7 +42,7 @@ private void PrepareState(BlockHeader blockHeader, IEnumerable
senders = blockStateCall.Calls?.Select(details => details.Transaction.SenderAddress) ?? Enumerable.Empty(); IEnumerable
targets = blockStateCall.Calls?.Select(details => details.Transaction.To!) ?? Enumerable.Empty(); - foreach (Address address in senders.Union(targets).Where(t=> t != null)) + foreach (Address address in senders.Union(targets).Where(t=> t is not null)) { stateProvider.CreateAccountIfNotExists(address, 0, 1); } From e4efdc63cd9786e5ceb78d53f47a91e32a35d31a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 14 May 2024 18:23:45 +0100 Subject: [PATCH 184/213] minor Trello issues fixes --- .../Proxy/Models/Simulate/SimulatePayload.cs | 4 ++-- .../Simulate/SimulateBridgeHelper.cs | 14 ++++---------- .../SimulateReadOnlyBlocksProcessingEnv.cs | 2 +- .../Simulate/SimulateVirtualMachine.cs | 2 +- .../SimulateTxExecutor.MultiCallTxExecutor.cs | 3 ++- .../Nethermind.Serialization.Rlp/Rlp.cs | 17 +++++++++++++++++ 6 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs index 6bc19755870..6896db89a88 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs @@ -13,11 +13,11 @@ public class SimulatePayload /// /// Should trace ETH Transfers /// - public bool TraceTransfers { get; set; } + public bool TraceTransfers { get; set; } = false; /// /// When true, the simulate does all validations that a normal EVM would do, except contract sender and signature /// checks. When false, multicall behaves like eth_call. /// - public bool Validation { get; set; } + public bool Validation { get; set; } = false; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 93a1fb5abb5..9e5ae7fa2b1 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -42,7 +42,7 @@ private void PrepareState(BlockHeader blockHeader, IEnumerable
senders = blockStateCall.Calls?.Select(details => details.Transaction.SenderAddress) ?? Enumerable.Empty(); IEnumerable
targets = blockStateCall.Calls?.Select(details => details.Transaction.To!) ?? Enumerable.Empty(); - foreach (Address address in senders.Union(targets).Where(t=> t != null)) + foreach (Address address in senders.Union(targets).Where(t => t != null)) { stateProvider.CreateAccountIfNotExists(address, 0, 1); } @@ -90,7 +90,7 @@ private bool TrySimulate( { callHeader.BaseFeePerGas = blockCall.BlockOverrides.BaseFeePerGas.Value; } - else if(!payload.Validation) + else if (!payload.Validation) { callHeader.BaseFeePerGas = 0; } @@ -111,15 +111,9 @@ private bool TrySimulate( suggestedBlocks[0] = currentBlock; - //try - //{ IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!, payload.Validation); - Block processedBlock = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer)[0]; - //} - //catch (Exception) - //{ - // return (false, $"invalid on block {callHeader.Number}"); - //} + Block processedBlock = + processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer)[0]; FinalizeStateAndBlock(stateProvider, processedBlock, spec, currentBlock, blockTree); parent = processedBlock.Header; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index d2f54f64c2a..02825318ad6 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -36,7 +36,7 @@ public SimulateBlockValidationTransactionsExecutor(ITransactionProcessorAdapter protected override void ProcessTransaction(in BlockExecutionContext blkCtx, Transaction currentTx, int index, BlockReceiptsTracer receiptsTracer, ProcessingOptions processingOptions) { - processingOptions |= ProcessingOptions.DoNotVerifyNonce; + processingOptions |= ProcessingOptions.ForceProcessing | ProcessingOptions.DoNotVerifyNonce | ProcessingOptions.NoValidation; base.ProcessTransaction(in blkCtx, currentTx, index, receiptsTracer, processingOptions); } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs index 654d814464f..5ea81093e80 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs @@ -12,7 +12,7 @@ public class SimulateVirtualMachine(IVirtualMachine virtualMachine) : IVirtualMa { public TransactionSubstate Run(EvmState state, IWorldState worldState, ITxTracer txTracer) where TTracingActions : struct, VirtualMachine.IIsTracing { - if (typeof(TTracingActions)== typeof(VirtualMachine.IsTracing) && TryGetLogsMutator(txTracer, out ITxLogsMutator logsMutator)) + if (typeof(TTracingActions) == typeof(VirtualMachine.IsTracing) && TryGetLogsMutator(txTracer, out ITxLogsMutator logsMutator)) { logsMutator.SetLogsToMutate(state.Logs); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs index 69abc7babb8..29f542e72ef 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.MultiCallTxExecutor.cs @@ -178,7 +178,8 @@ protected override ResultWrapper> Execute(Blo { SimulateOutput results = _blockchainBridge.Simulate(header, tx, token); - if (results.Error != null && results.Error.Contains("invalid transaction")) + if (results.Error != null && (results.Error.Contains("invalid transaction") + || results.Error.Contains("InsufficientBalanceException"))) results.ErrorCode = ErrorCodes.InvalidTransaction; return results.Error is null diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs b/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs index 923cb54f74f..102c558489c 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs @@ -1083,6 +1083,18 @@ private static void ThrowInvalidPrefix(ref ValueDecoderContext ctx, int prefix) throw new RlpException($"Unexpected prefix of {prefix} when decoding {nameof(Hash256)} at position {ctx.Position} in the message of length {ctx.Data.Length} starting with {ctx.Data[..Math.Min(DebugMessageContentLength, ctx.Data.Length)].ToHexString()}"); } + public static bool IsAllZeroes(ReadOnlySpan byteSpan) + { + foreach (byte b in byteSpan) + { + if (b != 0) + { + return false; + } + } + return true; + } + public UInt256 DecodeUInt256(int length = -1) { ReadOnlySpan byteSpan = DecodeByteArraySpan(); @@ -1093,6 +1105,11 @@ public UInt256 DecodeUInt256(int length = -1) if (length == -1) { + if (IsAllZeroes(byteSpan)) + { + return 0; + } + if (byteSpan.Length > 1 && byteSpan[0] == 0) { ThrowNonCanonicalUInt256(Position); From 17fdf8471607a0198ca7aae21a6bc57140d4c121 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 14 May 2024 20:12:37 +0100 Subject: [PATCH 185/213] minor fix --- src/Nethermind/Nethermind.Evm/VirtualMachine.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index e6fe1caf435..63c63e2d4df 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -2123,9 +2123,6 @@ private EvmExceptionType InstructionCall( !UpdateMemoryCost(vmState, ref gasAvailable, in outputOffset, outputLength) || !UpdateGas(gasExtra, ref gasAvailable)) return EvmExceptionType.OutOfGas; - CodeInfo codeInfo = GetCachedCodeInfo(_worldState, codeSource, spec); - codeInfo.AnalyseInBackgroundIfRequired(); - if (spec.Use63Over64Rule) { gasLimit = UInt256.Min((UInt256)(gasAvailable - gasAvailable / 64), gasLimit); @@ -2169,7 +2166,7 @@ private EvmExceptionType InstructionCall( Snapshot snapshot = _worldState.TakeSnapshot(); _state.SubtractFromBalance(caller, transferValue, spec); - CodeInfo codeInfo = _codeInfoRepository.GetCachedCodeInfo(_worldState, codeSource, spec) + CodeInfo codeInfo = _codeInfoRepository.GetCachedCodeInfo(_worldState, codeSource, spec); codeInfo.AnalyseInBackgroundIfRequired(); ExecutionEnvironment callEnv = new ( From d85bf1d139555d9bc1548485a6038f0896c47132 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 14 May 2024 20:13:48 +0100 Subject: [PATCH 186/213] dotnet format --- .../Collections/LinkedHashSet.cs | 2 +- .../TransactionSubstateTests.cs | 214 +++++++++++++++++- .../Simulate/SimulateBridgeHelper.cs | 2 +- .../Modules/Eth/SimulateTxExecutor.cs | 2 +- 4 files changed, 207 insertions(+), 13 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs b/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs index 864c61a1ec4..553448f9c60 100644 --- a/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs +++ b/src/Nethermind/Nethermind.Core/Collections/LinkedHashSet.cs @@ -195,7 +195,7 @@ public void UnionWith(IEnumerable? other) } #endregion - + #region ICollection public int Count => _dict.Count; diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs index b067d7539a0..5289830c09b 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs @@ -18,12 +18,79 @@ public void should_return_proper_revert_error_when_there_is_no_exception() { byte[] data = [ - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5, - 0x05, 0x06, 0x07, 0x08, 0x09 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0x20, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0x5, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09 ]; ReadOnlyMemory readOnlyMemory = new(data); TransactionSubstate transactionSubstate = new(readOnlyMemory, @@ -163,11 +230,138 @@ public void should_return_proper_revert_error_when_revert_custom_error() { byte[] data = [ - 0x22, 0x02, 0x66, 0xb6, // Keccak of `FailedOp(uint256,string)` == 0x220266b6 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, + 0x02, + 0x66, + 0xb6, // Keccak of `FailedOp(uint256,string)` == 0x220266b6 + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, 0x17, - 0x41, 0x41, 0x32, 0x31, 0x20, 0x64, 0x69, 0x64, 0x6e, 0x27, 0x74, 0x20, 0x70, 0x61, 0x79, 0x20, 0x70, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, // "AA21 didn't pay prefund" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x41, + 0x41, + 0x32, + 0x31, + 0x20, + 0x64, + 0x69, + 0x64, + 0x6e, + 0x27, + 0x74, + 0x20, + 0x70, + 0x61, + 0x79, + 0x20, + 0x70, + 0x72, + 0x65, + 0x66, + 0x75, + 0x6e, + 0x64, // "AA21 didn't pay prefund" + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 ]; ReadOnlyMemory readOnlyMemory = new(data); TransactionSubstate transactionSubstate = new( diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 490044a391e..c7adb1c0ad0 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -42,7 +42,7 @@ private void PrepareState(BlockHeader blockHeader, IEnumerable
senders = blockStateCall.Calls?.Select(details => details.Transaction.SenderAddress) ?? Enumerable.Empty(); IEnumerable
targets = blockStateCall.Calls?.Select(details => details.Transaction.To!) ?? Enumerable.Empty(); - foreach (Address address in senders.Union(targets).Where(t=> t is not null)) + foreach (Address address in senders.Union(targets).Where(t => t is not null)) { stateProvider.CreateAccountIfNotExists(address, 0, 1); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index 59703e67a99..327c6676bc7 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -155,7 +155,7 @@ public override ResultWrapper> Execute( HashSet existingBlockNumbers = [ - ..call.BlockStateCalls.Select(b => (long)(b.BlockOverrides?.Number ?? ulong.MinValue)) + .. call.BlockStateCalls.Select(b => (long)(b.BlockOverrides?.Number ?? ulong.MinValue)) ]; List> completeBlockStateCalls = call.BlockStateCalls; From 98f2a1f09eaa69c724f62e0f09134375396b842b Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 23:10:33 +0200 Subject: [PATCH 187/213] Add SimulateTransactionProcessor --- .../BuildUpTransactionProcessorAdapter.cs | 11 ++----- .../TransactionProcessor.cs | 14 ++------ .../SimulateReadOnlyBlocksProcessingEnv.cs | 11 ++----- .../Simulate/SimulateTransactionProcessor.cs | 32 +++++++++++++++++++ 4 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 src/Nethermind/Nethermind.Facade/Simulate/SimulateTransactionProcessor.cs diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/BuildUpTransactionProcessorAdapter.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/BuildUpTransactionProcessorAdapter.cs index d0215a41aa3..2ac0a3b8fcb 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/BuildUpTransactionProcessorAdapter.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/BuildUpTransactionProcessorAdapter.cs @@ -6,16 +6,9 @@ namespace Nethermind.Evm.TransactionProcessing { - public class BuildUpTransactionProcessorAdapter : ITransactionProcessorAdapter + public class BuildUpTransactionProcessorAdapter(ITransactionProcessor transactionProcessor) : ITransactionProcessorAdapter { - private readonly ITransactionProcessor _transactionProcessor; - - public BuildUpTransactionProcessorAdapter(ITransactionProcessor transactionProcessor) - { - _transactionProcessor = transactionProcessor; - } - public TransactionResult Execute(Transaction transaction, in BlockExecutionContext blkCtx, ITxTracer txTracer) => - _transactionProcessor.BuildUp(transaction, in blkCtx, txTracer); + transactionProcessor.BuildUp(transaction, in blkCtx, txTracer); } } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 88cf871c69b..15f5549fc8e 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -6,10 +6,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.CompilerServices; -using System.Threading; - using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; @@ -64,15 +61,13 @@ protected enum ExecutionOptions ///
CommitAndRestore = Commit | Restore | NoValidation } - private readonly ExecutionOptions _executeOptions; public TransactionProcessor( ISpecProvider? specProvider, IWorldState? worldState, IVirtualMachine? virtualMachine, ICodeInfoRepository? codeInfoRepository, - ILogManager? logManager, - bool forceNoValidationOnExecute = false) + ILogManager? logManager) { ArgumentNullException.ThrowIfNull(logManager, nameof(logManager)); ArgumentNullException.ThrowIfNull(specProvider, nameof(specProvider)); @@ -87,11 +82,6 @@ public TransactionProcessor( _codeInfoRepository = codeInfoRepository; Ecdsa = new EthereumEcdsa(specProvider.ChainId, logManager); - _executeOptions = ExecutionOptions.Commit; - if (forceNoValidationOnExecute) - { - _executeOptions |= ExecutionOptions.NoValidation; - } } public TransactionResult CallAndRestore(Transaction transaction, in BlockExecutionContext blCtx, ITxTracer txTracer) => @@ -106,7 +96,7 @@ public TransactionResult BuildUp(Transaction transaction, in BlockExecutionConte } public TransactionResult Execute(Transaction transaction, in BlockExecutionContext blCtx, ITxTracer txTracer) => - Execute(transaction, in blCtx, txTracer, _executeOptions); + Execute(transaction, in blCtx, txTracer, ExecutionOptions.Commit); public TransactionResult Trace(Transaction transaction, in BlockExecutionContext blCtx, ITxTracer txTracer) => Execute(transaction, in blCtx, txTracer, ExecutionOptions.NoValidation); diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index d2f54f64c2a..681a4e19ba1 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -21,8 +21,6 @@ namespace Nethermind.Facade.Simulate; - - public class SimulateBlockValidationTransactionsExecutor : BlockProcessor.BlockValidationTransactionsExecutor { public SimulateBlockValidationTransactionsExecutor(ITransactionProcessor transactionProcessor, IWorldState stateProvider) : base(transactionProcessor, stateProvider) @@ -55,7 +53,7 @@ public SimulateReadOnlyBlocksProcessingEnv( IBlockTree blockTree, ISpecProvider specProvider, ILogManager? logManager = null, - bool doValidation = false) + bool validate = false) : base(worldStateManager, blockTree, specProvider, logManager) { ReadOnlyBlockTree = baseBlockTree; @@ -65,15 +63,12 @@ public SimulateReadOnlyBlocksProcessingEnv( SpecProvider = specProvider; BlockTree = new BlockTreeOverlay(ReadOnlyBlockTree, blockTree); - BlockhashProvider = - new SimulateBlockhashProvider(new BlockhashProvider(BlockTree, specProvider, StateProvider, logManager), - BlockTree); + BlockhashProvider = new SimulateBlockhashProvider(new BlockhashProvider(BlockTree, specProvider, StateProvider, logManager), BlockTree); StateProvider = WorldStateManager.GlobalWorldState; StateReader = WorldStateManager.GlobalStateReader; CodeInfoRepository = new OverridableCodeInfoRepository(new CodeInfoRepository()); VirtualMachine = new SimulateVirtualMachine(new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager)); - _transactionProcessor = new TransactionProcessor(SpecProvider, StateProvider, VirtualMachine, - CodeInfoRepository, _logManager, !doValidation); + _transactionProcessor = new SimulateTransactionProcessor(SpecProvider, StateProvider, VirtualMachine, CodeInfoRepository, _logManager, validate); _blockValidator = CreateValidator(); BlockTransactionPicker = new BlockProductionTransactionPicker(specProvider, true); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTransactionProcessor.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTransactionProcessor.cs new file mode 100644 index 00000000000..79499458247 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTransactionProcessor.cs @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Evm; +using Nethermind.Evm.Tracing; +using Nethermind.Evm.TransactionProcessing; +using Nethermind.Logging; +using Nethermind.State; + +namespace Nethermind.Facade.Simulate; + +public class SimulateTransactionProcessor( + ISpecProvider? specProvider, + IWorldState? worldState, + IVirtualMachine? virtualMachine, + ICodeInfoRepository? codeInfoRepository, + ILogManager? logManager, + bool validate) + : TransactionProcessor(specProvider, worldState, virtualMachine, codeInfoRepository, logManager), ITransactionProcessor +{ + protected override TransactionResult Execute(Transaction tx, in BlockExecutionContext blCtx, ITxTracer tracer, ExecutionOptions opts) + { + if (!validate) + { + opts |= ExecutionOptions.NoValidation; + } + + return base.Execute(tx, in blCtx, tracer, opts); + } +} From 997ea5530c89d57b4ce44c7e7ae8990b0504b0fb Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 23:20:02 +0200 Subject: [PATCH 188/213] Bring back AnalyseInBackgroundIfRequired --- .../Nethermind.Evm/CodeInfoRepository.cs | 4 +++- .../Nethermind.Evm/VirtualMachine.cs | 19 ++++--------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs index 91272ffbf52..86994afd7d5 100644 --- a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -84,6 +84,7 @@ public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IR } cachedCodeInfo = new CodeInfo(code); + cachedCodeInfo.AnalyseInBackgroundIfRequired(); _codeCache.Set(codeHash, cachedCodeInfo); } else @@ -119,7 +120,8 @@ public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) public void InsertCode(IWorldState state, ReadOnlyMemory code, Address codeOwner, IReleaseSpec spec) { - var codeInfo = new CodeInfo(code); + CodeInfo codeInfo = new(code); + codeInfo.AnalyseInBackgroundIfRequired(); // Start generating the JumpDestinationBitmap in background. ThreadPool.UnsafeQueueUserWorkItem(codeInfo, preferLocal: false); diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 63c63e2d4df..860e73d274a 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -6,24 +6,18 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using Nethermind.Core; -using Nethermind.Core.Caching; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Evm.CodeAnalysis; using Nethermind.Evm.Precompiles; -using Nethermind.Evm.Precompiles.Bls; -using Nethermind.Evm.Precompiles.Snarks; using Nethermind.Evm.Tracing; using Nethermind.Logging; using Nethermind.State; using System.Diagnostics.CodeAnalysis; -using System.Diagnostics; using System.Runtime.Intrinsics; -using Nethermind.Core.Collections; using static Nethermind.Evm.VirtualMachine; using static System.Runtime.CompilerServices.Unsafe; -using ValueHash256 = Nethermind.Core.Crypto.ValueHash256; #if DEBUG using Nethermind.Evm.Tracing.Debugger; @@ -33,11 +27,6 @@ namespace Nethermind.Evm; -using System.Collections.Frozen; -using System.Linq; -using System.Runtime.InteropServices; -using System.Threading; - using Int256; public class VirtualMachine : IVirtualMachine @@ -51,20 +40,20 @@ public class VirtualMachine : IVirtualMachine internal static readonly byte[] BytesZero = { 0 }; internal static readonly byte[] BytesZero32 = - { + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; + ]; internal static readonly byte[] BytesMax32 = - { + [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - }; + ]; private readonly IVirtualMachine _evm; From 8b3757270255c41513e2a9a6f26ca0e17e6f73b3 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 23:22:36 +0200 Subject: [PATCH 189/213] fix --- src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs index 86994afd7d5..228fb7a9f44 100644 --- a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -122,8 +122,6 @@ public void InsertCode(IWorldState state, ReadOnlyMemory code, Address cod { CodeInfo codeInfo = new(code); codeInfo.AnalyseInBackgroundIfRequired(); - // Start generating the JumpDestinationBitmap in background. - ThreadPool.UnsafeQueueUserWorkItem(codeInfo, preferLocal: false); Hash256 codeHash = code.Length == 0 ? Keccak.OfAnEmptyString : Keccak.Compute(code.Span); state.InsertCode(codeOwner, codeHash, code, spec); From a72a6a8e5ed69392b20101e1924108f0e4d3da6c Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Tue, 14 May 2024 23:29:30 +0200 Subject: [PATCH 190/213] revert format --- .../TransactionSubstateTests.cs | 222 ++---------------- .../Nethermind.Evm/VirtualMachine.cs | 10 +- 2 files changed, 19 insertions(+), 213 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs index 5289830c09b..3b44d847768 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionSubstateTests.cs @@ -17,81 +17,14 @@ public class TransactionSubstateTests public void should_return_proper_revert_error_when_there_is_no_exception() { byte[] data = - [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x20, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x5, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09 - ]; + { + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5, + 0x05, 0x06, 0x07, 0x08, 0x09 + }; ReadOnlyMemory readOnlyMemory = new(data); TransactionSubstate transactionSubstate = new(readOnlyMemory, 0, @@ -229,140 +162,13 @@ public void should_return_proper_revert_error_when_using_special_functions((byte public void should_return_proper_revert_error_when_revert_custom_error() { byte[] data = - [ - 0x22, - 0x02, - 0x66, - 0xb6, // Keccak of `FailedOp(uint256,string)` == 0x220266b6 - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, + { + 0x22, 0x02, 0x66, 0xb6, // Keccak of `FailedOp(uint256,string)` == 0x220266b6 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, - 0x41, - 0x41, - 0x32, - 0x31, - 0x20, - 0x64, - 0x69, - 0x64, - 0x6e, - 0x27, - 0x74, - 0x20, - 0x70, - 0x61, - 0x79, - 0x20, - 0x70, - 0x72, - 0x65, - 0x66, - 0x75, - 0x6e, - 0x64, // "AA21 didn't pay prefund" - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 - ]; + 0x41, 0x41, 0x32, 0x31, 0x20, 0x64, 0x69, 0x64, 0x6e, 0x27, 0x74, 0x20, 0x70, 0x61, 0x79, 0x20, 0x70, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, // "AA21 didn't pay prefund" + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; ReadOnlyMemory readOnlyMemory = new(data); TransactionSubstate transactionSubstate = new( readOnlyMemory, diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 860e73d274a..26910a72692 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -37,23 +37,23 @@ public class VirtualMachine : IVirtualMachine internal static readonly UInt256 BigInt256 = 256; internal static readonly UInt256 BigInt32 = 32; - internal static readonly byte[] BytesZero = { 0 }; + internal static readonly byte[] BytesZero = [0]; internal static readonly byte[] BytesZero32 = - [ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; + }; internal static readonly byte[] BytesMax32 = - [ + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - ]; + }; private readonly IVirtualMachine _evm; From 0acf045373beefba5d84d1bb5910c2dd0ed7461d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 16 May 2024 06:30:21 +0100 Subject: [PATCH 191/213] Review updates --- .../Nethermind.Evm/VirtualMachine.cs | 5 +- .../Eth/Simulate/EthSimulateTestsHiveBase.cs | 550 ++---------------- .../Modules/Eth/SimulateTxExecutor.cs | 4 +- .../Nethermind.Serialization.Rlp/Rlp.cs | 14 +- 4 files changed, 62 insertions(+), 511 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 63c63e2d4df..7be299f9f09 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -2123,6 +2123,9 @@ private EvmExceptionType InstructionCall( !UpdateMemoryCost(vmState, ref gasAvailable, in outputOffset, outputLength) || !UpdateGas(gasExtra, ref gasAvailable)) return EvmExceptionType.OutOfGas; + CodeInfo codeInfo = _codeInfoRepository.GetCachedCodeInfo(_worldState, codeSource, spec); + codeInfo.AnalyseInBackgroundIfRequired(); + if (spec.Use63Over64Rule) { gasLimit = UInt256.Min((UInt256)(gasAvailable - gasAvailable / 64), gasLimit); @@ -2166,8 +2169,6 @@ private EvmExceptionType InstructionCall( Snapshot snapshot = _worldState.TakeSnapshot(); _state.SubtractFromBalance(caller, transferValue, spec); - CodeInfo codeInfo = _codeInfoRepository.GetCachedCodeInfo(_worldState, codeSource, spec); - codeInfo.AnalyseInBackgroundIfRequired(); ExecutionEnvironment callEnv = new ( txExecutionContext: in env.TxExecutionContext, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs index 14cad67e745..023a526c3d7 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs @@ -15,503 +15,67 @@ namespace Nethermind.JsonRpc.Test.Modules.Eth; public class EthSimulateTestsHiveBase { - [Test] - public async Task TestsimulateAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit() - { - EthereumJsonSerializer serializer = new(); - var input = - "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; - SimulatePayload? payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateAddMoreNonDefinedBlockStateCallsThanFitButNowWithFit"); + private static readonly object[] HiveTestCases = + { +new object[] {"multicall-add-more-non-defined-BlockStateCalls-than-fit-but-now-with-fit", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0xa\"}, \"stateOverrides\": {\"0xc100000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x\"}]}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x\"}]}, {\"blockOverrides\": {\"number\": \"0x14\"}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x\"}]}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x\"}]}]}"}, +new object[] {"multicall-basefee-too-low-without-validation-38012", "{\"blockStateCalls\": [{\"blockOverrides\": {\"baseFeePerGas\": \"0xa\"}, \"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}}, \"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"maxFeePerGas\": \"0x0\", \"maxPriorityFeePerGas\": \"0x0\"}]}]}"}, +new object[] {"multicall-block-override-reflected-in-contract-simple", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0xa\", \"time\": \"0x64\"}}, {\"blockOverrides\": {\"number\": \"0x14\", \"time\": \"0x65\"}}, {\"blockOverrides\": {\"number\": \"0x15\", \"time\": \"0xc8\"}}]}"}, +new object[] {"multicall-block-timestamps-incrementing", "{\"blockStateCalls\": [{\"blockOverrides\": {\"time\": \"0xb\"}}, {\"blockOverrides\": {\"time\": \"0xc\"}}]}"}, +new object[] {"multicall-blockhash-complex", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0xa\"}, \"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x1e8480\"}, \"0xc200000000000000000000000000000000000000\": {\"code\": \"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}]}, {\"blockOverrides\": {\"number\": \"0x14\"}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e000000000000000000000000000000000000000000000000000000000000000a\"}]}, {\"blockOverrides\": {\"number\": \"0x1e\"}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e000000000000000000000000000000000000000000000000000000000000001d\"}]}]}"}, +new object[] {"multicall-blockhash-simple", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc200000000000000000000000000000000000000\": {\"code\": \"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}]}]}"}, +new object[] {"multicall-blockhash-start-before-head", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0xa\"}, \"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x1e8480\"}, \"0xc200000000000000000000000000000000000000\": {\"code\": \"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000002\"}]}, {\"blockOverrides\": {\"number\": \"0x14\"}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000013\"}]}]}"}, +new object[] {"multicall-check-that-balance-is-there-after-new-block", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x2710\"}, \"0xc200000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}]}"}, +new object[] {"multicall-contract-calls-itself", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc000000000000000000000000000000000000000\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-empty-calls-and-overrides-multicall", "{\"blockStateCalls\": [{\"stateOverrides\": {}, \"calls\": [{}]}, {\"stateOverrides\": {}, \"calls\": [{}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-eth-send-should-not-produce-logs-by-default", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}]}"}, +new object[] {"multicall-eth-send-should-not-produce-logs-on-revert", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}, \"0xc100000000000000000000000000000000000000\": {\"code\": \"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-eth-send-should-produce-logs", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-eth-send-should-produce-more-logs-on-forward", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}, \"0xc100000000000000000000000000000000000000\": {\"code\": \"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\", \"input\": \"0x4b64e4920000000000000000000000000000000000000000000000000000000000000100\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-eth-send-should-produce-no-logs-on-forward-revert", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}, \"0xc100000000000000000000000000000000000000\": {\"code\": \"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"}, \"0xc200000000000000000000000000000000000000\": {\"code\": \"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\", \"input\": \"0x4b64e492c200000000000000000000000000000000000000000000000000000000000000\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-get-block-properties", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc100000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x\"}]}]}"}, +new object[] {"multicall-instrict-gas-38013", "{\"blockStateCalls\": [{\"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"gas\": \"0x0\"}]}]}"}, +new object[] {"multicall-logs", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc200000000000000000000000000000000000000\": {\"code\": \"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80600080a1600080f3\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x6057361d0000000000000000000000000000000000000000000000000000000000000005\"}]}]}"}, +new object[] {"multicall-move-account-twice", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x3e8\"}, \"0xc200000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}, \"0xc300000000000000000000000000000000000000\": {\"balance\": \"0xbb8\"}, \"0xc400000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}}}, {\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0xbb8\", \"MovePrecompileToAddress\": \"0xc200000000000000000000000000000000000000\"}, \"0xc200000000000000000000000000000000000000\": {\"balance\": \"0xfa0\", \"MovePrecompileToAddress\": \"0xc300000000000000000000000000000000000000\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc400000000000000000000000000000000000000\", \"input\": \"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc400000000000000000000000000000000000000\", \"input\": \"0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc400000000000000000000000000000000000000\", \"input\": \"0xf8b2cb4f000000000000000000000000c300000000000000000000000000000000000000\"}]}]}"}, +new object[] {"multicall-move-ecrecover-and-call", "{\"blockStateCalls\": [{\"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000001\", \"input\": \"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000001\", \"input\": \"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}]}, {\"stateOverrides\": {\"0x0000000000000000000000000000000000000001\": {\"MovePrecompileToAddress\": \"0x0000000000000000000000000000000000123456\"}}, \"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000123456\", \"input\": \"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000123456\", \"input\": \"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}]}]}"}, +new object[] {"multicall-move-to-address-itself-reference-38022", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x30d40\"}, \"0xc100000000000000000000000000000000000000\": {\"MovePrecompileToAddress\": \"0xc100000000000000000000000000000000000000\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x1\"}]}]}"}, +new object[] {"multicall-move-two-accounts-to-same-38023", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0x0000000000000000000000000000000000000001\": {\"MovePrecompileToAddress\": \"0xc200000000000000000000000000000000000000\"}, \"0x0000000000000000000000000000000000000002\": {\"MovePrecompileToAddress\": \"0xc200000000000000000000000000000000000000\"}}}]}"}, +new object[] {"multicall-move-two-non-precompiles-accounts-to-same", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0x0100000000000000000000000000000000000000\": {\"MovePrecompileToAddress\": \"0xc200000000000000000000000000000000000000\"}, \"0x0200000000000000000000000000000000000000\": {\"MovePrecompileToAddress\": \"0xc200000000000000000000000000000000000000\"}}}]}"}, +new object[] {"multicall-no-fields-call", "{\"blockStateCalls\": [{\"calls\": [{}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-only-from-to-transaction", "{\"blockStateCalls\": [{\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-only-from-transaction", "{\"blockStateCalls\": [{\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-override-address-twice-in-separate-BlockStateCalls", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}, {\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-override-all-in-BlockStateCalls", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0x3e9\", \"time\": \"0x3eb\", \"gasLimit\": \"0x3ec\", \"feeRecipient\": \"0xc200000000000000000000000000000000000000\", \"prevRandao\": \"0xc300000000000000000000000000000000000000000000000000000000000000\", \"baseFeePerGas\": \"0x3ef\"}}]}"}, +new object[] {"multicall-override-block-num", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0xb\"}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"input\": \"0x4360005260206000f3\"}]}, {\"blockOverrides\": {\"number\": \"0xc\"}, \"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x4360005260206000f3\"}]}]}"}, +new object[] {"multicall-override-ecrecover", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0x0000000000000000000000000000000000000001\": {\"code\": \"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\", \"MovePrecompileToAddress\": \"0x0000000000000000000000000000000000123456\"}, \"0xc100000000000000000000000000000000000000\": {\"balance\": \"0x30d40\"}}, \"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000123456\", \"input\": \"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000123456\", \"input\": \"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000001\", \"input\": \"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000001\", \"input\": \"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000001\", \"input\": \"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000001\", \"input\": \"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}"}, +new object[] {"multicall-override-identity", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0x0000000000000000000000000000000000000004\": {\"code\": \"0x\", \"MovePrecompileToAddress\": \"0x0000000000000000000000000000000000123456\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000123456\", \"input\": \"0x1234\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000004\", \"input\": \"0x1234\"}]}]}"}, +new object[] {"multicall-override-sha256", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0x0000000000000000000000000000000000000002\": {\"code\": \"0x\", \"MovePrecompileToAddress\": \"0x0000000000000000000000000000000000123456\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000123456\", \"input\": \"0x1234\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000002\", \"input\": \"0x1234\"}]}]}"}, +new object[] {"multicall-override-storage-slots", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}, \"0xc100000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80630ff4c916146100515780633033413b1461008157806344e12f871461009f5780637b8d56e3146100bd575b600080fd5b61006b600480360381019061006691906101f6565b6100d9565b6040516100789190610232565b60405180910390f35b61008961013f565b6040516100969190610232565b60405180910390f35b6100a7610145565b6040516100b49190610232565b60405180910390f35b6100d760048036038101906100d2919061024d565b61014b565b005b60006002821061011e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610115906102ea565b60405180910390fd5b6000820361012c5760005490505b6001820361013a5760015490505b919050565b60015481565b60005481565b6002821061018e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610185906102ea565b60405180910390fd5b600082036101a257806000819055506101b7565b600182036101b657806001819055506101b7565b5b5050565b600080fd5b6000819050919050565b6101d3816101c0565b81146101de57600080fd5b50565b6000813590506101f0816101ca565b92915050565b60006020828403121561020c5761020b6101bb565b5b600061021a848285016101e1565b91505092915050565b61022c816101c0565b82525050565b60006020820190506102476000830184610223565b92915050565b60008060408385031215610264576102636101bb565b5b6000610272858286016101e1565b9250506020610283858286016101e1565b9150509250929050565b600082825260208201905092915050565b7f746f6f2062696720736c6f740000000000000000000000000000000000000000600082015250565b60006102d4600c8361028d565b91506102df8261029e565b602082019050919050565b60006020820190508181036000830152610303816102c7565b905091905056fea2646970667358221220ceea194bb66b5b9f52c83e5bf5a1989255de8cb7157838eff98f970c3a04cb3064736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x7b8d56e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x7b8d56e300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x0ff4c9160000000000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x0ff4c9160000000000000000000000000000000000000000000000000000000000000001\"}]}, {\"stateOverrides\": {\"0xc100000000000000000000000000000000000000\": {\"stateDiff\": {\"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0x1200000000000000000000000000000000000000000000000000000000000000\"}}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x0ff4c9160000000000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x0ff4c9160000000000000000000000000000000000000000000000000000000000000001\"}]}, {\"stateOverrides\": {\"0xc100000000000000000000000000000000000000\": {\"state\": {\"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0x1200000000000000000000000000000000000000000000000000000000000000\"}}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x0ff4c9160000000000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x0ff4c9160000000000000000000000000000000000000000000000000000000000000001\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-precompile-is-sending-transaction", "{\"blockStateCalls\": [{\"calls\": [{\"from\": \"0x0000000000000000000000000000000000000004\", \"to\": \"0x0000000000000000000000000000000000000002\", \"input\": \"0x1234\"}]}]}"}, +new object[] {"multicall-run-gas-spending", "{\"blockStateCalls\": [{\"blockOverrides\": {\"gasLimit\": \"0x16e360\"}, \"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x1e8480\"}, \"0xc200000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063815b8ab414610030575b600080fd5b61004a600480360381019061004591906100b6565b61004c565b005b60005a90505b60011561007657815a826100669190610112565b106100715750610078565b610052565b505b50565b600080fd5b6000819050919050565b61009381610080565b811461009e57600080fd5b50565b6000813590506100b08161008a565b92915050565b6000602082840312156100cc576100cb61007b565b5b60006100da848285016100a1565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061011d82610080565b915061012883610080565b92508282039050818111156101405761013f6100e3565b5b9291505056fea2646970667358221220a659ba4db729a6ee4db02fcc5c1118db53246b0e5e686534fc9add6f2e93faec64736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x815b8ab40000000000000000000000000000000000000000000000000000000000000000\"}]}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x815b8ab40000000000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240\"}]}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x815b8ab40000000000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240\"}]}]}"}, +new object[] {"multicall-run-out-of-gas-in-block-38015", "{\"blockStateCalls\": [{\"blockOverrides\": {\"gasLimit\": \"0x16e360\"}, \"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x1e8480\"}, \"0xc200000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063815b8ab414610030575b600080fd5b61004a600480360381019061004591906100b6565b61004c565b005b60005a90505b60011561007657815a826100669190610112565b106100715750610078565b610052565b505b50565b600080fd5b6000819050919050565b61009381610080565b811461009e57600080fd5b50565b6000813590506100b08161008a565b92915050565b6000602082840312156100cc576100cb61007b565b5b60006100da848285016100a1565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061011d82610080565b915061012883610080565b92508282039050818111156101405761013f6100e3565b5b9291505056fea2646970667358221220a659ba4db729a6ee4db02fcc5c1118db53246b0e5e686534fc9add6f2e93faec64736f6c63430008120033\"}}}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240\"}]}]}"}, +new object[] {"multicall-self-destructing-state-override", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc200000000000000000000000000000000000000\": {\"code\": \"0x6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033\"}, \"0xc300000000000000000000000000000000000000\": {\"code\": \"0x73000000000000000000000000000000000000000030146080604052600436106100355760003560e01c8063dce4a4471461003a575b600080fd5b610054600480360381019061004f91906100f8565b61006a565b60405161006191906101b5565b60405180910390f35b6060813b6040519150601f19601f602083010116820160405280825280600060208401853c50919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100c58261009a565b9050919050565b6100d5816100ba565b81146100e057600080fd5b50565b6000813590506100f2816100cc565b92915050565b60006020828403121561010e5761010d610095565b5b600061011c848285016100e3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561015f578082015181840152602081019050610144565b60008484015250505050565b6000601f19601f8301169050919050565b600061018782610125565b6101918185610130565b93506101a1818560208601610141565b6101aa8161016b565b840191505092915050565b600060208201905081810360008301526101cf818461017c565b90509291505056fea26469706673582212206a5f0cd9f230619fa520fc4b9d4b518643258cad412f2fa33945ce528b4b895164736f6c63430008120033\"}}}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc300000000000000000000000000000000000000\", \"input\": \"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x83197ef0\"}]}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc300000000000000000000000000000000000000\", \"input\": \"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]}, {\"stateOverrides\": {\"0xc200000000000000000000000000000000000000\": {\"code\": \"0x6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033\"}}}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc300000000000000000000000000000000000000\", \"input\": \"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]}]}"}, +new object[] {"multicall-self-destructive-contract-produces-logs", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc200000000000000000000000000000000000000\": {\"code\": \"0x6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033\", \"balance\": \"0x1e8480\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x83197ef0\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-set-read-storage", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc200000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x6057361d0000000000000000000000000000000000000000000000000000000000000005\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0x2e64cec1\"}]}]}"}, +new object[] {"multicall-simple", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x3e8\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}]}"}, +new object[] {"multicall-simple-send-from-contract", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"code\": \"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\", \"balance\": \"0x3e8\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-simple-state-diff", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}, \"0xc100000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80630ff4c916146100515780633033413b1461008157806344e12f871461009f5780637b8d56e3146100bd575b600080fd5b61006b600480360381019061006691906101f6565b6100d9565b6040516100789190610232565b60405180910390f35b61008961013f565b6040516100969190610232565b60405180910390f35b6100a7610145565b6040516100b49190610232565b60405180910390f35b6100d760048036038101906100d2919061024d565b61014b565b005b60006002821061011e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610115906102ea565b60405180910390fd5b6000820361012c5760005490505b6001820361013a5760015490505b919050565b60015481565b60005481565b6002821061018e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610185906102ea565b60405180910390fd5b600082036101a257806000819055506101b7565b600182036101b657806001819055506101b7565b5b5050565b600080fd5b6000819050919050565b6101d3816101c0565b81146101de57600080fd5b50565b6000813590506101f0816101ca565b92915050565b60006020828403121561020c5761020b6101bb565b5b600061021a848285016101e1565b91505092915050565b61022c816101c0565b82525050565b60006020820190506102476000830184610223565b92915050565b60008060408385031215610264576102636101bb565b5b6000610272858286016101e1565b9250506020610283858286016101e1565b9150509250929050565b600082825260208201905092915050565b7f746f6f2062696720736c6f740000000000000000000000000000000000000000600082015250565b60006102d4600c8361028d565b91506102df8261029e565b602082019050919050565b60006020820190508181036000830152610303816102c7565b905091905056fea2646970667358221220ceea194bb66b5b9f52c83e5bf5a1989255de8cb7157838eff98f970c3a04cb3064736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x7b8d56e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x7b8d56e300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002\"}]}, {\"stateOverrides\": {\"0xc100000000000000000000000000000000000000\": {\"state\": {\"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0x1200000000000000000000000000000000000000000000000000000000000000\"}}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x0ff4c9160000000000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x0ff4c9160000000000000000000000000000000000000000000000000000000000000001\"}]}], \"traceTransfers\": true}"}, +new object[] {"multicall-simple-with-validation-no-funds", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x3e8\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}]}"}, +new object[] {"multicall-transaction-too-high-nonce", "{\"blockStateCalls\": [{\"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"nonce\": \"0x64\"}]}]}"}, +new object[] {"multicall-transaction-too-low-nonce-38010", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"nonce\": \"0xa\"}}, \"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"nonce\": \"0x0\"}]}]}"}, +}; + + [Test, TestCaseSource(nameof(HiveTestCases)), Parallelizable(ParallelScope.All)] + public async Task TestsimulateHive(string name, string data) + { + EthereumJsonSerializer serializer = new(); + SimulatePayload? payload = serializer.Deserialize>(data); + TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); + Console.WriteLine($"current test: {name}"); ResultWrapper> result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateAddMoreNonDefinedBlockStateCallsThanFit() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]},{\"blockOverrides\":{\"number\":\"0xb\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateAddMoreNonDefinedBlockStateCallsThanFit"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); - Assert.That(result.Result.Error!.Contains("number out of order")); - } - - [Test] - public async Task TestsimulateBasefeeTooLowWithValidation38012() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0x0\",\"maxPriorityFeePerGas\":\"0x0\"}]}],\"validation\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBasefeeTooLowWithValidation38012"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); - Assert.That(result.Result.Error!.Contains("Transaction cost (40000000) is higher than sender balance (2000)")); - - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateBasefeeTooLowWithoutValidation38012() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"baseFeePerGas\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"maxFeePerGas\":\"0x0\",\"maxPriorityFeePerGas\":\"0x0\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBasefeeTooLowWithoutValidation38012"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateBlockNumOrder38020() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xc\"},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]},{\"blockOverrides\":{\"number\":\"0xb\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBlockNumOrder38020"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); - Assert.That(result.Result.Error!.Contains("Block number out of order")); - } - - [Test] - public async Task TestsimulateBlockOverrideReflectedInContractSimple() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\",\"time\":\"0x64\"}},{\"blockOverrides\":{\"number\":\"0x14\",\"time\":\"0x65\"}},{\"blockOverrides\":{\"number\":\"0x15\",\"time\":\"0xc8\"}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBlockOverrideReflectedInContractSimple"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - - - [Test] - public async Task TestsimulateBlockTimestampAutoIncrement() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xb\"}},{\"blockOverrides\":{}},{\"blockOverrides\":{\"time\":\"0xc\"}},{\"blockOverrides\":{}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBlockTimestampAutoIncrement"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); - Assert.That(result.Result.Error!.Contains("Block timestamp out of order")); - } - - - [Test] - public async Task TestsimulateBlockTimestampsIncrementing() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"time\":\"0xb\"}},{\"blockOverrides\":{\"time\":\"0xc\"}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBlockTimestampsIncrementing"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateBlockhashComplex() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000010\"}]},{\"blockOverrides\":{\"number\":\"0x1e\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e000000000000000000000000000000000000000000000000000000000000001d\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBlockhashComplex"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateBlockhashSimple() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBlockhashSimple"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateBlockhashStartBeforeHead() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xa\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000002\"}]},{\"blockOverrides\":{\"number\":\"0x14\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000013\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateBlockhashStartBeforeHead"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - - [Test] - public async Task TestsimulateCheckThatBalanceIsThereAfterNewBlock() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x2710\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c100000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateCheckThatBalanceIsThereAfterNewBlock"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - - - [Test] - public async Task TestsimulateEmptyCallsAndOverrides() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{},\"calls\":[{}]},{\"stateOverrides\":{},\"calls\":[{}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateEmptyCallsAndOverrides"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateEthSendShouldNotProduceLogsByDefault() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateEthSendShouldNotProduceLogsByDefault"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateEthSendShouldNotProduceLogsOnRevert() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateEthSendShouldNotProduceLogsOnRevert"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateEthSendShouldProduceLogs() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateEthSendShouldProduceLogs"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateEthSendShouldProduceMoreLogsOnForward() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"input\":\"0x4b64e4920000000000000000000000000000000000000000000000000000000000000100\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateEthSendShouldProduceMoreLogsOnForward"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateEthSendShouldProduceNoLogsOnForwardRevert() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405260006042576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401603990609d565b60405180910390fd5b005b600082825260208201905092915050565b7f416c7761797320726576657274696e6720636f6e747261637400000000000000600082015250565b600060896019836044565b91506092826055565b602082019050919050565b6000602082019050818103600083015260b481607e565b905091905056fea264697066735822122005cbbbc709291f66fadc17416c1b0ed4d72941840db11468a21b8e1a0362024c64736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\",\"input\":\"0x4b64e492c200000000000000000000000000000000000000000000000000000000000000\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateEthSendShouldProduceNoLogsOnForwardRevert"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - - - - - - [Test] - public async Task TestsimulateGetBlockProperties() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc100000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateGetBlockProperties"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - - [Test] - public async Task TestsimulateLogs() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80600080a1600080f3\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x6057361d0000000000000000000000000000000000000000000000000000000000000005\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateLogs"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateMoveAccountTwice() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x3e8\"},\"0xc200000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"},\"0xc300000000000000000000000000000000000000\":{\"balance\":\"0xbb8\"},\"0xc400000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f8b2cb4f14610030575b600080fd5b61004a600480360381019061004591906100e4565b610060565b604051610057919061012a565b60405180910390f35b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100b182610086565b9050919050565b6100c1816100a6565b81146100cc57600080fd5b50565b6000813590506100de816100b8565b92915050565b6000602082840312156100fa576100f9610081565b5b6000610108848285016100cf565b91505092915050565b6000819050919050565b61012481610111565b82525050565b600060208201905061013f600083018461011b565b9291505056fea2646970667358221220172c443a163d8a43e018c339d1b749c312c94b6de22835953d960985daf228c764736f6c63430008120033\"}}},{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0xbb8\",\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"},\"0xc200000000000000000000000000000000000000\":{\"balance\":\"0xfa0\",\"MovePrecompileToAddress\":\"0xc300000000000000000000000000000000000000\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc400000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c000000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc400000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c200000000000000000000000000000000000000\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc400000000000000000000000000000000000000\",\"input\":\"0xf8b2cb4f000000000000000000000000c300000000000000000000000000000000000000\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateMoveAccountTwice"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateMoveEcrecoverAndCall() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}]},{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateMoveEcrecoverAndCall"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateMoveToAddressItselfReference38022() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"},\"0xc100000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc100000000000000000000000000000000000000\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x1\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateMoveToAddressItselfReference38022"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - [Test] - public async Task TestsimulateMoveTwoAccountsToSame38023() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"},\"0x0000000000000000000000000000000000000002\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"}}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateMoveTwoAccountsToSame38023"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); + Console.WriteLine(); Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); Assert.IsNotNull(result.Data); } - - [Test] - public async Task TestsimulateMoveTwoNonPrecompilesAccountsToSame() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0100000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"},\"0x0200000000000000000000000000000000000000\":{\"MovePrecompileToAddress\":\"0xc200000000000000000000000000000000000000\"}}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateMoveTwoNonPrecompilesAccountsToSame"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateOverrideAddressTwiceInSeparateBlockStateCalls() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]},{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateOverrideAddressTwiceInSeparateBlockStateCalls"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - - - [Test] - public async Task TestsimulateOverrideAllInBlockStateCalls() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0x3e9\",\"time\":\"0x3eb\",\"gasLimit\":\"0x3ec\",\"feeRecipient\":\"0xc200000000000000000000000000000000000000\",\"prevRandao\":\"0xc300000000000000000000000000000000000000000000000000000000000000\",\"baseFeePerGas\":\"0x3ef\"}}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateOverrideAllInBlockStateCalls"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateOverrideBlockNum() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"number\":\"0xb\"},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]},{\"blockOverrides\":{\"number\":\"0xc\"},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"input\":\"0x4360005260206000f3\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateOverrideBlockNum"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateOverrideEcrecover() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"},\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateOverrideEcrecover"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateOverrideIdentity() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000004\":{\"code\":\"0x\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1234\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000004\",\"input\":\"0x1234\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateOverrideIdentity"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateOverrideSha256() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000002\":{\"code\":\"0x\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1234\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000002\",\"input\":\"0x1234\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateOverrideSha256"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulatePrecompileIsSendingTransaction() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"calls\":[{\"from\":\"0x0000000000000000000000000000000000000004\",\"to\":\"0x0000000000000000000000000000000000000002\",\"input\":\"0x1234\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulatePrecompileIsSendingTransaction"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateRunOutOfGasInBlock38015() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"blockOverrides\":{\"gasLimit\":\"0x16e360\"},\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x1e8480\"},\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063815b8ab414610030575b600080fd5b61004a600480360381019061004591906100b6565b61004c565b005b60005a90505b60011561007657815a826100669190610112565b106100715750610078565b610052565b505b50565b600080fd5b6000819050919050565b61009381610080565b811461009e57600080fd5b50565b6000813590506100b08161008a565b92915050565b6000602082840312156100cc576100cb61007b565b5b60006100da848285016100a1565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061011d82610080565b915061012883610080565b92508282039050818111156101405761013f6100e3565b5b9291505056fea2646970667358221220a659ba4db729a6ee4db02fcc5c1118db53246b0e5e686534fc9add6f2e93faec64736f6c63430008120033\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x815b8ab400000000000000000000000000000000000000000000000000000000000f4240\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateRunOutOfGasInBlock38015"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateSelfDestructingStateOverride() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033\"},\"0xc300000000000000000000000000000000000000\":{\"code\":\"0x73000000000000000000000000000000000000000030146080604052600436106100355760003560e01c8063dce4a4471461003a575b600080fd5b610054600480360381019061004f91906100f8565b61006a565b60405161006191906101b5565b60405180910390f35b6060813b6040519150601f19601f602083010116820160405280825280600060208401853c50919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100c58261009a565b9050919050565b6100d5816100ba565b81146100e057600080fd5b50565b6000813590506100f2816100cc565b92915050565b60006020828403121561010e5761010d610095565b5b600061011c848285016100e3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561015f578082015181840152602081019050610144565b60008484015250505050565b6000601f19601f8301169050919050565b600061018782610125565b6101918185610130565b93506101a1818560208601610141565b6101aa8161016b565b840191505092915050565b600060208201905081810360008301526101cf818461017c565b90509291505056fea26469706673582212206a5f0cd9f230619fa520fc4b9d4b518643258cad412f2fa33945ce528b4b895164736f6c63430008120033\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"input\":\"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x83197ef0\"}]},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"input\":\"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]},{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x6080604052348015600f57600080fd5b506004361060285760003560e01c806383197ef014602d575b600080fd5b60336035565b005b600073ffffffffffffffffffffffffffffffffffffffff16fffea26469706673582212208e566fde20a17fff9658b9b1db37e27876fd8934ccf9b2aa308cabd37698681f64736f6c63430008120033\"}}},{\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"input\":\"0xdce4a447000000000000000000000000c200000000000000000000000000000000000000\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateSelfDestructingStateOverride"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateSetReadStorage() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc200000000000000000000000000000000000000\":{\"code\":\"0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x6057361d0000000000000000000000000000000000000000000000000000000000000005\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"input\":\"0x2e64cec1\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateSetReadStorage"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - - [Test] - public async Task TestsimulateSimpleSendFromContract() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"code\":\"0x60806040526004361061001e5760003560e01c80634b64e49214610023575b600080fd5b61003d6004803603810190610038919061011f565b61003f565b005b60008173ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050509050806100b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100af906101a9565b60405180910390fd5b5050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100ec826100c1565b9050919050565b6100fc816100e1565b811461010757600080fd5b50565b600081359050610119816100f3565b92915050565b600060208284031215610135576101346100bc565b5b60006101438482850161010a565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b600061019360148361014c565b915061019e8261015d565b602082019050919050565b600060208201905081810360008301526101c281610186565b905091905056fea2646970667358221220563acd6f5b8ad06a3faf5c27fddd0ecbc198408b99290ce50d15c2cf7043694964736f6c63430008120033\",\"balance\":\"0x3e8\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}],\"traceTransfers\":true}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateSimpleSendFromContract"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Success)); - Assert.IsNotNull(result.Data); - } - - [Test] - public async Task TestsimulateTransferOverBlockStateCalls() - { - EthereumJsonSerializer serializer = new(); - string input = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0xc000000000000000000000000000000000000000\":{\"balance\":\"0x7d0\"}},\"calls\":[{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc100000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc000000000000000000000000000000000000000\",\"to\":\"0xc300000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]},{\"stateOverrides\":{\"0xc300000000000000000000000000000000000000\":{\"balance\":\"0x0\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"},{\"from\":\"0xc300000000000000000000000000000000000000\",\"to\":\"0xc200000000000000000000000000000000000000\",\"value\":\"0x3e8\"}]}]}"; - var payload = serializer.Deserialize>(input); - TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); - Console.WriteLine("current test: simulateTransferOverBlockStateCalls"); - var result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); - Assert.That(result.Result.ResultType, Is.EqualTo(ResultType.Failure)); - } - } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index 327c6676bc7..f10e1ea16fe 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -88,8 +88,6 @@ public override ResultWrapper> Execute( BlockHeader header = searchResult.Object.Header; - if (blockParameter?.Type == BlockParameterType.Latest) header = _blockFinder.FindLatestBlock()?.Header; - if (!_blockchainBridge.HasStateForBlock(header!)) return ResultWrapper>.Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable); @@ -186,7 +184,7 @@ protected override ResultWrapper> Execute(Blo { SimulateOutput results = _blockchainBridge.Simulate(header, tx, token); - if (results.Error != null && (results.Error.Contains("invalid transaction") + if (results.Error is not null && (results.Error.Contains("invalid transaction") || results.Error.Contains("InsufficientBalanceException"))) results.ErrorCode = ErrorCodes.InvalidTransaction; diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs b/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs index 102c558489c..db2f9b225fb 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs @@ -1083,18 +1083,6 @@ private static void ThrowInvalidPrefix(ref ValueDecoderContext ctx, int prefix) throw new RlpException($"Unexpected prefix of {prefix} when decoding {nameof(Hash256)} at position {ctx.Position} in the message of length {ctx.Data.Length} starting with {ctx.Data[..Math.Min(DebugMessageContentLength, ctx.Data.Length)].ToHexString()}"); } - public static bool IsAllZeroes(ReadOnlySpan byteSpan) - { - foreach (byte b in byteSpan) - { - if (b != 0) - { - return false; - } - } - return true; - } - public UInt256 DecodeUInt256(int length = -1) { ReadOnlySpan byteSpan = DecodeByteArraySpan(); @@ -1105,7 +1093,7 @@ public UInt256 DecodeUInt256(int length = -1) if (length == -1) { - if (IsAllZeroes(byteSpan)) + if (byteSpan.IndexOfAnyExcept((byte)0) == -1) { return 0; } From 77fda4b752d58def6543bc710b850fbd481b7c14 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 16 May 2024 06:54:03 +0100 Subject: [PATCH 192/213] Minor fixes --- src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs | 3 --- src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs | 2 -- .../Simulate/SimulateReadOnlyBlocksProcessingEnv.cs | 1 - .../Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs | 1 + 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs b/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs index d58629e367e..c16834f63a8 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTreeOverlay.cs @@ -109,9 +109,6 @@ public IOwnedReadOnlyList FindHeaders(Hash256 hash, int numberOfBlo return overlayHeaders.Count > 0 ? overlayHeaders : _baseTree.FindHeaders(hash, numberOfBlocks, skip, reverse); } - public BlockHeader FindLowestCommonAncestor(BlockHeader firstDescendant, BlockHeader secondDescendant, long maxSearchDepth) => - _overlayTree.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth) ?? _baseTree.FindLowestCommonAncestor(firstDescendant, secondDescendant, maxSearchDepth); - public void DeleteInvalidBlock(Block invalidBlock) => _overlayTree.DeleteInvalidBlock(invalidBlock); diff --git a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs index 228fb7a9f44..645c18b0ce2 100644 --- a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -90,8 +90,6 @@ public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IR else { Db.Metrics.CodeDbCache++; - // need to touch code so that any collectors that track database access are informed - worldState.TouchCode(codeHash); } return cachedCodeInfo; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index cec15e2db50..2fdee0e5fb1 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -113,7 +113,6 @@ public IBlockProcessor GetProcessor(Hash256 stateRoot, bool validate) => : new SimulateBlockValidationTransactionsExecutor(_transactionProcessor, StateProvider), StateProvider, NullReceiptStorage.Instance, - NullWitnessCollector.Instance, new BlockhashStore(BlockTree, SpecProvider, StateProvider), _logManager); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs index 734d3518209..18414abbc10 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs @@ -66,6 +66,7 @@ public async Task Test_eth_simulate_create() //Check results byte[]? returnData = result.Data[0].Calls.First().ReturnData; + Assert.IsNotNull(returnData); } From 1ac41f5a469bdcb0da7c3f496c48038c44e4070e Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Fri, 17 May 2024 04:21:48 +0100 Subject: [PATCH 193/213] review RLP fixes Story of how how 1 line fix turns into performance optimisation when done wright... --- .../Simulate/SimulateDictionaryBlockStore.cs | 194 ++++++++++++++++++ .../Simulate/SimulateDictionaryHeaderStore.cs | 80 ++++++++ ...ulateReadOnlyBlocksProcessingEnvFactory.cs | 11 +- .../Nethermind.Serialization.Rlp/Rlp.cs | 5 - 4 files changed, 281 insertions(+), 9 deletions(-) create mode 100644 src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs create mode 100644 src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs new file mode 100644 index 00000000000..4890fc3d0e3 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs @@ -0,0 +1,194 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Buffers; +using System.Collections; +using System.Collections.Generic; +using Nethermind.Blockchain.Blocks; +using Nethermind.Core; +using Nethermind.Core.Buffers; +using Nethermind.Core.Crypto; +using Nethermind.Serialization.Rlp; + +namespace Nethermind.Facade.Simulate; + +public class SimulateDictionaryBlockStore : IBlockStore +{ + public class StructuralByteArrayComparer : IEqualityComparer + { + public bool Equals(byte[] x, byte[] y) + { + return StructuralComparisons.StructuralEqualityComparer.Equals(x, y); + } + + public int GetHashCode(byte[] obj) + { + return StructuralComparisons.StructuralEqualityComparer.GetHashCode(obj); + } + } + + + public class CappedArrayMemoryManager : MemoryManager + { + private readonly CappedArray _data; + private bool _isDisposed; + + public CappedArrayMemoryManager(CappedArray? data) + { + _data = data ?? throw new ArgumentNullException(nameof(data)); + _isDisposed = false; + } + + public override Span GetSpan() + { + if (_isDisposed) + { + throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); + } + + return _data.AsSpan(); + } + + public override MemoryHandle Pin(int elementIndex = 0) + { + if (_isDisposed) + { + throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); + } + + if (elementIndex < 0 || elementIndex >= _data.Length) + { + throw new ArgumentOutOfRangeException(nameof(elementIndex)); + } + // Pinning is a no-op in this managed implementation + return new MemoryHandle(); + } + + public override void Unpin() + { + if (_isDisposed) + { + throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); + } + // Unpinning is a no-op in this managed implementation + } + + protected override void Dispose(bool disposing) + { + _isDisposed = true; + } + + protected override bool TryGetArray(out ArraySegment segment) + { + if (_isDisposed) + { + throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); + } + + segment = new ArraySegment(_data.ToArray() ?? throw new InvalidOperationException()); + return true; + } + } + + private readonly IBlockStore _readonlyBaseBlockStore; + private readonly Dictionary _blockDict = new(); + private readonly Dictionary> _blockNumDict = new(); + private readonly Dictionary _metadataDict = new(new StructuralByteArrayComparer()); + private readonly BlockDecoder _blockDecoder = new(); + + public SimulateDictionaryBlockStore(IBlockStore readonlyBaseBlockStore) + { + _readonlyBaseBlockStore = readonlyBaseBlockStore; + } + + public void Insert(Block block, WriteFlags writeFlags = WriteFlags.None) + { + _blockDict[block.Hash] = block; + if (!_blockNumDict.ContainsKey(block.Number)) + { + _blockNumDict[block.Number] = new Dictionary(); + } + _blockNumDict[block.Number][block.Hash] = block; + } + + public void Delete(long blockNumber, Hash256 blockHash) + { + _blockDict.Remove(blockHash); + if (_blockNumDict.ContainsKey(blockNumber)) + { + _blockNumDict[blockNumber].Remove(blockHash); + if (_blockNumDict[blockNumber].Count == 0) + { + _blockNumDict.Remove(blockNumber); + } + } + _readonlyBaseBlockStore.Delete(blockNumber, blockHash); + } + + public Block? Get(long blockNumber, Hash256 blockHash, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = true) + { + if (_blockNumDict.TryGetValue(blockNumber, out var blockDict) && blockDict.TryGetValue(blockHash, out var block)) + { + return block; + } + + block = _readonlyBaseBlockStore.Get(blockNumber, blockHash, rlpBehaviors, shouldCache); + if (block != null && shouldCache) + { + Cache(block); + } + return block; + } + + public byte[]? GetRaw(long blockNumber, Hash256 blockHash) + { + if (_blockNumDict.TryGetValue(blockNumber, out var blockDict) && blockDict.TryGetValue(blockHash, out var block)) + { + using NettyRlpStream newRlp = _blockDecoder.EncodeToNewNettyStream(block); + return newRlp.AsSpan().ToArray(); + } + return _readonlyBaseBlockStore.GetRaw(blockNumber, blockHash); + } + + public IEnumerable GetAll() + { + var allBlocks = new HashSet(_readonlyBaseBlockStore.GetAll()); + foreach (var block in _blockDict.Values) + { + allBlocks.Add(block); + } + return allBlocks; + } + + public ReceiptRecoveryBlock? GetReceiptRecoveryBlock(long blockNumber, Hash256 blockHash) + { + if (_blockNumDict.TryGetValue(blockNumber, out var blockDict) && blockDict.TryGetValue(blockHash, out var block)) + { + using NettyRlpStream newRlp = _blockDecoder.EncodeToNewNettyStream(block); + using var memoryManager = new CappedArrayMemoryManager(newRlp.Data); + return BlockDecoder.DecodeToReceiptRecoveryBlock(memoryManager, memoryManager.Memory, RlpBehaviors.None); + } + return _readonlyBaseBlockStore.GetReceiptRecoveryBlock(blockNumber, blockHash); + } + + public void Cache(Block block) + { + Insert(block); + } + + public void SetMetadata(byte[] key, byte[] value) + { + _metadataDict[key] = value; + _readonlyBaseBlockStore.SetMetadata(key, value); + } + + public byte[]? GetMetadata(byte[] key) + { + if (_metadataDict.TryGetValue(key, out var value)) + { + return value; + } + return _readonlyBaseBlockStore.GetMetadata(key); + } +} diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs new file mode 100644 index 00000000000..045a87033d8 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using Nethermind.Blockchain.Headers; +using Nethermind.Core; +using Nethermind.Core.Crypto; + +namespace Nethermind.Facade.Simulate; + +/// +/// This type is needed for two things: +/// - Bypass issue of networking compatibility and RLPs not supporting BaseFeePerGas of 0 +/// - Improve performance to get faster local caching without re-encoding of data in Simulate blocks +/// +/// +public class SimulateDictionaryHeaderStore(IHeaderStore readonlyBaseHeaderStore) : IHeaderStore +{ + // SyncProgressResolver MaxLookupBack is 256, add 16 wiggle room + public const int CacheSize = 256 + 16; + + private readonly Dictionary _headerDict = new(); + private readonly Dictionary _blockNumberDict = new(); + + public void Insert(BlockHeader header) + { + _headerDict[header.Hash] = header; + InsertBlockNumber(header.Hash, header.Number); + } + + public BlockHeader? Get(Hash256 blockHash, bool shouldCache = false, long? blockNumber = null) + { + if (blockNumber == null) + { + blockNumber = GetBlockNumber(blockHash); + } + + if (blockNumber.HasValue && _headerDict.TryGetValue(blockHash, out var header)) + { + if (shouldCache) + { + Cache(header); + } + return header; + } + + header = readonlyBaseHeaderStore.Get(blockHash, shouldCache, blockNumber); + if (header != null && shouldCache) + { + Cache(header); + } + return header; + } + + public void Cache(BlockHeader header) + { + Insert(header); + } + + public void Delete(Hash256 blockHash) + { + _headerDict.Remove(blockHash); + _blockNumberDict.Remove(blockHash); + } + + public void InsertBlockNumber(Hash256 blockHash, long blockNumber) + { + _blockNumberDict[blockHash] = blockNumber; + } + + public long? GetBlockNumber(Hash256 blockHash) + { + if (_blockNumberDict.TryGetValue(blockHash, out var blockNumber)) + { + return blockNumber; + } + + return readonlyBaseHeaderStore.GetBlockNumber(blockHash); + } +} diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs index 9aefb1675fc..70052a49fb6 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs @@ -42,13 +42,16 @@ public SimulateReadOnlyBlocksProcessingEnv Create(bool traceTransfers, bool vali private static BlockTree CreateTempBlockTree(IReadOnlyDbProvider readOnlyDbProvider, ISpecProvider? specProvider, ILogManager? logManager, IReadOnlyDbProvider editableDbProvider) { - IBlockStore blockStore = new BlockStore(editableDbProvider.BlocksDb); - IHeaderStore headerStore = new HeaderStore(editableDbProvider.HeadersDb, editableDbProvider.BlockNumbersDb); + IBlockStore mainblockStore = new BlockStore(editableDbProvider.BlocksDb); + IHeaderStore mainHeaderStore = new HeaderStore(editableDbProvider.HeadersDb, editableDbProvider.BlockNumbersDb); + SimulateDictionaryHeaderStore tmpHeaderStore = new(mainHeaderStore); const int badBlocksStored = 1; + + SimulateDictionaryBlockStore tmpBlockStore = new(mainblockStore); IBlockStore badBlockStore = new BlockStore(editableDbProvider.BadBlocksDb, badBlocksStored); - return new(blockStore, - headerStore, + return new(tmpBlockStore, + tmpHeaderStore, editableDbProvider.BlockInfosDb, editableDbProvider.MetadataDb, badBlockStore, diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs b/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs index db2f9b225fb..923cb54f74f 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/Rlp.cs @@ -1093,11 +1093,6 @@ public UInt256 DecodeUInt256(int length = -1) if (length == -1) { - if (byteSpan.IndexOfAnyExcept((byte)0) == -1) - { - return 0; - } - if (byteSpan.Length > 1 && byteSpan[0] == 0) { ThrowNonCanonicalUInt256(Position); From dc24c3350561e1bd353acdbff32693a952c46cc4 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Fri, 17 May 2024 06:04:40 +0100 Subject: [PATCH 194/213] integrating SecondsPerSlot --- src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs | 6 +++++- .../Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs | 3 ++- .../Modules/BoundedModulePoolTests.cs | 4 +++- .../Eth/EthSimulateTestsPrecompilesWithRedirection.cs | 5 +++-- .../Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs | 7 ++++--- .../Modules/SingletonModulePoolTests.cs | 4 +++- .../Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs | 7 ++++--- .../Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs | 7 +++++-- .../Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs | 7 +++++-- .../Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs | 7 +++---- 10 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs index 3833df511bf..5638c4304d4 100644 --- a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs +++ b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Nethermind.Api; using Nethermind.Blockchain.FullPruning; +using Nethermind.Config; using Nethermind.Core; using Nethermind.Init.Steps.Migrations; using Nethermind.JsonRpc; @@ -79,6 +80,8 @@ public virtual async Task Execute(CancellationToken cancellationToken) IInitConfig initConfig = _api.Config(); IJsonRpcConfig rpcConfig = _api.Config(); INetworkConfig networkConfig = _api.Config(); + IBlocksConfig blockConfig = _api.Config(); + ulong SecondsPerSlot = blockConfig.SecondsPerSlot; // lets add threads to support parallel eth_getLogs ThreadPool.GetMinThreads(out int workerThreads, out int completionPortThreads); @@ -104,7 +107,8 @@ public virtual async Task Execute(CancellationToken cancellationToken) _api.ReceiptStorage, _api.GasPriceOracle, _api.EthSyncingInfo, - feeHistoryOracle); + feeHistoryOracle, + SecondsPerSlot); RpcLimits.Init(rpcConfig.RequestQueueLimit); rpcModuleProvider.RegisterBounded(ethModuleFactory, rpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, rpcConfig.Timeout); diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index de43a030073..246c6052c22 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -166,7 +166,8 @@ TransactionProcessor transactionProcessor specProvider, gasPriceOracle, ethSyncingInfo, - feeHistoryOracle); + feeHistoryOracle, + new BlocksConfig().SecondsPerSlot); } [Benchmark] diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs index 341c574c4dd..5a09f99127e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Synchronization; +using Nethermind.Config; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Db; @@ -56,7 +57,8 @@ public Task Initialize() Substitute.For(), Substitute.For(), Substitute.For(), - Substitute.For()), + Substitute.For(), + new BlocksConfig().SecondsPerSlot), 1, 1000); return Task.CompletedTask; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs index 18414abbc10..f6155a88301 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading.Tasks; using Nethermind.Blockchain.Find; +using Nethermind.Config; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; @@ -60,7 +61,7 @@ public async Task Test_eth_simulate_create() }; //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); @@ -177,7 +178,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( }; //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); Debug.Assert(contractAddress is not null, nameof(contractAddress) + " != null"); Assert.IsTrue(chain.State.AccountExists(contractAddress)); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 4f3bb344d17..07107bb2e9f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using FluentAssertions; using Nethermind.Blockchain.Find; +using Nethermind.Config; using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; @@ -74,7 +75,7 @@ public async Task Test_eth_simulate_serialisation() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; Assert.That(data.Count, Is.EqualTo(7)); @@ -147,7 +148,7 @@ public async Task Test_eth_simulate_eth_moved() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; @@ -227,7 +228,7 @@ public async Task Test_eth_simulate_transactions_forced_fail() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig()); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs index bc06fd5cb57..1ffb4b32cdb 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs @@ -24,6 +24,7 @@ using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Modules.Eth.FeeHistory; using Nethermind.JsonRpc.Modules.Eth.GasPrice; +using Nethermind.Config; namespace Nethermind.JsonRpc.Test.Modules { @@ -55,7 +56,8 @@ public Task Initialize() Substitute.For(), Substitute.For(), Substitute.For(), - Substitute.For()); + Substitute.For(), + new BlocksConfig().SecondsPerSlot); return Task.CompletedTask; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 18e85f49476..6fba1d025d9 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -127,7 +127,6 @@ protected override async Task Build( roBlockTree, SpecProvider, LimboLogs.Instance); - SimulateReadOnlyBlocksProcessingEnvFactory simulateProcessingEnvFactory = new SimulateReadOnlyBlocksProcessingEnvFactory( WorldStateManager, roBlockTree, @@ -135,8 +134,9 @@ protected override async Task Build( SpecProvider, LimboLogs.Instance); + BlocksConfig blocksConfig = new BlocksConfig(); ReceiptFinder ??= ReceiptStorage; - Bridge ??= new BlockchainBridge(processingEnv, simulateProcessingEnvFactory, TxPool, ReceiptFinder, filterStore, filterManager, EthereumEcdsa, Timestamper, LogFinder, SpecProvider, new BlocksConfig(), false); + Bridge ??= new BlockchainBridge(processingEnv, simulateProcessingEnvFactory, TxPool, ReceiptFinder, filterStore, filterManager, EthereumEcdsa, Timestamper, LogFinder, SpecProvider, blocksConfig, false); BlockFinder ??= BlockTree; GasPriceOracle ??= new GasPriceOracle(BlockFinder, SpecProvider, LogManager); @@ -160,7 +160,8 @@ protected override async Task Build( GasPriceOracle, new EthSyncingInfo(BlockTree, ReceiptStorage, syncConfig, new StaticSelector(SyncMode.All), Substitute.For(), LogManager), - FeeHistoryOracle); + FeeHistoryOracle, + blocksConfig.SecondsPerSlot); return this; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs index 7f174d89081..e2901e4af0f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs @@ -17,6 +17,7 @@ using Nethermind.Wallet; using System.Text.Json; using System.Text.Json.Serialization; +using Nethermind.Config; namespace Nethermind.JsonRpc.Modules.Eth { @@ -33,7 +34,8 @@ public class EthModuleFactory( IReceiptStorage receiptStorage, IGasPriceOracle gasPriceOracle, IEthSyncingInfo ethSyncingInfo, - IFeeHistoryOracle feeHistoryOracle) + IFeeHistoryOracle feeHistoryOracle, + ulong secondsPerSlot) : ModuleFactoryBase { private readonly IReadOnlyBlockTree _blockTree = blockTree.AsReadOnly(); @@ -65,7 +67,8 @@ public override IEthRpcModule Create() _specProvider, _gasPriceOracle, _ethSyncingInfo, - _feeHistoryOracle); + _feeHistoryOracle, + secondsPerSlot); } } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 9b49572026e..697cdcfff90 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -56,6 +56,7 @@ public partial class EthRpcModule : IEthRpcModule private readonly IEthSyncingInfo _ethSyncingInfo; private readonly IFeeHistoryOracle _feeHistoryOracle; + private readonly ulong _secondsPerSlot; public EthRpcModule( IJsonRpcConfig rpcConfig, @@ -70,7 +71,8 @@ public EthRpcModule( ISpecProvider specProvider, IGasPriceOracle gasPriceOracle, IEthSyncingInfo ethSyncingInfo, - IFeeHistoryOracle feeHistoryOracle) + IFeeHistoryOracle feeHistoryOracle, + ulong secondsPerSlot) { _logger = logManager.GetClassLogger(); _rpcConfig = rpcConfig ?? throw new ArgumentNullException(nameof(rpcConfig)); @@ -85,6 +87,7 @@ public EthRpcModule( _gasPriceOracle = gasPriceOracle ?? throw new ArgumentNullException(nameof(gasPriceOracle)); _ethSyncingInfo = ethSyncingInfo ?? throw new ArgumentNullException(nameof(ethSyncingInfo)); _feeHistoryOracle = feeHistoryOracle ?? throw new ArgumentNullException(nameof(feeHistoryOracle)); + _secondsPerSlot = secondsPerSlot; } public ResultWrapper eth_protocolVersion() @@ -341,7 +344,7 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa .ExecuteTx(transactionCall, blockParameter); public ResultWrapper> eth_simulateV1(SimulatePayload payload, BlockParameter? blockParameter = null) => - new SimulateTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) + new SimulateTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig, _secondsPerSlot) .Execute(payload, blockParameter); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index f10e1ea16fe..f4b6398f6c6 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -15,11 +15,10 @@ namespace Nethermind.JsonRpc.Modules.Eth; -public class SimulateTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig, IBlocksConfig? blocksConfig = null) +public class SimulateTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig, ulong _secondsPerSlot) : ExecutorBase, SimulatePayload, SimulatePayload>(blockchainBridge, blockFinder, rpcConfig) { - private readonly ulong _interBlocksTimings = (blocksConfig ?? new BlocksConfig()).SecondsPerSlot; private readonly long _blocksLimit = rpcConfig.MaxSimulateBlocksCap ?? 256; private long _gasCapBudget = rpcConfig.GasCap ?? long.MaxValue; @@ -127,8 +126,8 @@ public override ResultWrapper> Execute( ulong givenTime = blockToSimulate.BlockOverrides.Time ?? (lastBlockTime == 0 - ? header.Timestamp + _interBlocksTimings - : lastBlockTime + _interBlocksTimings); + ? header.Timestamp + _secondsPerSlot + : lastBlockTime + _secondsPerSlot); if (givenTime > lastBlockTime) { From c3923f35d9f634a1d131caa1775a3a1491171b43 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 23 May 2024 11:16:32 +0100 Subject: [PATCH 195/213] merge fixes --- .../Nethermind.Init/Steps/RegisterRpcModules.cs | 11 ++++++++--- .../Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs | 6 ++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs index 65ca222d4d9..a0080be3390 100644 --- a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs +++ b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs @@ -73,8 +73,7 @@ public virtual async Task Execute(CancellationToken cancellationToken) IInitConfig initConfig = _api.Config(); INetworkConfig networkConfig = _api.Config(); - IBlocksConfig blockConfig = _api.Config(); - ulong SecondsPerSlot = blockConfig.SecondsPerSlot; + // lets add threads to support parallel eth_getLogs ThreadPool.GetMinThreads(out int workerThreads, out int completionPortThreads); @@ -227,9 +226,14 @@ protected virtual ModuleFactoryBase CreateEthModuleFactory() StepDependencyException.ThrowIfNull(_api.StateReader); StepDependencyException.ThrowIfNull(_api.GasPriceOracle); StepDependencyException.ThrowIfNull(_api.EthSyncingInfo); + StepDependencyException.ThrowIfNull(_api.EthSyncingInfo); var feeHistoryOracle = new FeeHistoryOracle(_api.BlockTree, _api.ReceiptStorage, _api.SpecProvider); _api.DisposeStack.Push(feeHistoryOracle); + + IBlocksConfig blockConfig = _api.Config(); + ulong secondsPerSlot = blockConfig.SecondsPerSlot; + return new EthModuleFactory( _api.TxPool, _api.TxSender, @@ -243,6 +247,7 @@ protected virtual ModuleFactoryBase CreateEthModuleFactory() _api.ReceiptStorage, _api.GasPriceOracle, _api.EthSyncingInfo, - feeHistoryOracle); + feeHistoryOracle, + secondsPerSlot); } } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs index 2246e8fc29a..d1acce0336c 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs @@ -10,6 +10,7 @@ using Nethermind.Facade; using Nethermind.Facade.Eth; using Nethermind.Facade.Filters; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Client; @@ -185,6 +186,11 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa return _ethRpcModule.eth_call(transactionCall, blockParameter); } + public ResultWrapper> eth_simulateV1(SimulatePayload payload, BlockParameter? blockParameter = null) + { + return _ethRpcModule.eth_simulateV1(payload, blockParameter); + } + public ResultWrapper eth_estimateGas(TransactionForRpc transactionCall, BlockParameter? blockParameter = null) { return _ethRpcModule.eth_estimateGas(transactionCall, blockParameter); From f3c405663ea12614a00e7b82a0b0975adf2b146d Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Thu, 23 May 2024 12:18:14 +0100 Subject: [PATCH 196/213] minor review fixes --- .../CappedArrayMemoryManager.cs | 63 ++++++++ .../Simulate/SimulateDictionaryBlockStore.cs | 136 +++--------------- .../Simulate/SimulateDictionaryHeaderStore.cs | 19 +-- ...SimulateTestsPrecompilesWithRedirection.cs | 2 +- .../Modules/Eth/SimulateTxExecutor.cs | 8 +- 5 files changed, 94 insertions(+), 134 deletions(-) create mode 100644 src/Nethermind/Nethermind.Core/CappedArrayMemoryManager.cs diff --git a/src/Nethermind/Nethermind.Core/CappedArrayMemoryManager.cs b/src/Nethermind/Nethermind.Core/CappedArrayMemoryManager.cs new file mode 100644 index 00000000000..4b10e5c63bb --- /dev/null +++ b/src/Nethermind/Nethermind.Core/CappedArrayMemoryManager.cs @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Buffers; + +namespace Nethermind.Core.Buffers; + +public class CappedArrayMemoryManager(CappedArray? data) : MemoryManager +{ + private readonly CappedArray _data = data ?? throw new ArgumentNullException(nameof(data)); + private bool _isDisposed; + + public override Span GetSpan() + { + if (_isDisposed) + { + throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); + } + + return _data.AsSpan(); + } + + public override MemoryHandle Pin(int elementIndex = 0) + { + if (_isDisposed) + { + throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); + } + + if (elementIndex < 0 || elementIndex >= _data.Length) + { + throw new ArgumentOutOfRangeException(nameof(elementIndex)); + } + // Pinning is a no-op in this managed implementation + return new MemoryHandle(); + } + + public override void Unpin() + { + if (_isDisposed) + { + throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); + } + // Unpinning is a no-op in this managed implementation + } + + protected override void Dispose(bool disposing) + { + _isDisposed = true; + } + + protected override bool TryGetArray(out ArraySegment segment) + { + if (_isDisposed) + { + throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); + } + + segment = new ArraySegment(_data.ToArray() ?? throw new InvalidOperationException()); + return true; + } +} diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs index 4890fc3d0e3..e0000897a08 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs @@ -1,140 +1,44 @@ // SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; -using System.Buffers; -using System.Collections; using System.Collections.Generic; using Nethermind.Blockchain.Blocks; using Nethermind.Core; using Nethermind.Core.Buffers; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Serialization.Rlp; namespace Nethermind.Facade.Simulate; -public class SimulateDictionaryBlockStore : IBlockStore +public class SimulateDictionaryBlockStore(IBlockStore readonlyBaseBlockStore) : IBlockStore { - public class StructuralByteArrayComparer : IEqualityComparer - { - public bool Equals(byte[] x, byte[] y) - { - return StructuralComparisons.StructuralEqualityComparer.Equals(x, y); - } - - public int GetHashCode(byte[] obj) - { - return StructuralComparisons.StructuralEqualityComparer.GetHashCode(obj); - } - } - - - public class CappedArrayMemoryManager : MemoryManager - { - private readonly CappedArray _data; - private bool _isDisposed; - - public CappedArrayMemoryManager(CappedArray? data) - { - _data = data ?? throw new ArgumentNullException(nameof(data)); - _isDisposed = false; - } - - public override Span GetSpan() - { - if (_isDisposed) - { - throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); - } - - return _data.AsSpan(); - } - - public override MemoryHandle Pin(int elementIndex = 0) - { - if (_isDisposed) - { - throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); - } - - if (elementIndex < 0 || elementIndex >= _data.Length) - { - throw new ArgumentOutOfRangeException(nameof(elementIndex)); - } - // Pinning is a no-op in this managed implementation - return new MemoryHandle(); - } - - public override void Unpin() - { - if (_isDisposed) - { - throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); - } - // Unpinning is a no-op in this managed implementation - } - - protected override void Dispose(bool disposing) - { - _isDisposed = true; - } - - protected override bool TryGetArray(out ArraySegment segment) - { - if (_isDisposed) - { - throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); - } - - segment = new ArraySegment(_data.ToArray() ?? throw new InvalidOperationException()); - return true; - } - } - - private readonly IBlockStore _readonlyBaseBlockStore; - private readonly Dictionary _blockDict = new(); - private readonly Dictionary> _blockNumDict = new(); - private readonly Dictionary _metadataDict = new(new StructuralByteArrayComparer()); + private readonly Dictionary _blockDict = new(); + private readonly Dictionary _blockNumDict = new(); + private readonly Dictionary _metadataDict = new(Bytes.EqualityComparer); private readonly BlockDecoder _blockDecoder = new(); - public SimulateDictionaryBlockStore(IBlockStore readonlyBaseBlockStore) - { - _readonlyBaseBlockStore = readonlyBaseBlockStore; - } - public void Insert(Block block, WriteFlags writeFlags = WriteFlags.None) { _blockDict[block.Hash] = block; - if (!_blockNumDict.ContainsKey(block.Number)) - { - _blockNumDict[block.Number] = new Dictionary(); - } - _blockNumDict[block.Number][block.Hash] = block; + _blockNumDict[block.Number] = block; } public void Delete(long blockNumber, Hash256 blockHash) { _blockDict.Remove(blockHash); - if (_blockNumDict.ContainsKey(blockNumber)) - { - _blockNumDict[blockNumber].Remove(blockHash); - if (_blockNumDict[blockNumber].Count == 0) - { - _blockNumDict.Remove(blockNumber); - } - } - _readonlyBaseBlockStore.Delete(blockNumber, blockHash); + _blockNumDict.Remove(blockNumber); } public Block? Get(long blockNumber, Hash256 blockHash, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = true) { - if (_blockNumDict.TryGetValue(blockNumber, out var blockDict) && blockDict.TryGetValue(blockHash, out var block)) + if (_blockNumDict.TryGetValue(blockNumber, out Block block)) { return block; } - block = _readonlyBaseBlockStore.Get(blockNumber, blockHash, rlpBehaviors, shouldCache); - if (block != null && shouldCache) + block = readonlyBaseBlockStore.Get(blockNumber, blockHash, rlpBehaviors, false); + if (block is not null && shouldCache) { Cache(block); } @@ -143,18 +47,18 @@ public void Delete(long blockNumber, Hash256 blockHash) public byte[]? GetRaw(long blockNumber, Hash256 blockHash) { - if (_blockNumDict.TryGetValue(blockNumber, out var blockDict) && blockDict.TryGetValue(blockHash, out var block)) + if (_blockNumDict.TryGetValue(blockNumber, out Block block)) { using NettyRlpStream newRlp = _blockDecoder.EncodeToNewNettyStream(block); return newRlp.AsSpan().ToArray(); } - return _readonlyBaseBlockStore.GetRaw(blockNumber, blockHash); + return readonlyBaseBlockStore.GetRaw(blockNumber, blockHash); } public IEnumerable GetAll() { - var allBlocks = new HashSet(_readonlyBaseBlockStore.GetAll()); - foreach (var block in _blockDict.Values) + var allBlocks = new HashSet(readonlyBaseBlockStore.GetAll()); + foreach (Block? block in _blockDict.Values) { allBlocks.Add(block); } @@ -163,13 +67,13 @@ public IEnumerable GetAll() public ReceiptRecoveryBlock? GetReceiptRecoveryBlock(long blockNumber, Hash256 blockHash) { - if (_blockNumDict.TryGetValue(blockNumber, out var blockDict) && blockDict.TryGetValue(blockHash, out var block)) + if (_blockNumDict.TryGetValue(blockNumber, out Block block)) { using NettyRlpStream newRlp = _blockDecoder.EncodeToNewNettyStream(block); using var memoryManager = new CappedArrayMemoryManager(newRlp.Data); return BlockDecoder.DecodeToReceiptRecoveryBlock(memoryManager, memoryManager.Memory, RlpBehaviors.None); } - return _readonlyBaseBlockStore.GetReceiptRecoveryBlock(blockNumber, blockHash); + return readonlyBaseBlockStore.GetReceiptRecoveryBlock(blockNumber, blockHash); } public void Cache(Block block) @@ -180,15 +84,11 @@ public void Cache(Block block) public void SetMetadata(byte[] key, byte[] value) { _metadataDict[key] = value; - _readonlyBaseBlockStore.SetMetadata(key, value); + readonlyBaseBlockStore.SetMetadata(key, value); } public byte[]? GetMetadata(byte[] key) { - if (_metadataDict.TryGetValue(key, out var value)) - { - return value; - } - return _readonlyBaseBlockStore.GetMetadata(key); + return _metadataDict.TryGetValue(key, out var value) ? value : readonlyBaseBlockStore.GetMetadata(key); } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs index 045a87033d8..f7f52dc858b 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs @@ -19,8 +19,8 @@ public class SimulateDictionaryHeaderStore(IHeaderStore readonlyBaseHeaderStore) // SyncProgressResolver MaxLookupBack is 256, add 16 wiggle room public const int CacheSize = 256 + 16; - private readonly Dictionary _headerDict = new(); - private readonly Dictionary _blockNumberDict = new(); + private readonly Dictionary _headerDict = new(); + private readonly Dictionary _blockNumberDict = new(); public void Insert(BlockHeader header) { @@ -30,12 +30,12 @@ public void Insert(BlockHeader header) public BlockHeader? Get(Hash256 blockHash, bool shouldCache = false, long? blockNumber = null) { - if (blockNumber == null) + if (blockNumber is null) { blockNumber = GetBlockNumber(blockHash); } - if (blockNumber.HasValue && _headerDict.TryGetValue(blockHash, out var header)) + if (blockNumber.HasValue && _headerDict.TryGetValue(blockHash, out BlockHeader? header)) { if (shouldCache) { @@ -44,8 +44,8 @@ public void Insert(BlockHeader header) return header; } - header = readonlyBaseHeaderStore.Get(blockHash, shouldCache, blockNumber); - if (header != null && shouldCache) + header = readonlyBaseHeaderStore.Get(blockHash, false, blockNumber); + if (header is not null && shouldCache) { Cache(header); } @@ -70,11 +70,6 @@ public void InsertBlockNumber(Hash256 blockHash, long blockNumber) public long? GetBlockNumber(Hash256 blockHash) { - if (_blockNumberDict.TryGetValue(blockHash, out var blockNumber)) - { - return blockNumber; - } - - return readonlyBaseHeaderStore.GetBlockNumber(blockHash); + return _blockNumberDict.TryGetValue(blockHash, out var blockNumber) ? blockNumber : readonlyBaseHeaderStore.GetBlockNumber(blockHash); } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs index f6155a88301..3022a76aab8 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs @@ -180,7 +180,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); - Debug.Assert(contractAddress is not null, nameof(contractAddress) + " != null"); + Debug.Assert(contractAddress is not null, nameof(contractAddress) + " is not null"); Assert.IsTrue(chain.State.AccountExists(contractAddress)); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index f4b6398f6c6..30e3fc4a2b5 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -15,7 +15,7 @@ namespace Nethermind.JsonRpc.Modules.Eth; -public class SimulateTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig, ulong _secondsPerSlot) +public class SimulateTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig, ulong? secondsPerSlot = null) : ExecutorBase, SimulatePayload, SimulatePayload>(blockchainBridge, blockFinder, rpcConfig) { @@ -96,6 +96,8 @@ public override ResultWrapper> Execute( $"Too many blocks provided, node is configured to simulate up to {_blocksLimit} while {call.BlockStateCalls?.Count} were given", ErrorCodes.InvalidParams); + secondsPerSlot ??= new BlocksConfig().SecondsPerSlot; + if (call.BlockStateCalls is not null) { long lastBlockNumber = -1; @@ -126,8 +128,8 @@ public override ResultWrapper> Execute( ulong givenTime = blockToSimulate.BlockOverrides.Time ?? (lastBlockTime == 0 - ? header.Timestamp + _secondsPerSlot - : lastBlockTime + _secondsPerSlot); + ? header.Timestamp + secondsPerSlot.Value + : lastBlockTime + secondsPerSlot.Value); if (givenTime > lastBlockTime) { From 88fea582c43ede002ad882fe8e3e376e0c3d0fb8 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Tue, 28 May 2024 21:21:25 +0100 Subject: [PATCH 197/213] minor clean-up --- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 3 ++- src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index a76f7ba4f90..cfd7231690c 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -24,7 +24,8 @@ protected ReadOnlyTxProcessingEnvBase( ISpecProvider? specProvider, ILogManager? logManager, PreBlockCaches? preBlockCaches = null - ) { + ) + { ArgumentNullException.ThrowIfNull(specProvider); ArgumentNullException.ThrowIfNull(worldStateManager); SpecProvider = specProvider; diff --git a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs index 6aad769f04f..beb7c487049 100644 --- a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -53,7 +53,7 @@ public bool Set(in ValueHash256 codeHash, CodeInfo codeInfo) } -private static readonly FrozenDictionary _precompiles; + private static readonly FrozenDictionary _precompiles; private static readonly LruCache _codeCache = new(MemoryAllowance.CodeCacheSize, MemoryAllowance.CodeCacheSize, "VM bytecodes"); static CodeInfoRepository() From 9db68366a7a774515f7796d9e6a41ff1b9f17db3 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 29 May 2024 10:07:41 +0200 Subject: [PATCH 198/213] minor cleanup --- .../Processing/ReadOnlyTxProcessingEnvFactory.cs | 6 +++--- .../Simulate/SimulateReadOnlyBlocksProcessingEnv.cs | 1 - .../Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs | 1 - src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs | 4 ++-- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvFactory.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvFactory.cs index fc4d288193b..d4d7423c129 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvFactory.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvFactory.cs @@ -12,18 +12,18 @@ namespace Nethermind.Consensus.Processing; public class ReadOnlyTxProcessingEnvFactory( IWorldStateManager worldStateManager, - IReadOnlyBlockTree? readOnlyBlockTree, + IReadOnlyBlockTree readOnlyBlockTree, ISpecProvider? specProvider, ILogManager? logManager, PreBlockCaches? preBlockCaches = null) { public ReadOnlyTxProcessingEnvFactory( IWorldStateManager worldStateManager, - IBlockTree? blockTree, + IBlockTree blockTree, ISpecProvider? specProvider, ILogManager? logManager, PreBlockCaches? preBlockCaches = null) - : this(worldStateManager, blockTree?.AsReadOnly(), specProvider, logManager, preBlockCaches) + : this(worldStateManager, blockTree.AsReadOnly(), specProvider, logManager, preBlockCaches) { } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index f1072d2e48f..9f01db4f72d 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -46,7 +46,6 @@ public class SimulateReadOnlyBlocksProcessingEnv : ReadOnlyTxProcessingEnvBase, private readonly TransactionProcessor _transactionProcessor; public SimulateReadOnlyBlocksProcessingEnv( - bool traceTransfers, IWorldStateManager worldStateManager, IReadOnlyBlockTree baseBlockTree, IReadOnlyDbProvider readOnlyDbProvider, diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs index 70052a49fb6..01dae6c7003 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs @@ -30,7 +30,6 @@ public SimulateReadOnlyBlocksProcessingEnv Create(bool traceTransfers, bool vali BlockTree tempBlockTree = CreateTempBlockTree(editableDbProvider, specProvider, logManager, editableDbProvider); return new SimulateReadOnlyBlocksProcessingEnv( - traceTransfers, overlayWorldStateManager, baseBlockTree, editableDbProvider, diff --git a/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs b/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs index 449d3fb8843..bf94ae165ad 100644 --- a/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs +++ b/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs @@ -26,9 +26,9 @@ public class OverlayWorldStateManager( public IReadOnlyTrieStore TrieStore { get; } = overlayTrieStore.AsReadOnly(); - public IWorldState CreateResettableWorldState(PreBlockCaches? pbc = null) + public IWorldState CreateResettableWorldState(PreBlockCaches? sharedHashes = null) { - return new WorldState(overlayTrieStore, _codeDb, logManager, pbc); + return new WorldState(overlayTrieStore, _codeDb, logManager, sharedHashes); } public event EventHandler? ReorgBoundaryReached From 57461c3869d31467401f0bb265dc848931c164d2 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 29 May 2024 10:13:20 +0200 Subject: [PATCH 199/213] merge fix --- src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs index beb7c487049..3fc56dcf09e 100644 --- a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -53,13 +53,8 @@ public bool Set(in ValueHash256 codeHash, CodeInfo codeInfo) } - private static readonly FrozenDictionary _precompiles; - private static readonly LruCache _codeCache = new(MemoryAllowance.CodeCacheSize, MemoryAllowance.CodeCacheSize, "VM bytecodes"); - - static CodeInfoRepository() - { - _precompiles = InitializePrecompiledContracts(); - } + private static readonly FrozenDictionary _precompiles = InitializePrecompiledContracts(); + private static readonly CodeLruCache _codeCache = new(); private static FrozenDictionary InitializePrecompiledContracts() { From c8048519dcbcdedb151860fe713d3fa571277946 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 29 May 2024 10:17:26 +0200 Subject: [PATCH 200/213] fix --- .../Nethermind.Evm/CodeInfoRepository.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs index 3fc56dcf09e..1529be2c20c 100644 --- a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -37,19 +37,25 @@ public CodeLruCache() } } - public CodeInfo Get(in ValueHash256 codeHash) + public CodeInfo? Get(in ValueHash256 codeHash) { - var cache = _caches[GetCacheIndex(codeHash)]; + LruCache cache = _caches[GetCacheIndex(codeHash)]; return cache.Get(codeHash); } public bool Set(in ValueHash256 codeHash, CodeInfo codeInfo) { - var cache = _caches[GetCacheIndex(codeHash)]; + LruCache cache = _caches[GetCacheIndex(codeHash)]; return cache.Set(codeHash, codeInfo); } private static int GetCacheIndex(in ValueHash256 codeHash) => codeHash.Bytes[^1] & CacheMax; + + public bool TryGet(in ValueHash256 codeHash, [NotNullWhen(true)] out CodeInfo? codeInfo) + { + codeInfo = Get(codeHash); + return codeInfo is not null; + } } @@ -93,7 +99,7 @@ public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IR return _precompiles[codeSource]; } - CodeInfo cachedCodeInfo = null; + CodeInfo? cachedCodeInfo = null; ValueHash256 codeHash = worldState.GetCodeHash(codeSource); if (codeHash == Keccak.OfAnEmptyString.ValueHash256) { @@ -131,7 +137,7 @@ static void MissingCode(Address codeSource, in ValueHash256 codeHash) public CodeInfo GetOrAdd(ValueHash256 codeHash, ReadOnlySpan initCode) { - if (!_codeCache.TryGet(codeHash, out CodeInfo codeInfo)) + if (!_codeCache.TryGet(codeHash, out CodeInfo? codeInfo)) { codeInfo = new(initCode.ToArray()); From 9adf550d9053d4ef76ef519685fd99c48b5b89c1 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 29 May 2024 11:00:28 +0200 Subject: [PATCH 201/213] fix --- .../Nethermind.AccountAbstraction/AccountAbstractionPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.AccountAbstraction/AccountAbstractionPlugin.cs b/src/Nethermind/Nethermind.AccountAbstraction/AccountAbstractionPlugin.cs index 972f654dd15..327b7715335 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction/AccountAbstractionPlugin.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction/AccountAbstractionPlugin.cs @@ -123,7 +123,7 @@ private UserOperationSimulator UserOperationSimulator(Address entryPoint) ReadOnlyTxProcessingEnvFactory readOnlyTxProcessingEnvFactory = new( getFromApi.WorldStateManager!, - getFromApi.BlockTree, + getFromApi.BlockTree!, getFromApi.SpecProvider, getFromApi.LogManager); From 5f324a989791815cdb86c5fab62e0bdc3f2fd178 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Wed, 29 May 2024 13:00:26 +0200 Subject: [PATCH 202/213] merge fix --- src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs index a0ffd277601..48b67ddd52d 100644 --- a/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -33,7 +33,7 @@ public CodeLruCache() for (int i = 0; i < _caches.Length; i++) { // Cache per nibble to reduce contention as TxPool is very parallel - _caches[i] = new LruCacheLowObject(MemoryAllowance.CodeCacheSize / CacheCount, MemoryAllowance.CodeCacheSize / CacheCount, $"VM bytecodes {i}"); + _caches[i] = new LruCacheLowObject(MemoryAllowance.CodeCacheSize / CacheCount, $"VM bytecodes {i}"); } } From f84c67bd5465ad0dabfa435eb9f817ec9f6d5aa5 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 3 Jun 2024 05:33:33 +0100 Subject: [PATCH 203/213] Review based changes --- .../Nethermind.Core/Buffers/CappedArray.cs | 13 +++++++++++++ .../Nethermind.Core/CappedArrayMemoryManager.cs | 2 +- .../Simulate/SimulateDictionaryBlockStore.cs | 2 +- .../Simulate/SimulateTxMutatorTracer.cs | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs b/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs index 0d909d05077..be6a5d78a9b 100644 --- a/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs +++ b/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs @@ -110,4 +110,17 @@ public readonly Span AsSpan(int start, int length) if (_length == array.Length) return array; return AsSpan().ToArray(); } + + public readonly ArraySegment AsArraySegment() + { + return AsArraySegment(0, _length); + } + public readonly ArraySegment AsArraySegment(int start, int length) + { + if (_array == null || start < 0 || length < 0 || start + length > _length) + { + ThrowArgumentOutOfRangeException(); + } + return new ArraySegment(_array, start, length); + } } diff --git a/src/Nethermind/Nethermind.Core/CappedArrayMemoryManager.cs b/src/Nethermind/Nethermind.Core/CappedArrayMemoryManager.cs index 4b10e5c63bb..65d52241f0b 100644 --- a/src/Nethermind/Nethermind.Core/CappedArrayMemoryManager.cs +++ b/src/Nethermind/Nethermind.Core/CappedArrayMemoryManager.cs @@ -57,7 +57,7 @@ protected override bool TryGetArray(out ArraySegment segment) throw new ObjectDisposedException(nameof(CappedArrayMemoryManager)); } - segment = new ArraySegment(_data.ToArray() ?? throw new InvalidOperationException()); + segment = _data.AsArraySegment(); return true; } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs index e0000897a08..4b76d9bcdb5 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryBlockStore.cs @@ -58,7 +58,7 @@ public void Delete(long blockNumber, Hash256 blockHash) public IEnumerable GetAll() { var allBlocks = new HashSet(readonlyBaseBlockStore.GetAll()); - foreach (Block? block in _blockDict.Values) + foreach (Block block in _blockDict.Values) { allBlocks.Add(block); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs index ce234cc3eed..0c0b88c039c 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs @@ -22,7 +22,7 @@ internal sealed class SimulateTxMutatorTracer : TxTracer, ITxLogsMutator private static readonly Hash256 transferSignature = new AbiSignature("Transfer", AbiType.Address, AbiType.Address, AbiType.UInt256).Hash; - private static readonly Address Erc20Sender = new("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"); + private static readonly Address Erc20Sender = new("0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); private readonly Hash256 _currentBlockHash; private readonly ulong _currentBlockNumber; private readonly Hash256 _txHash; From 53a79b192041e6ed5a47825e2442e3b514ade231 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 3 Jun 2024 05:53:48 +0100 Subject: [PATCH 204/213] Minor review fixes --- src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs | 1 + .../Nethermind.Facade/Simulate/SimulateBridgeHelper.cs | 4 ++-- .../Simulate/SimulateDictionaryHeaderStore.cs | 3 --- .../Simulate/SimulateReadOnlyBlocksProcessingEnv.cs | 4 ++-- .../Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs | 2 +- src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs | 3 --- 6 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs b/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs index be6a5d78a9b..429da5feab5 100644 --- a/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs +++ b/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs @@ -115,6 +115,7 @@ public readonly ArraySegment AsArraySegment() { return AsArraySegment(0, _length); } + public readonly ArraySegment AsArraySegment(int start, int length) { if (_array == null || start < 0 || length < 0 || start + length > _length) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index c7adb1c0ad0..d5f95df591a 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -59,7 +59,7 @@ public bool TrySimulate( SimulatePayload payload, IBlockTracer tracer, [NotNullWhen(false)] out string? error) => - TrySimulate(parent, payload, tracer, simulateProcessingEnvFactory.Create(payload.TraceTransfers, payload.Validation), out error); + TrySimulate(parent, payload, tracer, simulateProcessingEnvFactory.Create(payload.Validation), out error); private bool TrySimulate( @@ -111,7 +111,7 @@ private bool TrySimulate( suggestedBlocks[0] = currentBlock; - IBlockProcessor processor = env.GetProcessor(currentBlock.StateRoot!, payload.Validation); + IBlockProcessor processor = env.GetProcessor(payload.Validation); Block processedBlock = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer)[0]; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs index f7f52dc858b..715df65eabb 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateDictionaryHeaderStore.cs @@ -16,9 +16,6 @@ namespace Nethermind.Facade.Simulate; /// public class SimulateDictionaryHeaderStore(IHeaderStore readonlyBaseHeaderStore) : IHeaderStore { - // SyncProgressResolver MaxLookupBack is 256, add 16 wiggle room - public const int CacheSize = 256 + 16; - private readonly Dictionary _headerDict = new(); private readonly Dictionary _blockNumberDict = new(); diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs index 9f01db4f72d..b11ce18308f 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnv.cs @@ -21,7 +21,7 @@ namespace Nethermind.Facade.Simulate; -public class SimulateBlockValidationTransactionsExecutor : BlockProcessor.BlockValidationTransactionsExecutor +public class SimulateBlockValidationTransactionsExecutor : BlockValidationTransactionsExecutor { public SimulateBlockValidationTransactionsExecutor(ITransactionProcessor transactionProcessor, IWorldState stateProvider) : base(transactionProcessor, stateProvider) { @@ -101,7 +101,7 @@ private SimulateBlockValidatorProxy CreateValidator() return new SimulateBlockValidatorProxy(blockValidator); } - public IBlockProcessor GetProcessor(Hash256 stateRoot, bool validate) => + public IBlockProcessor GetProcessor(bool validate) => new BlockProcessor(SpecProvider, _blockValidator, NoBlockRewards.Instance, diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs index 01dae6c7003..99078525673 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateReadOnlyBlocksProcessingEnvFactory.cs @@ -22,7 +22,7 @@ public class SimulateReadOnlyBlocksProcessingEnvFactory( ISpecProvider specProvider, ILogManager? logManager = null) { - public SimulateReadOnlyBlocksProcessingEnv Create(bool traceTransfers, bool validate) + public SimulateReadOnlyBlocksProcessingEnv Create(bool validate) { IReadOnlyDbProvider editableDbProvider = new ReadOnlyDbProvider(dbProvider, true); OverlayTrieStore overlayTrieStore = new(editableDbProvider.StateDb, worldStateManager.TrieStore, logManager); diff --git a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs index 7d52f856b12..50977e6ec5d 100644 --- a/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs +++ b/src/Nethermind/Nethermind.Trie/Pruning/OverlayTrieStore.cs @@ -24,7 +24,4 @@ public override TrieNode FindCachedOrUnknown(Hash256? address, in TreePath path, public override byte[]? TryLoadRlp(Hash256? address, in TreePath path, Hash256 hash, ReadFlags flags = ReadFlags.None) => base.TryLoadRlp(address, in path, hash, flags) ?? store.TryLoadRlp(address, in path, hash, flags); - - //public override byte[]? GetByHash(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) => - // base.GetByHash(key, flags) ?? store.GetByHash(key, flags); } From d1cde8f28ebc4e2864c106b8d44c4a080898249a Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 3 Jun 2024 11:11:08 +0100 Subject: [PATCH 205/213] some minor fixes --- src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs | 5 +++++ src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs | 1 + .../Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs index 59fdb17efdf..da91d178755 100644 --- a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs @@ -80,6 +80,11 @@ public interface IJsonRpcConfig : IConfig DefaultValue = "[Eth,Subscribe,Trace,TxPool,Web3,Personal,Proof,Net,Parity,Health,Rpc]")] string[] EnabledModules { get; set; } + [ConfigItem( + Description = "Enable experimental eth_simulate call (see https://github.com/ethereum/execution-apis/pull/484 for API refrence) ", + DefaultValue = "false")] + public bool EnabledRpcSimulate { get; set; } + [ConfigItem( Description = "An array of additional JSON-RPC URLs to listen at with protocol and JSON-RPC namespace list. For instance, `[http://localhost:8546|http;ws|eth;web3]`.", DefaultValue = "[]")] diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs index d1ee913c287..ef566afae92 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs @@ -31,6 +31,7 @@ public int WebSocketsPort public string? IpcUnixDomainSocketPath { get; set; } = null; public string[] EnabledModules { get; set; } = ModuleType.DefaultModules.ToArray(); + public bool EnabledRpcSimulate { get; set; } = false; public string[] AdditionalRpcUrls { get; set; } = Array.Empty(); public long? GasCap { get; set; } = 100000000; public int ReportIntervalSeconds { get; set; } = 300; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index 30e3fc4a2b5..d995c094d6b 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -73,6 +73,9 @@ public override ResultWrapper> Execute( SimulatePayload call, BlockParameter? blockParameter) { + if(!_rpcConfig.EnabledRpcSimulate) + return ResultWrapper>.Fail("Must EnableRpcSimulate JsonRpc config flag on the node", ErrorCodes.MethodNotSupported); + if (call.BlockStateCalls is null) return ResultWrapper>.Fail("Must contain BlockStateCalls", ErrorCodes.InvalidParams); @@ -112,6 +115,10 @@ public override ResultWrapper> Execute( return ResultWrapper>.Fail( $"Block number too big {givenNumber}!", ErrorCodes.InvalidParams); + if (givenNumber < (ulong)header.Number) + return ResultWrapper>.Fail( + $"Block number out of order {givenNumber} is < than given base number of {header.Number}!", ErrorCodes.InvalidInputBlocksOutOfOrder); + long given = (long)givenNumber; if (given > lastBlockNumber) { From aa6277b528d0eab751f2115d467891650beaa0eb Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 10 Jun 2024 12:44:39 +0100 Subject: [PATCH 206/213] new call result layout --- src/Nethermind/Nethermind.Core/BlockHeader.cs | 2 +- .../Models/Simulate/SimulateBlockResult.cs | 46 +++++++++++++------ .../Simulate/SimulateBlockTracer.cs | 28 ++++++----- .../Simulate/SimulateBridgeHelper.cs | 2 - .../Simulate/SimulateTxMutatorTracer.cs | 8 +++- .../Nethermind.JsonRpc/ErrorCodes.cs | 10 ++++ .../Modules/Eth/SimulateTxExecutor.cs | 18 +++++++- 7 files changed, 78 insertions(+), 36 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/BlockHeader.cs b/src/Nethermind/Nethermind.Core/BlockHeader.cs index e337ab3c735..005a035d238 100644 --- a/src/Nethermind/Nethermind.Core/BlockHeader.cs +++ b/src/Nethermind/Nethermind.Core/BlockHeader.cs @@ -14,7 +14,7 @@ namespace Nethermind.Core; [DebuggerDisplay("{Hash} ({Number})")] public class BlockHeader { - internal BlockHeader() { } + public BlockHeader() { } public BlockHeader( Hash256 parentHash, diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs index 25b7257f5e3..1a93496c2b3 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs @@ -1,27 +1,45 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Collections.Generic; +using System.Reflection; using Nethermind.Core; -using Nethermind.Core.Crypto; using Nethermind.Int256; namespace Nethermind.Facade.Proxy.Models.Simulate; -public class SimulateBlockResult +public class SimulateBlockResult : BlockHeader { - public ulong Number { get; set; } - public Hash256 Hash { get; set; } = Keccak.Zero; - public ulong Timestamp { get; set; } - public ulong GasLimit { get; set; } - public ulong GasUsed { get; set; } - public Address FeeRecipient { get; set; } = Address.Zero; - public UInt256 BaseFeePerGas { get; set; } - public List Calls { get; set; } = new(); - public byte[]? PrevRandao { get; set; } - public Withdrawal[] Withdrawals { get; set; } + public SimulateBlockResult(BlockHeader source) + { + MemberwiseCloneInto(source, this); + } + + public static void MemberwiseCloneInto(T source, T target) + { + if (source == null || target == null) + throw new ArgumentNullException("Source or/and Target are null"); + + Type type = typeof(T); + + foreach (PropertyInfo property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) + { + if (property.CanRead && property.CanWrite) + { + var value = property.GetValue(source, null); + property.SetValue(target, value, null); + } + } - public ulong BlobGasUsed { get; set; } - public UInt256 ExcessBlobGas { get; set; } + foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.Instance)) + { + var value = field.GetValue(source); + field.SetValue(target, value); + } + } + + + public List Calls { get; set; } = new(); public UInt256 BlobBaseFee { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index cbbcb2f2f3a..5f994885ae5 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -1,13 +1,13 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using System.Collections.Generic; using System.Linq; using Nethermind.Core; using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.Simulate; +using Nethermind.Int256; namespace Nethermind.Facade.Simulate; @@ -30,7 +30,8 @@ public override ITxTracer StartNewTxTrace(Transaction? tx) if (tx?.Hash is not null) { ulong txIndex = (ulong)_txTracers.Count; - SimulateTxMutatorTracer result = new(isTracingLogs, tx.Hash, (ulong)_currentBlock.Number, _currentBlock.Hash, txIndex); + SimulateTxMutatorTracer result = new(isTracingLogs, tx.Hash, (ulong)_currentBlock.Number, + _currentBlock.Hash, txIndex); _txTracers.Add(result); return result; } @@ -40,22 +41,19 @@ public override ITxTracer StartNewTxTrace(Transaction? tx) public override void EndBlockTrace() { - SimulateBlockResult? result = new() + SimulateBlockResult? result = new(_currentBlock.Header) { Calls = _txTracers.Select(t => t.TraceResult).ToList(), - Number = (ulong)_currentBlock.Number, - Hash = _currentBlock.Hash!, - GasLimit = (ulong)_currentBlock.GasLimit, - GasUsed = _txTracers.Aggregate(0ul, (s, t) => s + t.TraceResult!.GasUsed ?? 0ul), - Timestamp = _currentBlock.Timestamp, - FeeRecipient = _currentBlock.Beneficiary!, - BaseFeePerGas = _currentBlock.BaseFeePerGas, - PrevRandao = _currentBlock.Header!.Random?.BytesToArray(), - BlobGasUsed = _currentBlock.BlobGasUsed ?? 0, - ExcessBlobGas = _currentBlock.ExcessBlobGas ?? 0, - BlobBaseFee = new BlockExecutionContext(_currentBlock.Header).BlobBaseFee ?? 0, - Withdrawals = _currentBlock.Withdrawals ?? Array.Empty() + }; + if (_currentBlock.Header.ExcessBlobGas is not null) + { + if (!BlobGasCalculator.TryCalculateBlobGasPricePerUnit(_currentBlock.Header.ExcessBlobGas.Value, + out UInt256 blobGasPricePerUnit)) + { + result.BlobBaseFee = blobGasPricePerUnit; + } + } Results.Add(result); } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index d5f95df591a..b93f5594e41 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -256,8 +256,6 @@ private Transaction CreateTransaction(TransactionWithSourceDetails transactionDe transaction.DecodedMaxFeePerGas = transaction.GasPrice == 0 ? callHeader.BaseFeePerGas + 1 : transaction.GasPrice; - //UInt256.MultiplyOverflow((UInt256)transaction.GasLimit, transaction.MaxFeePerGas, out UInt256 maxGasFee); - //string err = $"insufficient sender balance for MaxFeePerGas: {callHeader.Number}, {transaction.SenderAddress} balance should be at least {maxGasFee + 1 + transaction.Value }"; } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs index 0c0b88c039c..fcc1c275520 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs @@ -49,8 +49,12 @@ public SimulateTxMutatorTracer(bool isTracingTransfers, Hash256 txHash, ulong cu public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); - var data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, new AbiSignature("", AbiType.UInt256), value); - _logsToMutate?.Add(new LogEntry(Erc20Sender, data, [transferSignature, from.ToHash(), to.ToHash()])); + if (value > 0) + { + var data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, new AbiSignature("", AbiType.UInt256), + value); + _logsToMutate?.Add(new LogEntry(Erc20Sender, data, [transferSignature, from.ToHash(), to.ToHash()])); + } } public override void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, diff --git a/src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs b/src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs index 6b2d8f2e47a..3990b33b775 100644 --- a/src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs +++ b/src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs @@ -92,11 +92,21 @@ public static class ErrorCodes ///
public const int InvalidInputBlocksOutOfOrder = -38020; + /// + /// Invalid RPC simulate call Block timestamp in sequence did not increase + /// + public const int BlockTimestampNotIncreased = -38021; + /// /// Invalid RPC simulate call containing too many blocks /// public const int InvalidInputTooManyBlocks = -38026; + /// + /// Invalid RPC simulate call Not enough gas provided to pay for intrinsic gas for a transaction + /// + public const int InsufficientIntrinsicGas = -38013; + /// /// Invalid RPC simulate call transaction /// diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index 15a815100f0..b0798888a55 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -138,6 +138,10 @@ public override ResultWrapper> Execute( ? header.Timestamp + secondsPerSlot.Value : lastBlockTime + secondsPerSlot.Value); + if (givenTime < header.Timestamp) + return ResultWrapper>.Fail( + $"Block timestamp out of order {givenTime} is < than given base timestamp of {header.Timestamp}!", ErrorCodes.BlockTimestampNotIncreased); + if (givenTime > lastBlockTime) { lastBlockTime = givenTime; @@ -145,7 +149,7 @@ public override ResultWrapper> Execute( else { return ResultWrapper>.Fail( - $"Block timestamp out of order {givenTime}!", ErrorCodes.InvalidInputBlocksOutOfOrder); + $"Block timestamp out of order {givenTime}!", ErrorCodes.BlockTimestampNotIncreased); } blockToSimulate.BlockOverrides.Time = givenTime; @@ -193,9 +197,19 @@ protected override ResultWrapper> Execute(Blo SimulateOutput results = _blockchainBridge.Simulate(header, tx, token); if (results.Error is not null && (results.Error.Contains("invalid transaction") - || results.Error.Contains("InsufficientBalanceException"))) + || results.Error.Contains("InsufficientBalanceException") + )) results.ErrorCode = ErrorCodes.InvalidTransaction; + if (results.Error is not null && results.Error.Contains("InvalidBlockException")) + results.ErrorCode = ErrorCodes.InvalidParams; + + + if (results.Error is not null && results.Error.Contains("below intrinsic gas")) + results.ErrorCode = ErrorCodes.InsufficientIntrinsicGas; + + + return results.Error is null ? ResultWrapper>.Success(results.Items) : results.ErrorCode is not null From 3838f3ec2567fc7cf1f6fe1e715626b7b2da3922 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 10 Jun 2024 14:01:16 +0100 Subject: [PATCH 207/213] move of RPC structures to Facade --- .../AccountAbstractionRpcModuleTests.cs | 1 + .../ProofCliModuleTests.cs | 1 + .../Nethermind.Cli/Modules/EthCliModule.cs | 1 + .../Nethermind.Facade/BlockchainBridge.cs | 2 +- .../Eth}/AccessListItemForRpc.cs | 2 +- .../Eth/BlockForRpc.cs | 2 +- .../Eth}/TransactionForRpc.cs | 3 +- .../Nethermind.Facade.csproj | 1 + .../Models/Simulate/SimulateBlockResult.cs | 34 +++---------------- .../Proxy/Models/Simulate/SimulatePayload.cs | 5 +++ .../Simulate/SimulateBlockTracer.cs | 6 ++-- ...usHelperTests.ReceiptsJsonRpcDataSource.cs | 1 + .../Data/AccessListItemForRpcTests.cs | 1 + .../Data/Eip2930Tests.cs | 1 + .../JsonRpcServiceTests.cs | 1 + .../Modules/DebugModuleTests.cs | 1 + .../Eth/EthRpcModuleTests.EstimateGas.cs | 1 + .../Modules/Eth/EthRpcModuleTests.EthCall.cs | 1 + .../Modules/Eth/EthRpcModuleTests.cs | 1 + .../Modules/Eth/EthRpcSimulateTestsBase.cs | 1 + ...SimulateTestsPrecompilesWithRedirection.cs | 1 + .../EthSimulateTestsBlocksAndTransactions.cs | 1 + .../Eth/Simulate/EthSimulateTestsHiveBase.cs | 7 ++-- .../Modules/Proof/ProofRpcModuleTests.cs | 1 + .../Modules/TraceRpcModuleTests.cs | 1 + .../TransactionForRpcConverterTests.cs | 1 + .../TraceStoreRpcModuleTests.cs | 1 + .../TraceStoreRpcModule.cs | 1 + .../Data/AccessListForRpc.cs | 1 + .../Data/TransactionForRpcWithTraceTypes.cs | 1 + .../Modules/DebugModule/DebugRpcModule.cs | 1 + .../Modules/DebugModule/IDebugRpcModule.cs | 1 + .../Modules/Eth/BadBlock.cs | 1 + .../Eth/EthRpcModule.TransactionExecutor.cs | 1 + .../Modules/Eth/SimulateTxExecutor.cs | 1 + .../Modules/Personal/IPersonalRpcModule.cs | 1 + .../Modules/Personal/PersonalRpcModule.cs | 1 + .../Modules/Proof/IProofRpcModule.cs | 1 + .../Modules/Proof/ProofRpcModule.cs | 1 + .../Modules/Proof/TransactionWithProof.cs | 1 + .../Modules/Subscribe/NewHeadSubscription.cs | 1 + .../NewPendingTransactionsSubscription.cs | 1 + .../Modules/Trace/ITraceRpcModule.cs | 1 + .../Modules/Trace/TraceRpcModule.cs | 1 + .../Modules/TxPool/TransactionPoolContent.cs | 1 + .../EngineModuleTests.V1.cs | 1 + .../ExternalRpcIntegrationTests.cs | 1 + .../Nethermind.Overseer.Test/CliqueTests.cs | 1 + .../Framework/CliqueContext.cs | 1 + .../Ethereum/Api/ApiBuilder.cs | 1 + 50 files changed, 63 insertions(+), 40 deletions(-) rename src/Nethermind/{Nethermind.JsonRpc/Data => Nethermind.Facade/Eth}/AccessListItemForRpc.cs (98%) rename src/Nethermind/{Nethermind.JsonRpc/Modules => Nethermind.Facade}/Eth/BlockForRpc.cs (99%) rename src/Nethermind/{Nethermind.JsonRpc/Data => Nethermind.Facade/Eth}/TransactionForRpc.cs (99%) diff --git a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.cs b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.cs index a08ba710e10..6862acc8a0b 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionRpcModuleTests.cs @@ -18,6 +18,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; +using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Test.Modules; diff --git a/src/Nethermind/Nethermind.Cli.Test/ProofCliModuleTests.cs b/src/Nethermind/Nethermind.Cli.Test/ProofCliModuleTests.cs index dac449f4a53..3eac4d9207c 100644 --- a/src/Nethermind/Nethermind.Cli.Test/ProofCliModuleTests.cs +++ b/src/Nethermind/Nethermind.Cli.Test/ProofCliModuleTests.cs @@ -7,6 +7,7 @@ using Nethermind.Cli.Modules; using Nethermind.Core.Crypto; using Nethermind.Core.Test.Builders; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Client; using Nethermind.JsonRpc.Data; diff --git a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs index bc002797513..961ce37bfe9 100644 --- a/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs +++ b/src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs @@ -7,6 +7,7 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; +using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.JsonRpc.Data; diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index fa46f8d471f..b127bd5b6ca 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -150,7 +150,7 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can public SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, CancellationToken cancellationToken) { - SimulateBlockTracer simulateOutputTracer = new(payload.TraceTransfers); + SimulateBlockTracer simulateOutputTracer = new(payload.TraceTransfers, payload.returnFullTransactionObjects, _specProvider); BlockReceiptsTracer tracer = new(); tracer.SetOtherTracer(simulateOutputTracer); SimulateOutput result = new(); diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/AccessListItemForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/AccessListItemForRpc.cs similarity index 98% rename from src/Nethermind/Nethermind.JsonRpc/Data/AccessListItemForRpc.cs rename to src/Nethermind/Nethermind.Facade/Eth/AccessListItemForRpc.cs index 17533dd0f25..0269aeeb0e6 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/AccessListItemForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/AccessListItemForRpc.cs @@ -12,7 +12,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Nethermind.JsonRpc.Data +namespace Nethermind.Facade.Eth { public struct AccessListItemForRpc : IEquatable { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/BlockForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs similarity index 99% rename from src/Nethermind/Nethermind.JsonRpc/Modules/Eth/BlockForRpc.cs rename to src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs index 4d0d491ce83..dde7bdd6e21 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/BlockForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs @@ -14,7 +14,7 @@ using System.Text.Json.Serialization; using System.Runtime.CompilerServices; -namespace Nethermind.JsonRpc.Modules.Eth; +namespace Nethermind.Facade.Eth; public class BlockForRpc { diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/TransactionForRpc.cs similarity index 99% rename from src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs rename to src/Nethermind/Nethermind.Facade/Eth/TransactionForRpc.cs index 9806860fad7..ab7a7bbc8ba 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/TransactionForRpc.cs @@ -10,8 +10,9 @@ using Nethermind.Core.Eip2930; using Nethermind.Core.Extensions; using Nethermind.Int256; +using Nethermind.JsonRpc.Data; -namespace Nethermind.JsonRpc.Data; +namespace Nethermind.Facade.Eth; public class TransactionForRpc { diff --git a/src/Nethermind/Nethermind.Facade/Nethermind.Facade.csproj b/src/Nethermind/Nethermind.Facade/Nethermind.Facade.csproj index 200aa01482e..7a90f4758a8 100644 --- a/src/Nethermind/Nethermind.Facade/Nethermind.Facade.csproj +++ b/src/Nethermind/Nethermind.Facade/Nethermind.Facade.csproj @@ -2,6 +2,7 @@ annotations + True diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs index 1a93496c2b3..4b4e300fe10 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs @@ -5,41 +5,15 @@ using System.Collections.Generic; using System.Reflection; using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Facade.Eth; using Nethermind.Int256; namespace Nethermind.Facade.Proxy.Models.Simulate; -public class SimulateBlockResult : BlockHeader +public class SimulateBlockResult(Block source, bool includeFullTransactionData, ISpecProvider specProvider) + : BlockForRpc(source, includeFullTransactionData, specProvider) { - public SimulateBlockResult(BlockHeader source) - { - MemberwiseCloneInto(source, this); - } - - public static void MemberwiseCloneInto(T source, T target) - { - if (source == null || target == null) - throw new ArgumentNullException("Source or/and Target are null"); - - Type type = typeof(T); - - foreach (PropertyInfo property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - if (property.CanRead && property.CanWrite) - { - var value = property.GetValue(source, null); - property.SetValue(target, value, null); - } - } - - foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.Instance)) - { - var value = field.GetValue(source); - field.SetValue(target, value); - } - } - - public List Calls { get; set; } = new(); public UInt256 BlobBaseFee { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs index 379bff98e68..0c69ce43f13 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs @@ -22,4 +22,9 @@ public class SimulatePayload /// checks. When false, multicall behaves like eth_call. /// public bool Validation { get; set; } = false; + + /// + /// When true, the simulate returns Full Tx Objects + /// + public bool returnFullTransactionObjects { get; set; } = false; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 5f994885ae5..9dc1fcbe462 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using Nethermind.Core; +using Nethermind.Core.Specs; using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Facade.Proxy.Models.Simulate; @@ -11,7 +12,7 @@ namespace Nethermind.Facade.Simulate; -public class SimulateBlockTracer(bool isTracingLogs) : BlockTracer +public class SimulateBlockTracer(bool isTracingLogs, bool isIncludingFullTxData, ISpecProvider spec) : BlockTracer { private readonly List _txTracers = new(); @@ -41,10 +42,9 @@ public override ITxTracer StartNewTxTrace(Transaction? tx) public override void EndBlockTrace() { - SimulateBlockResult? result = new(_currentBlock.Header) + SimulateBlockResult? result = new(_currentBlock, isIncludingFullTxData, spec) { Calls = _txTracers.Select(t => t.TraceResult).ToList(), - }; if (_currentBlock.Header.ExcessBlobGas is not null) { diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.ReceiptsJsonRpcDataSource.cs b/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.ReceiptsJsonRpcDataSource.cs index 081ebeddd34..fe635d2b871 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.ReceiptsJsonRpcDataSource.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/ConsensusHelperTests.ReceiptsJsonRpcDataSource.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading.Tasks; using Nethermind.Core.Crypto; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Serialization.Json; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Data/AccessListItemForRpcTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Data/AccessListItemForRpcTests.cs index 31345ac4e63..ae948e1d693 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Data/AccessListItemForRpcTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Data/AccessListItemForRpcTests.cs @@ -6,6 +6,7 @@ using Nethermind.Core; using Nethermind.Core.Eip2930; using Nethermind.Core.Test.Builders; +using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using NUnit.Framework; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Data/Eip2930Tests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Data/Eip2930Tests.cs index a9176491bdf..f34daa6963f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Data/Eip2930Tests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Data/Eip2930Tests.cs @@ -8,6 +8,7 @@ using Nethermind.Core.Eip2930; using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; +using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.Serialization.Json; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index c9c2dc2f016..00b2e77d735 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -16,6 +16,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; +using Nethermind.Facade.Eth; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; using Nethermind.JsonRpc.Data; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs index 064fff4e886..e66d93d334f 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugModuleTests.cs @@ -19,6 +19,7 @@ using Nethermind.Db; using Nethermind.Evm.Tracing.GethStyle; using Nethermind.Evm.Tracing.GethStyle.Custom; +using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.DebugModule; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs index e40b064b796..0bc1a37fb09 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs @@ -10,6 +10,7 @@ using Nethermind.Core.Test.Builders; using Nethermind.Evm; using Nethermind.Evm.Tracing; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.Specs; using Nethermind.Specs.Forks; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs index cd7fb615ec8..ed73767fcf1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs @@ -8,6 +8,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; using Nethermind.Evm; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.Specs; using Nethermind.Specs.Forks; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs index 78081289328..b613c75e75c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs @@ -22,6 +22,7 @@ using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Facade; +using Nethermind.Facade.Eth; using Nethermind.Facade.Filters; using Nethermind.Int256; using Nethermind.JsonRpc.Data; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs index 58c84bcef64..b3d887961c1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs @@ -13,6 +13,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Crypto; +using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.Logging; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs index d63ac2b4035..060260b3f72 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs @@ -13,6 +13,7 @@ using Nethermind.Core.Test.Builders; using Nethermind.Evm; using Nethermind.Evm.Precompiles; +using Nethermind.Facade.Eth; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.JsonRpc.Data; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 17db6825ed3..c05d6ef6062 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -12,6 +12,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; +using Nethermind.Facade.Eth; using Nethermind.Facade.Proxy.Models; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Int256; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs index 023a526c3d7..7c1b85e4325 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Nethermind.Blockchain.Find; +using Nethermind.Facade.Eth; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.JsonRpc.Data; using Nethermind.Serialization.Json; @@ -19,8 +20,8 @@ public class EthSimulateTestsHiveBase { new object[] {"multicall-add-more-non-defined-BlockStateCalls-than-fit-but-now-with-fit", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0xa\"}, \"stateOverrides\": {\"0xc100000000000000000000000000000000000000\": {\"code\": \"0x608060405234801561001057600080fd5b506000366060484641444543425a3a60014361002c919061009b565b406040516020016100469a99989796959493929190610138565b6040516020818303038152906040529050915050805190602001f35b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006100a682610062565b91506100b183610062565b92508282039050818111156100c9576100c861006c565b5b92915050565b6100d881610062565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610109826100de565b9050919050565b610119816100fe565b82525050565b6000819050919050565b6101328161011f565b82525050565b60006101408201905061014e600083018d6100cf565b61015b602083018c6100cf565b610168604083018b610110565b610175606083018a6100cf565b61018260808301896100cf565b61018f60a08301886100cf565b61019c60c08301876100cf565b6101a960e08301866100cf565b6101b76101008301856100cf565b6101c5610120830184610129565b9b9a505050505050505050505056fea26469706673582212205139ae3ba8d46d11c29815d001b725f9840c90e330884ed070958d5af4813d8764736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x\"}]}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x\"}]}, {\"blockOverrides\": {\"number\": \"0x14\"}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x\"}]}, {\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x\"}]}]}"}, new object[] {"multicall-basefee-too-low-without-validation-38012", "{\"blockStateCalls\": [{\"blockOverrides\": {\"baseFeePerGas\": \"0xa\"}, \"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}}, \"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"maxFeePerGas\": \"0x0\", \"maxPriorityFeePerGas\": \"0x0\"}]}]}"}, -new object[] {"multicall-block-override-reflected-in-contract-simple", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0xa\", \"time\": \"0x64\"}}, {\"blockOverrides\": {\"number\": \"0x14\", \"time\": \"0x65\"}}, {\"blockOverrides\": {\"number\": \"0x15\", \"time\": \"0xc8\"}}]}"}, -new object[] {"multicall-block-timestamps-incrementing", "{\"blockStateCalls\": [{\"blockOverrides\": {\"time\": \"0xb\"}}, {\"blockOverrides\": {\"time\": \"0xc\"}}]}"}, +//new object[] {"multicall-block-override-reflected-in-contract-simple", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0x12a\", \"time\": \"0x64\"}}, {\"blockOverrides\": {\"number\": \"0x14\", \"time\": \"0x65\"}}, {\"blockOverrides\": {\"number\": \"0x15\", \"time\": \"0xc8\"}}]}"}, +//new object[] {"multicall-block-timestamps-incrementing", "{\"blockStateCalls\": [{\"blockOverrides\": {\"time\": \"0x12b\"}}, {\"blockOverrides\": {\"time\": \"0x12c\"}}]}"}, new object[] {"multicall-blockhash-complex", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0xa\"}, \"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x1e8480\"}, \"0xc200000000000000000000000000000000000000\": {\"code\": \"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}]}, {\"blockOverrides\": {\"number\": \"0x14\"}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e000000000000000000000000000000000000000000000000000000000000000a\"}]}, {\"blockOverrides\": {\"number\": \"0x1e\"}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e000000000000000000000000000000000000000000000000000000000000001d\"}]}]}"}, new object[] {"multicall-blockhash-simple", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc200000000000000000000000000000000000000\": {\"code\": \"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}]}]}"}, new object[] {"multicall-blockhash-start-before-head", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0xa\"}, \"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x1e8480\"}, \"0xc200000000000000000000000000000000000000\": {\"code\": \"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b60436004803603810190603f91906098565b6057565b604051604e919060d7565b60405180910390f35b600081409050919050565b600080fd5b6000819050919050565b6078816067565b8114608257600080fd5b50565b6000813590506092816071565b92915050565b60006020828403121560ab5760aa6062565b5b600060b7848285016085565b91505092915050565b6000819050919050565b60d18160c0565b82525050565b600060208201905060ea600083018460ca565b9291505056fea2646970667358221220a4d7face162688805e99e86526524ac3dadfb01cc29366d0d68b70dadcf01afe64736f6c63430008120033\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000001\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000002\"}]}, {\"blockOverrides\": {\"number\": \"0x14\"}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc200000000000000000000000000000000000000\", \"input\": \"0xee82ac5e0000000000000000000000000000000000000000000000000000000000000013\"}]}]}"}, @@ -44,7 +45,7 @@ public class EthSimulateTestsHiveBase new object[] {"multicall-only-from-to-transaction", "{\"blockStateCalls\": [{\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\"}]}], \"traceTransfers\": true}"}, new object[] {"multicall-only-from-transaction", "{\"blockStateCalls\": [{\"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\"}]}], \"traceTransfers\": true}"}, new object[] {"multicall-override-address-twice-in-separate-BlockStateCalls", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}, {\"stateOverrides\": {\"0xc000000000000000000000000000000000000000\": {\"balance\": \"0x7d0\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0xc100000000000000000000000000000000000000\", \"value\": \"0x3e8\"}]}], \"traceTransfers\": true}"}, -new object[] {"multicall-override-all-in-BlockStateCalls", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0x3e9\", \"time\": \"0x3eb\", \"gasLimit\": \"0x3ec\", \"feeRecipient\": \"0xc200000000000000000000000000000000000000\", \"prevRandao\": \"0xc300000000000000000000000000000000000000000000000000000000000000\", \"baseFeePerGas\": \"0x3ef\"}}]}"}, +//new object[] {"multicall-override-all-in-BlockStateCalls", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0x3e9\", \"time\": \"0x3eb\", \"gasLimit\": \"0x3ec\", \"feeRecipient\": \"0xc200000000000000000000000000000000000000\", \"prevRandao\": \"0xc300000000000000000000000000000000000000000000000000000000000000\", \"baseFeePerGas\": \"0x3ef\"}}]}"}, new object[] {"multicall-override-block-num", "{\"blockStateCalls\": [{\"blockOverrides\": {\"number\": \"0xb\"}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"input\": \"0x4360005260206000f3\"}]}, {\"blockOverrides\": {\"number\": \"0xc\"}, \"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"input\": \"0x4360005260206000f3\"}]}]}"}, new object[] {"multicall-override-ecrecover", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0x0000000000000000000000000000000000000001\": {\"code\": \"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\", \"MovePrecompileToAddress\": \"0x0000000000000000000000000000000000123456\"}, \"0xc100000000000000000000000000000000000000\": {\"balance\": \"0x30d40\"}}, \"calls\": [{\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000123456\", \"input\": \"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000123456\", \"input\": \"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000001\", \"input\": \"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000001\", \"input\": \"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000001\", \"input\": \"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"}, {\"from\": \"0xc100000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000001\", \"input\": \"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}"}, new object[] {"multicall-override-identity", "{\"blockStateCalls\": [{\"stateOverrides\": {\"0x0000000000000000000000000000000000000004\": {\"code\": \"0x\", \"MovePrecompileToAddress\": \"0x0000000000000000000000000000000000123456\"}}, \"calls\": [{\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000123456\", \"input\": \"0x1234\"}, {\"from\": \"0xc000000000000000000000000000000000000000\", \"to\": \"0x0000000000000000000000000000000000000004\", \"input\": \"0x1234\"}]}]}"}, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs index 31a16936028..22d8e66c775 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs @@ -29,6 +29,7 @@ using FluentAssertions; using Nethermind.Consensus.Processing; using Nethermind.Core.Buffers; +using Nethermind.Facade.Eth; using Nethermind.State.Tracing; using NSubstitute; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs index 115afc9123f..e86796589e1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs @@ -25,6 +25,7 @@ using Nethermind.Db; using Nethermind.Evm; using Nethermind.Evm.Tracing.ParityStyle; +using Nethermind.Facade.Eth; using Nethermind.Serialization.Json; using Nethermind.Specs.Forks; using Nethermind.Specs.Test; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TransactionForRpcConverterTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TransactionForRpcConverterTests.cs index 9e1822b3e8e..6b6add97578 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TransactionForRpcConverterTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TransactionForRpcConverterTests.cs @@ -5,6 +5,7 @@ using FluentAssertions; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Test.Data; using Nethermind.Serialization.Json; diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore.Test/TraceStoreRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore.Test/TraceStoreRpcModuleTests.cs index dbe61f725b1..8c82d299e41 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore.Test/TraceStoreRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore.Test/TraceStoreRpcModuleTests.cs @@ -12,6 +12,7 @@ using Nethermind.Core.Test.Builders; using Nethermind.Db; using Nethermind.Evm.Tracing.ParityStyle; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Trace; using Nethermind.Logging; diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreRpcModule.cs index b01b95b265d..d9267e28112 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreRpcModule.cs @@ -7,6 +7,7 @@ using Nethermind.Core.Crypto; using Nethermind.Db; using Nethermind.Evm.Tracing.ParityStyle; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Trace; diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/AccessListForRpc.cs b/src/Nethermind/Nethermind.JsonRpc/Data/AccessListForRpc.cs index 84e569a4965..7c21797de61 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/AccessListForRpc.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/AccessListForRpc.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Collections.Generic; +using Nethermind.Facade.Eth; using Nethermind.Int256; namespace Nethermind.JsonRpc.Data diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpcWithTraceTypes.cs b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpcWithTraceTypes.cs index 061f0b02f11..5f5c98acaf1 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpcWithTraceTypes.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Data/TransactionForRpcWithTraceTypes.cs @@ -4,6 +4,7 @@ using System; using System.Text.Json; using System.Text.Json.Serialization; +using Nethermind.Facade.Eth; namespace Nethermind.JsonRpc.Data { diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs index 2c8813c7dbd..2de6e774830 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs @@ -18,6 +18,7 @@ using System.Collections.Generic; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Core.Specs; +using Nethermind.Facade.Eth; namespace Nethermind.JsonRpc.Modules.DebugModule; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs index 4a057892b70..6615e53f408 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs @@ -6,6 +6,7 @@ using Nethermind.Blockchain.Find; using Nethermind.Core.Crypto; using Nethermind.Evm.Tracing.GethStyle; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Synchronization.Reporting; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/BadBlock.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/BadBlock.cs index 3844a4a20ea..de2af695562 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/BadBlock.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/BadBlock.cs @@ -5,6 +5,7 @@ using Nethermind.Core; using Nethermind.Serialization.Rlp; using Nethermind.Core.Crypto; +using Nethermind.Facade.Eth; namespace Nethermind.JsonRpc.Modules.Eth; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs index 3a42062863a..6da17831925 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.TransactionExecutor.cs @@ -11,6 +11,7 @@ using Nethermind.Core.Extensions; using Nethermind.Evm; using Nethermind.Facade; +using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.Specs.Forks; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index b0798888a55..037649c02a8 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -9,6 +9,7 @@ using Nethermind.Config; using Nethermind.Core; using Nethermind.Facade; +using Nethermind.Facade.Eth; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Facade.Simulate; using Nethermind.JsonRpc.Data; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/IPersonalRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/IPersonalRpcModule.cs index f255d904da1..3ca1db260a6 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/IPersonalRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/IPersonalRpcModule.cs @@ -3,6 +3,7 @@ using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; namespace Nethermind.JsonRpc.Modules.Personal diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/PersonalRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/PersonalRpcModule.cs index 1070270a9d5..1116810731d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/PersonalRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/PersonalRpcModule.cs @@ -7,6 +7,7 @@ using Nethermind.Core.Attributes; using Nethermind.Core.Crypto; using Nethermind.Crypto; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.KeyStore; using Nethermind.Wallet; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/IProofRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/IProofRpcModule.cs index a7b8e9a450d..8e2123e5533 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/IProofRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/IProofRpcModule.cs @@ -3,6 +3,7 @@ using Nethermind.Blockchain.Find; using Nethermind.Core.Crypto; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; namespace Nethermind.JsonRpc.Modules.Proof diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs index 37780b8dcc0..e79f6fdd106 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/ProofRpcModule.cs @@ -14,6 +14,7 @@ using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Evm.Tracing.Proofs; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.Logging; using Nethermind.Serialization.Rlp; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/TransactionWithProof.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/TransactionWithProof.cs index 4294cfb4ee6..3069c957849 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/TransactionWithProof.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Proof/TransactionWithProof.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; namespace Nethermind.JsonRpc.Modules.Proof diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/NewHeadSubscription.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/NewHeadSubscription.cs index 11a414c1bf3..ed9fccd2511 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/NewHeadSubscription.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/NewHeadSubscription.cs @@ -5,6 +5,7 @@ using Nethermind.Blockchain; using Nethermind.Core; using Nethermind.Core.Specs; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Logging; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/NewPendingTransactionsSubscription.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/NewPendingTransactionsSubscription.cs index fe900bc6181..7ec4b75d77d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/NewPendingTransactionsSubscription.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Subscribe/NewPendingTransactionsSubscription.cs @@ -3,6 +3,7 @@ using System; using System.Threading.Tasks; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Logging; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ITraceRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ITraceRpcModule.cs index d3b06c6675e..dae0f773487 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ITraceRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ITraceRpcModule.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using Nethermind.Blockchain.Find; using Nethermind.Core.Crypto; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; namespace Nethermind.JsonRpc.Modules.Trace diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs index dce79316b4d..3ee10c8bcb3 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs @@ -15,6 +15,7 @@ using Nethermind.Evm.Tracing; using Nethermind.Evm.Tracing.ParityStyle; using Nethermind.Facade; +using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.JsonRpc.Data; using Nethermind.Logging; diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/TxPool/TransactionPoolContent.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/TxPool/TransactionPoolContent.cs index 5d0b6c0f3ba..2040cc403e8 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/TxPool/TransactionPoolContent.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/TxPool/TransactionPoolContent.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using Nethermind.Core; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.TxPool; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs index bfd1368d636..e742e263aa0 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.cs @@ -20,6 +20,7 @@ using Nethermind.Core.Test.Builders; using Nethermind.Crypto; using Nethermind.Evm; +using Nethermind.Facade.Eth; using Nethermind.HealthChecks; using Nethermind.Int256; using Nethermind.JsonRpc; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/ExternalRpcIntegrationTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/ExternalRpcIntegrationTests.cs index 194e413c785..23b20746b5b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/ExternalRpcIntegrationTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/ExternalRpcIntegrationTests.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; +using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Overseer.Test.JsonRpc; diff --git a/src/Nethermind/Nethermind.Overseer.Test/CliqueTests.cs b/src/Nethermind/Nethermind.Overseer.Test/CliqueTests.cs index 5088be5b61f..bec343e4e35 100644 --- a/src/Nethermind/Nethermind.Overseer.Test/CliqueTests.cs +++ b/src/Nethermind/Nethermind.Overseer.Test/CliqueTests.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Nethermind.Core.Extensions; using Nethermind.Crypto; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.Overseer.Test.Framework; using NUnit.Framework; diff --git a/src/Nethermind/Nethermind.Overseer.Test/Framework/CliqueContext.cs b/src/Nethermind/Nethermind.Overseer.Test/Framework/CliqueContext.cs index 8affec1b268..9d22da0ee84 100644 --- a/src/Nethermind/Nethermind.Overseer.Test/Framework/CliqueContext.cs +++ b/src/Nethermind/Nethermind.Overseer.Test/Framework/CliqueContext.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.Overseer.Test.JsonRpc; diff --git a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs index 217cb5fbd6c..2d097c4a769 100644 --- a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs +++ b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs @@ -11,6 +11,7 @@ using Nethermind.Config; using Nethermind.Consensus; using Nethermind.Core; +using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Data; using Nethermind.Logging; using Nethermind.Serialization.Json; From b559c8ccf5f72b240ba9a247b6bea1f6e5aa1ecd Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 10 Jun 2024 14:12:00 +0100 Subject: [PATCH 208/213] Removing a flag --- src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs | 5 ----- .../Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs index 70c6f920104..e52d9d1e265 100644 --- a/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/IJsonRpcConfig.cs @@ -80,11 +80,6 @@ public interface IJsonRpcConfig : IConfig DefaultValue = "[Eth,Subscribe,Trace,TxPool,Web3,Personal,Proof,Net,Parity,Health,Rpc]")] string[] EnabledModules { get; set; } - [ConfigItem( - Description = "Enable experimental eth_simulate call (see https://github.com/ethereum/execution-apis/pull/484 for API refrence) ", - DefaultValue = "false")] - public bool EnabledRpcSimulate { get; set; } - [ConfigItem( Description = "An array of additional JSON-RPC URLs to listen at with protocol and JSON-RPC namespace list. For instance, `[http://localhost:8546|http;ws|eth;web3]`.", DefaultValue = "[]")] diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index 037649c02a8..898f13ae6b2 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -74,9 +74,6 @@ public override ResultWrapper> Execute( SimulatePayload call, BlockParameter? blockParameter) { - if (!_rpcConfig.EnabledRpcSimulate) - return ResultWrapper>.Fail("Must EnableRpcSimulate JsonRpc config flag on the node", ErrorCodes.MethodNotSupported); - if (call.BlockStateCalls is null) return ResultWrapper>.Fail("Must contain BlockStateCalls", ErrorCodes.InvalidParams); From e1a1f93117e0f01d7865b0256598dfdca0823b15 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 10 Jun 2024 14:19:52 +0100 Subject: [PATCH 209/213] minor fixes --- src/Nethermind/Nethermind.Core/BlockHeader.cs | 2 +- src/Nethermind/Nethermind.Facade/BlockchainBridge.cs | 2 +- .../Proxy/Models/Simulate/SimulatePayload.cs | 2 +- .../Nethermind.Facade/Simulate/SimulateBlockTracer.cs | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/BlockHeader.cs b/src/Nethermind/Nethermind.Core/BlockHeader.cs index 005a035d238..e337ab3c735 100644 --- a/src/Nethermind/Nethermind.Core/BlockHeader.cs +++ b/src/Nethermind/Nethermind.Core/BlockHeader.cs @@ -14,7 +14,7 @@ namespace Nethermind.Core; [DebuggerDisplay("{Hash} ({Number})")] public class BlockHeader { - public BlockHeader() { } + internal BlockHeader() { } public BlockHeader( Hash256 parentHash, diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index b127bd5b6ca..0a0ca34345a 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -150,7 +150,7 @@ public CallOutput Call(BlockHeader header, Transaction tx, CancellationToken can public SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, CancellationToken cancellationToken) { - SimulateBlockTracer simulateOutputTracer = new(payload.TraceTransfers, payload.returnFullTransactionObjects, _specProvider); + SimulateBlockTracer simulateOutputTracer = new(payload.TraceTransfers, payload.ReturnFullTransactionObjects, _specProvider); BlockReceiptsTracer tracer = new(); tracer.SetOtherTracer(simulateOutputTracer); SimulateOutput result = new(); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs index 0c69ce43f13..ad81f77158e 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulatePayload.cs @@ -26,5 +26,5 @@ public class SimulatePayload /// /// When true, the simulate returns Full Tx Objects /// - public bool returnFullTransactionObjects { get; set; } = false; + public bool ReturnFullTransactionObjects { get; set; } = false; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index 9dc1fcbe462..c6ab396eedc 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -12,7 +12,7 @@ namespace Nethermind.Facade.Simulate; -public class SimulateBlockTracer(bool isTracingLogs, bool isIncludingFullTxData, ISpecProvider spec) : BlockTracer +public class SimulateBlockTracer(bool isTracingLogs, bool includeFullTxData, ISpecProvider spec) : BlockTracer { private readonly List _txTracers = new(); @@ -42,7 +42,7 @@ public override ITxTracer StartNewTxTrace(Transaction? tx) public override void EndBlockTrace() { - SimulateBlockResult? result = new(_currentBlock, isIncludingFullTxData, spec) + SimulateBlockResult? result = new(_currentBlock, includeFullTxData, spec) { Calls = _txTracers.Select(t => t.TraceResult).ToList(), }; From 9b8da71044d719eea318f31106d0f31a9cf98b91 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 10 Jun 2024 14:24:15 +0100 Subject: [PATCH 210/213] minor fix --- .../Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs index fcc1c275520..4234b78edf9 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateTxMutatorTracer.cs @@ -49,7 +49,7 @@ public SimulateTxMutatorTracer(bool isTracingTransfers, Hash256 txHash, ulong cu public override void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) { base.ReportAction(gas, value, from, to, input, callType, isPrecompileCall); - if (value > 0) + if (value > UInt256.Zero) { var data = AbiEncoder.Instance.Encode(AbiEncodingStyle.Packed, new AbiSignature("", AbiType.UInt256), value); From 9ce74e74af2df5b66b64b407d5dd4a671a4da087 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 10 Jun 2024 14:33:23 +0100 Subject: [PATCH 211/213] minor fixes --- src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs | 6 +----- src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs b/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs index 429da5feab5..9dfa54cf9a0 100644 --- a/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs +++ b/src/Nethermind/Nethermind.Core/Buffers/CappedArray.cs @@ -118,10 +118,6 @@ public readonly ArraySegment AsArraySegment() public readonly ArraySegment AsArraySegment(int start, int length) { - if (_array == null || start < 0 || length < 0 || start + length > _length) - { - ThrowArgumentOutOfRangeException(); - } - return new ArraySegment(_array, start, length); + return new ArraySegment(_array!, start, length); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs b/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs index 946c695453f..26d3d32760e 100644 --- a/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs +++ b/src/Nethermind/Nethermind.JsonRpc/JsonRpcConfig.cs @@ -31,7 +31,6 @@ public int WebSocketsPort public string? IpcUnixDomainSocketPath { get; set; } = null; public string[] EnabledModules { get; set; } = ModuleType.DefaultModules.ToArray(); - public bool EnabledRpcSimulate { get; set; } = false; public string[] AdditionalRpcUrls { get; set; } = Array.Empty(); public long? GasCap { get; set; } = 100000000; public int ReportIntervalSeconds { get; set; } = 300; From c14d0887a49091e54fb1cd78670c5f250fce8a0c Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 10 Jun 2024 14:54:55 +0100 Subject: [PATCH 212/213] minor fixes --- .../Eth/EthSimulateTestsPrecompilesWithRedirection.cs | 4 ++-- .../Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs | 6 +++--- .../Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs index 060260b3f72..33d80a28d30 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs @@ -62,7 +62,7 @@ public async Task Test_eth_simulate_create() }; //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig() { EnabledRpcSimulate = true }, new BlocksConfig().SecondsPerSlot); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); @@ -179,7 +179,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( }; //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig() { EnabledRpcSimulate = true }, new BlocksConfig().SecondsPerSlot); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); Debug.Assert(contractAddress is not null, nameof(contractAddress) + " is not null"); Assert.IsTrue(chain.State.AccountExists(contractAddress)); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index c05d6ef6062..233f9bd8d49 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -76,7 +76,7 @@ public async Task Test_eth_simulate_serialisation() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig() { EnabledRpcSimulate = true }, new BlocksConfig().SecondsPerSlot); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; Assert.That(data.Count, Is.EqualTo(7)); @@ -149,7 +149,7 @@ public async Task Test_eth_simulate_eth_moved() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig() { EnabledRpcSimulate = true }, new BlocksConfig().SecondsPerSlot); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); IReadOnlyList data = result.Data; @@ -229,7 +229,7 @@ public async Task Test_eth_simulate_transactions_forced_fail() chain.BlockTree.UpdateHeadBlock(chain.BlockFinder.Head!.Hash!); //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not - SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig() { EnabledRpcSimulate = true }, new BlocksConfig().SecondsPerSlot); + SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index e8cc9095833..6fba1d025d9 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -38,7 +38,7 @@ namespace Nethermind.JsonRpc.Test.Modules { public class TestRpcBlockchain : TestBlockchain { - public IJsonRpcConfig RpcConfig { get; private set; } = new JsonRpcConfig() { EnabledRpcSimulate = true }; + public IJsonRpcConfig RpcConfig { get; private set; } = new JsonRpcConfig(); public IEthRpcModule EthRpcModule { get; private set; } = null!; public IBlockchainBridge Bridge { get; private set; } = null!; public ITxSealer TxSealer { get; private set; } = null!; From 3acbf4a8a2f1501052cc95760e82798e49b50b75 Mon Sep 17 00:00:00 2001 From: Oleg Jakushkin Date: Mon, 10 Jun 2024 15:42:50 +0100 Subject: [PATCH 213/213] merge fixes --- .../Processing/ReadOnlyTxProcessingEnv.cs | 8 +++---- .../Processing/ReadOnlyTxProcessingEnvBase.cs | 4 ++-- .../Simulate/SimulateOutput.cs | 1 + .../OverlayWorldStateManager.cs | 15 +++++++++++-- .../ReadOnlyWorldStateManager.cs | 21 ++++++++++++------- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs index c226a44a094..3290d6d1c0b 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnv.cs @@ -25,8 +25,8 @@ public ReadOnlyTxProcessingEnv( IBlockTree blockTree, ISpecProvider? specProvider, ILogManager? logManager, - PreBlockCaches? preBlockCaches = null) - : this(worldStateManager, blockTree.AsReadOnly(), specProvider, logManager, preBlockCaches) + IWorldState? worldStateToWarmUp = null) + : this(worldStateManager, blockTree.AsReadOnly(), specProvider, logManager, worldStateToWarmUp) { } @@ -35,8 +35,8 @@ public ReadOnlyTxProcessingEnv( IReadOnlyBlockTree readOnlyBlockTree, ISpecProvider? specProvider, ILogManager? logManager, - PreBlockCaches? preBlockCaches = null - ) : base(worldStateManager, readOnlyBlockTree, specProvider, logManager, preBlockCaches) + IWorldState? worldStateToWarmUp = null + ) : base(worldStateManager, readOnlyBlockTree, specProvider, logManager, worldStateToWarmUp) { CodeInfoRepository = new CodeInfoRepository(); Machine = new VirtualMachine(BlockhashProvider, specProvider, CodeInfoRepository, logManager); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs index d6156aadb34..7b990da55e6 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ReadOnlyTxProcessingEnvBase.cs @@ -25,14 +25,14 @@ protected ReadOnlyTxProcessingEnvBase( IBlockTree readOnlyBlockTree, ISpecProvider? specProvider, ILogManager? logManager, - PreBlockCaches? preBlockCaches = null + IWorldState? worldStateToWarmUp = null ) { ArgumentNullException.ThrowIfNull(specProvider); ArgumentNullException.ThrowIfNull(worldStateManager); SpecProvider = specProvider; StateReader = worldStateManager.GlobalStateReader; - StateProvider = worldStateManager.CreateResettableWorldState(preBlockCaches); + StateProvider = worldStateManager.CreateResettableWorldState(worldStateToWarmUp); BlockTree = readOnlyBlockTree ?? throw new ArgumentNullException(nameof(readOnlyBlockTree)); BlockhashProvider = new BlockhashProvider(BlockTree, specProvider, StateProvider, logManager); LogManager = logManager; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs index 448147f8566..939de8f3021 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs @@ -8,6 +8,7 @@ namespace Nethermind.Facade.Simulate; public class SimulateOutput { + public string? Error { get; set; } public int? ErrorCode { get; set; } diff --git a/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs b/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs index bf94ae165ad..a4dda8fdd65 100644 --- a/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs +++ b/src/Nethermind/Nethermind.State/OverlayWorldStateManager.cs @@ -4,6 +4,7 @@ using System; using Nethermind.Db; using Nethermind.Logging; +using Nethermind.Trie; using Nethermind.Trie.Pruning; namespace Nethermind.State; @@ -26,9 +27,19 @@ public class OverlayWorldStateManager( public IReadOnlyTrieStore TrieStore { get; } = overlayTrieStore.AsReadOnly(); - public IWorldState CreateResettableWorldState(PreBlockCaches? sharedHashes = null) + public IWorldState CreateResettableWorldState(IWorldState? forWarmup = null) { - return new WorldState(overlayTrieStore, _codeDb, logManager, sharedHashes); + PreBlockCaches? preBlockCaches = (forWarmup as IPreBlockCaches)?.Caches; + return preBlockCaches is not null + ? new WorldState( + new PreCachedTrieStore(overlayTrieStore, preBlockCaches.RlpCache), + _codeDb, + logManager, + preBlockCaches) + : new WorldState( + overlayTrieStore, + _codeDb, + logManager); } public event EventHandler? ReorgBoundaryReached diff --git a/src/Nethermind/Nethermind.State/ReadOnlyWorldStateManager.cs b/src/Nethermind/Nethermind.State/ReadOnlyWorldStateManager.cs index 0bf8ba6ee1e..ed09e9574b6 100644 --- a/src/Nethermind/Nethermind.State/ReadOnlyWorldStateManager.cs +++ b/src/Nethermind/Nethermind.State/ReadOnlyWorldStateManager.cs @@ -38,13 +38,20 @@ ILogManager logManager public IReadOnlyTrieStore TrieStore => _readOnlyTrieStore; - public IWorldState CreateResettableWorldState(PreBlockCaches? sharedHashes = null) => - new WorldState(sharedHashes is not null - ? new PreCachedTrieStore(_readOnlyTrieStore, sharedHashes.RlpCache) - : _readOnlyTrieStore, - _codeDb, - _logManager, - sharedHashes); + public IWorldState CreateResettableWorldState(IWorldState? forWarmup = null) + { + PreBlockCaches? preBlockCaches = (forWarmup as IPreBlockCaches)?.Caches; + return preBlockCaches is not null + ? new WorldState( + new PreCachedTrieStore(_readOnlyTrieStore, preBlockCaches.RlpCache), + _codeDb, + _logManager, + preBlockCaches) + : new WorldState( + _readOnlyTrieStore, + _codeDb, + _logManager); + } public virtual event EventHandler? ReorgBoundaryReached {