diff --git a/Directory.Packages.props b/Directory.Packages.props index 74e1fde4d82..87cd3cf32b8 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -48,7 +48,6 @@ - @@ -57,6 +56,7 @@ + diff --git a/README.md b/README.md index a989abb7d9b..5b34a6e61d3 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ The standalone release builds are available on [GitHub Releases](https://github. On Windows, Nethermind can be installed via Windows Package Manager: ```powershell - winget install nethermind + winget install --id Nethermind.Nethermind ``` - **macOS** diff --git a/nuget.config b/nuget.config index 9c3244f50fa..647f42894be 100644 --- a/nuget.config +++ b/nuget.config @@ -3,14 +3,14 @@ - + - + --> diff --git a/src/Nethermind/Benchmarks.slnx b/src/Nethermind/Benchmarks.slnx index 7ba0c11e37f..1466a214d66 100644 --- a/src/Nethermind/Benchmarks.slnx +++ b/src/Nethermind/Benchmarks.slnx @@ -14,6 +14,7 @@ + diff --git a/src/Nethermind/Nethermind.Api/BasicApiExtensions.cs b/src/Nethermind/Nethermind.Api/BasicApiExtensions.cs index 6afb0a78299..9f8fa9db333 100644 --- a/src/Nethermind/Nethermind.Api/BasicApiExtensions.cs +++ b/src/Nethermind/Nethermind.Api/BasicApiExtensions.cs @@ -12,10 +12,5 @@ public static T Config(this IBasicApi api) where T : IConfig { return api.ConfigProvider.GetConfig(); } - - public static T Db(this IBasicApi api, string dbName) where T : class, IDb - { - return api.DbProvider!.GetDb(dbName); - } } } diff --git a/src/Nethermind/Nethermind.Api/IApiWithStores.cs b/src/Nethermind/Nethermind.Api/IApiWithStores.cs index e14288276da..5ee936c38d6 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithStores.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithStores.cs @@ -17,7 +17,7 @@ namespace Nethermind.Api { public interface IApiWithStores : IBasicApi { - IBlobTxStorage? BlobTxStorage { get; set; } + IBlobTxStorage BlobTxStorage { get; } IBlockTree? BlockTree { get; set; } IBloomStorage? BloomStorage { get; set; } IChainLevelInfoRepository? ChainLevelInfoRepository { get; set; } diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs index 0cc05b460cb..f8ff0fa9055 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -31,8 +31,7 @@ public interface IBasicApi [SkipServiceCollection] IConfigProvider ConfigProvider { get; } ICryptoRandom CryptoRandom { get; } - IDbProvider? DbProvider { get; set; } - IDbFactory? DbFactory { get; set; } + IDbProvider DbProvider { get; } IEthereumEcdsa EthereumEcdsa { get; } [SkipServiceCollection] IJsonSerializer EthereumJsonSerializer { get; } diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 853f0e71fa0..bf9f7af369c 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO.Abstractions; using Autofac; -using Nethermind.Abi; using Nethermind.Api.Extensions; using Nethermind.Blockchain; using Nethermind.Blockchain.Blocks; @@ -71,7 +70,7 @@ public IBlockchainBridge CreateBlockchainBridge() return Context.Resolve().CreateBlockchainBridge(); } - public IBlobTxStorage? BlobTxStorage { get; set; } + public IBlobTxStorage BlobTxStorage => Context.Resolve(); public CompositeBlockPreprocessorStep BlockPreprocessor { get; } = new(); public IBlockProcessingQueue? BlockProcessingQueue { get; set; } public IBlockProducer? BlockProducer { get; set; } @@ -82,8 +81,7 @@ public IBlockchainBridge CreateBlockchainBridge() public IChainLevelInfoRepository? ChainLevelInfoRepository { get; set; } public IConfigProvider ConfigProvider => _dependencies.ConfigProvider; public ICryptoRandom CryptoRandom => Context.Resolve(); - public IDbProvider? DbProvider { get; set; } - public IDbFactory? DbFactory { get; set; } + public IDbProvider DbProvider => Context.Resolve(); public ISigner? EngineSigner { get; set; } public ISignerStore? EngineSignerStore { get; set; } public IEnode? Enode { get; set; } diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs index 7e5c393078a..d520f50b3c1 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs @@ -43,7 +43,6 @@ public void Init_when_not_AuRa_doesnt_trow() Substitute.For(), testNethermindContainer); AuRaNethermindApi api = new AuRaNethermindApi(apiDependencies); - api.DbProvider = TestMemDbProvider.Init(); Action init = () => auRaPlugin.Init(api); init.Should().NotThrow(); } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs index 2851766175b..411681ccf17 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs @@ -524,7 +524,7 @@ public async Task Can_process_fast_sync() new FixedForkActivationChainHeadSpecProvider(specProvider, fixedBlock: 10_000_000), blockTree, readOnlyState, - new CodeInfoRepository()) + new EthereumCodeInfoRepository()) { HasSynced = true }; diff --git a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs index e01f5edfb9f..735c602aa5d 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/FullPruning/FullPruningDiskTest.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Autofac; using FluentAssertions; +using Nethermind.Api; using Nethermind.Blockchain.FullPruning; using Nethermind.Config; using Nethermind.Core; @@ -75,16 +76,14 @@ protected override async Task Build(Action? co return chain; } - protected override ContainerBuilder ConfigureContainer(ContainerBuilder builder, IConfigProvider configProvider) - { - IDbProvider dbProvider = new DbProvider(); - RocksDbFactory rocksDbFactory = new(new DbConfig(), LimboLogs.Instance, TempDirectory.Path); - StandardDbInitializer standardDbInitializer = new(dbProvider, rocksDbFactory, new FileSystem()); - standardDbInitializer.InitStandardDbs(true); - - return base.ConfigureContainer(builder, configProvider) - .AddSingleton(dbProvider); - } + protected override ContainerBuilder ConfigureContainer(ContainerBuilder builder, IConfigProvider configProvider) => + // Reenable rocksdb + base.ConfigureContainer(builder, configProvider) + .AddSingleton() + .Intercept((initConfig) => + { + initConfig.BaseDbPath = TempDirectory.Path; + }); public override void Dispose() { diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs index d2cb2d48d99..87e39b16a3a 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs @@ -2,31 +2,16 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Threading; +using Autofac; using FluentAssertions; -using Nethermind.Blockchain.BeaconBlockRoot; -using Nethermind.Blockchain.Blocks; -using Nethermind.Blockchain.Receipts; -using Nethermind.Config; +using Nethermind.Api; using Nethermind.Consensus; -using Nethermind.Consensus.ExecutionRequests; -using Nethermind.Consensus.Processing; using Nethermind.Consensus.Producers; -using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Transactions; using Nethermind.Consensus.Validators; -using Nethermind.Consensus.Withdrawals; using Nethermind.Core; -using Nethermind.Core.Specs; -using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; -using Nethermind.Db; -using Nethermind.Evm; -using Nethermind.Evm.Config; -using Nethermind.Evm.TransactionProcessing; -using Nethermind.Logging; -using Nethermind.Specs; -using Nethermind.Evm.State; -using Nethermind.State; +using Nethermind.Core.Test.Modules; using NUnit.Framework; namespace Nethermind.Blockchain.Test.Producers; @@ -36,70 +21,18 @@ public class DevBlockProducerTests [Test, MaxTime(Timeout.MaxTestTime)] public void Test() { - ISpecProvider specProvider = MainnetSpecProvider.Instance; - DbProvider dbProvider = new(); - dbProvider.RegisterDb(DbNames.BlockInfos, new MemDb()); - dbProvider.RegisterDb(DbNames.Blocks, new MemDb()); - dbProvider.RegisterDb(DbNames.Headers, new MemDb()); - dbProvider.RegisterDb(DbNames.State, new MemDb()); - dbProvider.RegisterDb(DbNames.Code, new MemDb()); - dbProvider.RegisterDb(DbNames.Metadata, new MemDb()); + using IContainer container = new ContainerBuilder() + .AddModule(new TestNethermindModule()) + .AddSingleton(Always.Valid) + .AddSingleton() + .AddScoped>() + .Build(); - BlockTree blockTree = Build.A.BlockTree() - .WithoutSettingHead - .TestObject; + IBlockTree blockTree = container.Resolve(); + IManualBlockProductionTrigger trigger = container.Resolve(); - IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(dbProvider, LimboLogs.Instance); - IWorldState stateProvider = worldStateManager.GlobalWorldState; - IStateReader stateReader = worldStateManager.GlobalStateReader; - BlockhashProvider blockhashProvider = new(blockTree, specProvider, stateProvider, LimboLogs.Instance); - CodeInfoRepository codeInfoRepository = new(); - VirtualMachine virtualMachine = new( - blockhashProvider, - specProvider, - LimboLogs.Instance); - TransactionProcessor txProcessor = new( - specProvider, - stateProvider, - virtualMachine, - codeInfoRepository, - LimboLogs.Instance); - BlockProcessor blockProcessor = new BlockProcessor( - specProvider, - Always.Valid, - NoBlockRewards.Instance, - new BlockProcessor.BlockValidationTransactionsExecutor(new ExecuteTransactionProcessorAdapter(txProcessor), stateProvider), - stateProvider, - NullReceiptStorage.Instance, - new BeaconBlockRootHandler(txProcessor, stateProvider), - new BlockhashStore(specProvider, stateProvider), - LimboLogs.Instance, - new WithdrawalProcessor(stateProvider, LimboLogs.Instance), - new ExecutionRequestsProcessor(txProcessor)); - BlockchainProcessor blockchainProcessor = new( - blockTree, - blockProcessor, - NullRecoveryStep.Instance, - stateReader, - LimboLogs.Instance, - BlockchainProcessor.Options.Default); - BuildBlocksWhenRequested trigger = new(); - ManualTimestamper timestamper = new ManualTimestamper(); - DevBlockProducer devBlockProducer = new( - EmptyTxSource.Instance, - blockchainProcessor, - stateProvider, - blockTree, - timestamper, - specProvider, - new BlocksConfig(), - LimboLogs.Instance); - - StandardBlockProducerRunner blockProducerRunner = new StandardBlockProducerRunner(trigger, blockTree, devBlockProducer); - - blockchainProcessor.Start(); - blockProducerRunner.Start(); - ProducedBlockSuggester _ = new ProducedBlockSuggester(blockTree, blockProducerRunner); + container.Resolve().BlockchainProcessor.Start(); + container.Resolve().Start(); AutoResetEvent autoResetEvent = new(false); @@ -112,4 +45,12 @@ public void Test() autoResetEvent.WaitOne(1000).Should().BeTrue("1"); blockTree.Head!.Number.Should().Be(1); } + + private class EmptyTxSourceFactory : IBlockProducerTxSourceFactory + { + public ITxSource Create() + { + return EmptyTxSource.Instance; + } + } } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs index f363de705bb..7fb0dbc214e 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs @@ -17,6 +17,7 @@ using Nethermind.Core.Specs; using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; +using Nethermind.Core.Test.Db; using Nethermind.Crypto; using Nethermind.Db; using Nethermind.Evm; @@ -73,7 +74,7 @@ public void Setup() .WithSpecProvider(specProvider) .TestObject; - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); TxPool.TxPool txPool = new( ecdsa, new BlobTxStorage(), diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs index 5d2096cd3b7..c1365b1f81e 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorEip7702Tests.cs @@ -19,6 +19,7 @@ using Nethermind.Core.Crypto; using System; using System.Linq; +using Nethermind.Blockchain; using Nethermind.Blockchain.Tracing; using Nethermind.Core.Test; using Nethermind.Int256; @@ -40,7 +41,7 @@ public void Setup() _specProvider = new TestSpecProvider(Prague.Instance); IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); _stateProvider = worldStateManager.GlobalWorldState; - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new(new TestBlockhashProvider(_specProvider), _specProvider, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs index 99fe538bc62..e515a2480ec 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs @@ -25,6 +25,7 @@ using NUnit.Framework; using Nethermind.Config; using System.Collections.Generic; +using Nethermind.Blockchain; using Nethermind.Blockchain.Tracing; using Nethermind.Core.Test; using Nethermind.State; @@ -60,7 +61,7 @@ public void Setup() _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(0); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new(new TestBlockhashProvider(_specProvider), _specProvider, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId); diff --git a/src/Nethermind/Nethermind.Blockchain/CachedCodeInfoRepository.cs b/src/Nethermind/Nethermind.Blockchain/CachedCodeInfoRepository.cs new file mode 100644 index 00000000000..8ce1fbc8099 --- /dev/null +++ b/src/Nethermind/Nethermind.Blockchain/CachedCodeInfoRepository.cs @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Concurrent; +using System.Collections.Frozen; +using System.Collections.Generic; +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Evm; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Evm.Precompiles; +using Nethermind.State; + +namespace Nethermind.Blockchain; + +public class CachedCodeInfoRepository( + FrozenDictionary precompiles, + ConcurrentDictionary? precompileCache) : CodeInfoRepository( + precompileCache is null + ? precompiles + : precompiles.ToFrozenDictionary(kvp => kvp.Key, kvp => CreateCachedPrecompile(kvp, precompileCache))) +{ + private static PrecompileInfo CreateCachedPrecompile( + in KeyValuePair originalPrecompile, + ConcurrentDictionary cache) => + new PrecompileInfo(new CachedPrecompile(originalPrecompile.Key.Value, originalPrecompile.Value.Precompile!, cache)); + + private class CachedPrecompile( + Address address, + IPrecompile precompile, + ConcurrentDictionary cache) : IPrecompile + { + public static Address Address => Address.Zero; + + public static string Name => ""; + + public long BaseGasCost(IReleaseSpec releaseSpec) => precompile.BaseGasCost(releaseSpec); + + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => precompile.DataGasCost(inputData, releaseSpec); + + public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + PreBlockCaches.PrecompileCacheKey key = new(address, inputData); + if (!cache.TryGetValue(key, out (byte[], bool) result)) + { + result = precompile.Run(inputData, releaseSpec); + // we need to rebuild the key with data copy as the data can be changed by VM processing + key = new PreBlockCaches.PrecompileCacheKey(address, inputData.ToArray()); + cache.TryAdd(key, result); + } + + return result; + } + } +} diff --git a/src/Nethermind/Nethermind.Blockchain/EthereumCodeInfoRepository.cs b/src/Nethermind/Nethermind.Blockchain/EthereumCodeInfoRepository.cs new file mode 100644 index 00000000000..c306c6abab4 --- /dev/null +++ b/src/Nethermind/Nethermind.Blockchain/EthereumCodeInfoRepository.cs @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Concurrent; +using System.Collections.Frozen; +using System.Collections.Generic; +using Nethermind.Core; +using Nethermind.Evm.CodeAnalysis; +using Nethermind.Evm.Precompiles; +using Nethermind.Evm.Precompiles.Bls; +using Nethermind.State; + +namespace Nethermind.Blockchain; + +public class EthereumCodeInfoRepository( + ConcurrentDictionary? precompileCache = null) + : CachedCodeInfoRepository(Precompiles, precompileCache) +{ + private static FrozenDictionary Precompiles + { + get => 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), + [G1MSMPrecompile.Address] = new(G1MSMPrecompile.Instance), + [G2AddPrecompile.Address] = new(G2AddPrecompile.Instance), + [G2MSMPrecompile.Address] = new(G2MSMPrecompile.Instance), + [PairingCheckPrecompile.Address] = new(PairingCheckPrecompile.Instance), + [MapFpToG1Precompile.Address] = new(MapFpToG1Precompile.Instance), + [MapFp2ToG2Precompile.Address] = new(MapFp2ToG2Precompile.Instance), + + [PointEvaluationPrecompile.Address] = new(PointEvaluationPrecompile.Instance), + + [Secp256r1Precompile.Address] = new(Secp256r1Precompile.Instance), + }.ToFrozenDictionary(); + } +} diff --git a/src/Nethermind/Nethermind.Blockchain/Metrics.cs b/src/Nethermind/Nethermind.Blockchain/Metrics.cs index a778115dde6..91864c136fb 100644 --- a/src/Nethermind/Nethermind.Blockchain/Metrics.cs +++ b/src/Nethermind/Nethermind.Blockchain/Metrics.cs @@ -6,105 +6,104 @@ using Nethermind.Core.Attributes; using Nethermind.Core.Metric; using Nethermind.Int256; + // ReSharper disable InconsistentNaming -namespace Nethermind.Blockchain +namespace Nethermind.Blockchain; + +public static class Metrics { - public static class Metrics - { - [CounterMetric] - [Description("Total MGas processed")] - public static double Mgas { get; set; } - - [GaugeMetric] - [Description("MGas processed per second")] - public static double MgasPerSec { get; set; } - - [CounterMetric] - [Description("Total number of transactions processed")] - public static long Transactions { get; set; } - - [GaugeMetric] - [Description("Total number of blocks processed")] - public static long Blocks { get; set; } - - [CounterMetric] - [Description("Total number of chain reorganizations")] - public static long Reorganizations { get; set; } - - [GaugeMetric] - [Description("Number of blocks awaiting for recovery of public keys from signatures.")] - public static long RecoveryQueueSize { get; set; } - - [GaugeMetric] - [Description("Number of blocks awaiting for processing.")] - public static long ProcessingQueueSize { get; set; } - - [CounterMetric] - [Description("Total number of sealed blocks")] - public static long BlocksSealed { get; set; } - - [CounterMetric] - [Description("Total number of failed block seals")] - public static long FailedBlockSeals { get; set; } - - [GaugeMetric] - [Description("Gas Used in processed blocks")] - public static long GasUsed { get; set; } - - [GaugeMetric] - [Description("Gas Limit for processed blocks")] - public static long GasLimit { get; set; } - - [GaugeMetric] - [Description("Total difficulty on the chain")] - public static UInt256 TotalDifficulty { get; set; } - - [GaugeMetric] - [Description("Difficulty of the last block")] - public static UInt256 LastDifficulty { get; set; } - - [GaugeMetric] - [Description("Indicator if blocks can be produced")] - public static long CanProduceBlocks; - - [GaugeMetric] - [Description("Number of ms to process the last processed block.")] - public static long LastBlockProcessingTimeInMs; - - //EIP-2159: Common Prometheus Metrics Names for Clients - [GaugeMetric] - [Description("The current height of the canonical chain.")] - [DataMember(Name = "ethereum_blockchain_height")] - public static long BlockchainHeight { get; set; } - - //EIP-2159: Common Prometheus Metrics Names for Clients - [GaugeMetric] - [Description("The estimated highest block available.")] - [DataMember(Name = "ethereum_best_known_block_number")] - public static long BestKnownBlockNumber { get; set; } - - [GaugeMetric] - [Description("Number of invalid blocks.")] - public static long BadBlocks; - - [GaugeMetric] - [Description("Number of invalid blocks with extra data set to 'Nethermind'.")] - public static long BadBlocksByNethermindNodes; - - [GaugeMetric] - [Description("State root calculation time")] - public static double StateMerkleizationTime { get; set; } - - [DetailedMetric] - [ExponentialPowerHistogramMetric(Start = 10, Factor = 1.2, Count = 30)] - [Description("Histogram of block MGas per second")] - public static IMetricObserver BlockMGasPerSec { get; set; } = new NoopMetricObserver(); - - [DetailedMetric] - [ExponentialPowerHistogramMetric(Start = 100, Factor = 1.25, Count = 50)] - [Description("Histogram of block prorcessing time")] - public static IMetricObserver BlockProcessingTimeMicros { get; set; } = new NoopMetricObserver(); - - } + [CounterMetric] + [Description("Total MGas processed")] + public static double Mgas { get; set; } + + [GaugeMetric] + [Description("MGas processed per second")] + public static double MgasPerSec { get; set; } + + [CounterMetric] + [Description("Total number of transactions processed")] + public static long Transactions { get; set; } + + [GaugeMetric] + [Description("Total number of blocks processed")] + public static long Blocks { get; set; } + + [CounterMetric] + [Description("Total number of chain reorganizations")] + public static long Reorganizations { get; set; } + + [GaugeMetric] + [Description("Number of blocks awaiting for recovery of public keys from signatures.")] + public static long RecoveryQueueSize { get; set; } + + [GaugeMetric] + [Description("Number of blocks awaiting for processing.")] + public static long ProcessingQueueSize { get; set; } + + [CounterMetric] + [Description("Total number of sealed blocks")] + public static long BlocksSealed { get; set; } + + [CounterMetric] + [Description("Total number of failed block seals")] + public static long FailedBlockSeals { get; set; } + + [GaugeMetric] + [Description("Gas Used in processed blocks")] + public static long GasUsed { get; set; } + + [GaugeMetric] + [Description("Gas Limit for processed blocks")] + public static long GasLimit { get; set; } + + [GaugeMetric] + [Description("Total difficulty on the chain")] + public static UInt256 TotalDifficulty { get; set; } + + [GaugeMetric] + [Description("Difficulty of the last block")] + public static UInt256 LastDifficulty { get; set; } + + [GaugeMetric] + [Description("Indicator if blocks can be produced")] + public static long CanProduceBlocks; + + [GaugeMetric] + [Description("Number of ms to process the last processed block.")] + public static long LastBlockProcessingTimeInMs; + + //EIP-2159: Common Prometheus Metrics Names for Clients + [GaugeMetric] + [Description("The current height of the canonical chain.")] + [DataMember(Name = "ethereum_blockchain_height")] + public static long BlockchainHeight { get; set; } + + //EIP-2159: Common Prometheus Metrics Names for Clients + [GaugeMetric] + [Description("The estimated highest block available.")] + [DataMember(Name = "ethereum_best_known_block_number")] + public static long BestKnownBlockNumber { get; set; } + + [GaugeMetric] + [Description("Number of invalid blocks.")] + public static long BadBlocks; + + [GaugeMetric] + [Description("Number of invalid blocks with extra data set to 'Nethermind'.")] + public static long BadBlocksByNethermindNodes; + + [GaugeMetric] + [Description("State root calculation time")] + public static double StateMerkleizationTime { get; set; } + + [DetailedMetric] + [ExponentialPowerHistogramMetric(Start = 10, Factor = 1.2, Count = 30)] + [Description("Histogram of block MGas per second")] + public static IMetricObserver BlockMGasPerSec { get; set; } = new NoopMetricObserver(); + + [DetailedMetric] + [ExponentialPowerHistogramMetric(Start = 100, Factor = 1.25, Count = 50)] + [Description("Histogram of block prorcessing time")] + public static IMetricObserver BlockProcessingTimeMicros { get; set; } = new NoopMetricObserver(); } diff --git a/src/Nethermind/Nethermind.Blockchain/Nethermind.Blockchain.csproj b/src/Nethermind/Nethermind.Blockchain/Nethermind.Blockchain.csproj index 548e4443439..a760ccb873b 100644 --- a/src/Nethermind/Nethermind.Blockchain/Nethermind.Blockchain.csproj +++ b/src/Nethermind/Nethermind.Blockchain/Nethermind.Blockchain.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs index 7d75114dc6a..76427295f53 100644 --- a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs @@ -122,7 +122,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f ITransactionComparerProvider transactionComparerProvider = new TransactionComparerProvider(specProvider, blockTree); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); TxPool.TxPool txPool = new(_ethereumEcdsa, new BlobTxStorage(), new ChainHeadInfoProvider(new FixedForkActivationChainHeadSpecProvider(SepoliaSpecProvider.Instance), blockTree, stateProvider, codeInfoRepository), diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs index f0222a28601..7d6b1015565 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/StartBlockProducerAuRa.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Autofac; using Autofac.Features.AttributeFilters; using Nethermind.Abi; using Nethermind.Blockchain; @@ -64,13 +65,14 @@ public class StartBlockProducerAuRa( ITxPool txPool, IStateReader apiStateReader, ITransactionComparerProvider transactionComparerProvider, - CompositeBlockPreprocessorStep compositeBlockPreprocessorStep, [KeyFilter(IProtectedPrivateKey.NodeKey)] IProtectedPrivateKey protectedPrivateKey, ICryptoRandom cryptoRandom, IBlockValidator blockValidator, IRewardCalculatorSource rewardCalculatorSource, IAuRaStepCalculator stepCalculator, AuRaGasLimitOverrideFactory gasLimitOverrideFactory, + IWorldStateManager worldStateManager, + ILifetimeScope lifetimeScope, ILogManager logManager) { private readonly AuRaChainSpecEngineParameters _parameters = chainSpec.EngineChainSpecParametersProvider @@ -125,14 +127,14 @@ public IBlockProducer BuildProducer() return blockProducer; } - private BlockProcessor CreateBlockProcessor(IReadOnlyTxProcessingScope changeableTxProcessingEnv) + private BlockProcessor CreateBlockProcessor(ITransactionProcessor txProcessor, IWorldState worldState) { ITxFilter auRaTxFilter = apiTxAuRaFilterBuilders.CreateAuRaTxFilter( new LocalTxFilter(engineSigner)); _validator = new AuRaValidatorFactory(abiEncoder, - changeableTxProcessingEnv.WorldState, - changeableTxProcessingEnv.TransactionProcessor, + worldState, + txProcessor, blockTree, readOnlyTxProcessingEnvFactory.Create(), receiptStorage, @@ -158,9 +160,6 @@ private BlockProcessor CreateBlockProcessor(IReadOnlyTxProcessingScope changeabl IDictionary> rewriteBytecode = _parameters.RewriteBytecode; ContractRewriter? contractRewriter = rewriteBytecode?.Count > 0 ? new ContractRewriter(rewriteBytecode) : null; - ITransactionProcessor txProcessor = changeableTxProcessingEnv.TransactionProcessor; - IWorldState worldState = changeableTxProcessingEnv.WorldState; - var transactionExecutor = new BlockProcessor.BlockProductionTransactionsExecutor( new BuildUpTransactionProcessorAdapter(txProcessor), worldState, @@ -258,24 +257,17 @@ BlockProducerEnv Create() { ReadOnlyBlockTree readOnlyBlockTree = blockTree.AsReadOnly(); - IReadOnlyTxProcessorSource txProcessingEnv = readOnlyTxProcessingEnvFactory.Create(); - IReadOnlyTxProcessingScope scope = txProcessingEnv.Build(null); - BlockProcessor blockProcessor = CreateBlockProcessor(scope); - - IBlockchainProcessor blockchainProcessor = - new BlockchainProcessor( - readOnlyBlockTree, - blockProcessor, - compositeBlockPreprocessorStep, - apiStateReader, - logManager, - BlockchainProcessor.Options.NoReceipts); + IWorldState worldState = worldStateManager.CreateResettableWorldState(); + ILifetimeScope innerLifetime = lifetimeScope.BeginLifetimeScope((builder) => builder + .AddSingleton(worldState) + .AddSingleton(BlockchainProcessor.Options.NoReceipts) + .AddSingleton(CreateBlockProcessor) + .AddDecorator()); + lifetimeScope.Disposer.AddInstanceForAsyncDisposal(innerLifetime); - OneTimeChainProcessor chainProcessor = new( - scope.WorldState, - blockchainProcessor); + IBlockchainProcessor chainProcessor = innerLifetime.Resolve(); - return new BlockProducerEnv(readOnlyBlockTree, chainProcessor, scope.WorldState, CreateTxSourceForProducer()); + return new BlockProducerEnv(readOnlyBlockTree, chainProcessor, worldState, CreateTxSourceForProducer()); } return _blockProducerContext ??= Create(); diff --git a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs index f909b71f131..e782eac5931 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/SnapshotManager.cs @@ -67,7 +67,7 @@ public Address GetBlockSealer(BlockHeader header) Signature signature = new(signatureBytes); signature.V += Signature.VOffset; ValueHash256 message = CalculateCliqueHeaderHash(header); - Address address = _ecdsa.RecoverAddress(signatureBytes, in message); + Address address = _ecdsa.RecoverAddress(signature, in message); _signatures.Set(header.Hash, address); return address; } diff --git a/src/Nethermind/Nethermind.Consensus.Test/CensorshipDetectorTests.cs b/src/Nethermind/Nethermind.Consensus.Test/CensorshipDetectorTests.cs index d2797b8a1d5..8c5650976ba 100644 --- a/src/Nethermind/Nethermind.Consensus.Test/CensorshipDetectorTests.cs +++ b/src/Nethermind/Nethermind.Consensus.Test/CensorshipDetectorTests.cs @@ -259,7 +259,7 @@ private TxPool.TxPool CreatePool(bool eip1559Enabled = true) return new( _ethereumEcdsa, new BlobTxStorage(), - new ChainHeadInfoProvider(_specProvider, _blockTree, _stateProvider, new CodeInfoRepository()), + new ChainHeadInfoProvider(_specProvider, _blockTree, _stateProvider, new EthereumCodeInfoRepository()), new TxPoolConfig(), new TxValidator(_specProvider.ChainId), _logManager, diff --git a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs index 9ef10276ead..04aac92a486 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/ProcessingStats.cs @@ -73,7 +73,7 @@ public void CaptureStartStats() _startSStoreOps = Evm.Metrics.ThreadLocalSStoreOpcode; _startCallOps = Evm.Metrics.ThreadLocalCalls; _startEmptyCalls = Evm.Metrics.ThreadLocalEmptyCalls; - _startCachedContractsUsed = Db.Metrics.ThreadLocalCodeDbCache; + _startCachedContractsUsed = Evm.Metrics.ThreadLocalCodeDbCache; _startContractsAnalyzed = Evm.Metrics.ThreadLocalContractsAnalysed; _startCreateOps = Evm.Metrics.ThreadLocalCreates; _startSelfDestructOps = Evm.Metrics.ThreadLocalSelfDestructs; @@ -106,7 +106,7 @@ public void UpdateStats(Block? block, BlockHeader? baseBlock, long blockProcessi blockData.CurrentSStoreOps = Evm.Metrics.ThreadLocalSStoreOpcode; blockData.CurrentCallOps = Evm.Metrics.ThreadLocalCalls; blockData.CurrentEmptyCalls = Evm.Metrics.ThreadLocalEmptyCalls; - blockData.CurrentCachedContractsUsed = Db.Metrics.ThreadLocalCodeDbCache; + blockData.CurrentCachedContractsUsed = Evm.Metrics.ThreadLocalCodeDbCache; blockData.CurrentContractsAnalyzed = Evm.Metrics.ThreadLocalContractsAnalysed; blockData.CurrentCreatesOps = Evm.Metrics.ThreadLocalCreates; blockData.CurrentSelfDestructOps = Evm.Metrics.ThreadLocalSelfDestructs; diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index 967729a330a..b9fac250056 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -41,6 +41,7 @@ using Nethermind.Specs.ChainSpecStyle; using Nethermind.Specs.Test; using Nethermind.Evm.State; +using Nethermind.Network; using Nethermind.State; using Nethermind.State.Repositories; using Nethermind.TxPool; @@ -58,6 +59,7 @@ public class TestBlockchain : IDisposable public IMainProcessingContext MainProcessingContext => _fromContainer.MainProcessingContext; public IReceiptStorage ReceiptStorage => _fromContainer.ReceiptStorage; public ITxPool TxPool => _fromContainer.TxPool; + public IForkInfo ForkInfo => _fromContainer.ForkInfo; public IWorldStateManager WorldStateManager => _fromContainer.WorldStateManager; public IReadOnlyTxProcessingEnvFactory ReadOnlyTxProcessingEnvFactory => _fromContainer.ReadOnlyTxProcessingEnvFactory; public IShareableTxProcessorSource ShareableTxProcessorSource => _fromContainer.ShareableTxProcessorSource; @@ -162,7 +164,8 @@ private record FromContainer( ManualTimestamper ManualTimestamper, IManualBlockProductionTrigger BlockProductionTrigger, IShareableTxProcessorSource ShareableTxProcessorSource, - ISealer Sealer + ISealer Sealer, + IForkInfo ForkInfo ) { } diff --git a/src/Nethermind/Nethermind.Core.Test/Container/KeyedMapperRegistrationSourceTests.cs b/src/Nethermind/Nethermind.Core.Test/Container/KeyedMapperRegistrationSourceTests.cs new file mode 100644 index 00000000000..9b697e1c3c6 --- /dev/null +++ b/src/Nethermind/Nethermind.Core.Test/Container/KeyedMapperRegistrationSourceTests.cs @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Autofac; +using FluentAssertions; +using NUnit.Framework; + +namespace Nethermind.Core.Test.Container; + +public class KeyedMapperRegistrationSourceTests +{ + [Test] + public void TestCanMap() + { + using IContainer cont = new ContainerBuilder() + .AddKeyedSingleton("Key", new ClassA("Property1")) + .AddKeyedAdapter((a) => new ClassB(a.Property)) + .Build(); + + cont.ResolveKeyed("Key").Property.Should().Be("Property1"); + } + + private record ClassA(string Property); + private record ClassB(string Property); +} diff --git a/src/Nethermind/Nethermind.Core.Test/Db/TestMemDbProvider.cs b/src/Nethermind/Nethermind.Core.Test/Db/TestMemDbProvider.cs new file mode 100644 index 00000000000..b13c69f5aff --- /dev/null +++ b/src/Nethermind/Nethermind.Core.Test/Db/TestMemDbProvider.cs @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + + +using System; +using System.Threading.Tasks; +using Autofac; +using Nethermind.Api; +using Nethermind.Blockchain.Receipts; +using Nethermind.Blockchain.Synchronization; +using Nethermind.Db; +using Nethermind.Init.Modules; + +namespace Nethermind.Core.Test.Db +{ + public class TestMemDbProvider + { + public static Task InitAsync() + { + return Task.FromResult(Init()); + } + + public static IDbProvider Init() + { + return new ContainerBuilder() + .AddModule(new DbModule(new InitConfig() { DiagnosticMode = DiagnosticMode.MemDb }, new ReceiptConfig(), new SyncConfig())) + .AddSingleton() + .Build() + .Resolve(); + } + } + + /// + /// Like , but also dispose lifetime scope. Useful for existing test to make sure + /// container is disposed properly. + /// + public class ContainerOwningDbProvider(ILifetimeScope ctx) : DbProvider(ctx), IDisposable + { + public override void Dispose() + { + ctx.Dispose(); + } + } +} diff --git a/src/Nethermind/Nethermind.Core.Test/Modules/PseudoNethermindModule.cs b/src/Nethermind/Nethermind.Core.Test/Modules/PseudoNethermindModule.cs index c141f4418e9..5d2a0f13e2a 100644 --- a/src/Nethermind/Nethermind.Core.Test/Modules/PseudoNethermindModule.cs +++ b/src/Nethermind/Nethermind.Core.Test/Modules/PseudoNethermindModule.cs @@ -61,7 +61,6 @@ protected override void Load(ContainerBuilder builder) initConfig.BackgroundTaskMaxNumber, logManager)) .AddSingleton(new FileSystem()) - .AddSingleton(new DbProvider()) .AddSingleton(new ProcessExitSource(default)) .AddSingleton() diff --git a/src/Nethermind/Nethermind.Core.Test/Modules/TestBlockProcessingModule.cs b/src/Nethermind/Nethermind.Core.Test/Modules/TestBlockProcessingModule.cs index d9fcb974266..07434083950 100644 --- a/src/Nethermind/Nethermind.Core.Test/Modules/TestBlockProcessingModule.cs +++ b/src/Nethermind/Nethermind.Core.Test/Modules/TestBlockProcessingModule.cs @@ -38,7 +38,7 @@ protected override void Load(ContainerBuilder builder) { IWorldState worldState = ctx.Resolve().GlobalWorldState; PreBlockCaches? preBlockCaches = (worldState as IPreBlockCaches)?.Caches; - return new CodeInfoRepository(preBlockCaches?.PrecompileCache); + return new EthereumCodeInfoRepository(preBlockCaches?.PrecompileCache); }) .AddSingleton() @@ -115,7 +115,7 @@ private MainBlockProcessingContext ConfigureMainBlockProcessingContext(ILifetime return innerScope.Resolve(); } - private class AutoBlockProducerFactory(ILifetimeScope rootLifetime, IBlockProducerEnvFactory producerEnvFactory) : IBlockProducerFactory where T : IBlockProducer + public class AutoBlockProducerFactory(ILifetimeScope rootLifetime, IBlockProducerEnvFactory producerEnvFactory) : IBlockProducerFactory where T : IBlockProducer { public IBlockProducer InitBlockProducer() { diff --git a/src/Nethermind/Nethermind.Core.Test/Modules/TestEnvironmentModule.cs b/src/Nethermind/Nethermind.Core.Test/Modules/TestEnvironmentModule.cs index 664c4a0c3cb..90b4e668fb9 100644 --- a/src/Nethermind/Nethermind.Core.Test/Modules/TestEnvironmentModule.cs +++ b/src/Nethermind/Nethermind.Core.Test/Modules/TestEnvironmentModule.cs @@ -39,7 +39,6 @@ protected override void Load(ContainerBuilder builder) builder .AddSingleton(new TestLogManager(LogLevel.Error)) // Limbologs actually have IsTrace set to true, so actually slow. .AddSingleton((_) => new MemDbFactory()) - .AddSingleton(TestMemDbProvider.Init()) // These two dont use db provider .AddKeyedSingleton(DbNames.PeersDb, (_) => new MemDb()) .AddKeyedSingleton(DbNames.DiscoveryNodes, (_) => new MemDb()) diff --git a/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs b/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs index 27517c12d8f..afe1a55f29a 100644 --- a/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs +++ b/src/Nethermind/Nethermind.Core.Test/TestWorldStateFactory.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Consensus.Validators; +using Nethermind.Core.Test.Db; using Nethermind.Db; using Nethermind.Logging; using Nethermind.Evm.State; diff --git a/src/Nethermind/Nethermind.Core/Container/KeyedMapperRegistrationSource.cs b/src/Nethermind/Nethermind.Core/Container/KeyedMapperRegistrationSource.cs new file mode 100644 index 00000000000..dd0e7b21ed1 --- /dev/null +++ b/src/Nethermind/Nethermind.Core/Container/KeyedMapperRegistrationSource.cs @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using System.Linq; +using Autofac; +using Autofac.Core; +using Autofac.Core.Activators.Delegate; +using Autofac.Core.Lifetime; +using Autofac.Core.Registration; + +namespace Nethermind.Core.Container; + +/// +/// Utility that map between two type that act on keyed service. +/// +/// +/// +/// +public class KeyedMapperRegistrationSource(Func mapper) : IRegistrationSource where TFrom : notnull +{ + public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) + { + if (service is not KeyedService keyedService || keyedService.ServiceType != typeof(TTo)) + { + // Not a keyed service + return Enumerable.Empty(); + } + + ComponentRegistration registration = new ComponentRegistration( + Guid.NewGuid(), + new DelegateActivator(keyedService.ServiceType, (c, p) => + { + TFrom from = c.ResolveKeyed(keyedService.ServiceKey); + return mapper(from)!; + }), + new RootScopeLifetime(), + InstanceSharing.Shared, + InstanceOwnership.OwnedByLifetimeScope, + new[] { service }, + new Dictionary()); + + return [registration]; + } + + public bool IsAdapterForIndividualComponents => true; +} diff --git a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs b/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs index b33a3e412c4..0fe01a8c5ca 100644 --- a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs +++ b/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs @@ -486,6 +486,11 @@ public static IRegistrationBuilder Fixed(this reg.RegistrationData.Options |= RegistrationOptions.Fixed; return reg; } + + public static ContainerBuilder AddKeyedAdapter(this ContainerBuilder builder, Func mapper) where TFrom : notnull + { + return builder.AddSource(new KeyedMapperRegistrationSource(mapper)); + } } /// diff --git a/src/Nethermind/Nethermind.Core/Eip2935Constants.cs b/src/Nethermind/Nethermind.Core/Eip2935Constants.cs index 63664121d6a..1cfd0c1efc0 100644 --- a/src/Nethermind/Nethermind.Core/Eip2935Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip2935Constants.cs @@ -8,6 +8,8 @@ namespace Nethermind.Core; /// public static class Eip2935Constants { + public const string ContractAddressKey = "HISTORY_STORAGE_ADDRESS"; + /// /// The HISTORY_STORAGE_ADDRESS parameter. /// diff --git a/src/Nethermind/Nethermind.Core/Eip4788Constants.cs b/src/Nethermind/Nethermind.Core/Eip4788Constants.cs index fed5db663d8..af10e162a95 100644 --- a/src/Nethermind/Nethermind.Core/Eip4788Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip4788Constants.cs @@ -8,6 +8,8 @@ namespace Nethermind.Core; /// public static class Eip4788Constants { + public const string ContractAddressKey = "BEACON_ROOTS_ADDRESS"; + /// /// Gets the BEACON_ROOTS_ADDRESS parameter. /// diff --git a/src/Nethermind/Nethermind.Core/Eip6110Constants.cs b/src/Nethermind/Nethermind.Core/Eip6110Constants.cs index 98eb35fa328..2fadd552747 100644 --- a/src/Nethermind/Nethermind.Core/Eip6110Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip6110Constants.cs @@ -5,6 +5,8 @@ namespace Nethermind.Core; public static class Eip6110Constants { + public const string ContractAddressKey = "DEPOSIT_CONTRACT_ADDRESS"; + public static readonly Address MainnetDepositContractAddress = new("0x00000000219ab540356cbb839cbe05303d7705fa"); public static readonly Address HoleskyDepositContractAddress = new("0x4242424242424242424242424242424242424242"); public static readonly Address SepoliaDepositContractAddress = new("0x7f02c3e3c98b133055b8b348b2ac625669ed295d"); diff --git a/src/Nethermind/Nethermind.Core/Eip7002Constants.cs b/src/Nethermind/Nethermind.Core/Eip7002Constants.cs index b786664cd81..f7033eae7c4 100644 --- a/src/Nethermind/Nethermind.Core/Eip7002Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip7002Constants.cs @@ -5,5 +5,7 @@ namespace Nethermind.Core; public static class Eip7002Constants { + public const string ContractAddressKey = "WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS"; + public static readonly Address WithdrawalRequestPredeployAddress = new("0x00000961Ef480Eb55e80D19ad83579A64c007002"); } diff --git a/src/Nethermind/Nethermind.Core/Eip7251Constants.cs b/src/Nethermind/Nethermind.Core/Eip7251Constants.cs index a0a453010e4..171c30d2abf 100644 --- a/src/Nethermind/Nethermind.Core/Eip7251Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip7251Constants.cs @@ -5,5 +5,7 @@ namespace Nethermind.Core; public static class Eip7251Constants { + public const string ContractAddressKey = "CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS"; + public static readonly Address ConsolidationRequestPredeployAddress = new("0x0000BBdDc7CE488642fb579F8B00f3a590007251"); } diff --git a/src/Nethermind/Nethermind.Core/Extensions/ByteArrayExtensions.cs b/src/Nethermind/Nethermind.Core/Extensions/ByteArrayExtensions.cs index 92bda49291a..94c1c12f86a 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/ByteArrayExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/ByteArrayExtensions.cs @@ -56,18 +56,23 @@ public static byte[] SliceWithZeroPaddingEmptyOnError(this byte[] bytes, int sta return slice; } - public static byte[] SliceWithZeroPaddingEmptyOnError(this ReadOnlySpan bytes, int startIndex, int length) + public static ReadOnlySpan SliceWithZeroPaddingEmptyOnError(this ReadOnlySpan bytes, int startIndex, int length) { int copiedFragmentLength = Math.Min(bytes.Length - startIndex, length); if (copiedFragmentLength <= 0) { - return []; + return default; } - byte[] slice = new byte[length]; + ReadOnlySpan sliced = bytes.Slice(startIndex, copiedFragmentLength); + if (copiedFragmentLength < length) + { + byte[] extended = new byte[length]; + sliced.CopyTo(extended); + sliced = extended; + } - bytes.Slice(startIndex, copiedFragmentLength).CopyTo(slice.AsSpan(0, copiedFragmentLength)); - return slice; + return sliced; } } diff --git a/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs b/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs index 0f78e509169..39158a6c10b 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs @@ -182,7 +182,7 @@ public static bool IsZero(this ReadOnlySpan bytes) return bytes.IndexOfAnyExcept((byte)0) < 0; } - public static int LeadingZerosCount(this Span bytes, int startIndex = 0) + public static int LeadingZerosCount(this ReadOnlySpan bytes, int startIndex = 0) { int nonZeroIndex = bytes[startIndex..].IndexOfAnyExcept((byte)0); return nonZeroIndex < 0 ? bytes.Length - startIndex : nonZeroIndex; diff --git a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs index f3250d2437f..ef0163a626c 100644 --- a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs @@ -402,7 +402,7 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec public bool ModExpEnabled => IsEip198Enabled; - public bool Bn128Enabled => IsEip196Enabled && IsEip197Enabled; + public bool BN254Enabled => IsEip196Enabled && IsEip197Enabled; public bool BlakeEnabled => IsEip152Enabled; diff --git a/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs b/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs index 2da9efc5a45..65aef9301ec 100644 --- a/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs +++ b/src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs @@ -112,7 +112,7 @@ public class ReleaseSpecDecorator(IReleaseSpec spec) : IReleaseSpec public virtual bool UseTxAccessLists => spec.UseTxAccessLists; public virtual bool AddCoinbaseToTxAccessList => spec.AddCoinbaseToTxAccessList; public virtual bool ModExpEnabled => spec.ModExpEnabled; - public virtual bool Bn128Enabled => spec.Bn128Enabled; + public virtual bool BN254Enabled => spec.BN254Enabled; public virtual bool BlakeEnabled => spec.BlakeEnabled; public virtual bool Bls381Enabled => spec.Bls381Enabled; public virtual bool ChargeForTopLevelCreate => spec.ChargeForTopLevelCreate; diff --git a/src/Nethermind/Nethermind.Crypto/EthereumEcdsa.cs b/src/Nethermind/Nethermind.Crypto/EthereumEcdsa.cs index 00fd2905cef..73f844d8aca 100644 --- a/src/Nethermind/Nethermind.Crypto/EthereumEcdsa.cs +++ b/src/Nethermind/Nethermind.Crypto/EthereumEcdsa.cs @@ -4,10 +4,8 @@ using System; using System.Globalization; using System.Numerics; -using System.Runtime.CompilerServices; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Core.Specs; namespace Nethermind.Crypto { @@ -27,15 +25,9 @@ public class EthereumEcdsa(ulong chainId) : Ecdsa, IEthereumEcdsa public ulong ChainId => chainId; - public EthereumEcdsa(ISpecProvider specProvider) : this(specProvider.ChainId) - { - } - public Address? RecoverAddress(Signature signature, in ValueHash256 message) => RecoverAddress(signature.Bytes, signature.RecoveryId, message.Bytes); - public Address? RecoverAddress(Span signatureBytes65, in ValueHash256 message) => RecoverAddress(signatureBytes65[..64], signatureBytes65[64], message.Bytes); - - public static Address? RecoverAddress(Span signatureBytes64, byte v, ReadOnlySpan message) + private static Address? RecoverAddress(Span signatureBytes64, byte v, ReadOnlySpan message) { Span publicKey = stackalloc byte[65]; bool success = SpanSecP256k1.RecoverKeyFromCompact( diff --git a/src/Nethermind/Nethermind.Crypto/IEthereumEcdsa.cs b/src/Nethermind/Nethermind.Crypto/IEthereumEcdsa.cs index ed03f79d939..b4a02f65c09 100644 --- a/src/Nethermind/Nethermind.Crypto/IEthereumEcdsa.cs +++ b/src/Nethermind/Nethermind.Crypto/IEthereumEcdsa.cs @@ -14,8 +14,5 @@ public interface IEthereumEcdsa : IEcdsa => RecoverAddress(signature, in message.ValueHash256); Address? RecoverAddress(Signature signature, in ValueHash256 message); - Address? RecoverAddress(Span signatureBytes, Hash256 message) - => RecoverAddress(signatureBytes, in message.ValueHash256); - Address? RecoverAddress(Span signatureBytes, in ValueHash256 message); } } diff --git a/src/Nethermind/Nethermind.Crypto/NullEthereumEcdsa.cs b/src/Nethermind/Nethermind.Crypto/NullEthereumEcdsa.cs index 739d61d290c..9274ff54140 100644 --- a/src/Nethermind/Nethermind.Crypto/NullEthereumEcdsa.cs +++ b/src/Nethermind/Nethermind.Crypto/NullEthereumEcdsa.cs @@ -37,11 +37,6 @@ public Address RecoverAddress(Transaction tx, bool useSignatureChainId = false) throw new InvalidOperationException($"{nameof(NullEthereumEcdsa)} does not expect any calls"); } - public Address RecoverAddress(Span signatureBytes, in ValueHash256 message) - { - throw new InvalidOperationException($"{nameof(NullEthereumEcdsa)} does not expect any calls"); - } - public bool Verify(Address sender, Transaction tx) { throw new InvalidOperationException($"{nameof(NullEthereumEcdsa)} does not expect any calls"); diff --git a/src/Nethermind/Nethermind.Db.Rocks/RocksDbFactory.cs b/src/Nethermind/Nethermind.Db.Rocks/RocksDbFactory.cs index 53eb3eb7c50..e0c02bbbe04 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/RocksDbFactory.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/RocksDbFactory.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using Nethermind.Api; using Nethermind.Db.Rocks.Config; using Nethermind.Logging; @@ -17,6 +18,12 @@ public class RocksDbFactory : IDbFactory private readonly IntPtr _sharedCache; + public RocksDbFactory(IDbConfig dbConfig, IInitConfig initConfig, ILogManager logManager) + : this(dbConfig, logManager, initConfig.BaseDbPath) + { + + } + public RocksDbFactory(IDbConfig dbConfig, ILogManager logManager, string basePath) { _dbConfig = dbConfig; diff --git a/src/Nethermind/Nethermind.Db.Test/DbProviderTests.cs b/src/Nethermind/Nethermind.Db.Test/DbProviderTests.cs deleted file mode 100644 index edc441243f8..00000000000 --- a/src/Nethermind/Nethermind.Db.Test/DbProviderTests.cs +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using NUnit.Framework; - -namespace Nethermind.Db.Test; - -[Parallelizable(ParallelScope.All)] -public class DbProviderTests -{ - [Test] - public void DbProvider_CanRegisterMemDb() - { - MemDbFactory memDbFactory = new MemDbFactory(); - using (DbProvider dbProvider = new DbProvider()) - { - IDb memDb = memDbFactory.CreateDb(new DbSettings("MemDb", "MemDb")); - dbProvider.RegisterDb("MemDb", memDb); - IDb db = dbProvider.GetDb("MemDb"); - Assert.That(db, Is.EqualTo(memDb)); - } - } - - [Test] - public void DbProvider_CanRegisterColumnsDb() - { - using (DbProvider dbProvider = new DbProvider()) - { - MemDbFactory memDbFactory = new MemDbFactory(); - IColumnsDb memSnapshotableDb = memDbFactory.CreateColumnsDb("ColumnsDb"); - dbProvider.RegisterColumnDb("ColumnsDb", memSnapshotableDb); - IColumnsDb columnsDb = dbProvider.GetColumnDb("ColumnsDb"); - Assert.That(columnsDb, Is.EqualTo(memSnapshotableDb)); - Assert.That(memSnapshotableDb is IColumnsDb, Is.True); - } - } - - [Test] - public void DbProvider_ThrowExceptionOnRegisteringTheSameDb() - { - using (DbProvider dbProvider = new DbProvider()) - { - MemDbFactory memDbFactory = new MemDbFactory(); - IColumnsDb memSnapshotableDb = memDbFactory.CreateColumnsDb("ColumnsDb"); - dbProvider.RegisterColumnDb("ColumnsDb", memSnapshotableDb); - Assert.Throws(() => dbProvider.RegisterColumnDb("columnsdb", new MemColumnsDb())); - } - } - - [Test] - public void DbProvider_ThrowExceptionOnGettingNotRegisteredDb() - { - using (DbProvider dbProvider = new DbProvider()) - { - MemDbFactory memDbFactory = new MemDbFactory(); - IColumnsDb memSnapshotableDb = memDbFactory.CreateColumnsDb("ColumnsDb"); - dbProvider.RegisterColumnDb("ColumnsDb", memSnapshotableDb); - Assert.Throws(() => dbProvider.GetColumnDb("differentdb")); - } - } -} diff --git a/src/Nethermind/Nethermind.Db.Test/DbTrackerTests.cs b/src/Nethermind/Nethermind.Db.Test/DbTrackerTests.cs new file mode 100644 index 00000000000..27a1344fc3f --- /dev/null +++ b/src/Nethermind/Nethermind.Db.Test/DbTrackerTests.cs @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Linq; +using Autofac; +using FluentAssertions; +using Nethermind.Core; +using NUnit.Framework; + +namespace Nethermind.Db.Test; + +public class DbTrackerTests +{ + [Test] + public void TestTrackOnlyCreatedDb() + { + using IContainer container = new ContainerBuilder() + .AddSingleton() + .AddDecorator() + .AddSingleton() + .Build(); + + IDbFactory dbFactory = container.Resolve(); + + DbTracker tracker = container.Resolve(); + tracker.GetAllDbMeta().Count().Should().Be(0); + + dbFactory.CreateDb(new DbSettings("TestDb", "TestDb")); + + tracker.GetAllDbMeta().Count().Should().Be(1); + var firstEntry = tracker.GetAllDbMeta().First(); + firstEntry.Key.Should().Be("TestDb"); + } +} diff --git a/src/Nethermind/Nethermind.Db.Test/ReadOnlyDbProviderTests.cs b/src/Nethermind/Nethermind.Db.Test/ReadOnlyDbProviderTests.cs index 5bb30423e2d..7bbeaa18d68 100644 --- a/src/Nethermind/Nethermind.Db.Test/ReadOnlyDbProviderTests.cs +++ b/src/Nethermind/Nethermind.Db.Test/ReadOnlyDbProviderTests.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using NSubstitute; using NUnit.Framework; namespace Nethermind.Db.Test @@ -12,7 +13,7 @@ public class ReadOnlyDbProviderTests [TestCase(false)] public void Can_clear(bool localChanges) { - ReadOnlyDbProvider dbProvider = new(new DbProvider(), localChanges); + ReadOnlyDbProvider dbProvider = new(Substitute.For(), localChanges); dbProvider.ClearTempChanges(); } } diff --git a/src/Nethermind/Nethermind.Db.Test/Rpc/RpcDbFactoryTests.cs b/src/Nethermind/Nethermind.Db.Test/Rpc/RpcDbFactoryTests.cs index 276b7251286..09b1d477fbb 100644 --- a/src/Nethermind/Nethermind.Db.Test/Rpc/RpcDbFactoryTests.cs +++ b/src/Nethermind/Nethermind.Db.Test/Rpc/RpcDbFactoryTests.cs @@ -2,7 +2,10 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.IO.Abstractions; +using Autofac; using FluentAssertions; +using Nethermind.Core; +using Nethermind.Core.Test.Modules; using Nethermind.Db.FullPruning; using Nethermind.Db.Rpc; using Nethermind.JsonRpc.Client; @@ -31,9 +34,12 @@ static void ValidateDb(params object[] dbs) IJsonRpcClient jsonRpcClient = Substitute.For(); IDbFactory rpcDbFactory = new RpcDbFactory(new MemDbFactory(), jsonSerializer, jsonRpcClient, LimboLogs.Instance); - IDbProvider memDbProvider = new DbProvider(); - StandardDbInitializer standardDbInitializer = new(memDbProvider, rpcDbFactory, Substitute.For()); - standardDbInitializer.InitStandardDbs(true); + using IContainer container = new ContainerBuilder() + .AddModule(new TestNethermindModule()) + .AddSingleton(rpcDbFactory) + .Build(); + + IDbProvider memDbProvider = container.Resolve(); ValidateDb>( memDbProvider.ReceiptsDb); diff --git a/src/Nethermind/Nethermind.Db.Test/StandardDbInitializerTests.cs b/src/Nethermind/Nethermind.Db.Test/StandardDbInitializerTests.cs index 6b927954aae..c47dfff4c42 100644 --- a/src/Nethermind/Nethermind.Db.Test/StandardDbInitializerTests.cs +++ b/src/Nethermind/Nethermind.Db.Test/StandardDbInitializerTests.cs @@ -5,10 +5,17 @@ using System.IO; using System.IO.Abstractions; using System.Threading.Tasks; +using Autofac; using FluentAssertions; +using Nethermind.Api; +using Nethermind.Blockchain.Receipts; +using Nethermind.Blockchain.Synchronization; +using Nethermind.Core; +using Nethermind.Core.Test.Db; using Nethermind.Db.FullPruning; using Nethermind.Db.Rocks; using Nethermind.Db.Rocks.Config; +using Nethermind.Init.Modules; using Nethermind.Logging; using NSubstitute; using NUnit.Framework; @@ -66,16 +73,31 @@ public async Task InitializerTests_WithPruning() dbProvider.StateDb.Should().BeOfType(); } - private async Task InitializeStandardDb(bool useReceipts, bool useMemDb, string path) + private Task InitializeStandardDb(bool useReceipts, bool useMemDb, string path) { - IDbProvider dbProvider = new DbProvider(); - IDbFactory dbFactory = useMemDb - ? new MemDbFactory() - : new RocksDbFactory(new DbConfig(), LimboLogs.Instance, Path.Combine(_folderWithDbs, path)); + IInitConfig initConfig = new InitConfig() + { + DiagnosticMode = useMemDb ? DiagnosticMode.MemDb : DiagnosticMode.None, + BaseDbPath = path + }; - StandardDbInitializer initializer = new(dbProvider, dbFactory, Substitute.For()); - await initializer.InitStandardDbsAsync(useReceipts); - return dbProvider; + IContainer container = new ContainerBuilder() + .AddModule(new DbModule(initConfig, new ReceiptConfig() + { + StoreReceipts = useReceipts + }, new SyncConfig() + { + DownloadReceiptsInFastSync = useReceipts + })) + .AddModule(new WorldStateModule(initConfig)) // For the full pruning db + .AddSingleton(new DbConfig()) + .AddSingleton(initConfig) + .AddSingleton(LimboLogs.Instance) + .AddSingleton() + .AddSingleton() + .Build(); + + return Task.FromResult(container.Resolve()); } private static Type GetReceiptsType(bool useReceipts, Type receiptType = null) => useReceipts ? receiptType ?? typeof(ColumnsDb) : typeof(ReadOnlyColumnsDb); diff --git a/src/Nethermind/Nethermind.Db/DbModule.cs b/src/Nethermind/Nethermind.Db/DbModule.cs deleted file mode 100644 index 9405740570a..00000000000 --- a/src/Nethermind/Nethermind.Db/DbModule.cs +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Autofac; -using Nethermind.Core; - -namespace Nethermind.Db; - -public class DbModule : Module -{ - protected override void Load(ContainerBuilder builder) - { - base.Load(builder); - builder - .AddScoped((dbProvider) => dbProvider.AsReadOnly(false)); - - // TODO: Have hooks that automatically get these - string[] dbNames = [ - DbNames.State, - DbNames.Code, - DbNames.Metadata, - DbNames.BlockNumbers, - DbNames.BadBlocks, - DbNames.Blocks, - DbNames.Headers, - DbNames.BlockInfos, - DbNames.BadBlocks, - DbNames.Bloom, - DbNames.Metadata, - ]; - foreach (string dbName in dbNames) - { - ConfigureDb(builder, dbName); - } - - ConfigureColumnDb(builder, DbNames.Receipts); - } - - private static void ConfigureDb(ContainerBuilder builder, string dbName) - { - builder.Register((ctx) => - { - IDbProvider dbProvider = ctx.Resolve(); - IDb db = dbProvider.GetDb(dbName); - return db; - }) - .ExternallyOwned() - .Named(dbName) - .Named(dbName) - .Named(dbName) - .Named(dbName); - - builder.Register((ctx) => - { - IDbProvider dbProvider = ctx.Resolve(); - IDb db = dbProvider.GetDb(dbName); - return db as ITunableDb ?? new NoopTunableDb(); - }) - .ExternallyOwned() - .Named(dbName); - } - - - private static void ConfigureColumnDb(ContainerBuilder builder, string dbName) - { - builder.Register((ctx) => - { - IDbProvider dbProvider = ctx.Resolve(); - IColumnsDb db = dbProvider.GetColumnDb(dbName); - return db; - }) - .ExternallyOwned() - .As>(); - - builder.Register((ctx) => - { - IDbProvider dbProvider = ctx.Resolve(); - IColumnsDb db = dbProvider.GetColumnDb(dbName); - return db as ITunableDb ?? new NoopTunableDb(); - }) - .ExternallyOwned() - .Named(dbName); - } -} diff --git a/src/Nethermind/Nethermind.Db/DbProvider.cs b/src/Nethermind/Nethermind.Db/DbProvider.cs index bf7b9ee02e4..4c4583025ea 100644 --- a/src/Nethermind/Nethermind.Db/DbProvider.cs +++ b/src/Nethermind/Nethermind.Db/DbProvider.cs @@ -1,94 +1,24 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; +using Autofac; namespace Nethermind.Db { - public class DbProvider : IDbProvider + public class DbProvider(IComponentContext ctx) : IDbProvider { - private readonly ConcurrentDictionary _registeredDbs = - new(StringComparer.InvariantCultureIgnoreCase); - private readonly ConcurrentDictionary _registeredColumnDbs = - new(StringComparer.InvariantCultureIgnoreCase); - - public IDictionary RegisteredDbs => _registeredDbs; - public IDictionary RegisteredColumnDbs => _registeredColumnDbs; - - public void Dispose() + public virtual void Dispose() { - foreach (KeyValuePair registeredDb in _registeredDbs) - { - registeredDb.Value?.Dispose(); - } } public T GetDb(string dbName) where T : class, IDb { - if (!_registeredDbs.TryGetValue(dbName, out IDb? found)) - { - throw new ArgumentException($"{dbName} database has not been registered in {nameof(DbProvider)}."); - } - - if (found is not T result) - { - throw new IOException( - $"An attempt was made to resolve DB {dbName} as {typeof(T)} while its type is {found.GetType()}."); - } - - return result; - } - - public void RegisterDb(string dbName, T db) where T : class, IDb - { - if (_registeredDbs.ContainsKey(dbName)) - { - throw new ArgumentException($"{dbName} has already registered."); - } - - _registeredDbs.TryAdd(dbName, db); + return (T)ctx.ResolveKeyed(dbName); } public IColumnsDb GetColumnDb(string dbName) { - if (!_registeredColumnDbs.TryGetValue(dbName, out object found)) - { - throw new ArgumentException($"{dbName} database has not been registered in {nameof(DbProvider)}."); - } - - if (found is not IColumnsDb result) - { - throw new IOException( - $"An attempt was made to resolve DB {dbName} as {typeof(T)} while its type is {found.GetType()}."); - } - - return result; - } - - public void RegisterColumnDb(string dbName, IColumnsDb db) - { - if (_registeredColumnDbs.ContainsKey(dbName)) - { - throw new ArgumentException($"{dbName} has already registered."); - } - - _registeredColumnDbs.TryAdd(dbName, db); - } - - public IEnumerable> GetAllDbMeta() - { - foreach (KeyValuePair kv in _registeredDbs) - { - yield return new KeyValuePair(kv.Key, kv.Value); - } - - foreach (KeyValuePair kv in _registeredColumnDbs) - { - yield return new KeyValuePair(kv.Key, (IDbMeta)kv.Value); - } + return ctx.Resolve>(); } } } diff --git a/src/Nethermind/Nethermind.Db/DbTracker.cs b/src/Nethermind/Nethermind.Db/DbTracker.cs new file mode 100644 index 00000000000..343d51f0d0f --- /dev/null +++ b/src/Nethermind/Nethermind.Db/DbTracker.cs @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using NonBlocking; + +namespace Nethermind.Db; + +public class DbTracker +{ + private readonly ConcurrentDictionary _createdDbs = new ConcurrentDictionary(); + + public void AddDb(string name, IDbMeta dbMeta) + { + _createdDbs.TryAdd(name, dbMeta); + } + + public IEnumerable> GetAllDbMeta() + { + return _createdDbs; + } + + public class DbFactoryInterceptor(DbTracker tracker, IDbFactory baseFactory) : IDbFactory + { + public IDb CreateDb(DbSettings dbSettings) + { + IDb db = baseFactory.CreateDb(dbSettings); + if (db is IDbMeta dbMeta) + { + tracker.AddDb(dbSettings.DbName, dbMeta); + } + return db; + } + + public IColumnsDb CreateColumnsDb(DbSettings dbSettings) where T : struct, Enum + { + IColumnsDb db = baseFactory.CreateColumnsDb(dbSettings); + if (db is IDbMeta dbMeta) + { + tracker.AddDb(dbSettings.DbName, dbMeta); + } + return db; + } + } +} diff --git a/src/Nethermind/Nethermind.Db/IDbProvider.cs b/src/Nethermind/Nethermind.Db/IDbProvider.cs index 7786271bc74..038d70c3842 100644 --- a/src/Nethermind/Nethermind.Db/IDbProvider.cs +++ b/src/Nethermind/Nethermind.Db/IDbProvider.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Collections.Generic; namespace Nethermind.Db { @@ -26,9 +25,5 @@ public interface IDbProvider : IDisposable T GetDb(string dbName) where T : class, IDb; IColumnsDb GetColumnDb(string dbName); - - void RegisterDb(string dbName, T db) where T : class, IDb; - void RegisterColumnDb(string dbName, IColumnsDb db); - IEnumerable> GetAllDbMeta(); } } diff --git a/src/Nethermind/Nethermind.Db/Metrics.cs b/src/Nethermind/Nethermind.Db/Metrics.cs index 8a510db9880..b4889866ab9 100644 --- a/src/Nethermind/Nethermind.Db/Metrics.cs +++ b/src/Nethermind/Nethermind.Db/Metrics.cs @@ -16,14 +16,6 @@ namespace Nethermind.Db { public static class Metrics { - [CounterMetric] - [Description("Number of Code DB cache reads.")] - public static long CodeDbCache => _codeDbCache.GetTotalValue(); - private static readonly ZeroContentionCounter _codeDbCache = new(); - [Description("Number of Code DB cache reads on thread.")] - internal static long ThreadLocalCodeDbCache => _codeDbCache.ThreadLocalValue; - internal static void IncrementCodeDbCache() => _codeDbCache.Increment(); - [CounterMetric] [Description("Number of State Trie cache hits.")] public static long StateTreeCache => _stateTreeCacheHits.GetTotalValue(); diff --git a/src/Nethermind/Nethermind.Db/ReadOnlyDbProvider.cs b/src/Nethermind/Nethermind.Db/ReadOnlyDbProvider.cs index 60f10da4bbb..e3546012967 100644 --- a/src/Nethermind/Nethermind.Db/ReadOnlyDbProvider.cs +++ b/src/Nethermind/Nethermind.Db/ReadOnlyDbProvider.cs @@ -56,20 +56,5 @@ public IColumnsDb GetColumnDb(string dbName) .GetColumnDb(dbName) .CreateReadOnly(_createInMemoryWriteStore)); } - - public void RegisterDb(string dbName, T db) where T : class, IDb - { - _wrappedProvider.RegisterDb(dbName, db); - } - - public void RegisterColumnDb(string dbName, IColumnsDb db) - { - _wrappedProvider.RegisterColumnDb(dbName, db); - } - - public IEnumerable> GetAllDbMeta() - { - return _wrappedProvider.GetAllDbMeta(); - } } } diff --git a/src/Nethermind/Nethermind.Db/RocksDbInitializer.cs b/src/Nethermind/Nethermind.Db/RocksDbInitializer.cs deleted file mode 100644 index 26be4d0ff27..00000000000 --- a/src/Nethermind/Nethermind.Db/RocksDbInitializer.cs +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Nethermind.Core.Collections; - -namespace Nethermind.Db -{ - public abstract class RocksDbInitializer - { - private readonly IDbProvider _dbProvider; - protected IDbFactory DbFactory { get; } - - private readonly List _registrations = new(); - - protected RocksDbInitializer(IDbProvider? dbProvider, IDbFactory? dbFactory) - { - _dbProvider = dbProvider ?? throw new ArgumentNullException(nameof(dbProvider)); - DbFactory = dbFactory ?? NullDbFactory.Instance; - } - - protected void RegisterCustomDb(string dbName, Func dbFunc) - { - void Action() - { - IDb db = dbFunc(); - _dbProvider.RegisterDb(dbName, db); - } - - _registrations.Add(Action); - } - - protected void RegisterCustomColumnDb(string dbName, Func> dbFunc) - { - void Action() - { - IColumnsDb db = dbFunc(); - _dbProvider.RegisterColumnDb(dbName, db); - } - - _registrations.Add(Action); - } - - protected void RegisterDb(DbSettings settings) => - AddRegisterAction(settings.DbName, () => CreateDb(settings)); - - protected void RegisterColumnsDb(DbSettings settings) where T : struct, Enum => - AddRegisterAction(settings.DbName, () => CreateColumnDb(settings)); - - private void AddRegisterAction(string dbName, Func dbCreation) => - _registrations.Add(() => _dbProvider.RegisterDb(dbName, dbCreation())); - private void AddRegisterAction(string dbName, Func> dbCreation) => - _registrations.Add(() => _dbProvider.RegisterColumnDb(dbName, dbCreation())); - - private IDb CreateDb(DbSettings settings) => DbFactory.CreateDb(settings); - - private IColumnsDb CreateColumnDb(DbSettings settings) where T : struct, Enum => - DbFactory.CreateColumnsDb(settings); - - protected void InitAll() - { - foreach (var registration in _registrations) - { - registration.Invoke(); - } - } - - protected async Task InitAllAsync() - { - using ArrayPoolList allInitializers = new(_registrations.Count); - foreach (Action registration in _registrations) - { - allInitializers.Add(Task.Run(() => registration.Invoke())); - } - - await Task.WhenAll(allInitializers.AsSpan()); - } - - protected static string GetTitleDbName(string dbName) => char.ToUpper(dbName[0]) + dbName[1..]; - } -} diff --git a/src/Nethermind/Nethermind.Db/StandardDbInitializer.cs b/src/Nethermind/Nethermind.Db/StandardDbInitializer.cs deleted file mode 100644 index 8a91bd8a4bc..00000000000 --- a/src/Nethermind/Nethermind.Db/StandardDbInitializer.cs +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System.IO.Abstractions; -using System.Threading; -using System.Threading.Tasks; -using Nethermind.Db.FullPruning; - -namespace Nethermind.Db -{ - public class StandardDbInitializer : RocksDbInitializer - { - private readonly IFileSystem _fileSystem; - - public StandardDbInitializer( - IDbProvider? dbProvider, - IDbFactory? rocksDbFactory, - IFileSystem? fileSystem = null) - : base(dbProvider, rocksDbFactory) - { - _fileSystem = fileSystem ?? new FileSystem(); - } - - public void InitStandardDbs(bool useReceiptsDb, bool useBlobsDb = true) - { - RegisterAll(useReceiptsDb, useBlobsDb); - InitAll(); - } - - public Task InitStandardDbsAsync(bool useReceiptsDb, bool useBlobsDb = true) - { - RegisterAll(useReceiptsDb, useBlobsDb); - return InitAllAsync(); - } - - private void RegisterAll(bool useReceiptsDb, bool useBlobsDb) - { - RegisterDb(BuildDbSettings(DbNames.Blocks)); - RegisterDb(BuildDbSettings(DbNames.Headers)); - RegisterDb(BuildDbSettings(DbNames.BlockNumbers)); - RegisterDb(BuildDbSettings(DbNames.BlockInfos)); - RegisterDb(BuildDbSettings(DbNames.BadBlocks)); - - DbSettings stateDbSettings = BuildDbSettings(DbNames.State); - RegisterCustomDb(DbNames.State, () => new FullPruningDb( - stateDbSettings, - DbFactory is not MemDbFactory - ? new FullPruningInnerDbFactory(DbFactory, _fileSystem, stateDbSettings.DbPath) - : DbFactory, - () => Interlocked.Increment(ref Metrics.StateDbInPruningWrites))); - - RegisterDb(BuildDbSettings(DbNames.Code)); - RegisterDb(BuildDbSettings(DbNames.Bloom)); - if (useReceiptsDb) - { - RegisterColumnsDb(BuildDbSettings(DbNames.Receipts)); - } - else - { - RegisterCustomColumnDb(DbNames.Receipts, () => new ReadOnlyColumnsDb(new MemColumnsDb(), false)); - } - RegisterDb(BuildDbSettings(DbNames.Metadata)); - if (useBlobsDb) - { - RegisterColumnsDb(BuildDbSettings(DbNames.BlobTransactions)); - } - } - - private static DbSettings BuildDbSettings(string dbName, bool deleteOnStart = false) - { - return new(GetTitleDbName(dbName), dbName) - { - DeleteOnStart = deleteOnStart - }; - } - } -} diff --git a/src/Nethermind/Nethermind.Db/TestMemDbProvider.cs b/src/Nethermind/Nethermind.Db/TestMemDbProvider.cs deleted file mode 100644 index b8276b5a583..00000000000 --- a/src/Nethermind/Nethermind.Db/TestMemDbProvider.cs +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - - -using System.Threading.Tasks; - -namespace Nethermind.Db -{ - public class TestMemDbProvider - { - public static async Task InitAsync() - { - IDbProvider memDbProvider = new DbProvider(); - StandardDbInitializer? standardDbInitializer = new StandardDbInitializer(memDbProvider, new MemDbFactory()); - await standardDbInitializer.InitStandardDbsAsync(true); - return memDbProvider; - } - - public static IDbProvider Init() - { - IDbProvider memDbProvider = new DbProvider(); - StandardDbInitializer? standardDbInitializer = new StandardDbInitializer(memDbProvider, new MemDbFactory()); - standardDbInitializer.InitStandardDbs(true); - return memDbProvider; - } - } -} diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs index 139ddfd7e2c..1a7d7d43fc7 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/EvmBenchmarks.cs @@ -20,7 +20,7 @@ using Microsoft.Diagnostics.Runtime; using Nethermind.Evm.Config; using Microsoft.Diagnostics.Tracing.Parsers; -using Nethermind.Evm.Tracing.GethStyle; +using Nethermind.Blockchain.Tracing.GethStyle; using static System.Runtime.InteropServices.JavaScript.JSType; using System.Collections.Generic; using Nethermind.Blockchain; @@ -31,7 +31,7 @@ using BenchmarkDotNet.Running; using Nethermind.Specs.Forks; using Nethermind.Abi; -using Nethermind.Evm.Tracing.GethStyle.Custom.JavaScript; +using Nethermind.Blockchain.Tracing.GethStyle.Custom.JavaScript; using Nethermind.Evm.Test.ILEVM; using Nethermind.Crypto; using Nethermind.Evm.Test; @@ -95,14 +95,16 @@ public LocalSetup(string name, byte[] _bytecode) bytecode = _bytecode; - codeInfoRepository = new TestCodeInfoRepository(); ILogManager logmanager = NullLogManager.Instance; _logger = logmanager.GetClassLogger(); - _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, logmanager, vmConfig); - + EthereumCodeInfoRepository _codeInfoRepository = new(); + codeInfoRepository = new TestCodeInfoRepository(); + _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, LimboLogs.Instance); + _virtualMachine.SetBlockExecutionContext(new BlockExecutionContext(_header, _spec)); + _virtualMachine.SetTxExecutionContext(new TxExecutionContext(Address.Zero, codeInfoRepository, null, 0)); var (address, targetCodeHash) = InsertCode(bytecode); var driver = diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs index 69df78ea3d8..1eecba667b4 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/MultipleUnsignedOperations.cs @@ -19,6 +19,7 @@ using Nethermind.Specs.Forks; using Nethermind.State; using Nethermind.Trie.Pruning; +using Nethermind.Blockchain; namespace Nethermind.Evm.Benchmark; @@ -76,7 +77,7 @@ public void GlobalSetup() _stateProvider.Commit(_spec); Console.WriteLine(MuirGlacier.Instance); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, new OneLoggerLogManager(NullLogger.Instance)); _virtualMachine.SetBlockExecutionContext(new BlockExecutionContext(_header, _spec)); _virtualMachine.SetTxExecutionContext(new TxExecutionContext(Address.Zero, codeInfoRepository, null, 0)); diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs index bddc49f0e2a..0b91cd4607f 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/StaticCallBenchmarks.cs @@ -19,6 +19,7 @@ using Nethermind.Specs.Forks; using Nethermind.State; using Nethermind.Trie.Pruning; +using Nethermind.Blockchain; namespace Nethermind.Evm.Benchmark { @@ -87,7 +88,7 @@ public void GlobalSetup() _stateProvider.Commit(_spec); Console.WriteLine(MuirGlacier.Instance); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); _virtualMachine = new VirtualMachine(_blockhashProvider, MainnetSpecProvider.Instance, new OneLoggerLogManager(NullLogger.Instance)); _virtualMachine.SetBlockExecutionContext(new BlockExecutionContext(_header, _spec)); _virtualMachine.SetTxExecutionContext(new TxExecutionContext(Address.Zero, codeInfoRepository, null, 0)); diff --git a/src/Nethermind/Nethermind.Evm.Benchmark/WethBenchmarks.cs b/src/Nethermind/Nethermind.Evm.Benchmark/WethBenchmarks.cs index 339627048c4..8d2696df852 100644 --- a/src/Nethermind/Nethermind.Evm.Benchmark/WethBenchmarks.cs +++ b/src/Nethermind/Nethermind.Evm.Benchmark/WethBenchmarks.cs @@ -29,6 +29,7 @@ using BenchmarkDotNet.Loggers; using Nethermind.Evm.CodeAnalysis; using Nethermind.Trie; +using Nethermind.Evm.State; namespace Nethermind.Evm.Benchmark { diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/BN254.cs b/src/Nethermind/Nethermind.Evm.Precompiles/BN254.cs new file mode 100644 index 00000000000..fb4ced5f60f --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/BN254.cs @@ -0,0 +1,211 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Nethermind.MclBindings; + +namespace Nethermind.Evm.Precompiles; + +using static Mcl; + +[SkipLocalsInit] +internal static unsafe class BN254 +{ + internal const int PairSize = 192; + + static BN254() + { + if (mclBn_init(MCL_BN_SNARK1, MCLBN_COMPILED_TIME_VAR) != 0) + throw new InvalidOperationException("MCL initialization failed"); + } + + internal static bool Add(Span input, Span output) + { + if (input.Length != 128) + return false; + + if (!DeserializeG1(input[0..64], out mclBnG1 x)) + return false; + + if (!DeserializeG1(input[64..128], out mclBnG1 y)) + return false; + + mclBnG1_add(ref x, x, y); // x += y + mclBnG1_normalize(ref x, x); + + return SerializeG1(x, output); + } + + internal static bool Mul(Span input, Span output) + { + if (input.Length != 96) + return false; + + if (!DeserializeG1(input[0..64], out mclBnG1 x)) + return false; + + Span yData = input[64..]; + yData.Reverse(); // To little-endian + + mclBnFr y = default; + + fixed (byte* ptr = &MemoryMarshal.GetReference(yData)) + { + if (mclBnFr_setLittleEndianMod(ref y, (nint)ptr, 32) == -1 || mclBnFr_isValid(y) == 0) + return false; + } + + mclBnG1_mul(ref x, x, y); // x *= y + mclBnG1_normalize(ref x, x); + + return SerializeG1(x, output); + } + + internal static bool CheckPairing(Span input, Span output) + { + if (input.Length == 0) + { + output[31] = 1; + return true; + } + + if (input.Length % PairSize != 0) + return false; + + mclBnGT gt = default; + Unsafe.SkipInit(out mclBnGT previous); + var hasPrevious = false; + + for (int i = 0, count = input.Length; i < count; i += PairSize) + { + var i64 = i + 64; + + if (!DeserializeG1(input[i..i64], out mclBnG1 g1)) + return false; + + if (!DeserializeG2(input[i64..(i64 + 128)], out mclBnG2 g2)) + return false; + + if (mclBnG1_isZero(g1) == 1 || mclBnG2_isZero(g2) == 1) + continue; + + mclBn_pairing(ref gt, g1, g2); + + // Skip multiplication for the first pairing as there's no previous result + if (hasPrevious) + mclBnGT_mul(ref gt, gt, previous); // gt *= previous + + previous = gt; + hasPrevious = true; + } + + // If gt is zero, then no pairing was computed, and it's considered valid + if (mclBnGT_isOne(gt) == 1 || mclBnGT_isZero(gt) == 1) + { + output[31] = 1; + return true; + } + + return mclBnGT_isValid(gt) == 1; + } + + private static bool DeserializeG1(Span data, out mclBnG1 point) + { + point = default; + + // Check for all-zero data + if (data.IndexOfAnyExcept((byte)0) == -1) + return true; + + Span x = data[0..32]; + x.Reverse(); // To little-endian + + fixed (byte* ptr = &MemoryMarshal.GetReference(x)) + { + if (mclBnFp_deserialize(ref point.x, (nint)ptr, 32) == nuint.Zero) + return false; + } + + Span y = data[32..64]; + y.Reverse(); // To little-endian + + fixed (byte* ptr = &MemoryMarshal.GetReference(y)) + { + if (mclBnFp_deserialize(ref point.y, (nint)ptr, 32) == nuint.Zero) + return false; + } + + mclBnFp_setInt32(ref point.z, 1); + + return mclBnG1_isValid(point) == 1; + } + + private static bool DeserializeG2(Span data, out mclBnG2 point) + { + point = default; + + // Check for all-zero data + if (data.IndexOfAnyExcept((byte)0) == -1) + return true; + + Span x0 = data[32..64]; + Span x1 = data[0..32]; + x0.Reverse(); // To little-endian + x1.Reverse(); // To little-endian + + fixed (byte* ptr0 = &MemoryMarshal.GetReference(x0)) + fixed (byte* ptr1 = &MemoryMarshal.GetReference(x1)) + { + if (mclBnFp_deserialize(ref point.x.d0, (nint)ptr0, 32) == nuint.Zero) + return false; + + if (mclBnFp_deserialize(ref point.x.d1, (nint)ptr1, 32) == nuint.Zero) + return false; + } + + Span y0 = data[96..128]; + Span y1 = data[64..96]; + y0.Reverse(); // To little-endian + y1.Reverse(); // To little-endian + + fixed (byte* ptr0 = &MemoryMarshal.GetReference(y0)) + fixed (byte* ptr1 = &MemoryMarshal.GetReference(y1)) + { + if (mclBnFp_deserialize(ref point.y.d0, (nint)ptr0, 32) == nuint.Zero) + return false; + + if (mclBnFp_deserialize(ref point.y.d1, (nint)ptr1, 32) == nuint.Zero) + return false; + } + + mclBnFp_setInt32(ref point.z.d0, 1); + + return mclBnG2_isValid(point) == 1 && mclBnG2_isValidOrder(point) == 1; + } + + private static bool SerializeG1(in mclBnG1 point, Span output) + { + Span x = output[0..32]; + + fixed (byte* ptr = &MemoryMarshal.GetReference(x)) + { + if (mclBnFp_getLittleEndian((nint)ptr, 32, point.x) == nuint.Zero) + return false; + } + + Span y = output[32..64]; + + fixed (byte* ptr = &MemoryMarshal.GetReference(y)) + { + if (mclBnFp_getLittleEndian((nint)ptr, 32, point.y) == nuint.Zero) + return false; + } + + x.Reverse(); // To big-endian + y.Reverse(); // To big-endian + + return true; + } +} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/BN254AddPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/BN254AddPrecompile.cs new file mode 100644 index 00000000000..0d7ee731e6d --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/BN254AddPrecompile.cs @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Core; +using Nethermind.Core.Specs; + +namespace Nethermind.Evm.Precompiles; + +/// +public class BN254AddPrecompile : IPrecompile +{ + public static readonly BN254AddPrecompile Instance = new(); + + public static Address Address { get; } = Address.FromNumber(6); + + /// + public static string Name => "BN256_ADD"; + + /// + public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 150L : 500L; + + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; + + public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + Metrics.Bn254AddPrecompile++; + + Span input = stackalloc byte[128]; + Span output = stackalloc byte[64]; + + inputData.Span[0..Math.Min(inputData.Length, input.Length)].CopyTo(input); + + return BN254.Add(input, output) ? (output.ToArray(), true) : IPrecompile.Failure; + } +} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/BN254MulPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/BN254MulPrecompile.cs new file mode 100644 index 00000000000..3baddb95bf3 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/BN254MulPrecompile.cs @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Core; +using Nethermind.Core.Specs; + +namespace Nethermind.Evm.Precompiles; + +/// +public class BN254MulPrecompile : IPrecompile +{ + public static readonly BN254MulPrecompile Instance = new(); + + public static Address Address { get; } = Address.FromNumber(7); + + /// + public static string Name => "BN256_MUL"; + + /// + public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 6_000L : 40_000L; + + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; + + public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + Metrics.Bn254MulPrecompile++; + + Span input = stackalloc byte[96]; + Span output = stackalloc byte[64]; + + inputData.Span[0..Math.Min(inputData.Length, input.Length)].CopyTo(input); + + return BN254.Mul(input, output) ? (output.ToArray(), true) : IPrecompile.Failure; + } +} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/BN254PairingPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/BN254PairingPrecompile.cs new file mode 100644 index 00000000000..713c280a1e6 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/BN254PairingPrecompile.cs @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Buffers; +using Nethermind.Core; +using Nethermind.Core.Specs; + +namespace Nethermind.Evm.Precompiles; + +/// +public class BN254PairingPrecompile : IPrecompile +{ + private const int PairingMaxInputSizeGranite = 112_687; + + public static readonly BN254PairingPrecompile Instance = new(); + + public static Address Address { get; } = Address.FromNumber(8); + + /// + public static string Name => "BN256_PAIRING"; + + /// + public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 45_000L : 100_000L; + + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => + (releaseSpec.IsEip1108Enabled ? 34_000L : 80_000L) * (inputData.Length / BN254.PairSize); + + public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + Metrics.Bn254PairingPrecompile++; + + if (releaseSpec.IsOpGraniteEnabled && inputData.Length > PairingMaxInputSizeGranite || + inputData.Length % BN254.PairSize > 0) + { + return IPrecompile.Failure; + } + + var input = ArrayPool.Shared.Rent(inputData.Length); + Span output = stackalloc byte[32]; + + inputData.CopyTo(input); + + var result = BN254.CheckPairing(input.AsSpan(0, inputData.Length), output); + + ArrayPool.Shared.Return(input); + + return result ? (output.ToArray(), true) : IPrecompile.Failure; + } +} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Blake2FPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Blake2FPrecompile.cs new file mode 100644 index 00000000000..74762e7ebd5 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Blake2FPrecompile.cs @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Core; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Crypto.Blake2; + +namespace Nethermind.Evm.Precompiles; + +public class Blake2FPrecompile : IPrecompile +{ + private const int RequiredInputLength = 213; + + private readonly Blake2Compression _blake = new(); + + public static readonly Blake2FPrecompile Instance = new(); + + public static Address Address { get; } = Address.FromNumber(9); + + public static string Name => "BLAKE2F"; + + public long BaseGasCost(IReleaseSpec releaseSpec) => 0; + + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + if (inputData.Length != RequiredInputLength) + { + return 0; + } + + byte finalByte = inputData.Span[212]; + if (finalByte != 0 && finalByte != 1) + { + return 0; + } + + uint rounds = inputData[..4].Span.ReadEthUInt32(); + + return rounds; + } + + public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + if (inputData.Length != RequiredInputLength) + { + return IPrecompile.Failure; + } + + byte finalByte = inputData.Span[212]; + if (finalByte != 0 && finalByte != 1) + { + return IPrecompile.Failure; + } + + byte[] result = new byte[64]; + _blake.Compress(inputData.Span, result); + + return (result, true); + } +} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/BlsConst.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/BlsConst.cs similarity index 98% rename from src/Nethermind/Nethermind.Evm/Precompiles/Bls/BlsConst.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/Bls/BlsConst.cs index 595e6ebcddd..513bfbfe946 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/BlsConst.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/BlsConst.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using System.Linq; namespace Nethermind.Evm.Precompiles.Bls; diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/BlsExtensions.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/BlsExtensions.cs similarity index 100% rename from src/Nethermind/Nethermind.Evm/Precompiles/Bls/BlsExtensions.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/Bls/BlsExtensions.cs diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Bls/Discount.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/Discount.cs new file mode 100644 index 00000000000..4db149d1c9d --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/Discount.cs @@ -0,0 +1,149 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +namespace Nethermind.Evm.Precompiles.Bls; + +/// +/// https://eips.ethereum.org/EIPS/eip-2537 +/// +internal static class Discount +{ + public static int ForG1(int k) => k >= 128 ? _maxDiscountG1 : _discountTable[k].g1; + public static int ForG2(int k) => k >= 128 ? _maxDiscountG2 : _discountTable[k].g2; + + private const int _maxDiscountG1 = 519; + private const int _maxDiscountG2 = 524; + + private static readonly (int g1, int g2)[] _discountTable = + { + (0, 0), // 0 + (1000, 1000), // 1 + (949, 1000), // 2 + (848, 923), // 3 + (797, 884), // 4 + (764, 855), // 5 + (750, 832), // 6 + (738, 812), // 7 + (728, 796), // 8 + (719, 782), // 9 + (712, 770), // 10 + (705, 759), // 11 + (698, 749), // 12 + (692, 740), // 13 + (687, 732), // 14 + (682, 724), // 15 + (677, 717), // 16 + (673, 711), // 17 + (669, 704), // 18 + (665, 699), // 19 + (661, 693), // 20 + (658, 688), // 21 + (654, 683), // 22 + (651, 679), // 23 + (648, 674), // 24 + (645, 670), // 25 + (642, 666), // 26 + (640, 663), // 27 + (637, 659), // 28 + (635, 655), // 29 + (632, 652), // 30 + (630, 649), // 31 + (627, 646), // 32 + (625, 643), // 33 + (623, 640), // 34 + (621, 637), // 35 + (619, 634), // 36 + (617, 632), // 37 + (615, 629), // 38 + (613, 627), // 39 + (611, 624), // 40 + (609, 622), // 41 + (608, 620), // 42 + (606, 618), // 43 + (604, 615), // 44 + (603, 613), // 45 + (601, 611), // 46 + (599, 609), // 47 + (598, 607), // 48 + (596, 606), // 49 + (595, 604), // 50 + (593, 602), // 51 + (592, 600), // 52 + (591, 598), // 53 + (589, 597), // 54 + (588, 595), // 55 + (586, 593), // 56 + (585, 592), // 57 + (584, 590), // 58 + (582, 589), // 59 + (581, 587), // 60 + (580, 586), // 61 + (579, 584), // 62 + (577, 583), // 63 + (576, 582), // 64 + (575, 580), // 65 + (574, 579), // 66 + (573, 578), // 67 + (572, 576), // 68 + (570, 575), // 69 + (569, 574), // 70 + (568, 573), // 71 + (567, 571), // 72 + (566, 570), // 73 + (565, 569), // 74 + (564, 568), // 75 + (563, 567), // 76 + (562, 566), // 77 + (561, 565), // 78 + (560, 563), // 79 + (559, 562), // 80 + (558, 561), // 81 + (557, 560), // 82 + (556, 559), // 83 + (555, 558), // 84 + (554, 557), // 85 + (553, 556), // 86 + (552, 555), // 87 + (551, 554), // 88 + (550, 553), // 89 + (549, 552), // 90 + (548, 552), // 91 + (547, 551), // 92 + (547, 550), // 93 + (546, 549), // 94 + (545, 548), // 95 + (544, 547), // 96 + (543, 546), // 97 + (542, 545), // 98 + (541, 545), // 99 + (540, 544), // 100 + (540, 543), // 101 + (539, 542), // 102 + (538, 541), // 103 + (537, 541), // 104 + (536, 540), // 105 + (536, 539), // 106 + (535, 538), // 107 + (534, 537), // 108 + (533, 537), // 109 + (532, 536), // 110 + (532, 535), // 111 + (531, 535), // 112 + (530, 534), // 113 + (529, 533), // 114 + (528, 532), // 115 + (528, 532), // 116 + (527, 531), // 117 + (526, 530), // 118 + (525, 530), // 119 + (525, 529), // 120 + (524, 528), // 121 + (523, 528), // 122 + (522, 527), // 123 + (522, 526), // 124 + (521, 526), // 125 + (520, 525), // 126 + (520, 524), // 127 + (519, 524) // 128 + }; +} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1AddPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/G1AddPrecompile.cs similarity index 95% rename from src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1AddPrecompile.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/Bls/G1AddPrecompile.cs index eddb4893252..85ecf7dae0d 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1AddPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/G1AddPrecompile.cs @@ -5,7 +5,7 @@ using System.Runtime.CompilerServices; using Nethermind.Core; using Nethermind.Core.Specs; - +using Nethermind.Evm.Precompiles; using G1 = Nethermind.Crypto.Bls.P1; namespace Nethermind.Evm.Precompiles.Bls; @@ -23,6 +23,8 @@ private G1AddPrecompile() public static Address Address { get; } = Address.FromNumber(0x0b); + public static string Name => "BLS12_G1ADD"; + public long BaseGasCost(IReleaseSpec releaseSpec) => 375L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1MSMPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/G1MSMPrecompile.cs similarity index 98% rename from src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1MSMPrecompile.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/Bls/G1MSMPrecompile.cs index 9e5e466a997..80e92ab1cbf 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G1MSMPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/G1MSMPrecompile.cs @@ -9,6 +9,7 @@ using G1 = Nethermind.Crypto.Bls.P1; using System.Runtime.CompilerServices; +using Nethermind.Evm.Precompiles; namespace Nethermind.Evm.Precompiles.Bls; @@ -25,6 +26,8 @@ private G1MSMPrecompile() public static Address Address { get; } = Address.FromNumber(0x0c); + public static string Name => "BLS12_G1MSM"; + public long BaseGasCost(IReleaseSpec releaseSpec) => 0L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2AddPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/G2AddPrecompile.cs similarity index 95% rename from src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2AddPrecompile.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/Bls/G2AddPrecompile.cs index 6e9094f6084..734d8602449 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2AddPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/G2AddPrecompile.cs @@ -5,7 +5,7 @@ using System.Runtime.CompilerServices; using Nethermind.Core; using Nethermind.Core.Specs; - +using Nethermind.Evm.Precompiles; using G2 = Nethermind.Crypto.Bls.P2; namespace Nethermind.Evm.Precompiles.Bls; @@ -23,6 +23,8 @@ private G2AddPrecompile() public static Address Address { get; } = Address.FromNumber(0x0d); + public static string Name => "BLS12_G2ADD"; + public long BaseGasCost(IReleaseSpec releaseSpec) => 600L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2MSMPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/G2MSMPrecompile.cs similarity index 98% rename from src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2MSMPrecompile.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/Bls/G2MSMPrecompile.cs index 3ed9ccc8396..8151e8c5f6a 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/G2MSMPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/G2MSMPrecompile.cs @@ -9,6 +9,7 @@ using G2 = Nethermind.Crypto.Bls.P2; using System.Runtime.CompilerServices; +using Nethermind.Evm.Precompiles; namespace Nethermind.Evm.Precompiles.Bls; @@ -25,6 +26,8 @@ private G2MSMPrecompile() public static Address Address { get; } = Address.FromNumber(0xe); + public static string Name => "BLS12_G2MSM"; + public long BaseGasCost(IReleaseSpec releaseSpec) => 0L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/MapFp2ToG2Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/MapFp2ToG2Precompile.cs similarity index 94% rename from src/Nethermind/Nethermind.Evm/Precompiles/Bls/MapFp2ToG2Precompile.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/Bls/MapFp2ToG2Precompile.cs index d86a2f50c24..cac3f490ff5 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/MapFp2ToG2Precompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/MapFp2ToG2Precompile.cs @@ -5,7 +5,7 @@ using System.Runtime.CompilerServices; using Nethermind.Core; using Nethermind.Core.Specs; - +using Nethermind.Evm.Precompiles; using G2 = Nethermind.Crypto.Bls.P2; namespace Nethermind.Evm.Precompiles.Bls; @@ -23,6 +23,8 @@ private MapFp2ToG2Precompile() public static Address Address { get; } = Address.FromNumber(0x11); + public static string Name => "BLS12_MAP_FP2_TO_G2"; + public long BaseGasCost(IReleaseSpec releaseSpec) => 23800L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/MapFpToG1Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/MapFpToG1Precompile.cs similarity index 94% rename from src/Nethermind/Nethermind.Evm/Precompiles/Bls/MapFpToG1Precompile.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/Bls/MapFpToG1Precompile.cs index bd1c776f296..f3689b5b98f 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/MapFpToG1Precompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/MapFpToG1Precompile.cs @@ -5,6 +5,7 @@ using System.Runtime.CompilerServices; using Nethermind.Core; using Nethermind.Core.Specs; +using Nethermind.Evm.Precompiles; using G1 = Nethermind.Crypto.Bls.P1; namespace Nethermind.Evm.Precompiles.Bls; @@ -22,6 +23,8 @@ private MapFpToG1Precompile() public static Address Address { get; } = Address.FromNumber(0x10); + public static string Name => "BLS12_MAP_FP_TO_G1"; + public long BaseGasCost(IReleaseSpec releaseSpec) => 5500L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/PairingCheckPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/PairingCheckPrecompile.cs similarity index 96% rename from src/Nethermind/Nethermind.Evm/Precompiles/Bls/PairingCheckPrecompile.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/Bls/PairingCheckPrecompile.cs index 66270d26468..de45b8838a9 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/PairingCheckPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Bls/PairingCheckPrecompile.cs @@ -6,7 +6,7 @@ using Nethermind.Core; using Nethermind.Core.Collections; using Nethermind.Core.Specs; - +using Nethermind.Evm.Precompiles; using G1 = Nethermind.Crypto.Bls.P1; using G2 = Nethermind.Crypto.Bls.P2; using GT = Nethermind.Crypto.Bls.PT; @@ -25,6 +25,8 @@ private PairingCheckPrecompile() { } public static Address Address { get; } = Address.FromNumber(0xf); + public static string Name => "BLS12_PAIRING_CHECK"; + public long BaseGasCost(IReleaseSpec releaseSpec) => 37700L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 32600L * (inputData.Length / PairSize); diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/EcRecoverPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/EcRecoverPrecompile.cs new file mode 100644 index 00000000000..a828db49404 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/EcRecoverPrecompile.cs @@ -0,0 +1,76 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Runtime.CompilerServices; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Crypto; +using Nethermind.Evm.Precompiles; + +namespace Nethermind.Evm.Precompiles; + +public class EcRecoverPrecompile : IPrecompile +{ + public static readonly EcRecoverPrecompile Instance = new(); + + private EcRecoverPrecompile() + { + } + + public static Address Address { get; } = Address.FromNumber(1); + + public static string Name => "ECREC"; + + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; + + public long BaseGasCost(IReleaseSpec releaseSpec) => 3000L; + + private readonly byte[] _zero31 = new byte[31]; + + public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + Metrics.EcRecoverPrecompile++; + return inputData.Length >= 128 ? RunInternal(inputData.Span) : RunInternal(inputData); + } + + private (byte[], bool) RunInternal(ReadOnlyMemory inputData) + { + Span inputDataSpan = stackalloc byte[128]; + inputData.Span[..Math.Min(128, inputData.Length)] + .CopyTo(inputDataSpan[..Math.Min(128, inputData.Length)]); + + return RunInternal(inputDataSpan); + } + + private (byte[], bool) RunInternal(ReadOnlySpan inputDataSpan) + { + ReadOnlySpan vBytes = inputDataSpan.Slice(32, 32); + + // TEST: CALLCODEEcrecoverV_prefixedf0_d0g0v0 + // TEST: CALLCODEEcrecoverV_prefixedf0_d1g0v0 + if (!Bytes.AreEqual(_zero31, vBytes[..31])) + { + return ([], true); + } + + byte v = vBytes[31]; + if (v != 27 && v != 28) + { + return ([], true); + } + + Span publicKey = stackalloc byte[65]; + if (!EthereumEcdsa.RecoverAddressRaw(inputDataSpan.Slice(64, 64), Signature.GetRecoveryId(v), + inputDataSpan[..32], publicKey)) + { + return ([], true); + } + + byte[] result = ValueKeccak.Compute(publicKey.Slice(1, 64)).ToByteArray(); + result.AsSpan(0, 12).Clear(); + return (result, true); + } +} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Extensions.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Extensions.cs new file mode 100644 index 00000000000..834de118fe2 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Extensions.cs @@ -0,0 +1,77 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Evm.Precompiles.Bls; +using System.Collections.Generic; + +namespace Nethermind.Evm.Precompiles; + +public static class Extensions +{ + public static OrderedDictionary ListPrecompiles(this IReleaseSpec spec) + { + OrderedDictionary precompiles = []; + + AddPrecompile(); + AddPrecompile(); + AddPrecompile(); + AddPrecompile(); + + if (spec.ModExpEnabled) + { + AddPrecompile(); + } + + if (spec.BN254Enabled) + { + AddPrecompile(); + AddPrecompile(); + AddPrecompile(); + } + + if (spec.BlakeEnabled) + { + AddPrecompile(); + } + + if (spec.IsEip4844Enabled) + { + AddPrecompile(); + } + + if (spec.Bls381Enabled) + { + AddPrecompile(); + AddPrecompile(); + AddPrecompile(); + AddPrecompile(); + AddPrecompile(); + AddPrecompile(); + AddPrecompile(); + } + + if (spec.IsEip7951Enabled) + { + AddPrecompile(); + } + + return precompiles; + + void AddPrecompile() where T : IPrecompile => precompiles[T.Address] = T.Name; + } + + public static OrderedDictionary ListSystemContracts(this IReleaseSpec spec) + { + OrderedDictionary systemContracts = []; + + if (spec.IsBeaconBlockRootAvailable) systemContracts[Eip4788Constants.ContractAddressKey] = Eip4788Constants.BeaconRootsAddress; + if (spec.ConsolidationRequestsEnabled) systemContracts[Eip7251Constants.ContractAddressKey] = Eip7251Constants.ConsolidationRequestPredeployAddress; + if (spec.DepositsEnabled) systemContracts[Eip6110Constants.ContractAddressKey] = spec.DepositContractAddress; + if (spec.IsEip2935Enabled) systemContracts[Eip2935Constants.ContractAddressKey] = Eip2935Constants.BlockHashHistoryAddress; + if (spec.WithdrawalRequestsEnabled) systemContracts[Eip7002Constants.ContractAddressKey] = Eip7002Constants.WithdrawalRequestPredeployAddress; + + return systemContracts; + } +} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs new file mode 100644 index 00000000000..67317a39a42 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/IdentityPrecompile.cs @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Evm; +using Nethermind.Evm.Precompiles; + +namespace Nethermind.Evm.Precompiles; + +public class IdentityPrecompile : IPrecompile +{ + public static readonly IdentityPrecompile Instance = new(); + + private IdentityPrecompile() + { + } + + public static Address Address { get; } = Address.FromNumber(4); + + public static string Name => "ID"; + + public long BaseGasCost(IReleaseSpec releaseSpec) => 15L; + + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => + 3L * EvmInstructions.Div32Ceiling((ulong)inputData.Length); + + public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + return (inputData.ToArray(), true); + } +} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Metrics.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Metrics.cs new file mode 100644 index 00000000000..df9e22c613f --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Metrics.cs @@ -0,0 +1,82 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.ComponentModel; +using Nethermind.Core.Attributes; + +namespace Nethermind.Evm.Precompiles; + +public class Metrics +{ + [CounterMetric] + [Description("Number of BN254_MUL precompile calls.")] + public static long Bn254MulPrecompile { get; set; } + + [CounterMetric] + [Description("Number of BN254_ADD precompile calls.")] + public static long Bn254AddPrecompile { get; set; } + + [CounterMetric] + [Description("Number of BN254_PAIRING precompile calls.")] + public static long Bn254PairingPrecompile { get; set; } + + [CounterMetric] + [Description("Number of BLS12_G1ADD precompile calls.")] + public static long BlsG1AddPrecompile { get; set; } + + [CounterMetric] + [Description("Number of BLS12_G1MUL precompile calls.")] + public static long BlsG1MulPrecompile { get; set; } + + [CounterMetric] + [Description("Number of BLS12_G1MSM precompile calls.")] + public static long BlsG1MSMPrecompile { get; set; } + + [CounterMetric] + [Description("Number of BLS12_G2ADD precompile calls.")] + public static long BlsG2AddPrecompile { get; set; } + + [CounterMetric] + [Description("Number of BLS12_G2MUL precompile calls.")] + public static long BlsG2MulPrecompile { get; set; } + + [CounterMetric] + [Description("Number of BLS12_G2MSM precompile calls.")] + public static long BlsG2MSMPrecompile { get; set; } + + [CounterMetric] + [Description("Number of BLS12_PAIRING_CHECK precompile calls.")] + public static long BlsPairingCheckPrecompile { get; set; } + + [CounterMetric] + [Description("Number of BLS12_MAP_FP_TO_G1 precompile calls.")] + public static long BlsMapFpToG1Precompile { get; set; } + + [CounterMetric] + [Description("Number of BLS12_MAP_FP2_TO_G2 precompile calls.")] + public static long BlsMapFp2ToG2Precompile { get; set; } + + [CounterMetric] + [Description("Number of EC_RECOVERY precompile calls.")] + public static long EcRecoverPrecompile { get; set; } + + [CounterMetric] + [Description("Number of MODEXP precompile calls.")] + public static long ModExpPrecompile { get; set; } + + [CounterMetric] + [Description("Number of RIPEMD160 precompile calls.")] + public static long Ripemd160Precompile { get; set; } + + [CounterMetric] + [Description("Number of SHA256 precompile calls.")] + public static long Sha256Precompile { get; set; } + + [CounterMetric] + [Description("Number of Secp256r1 precompile calls.")] + public static long Secp256r1Precompile { get; set; } + + [CounterMetric] + [Description("Number of Point Evaluation precompile calls.")] + public static long PointEvaluationPrecompile { get; set; } +} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs new file mode 100644 index 00000000000..010a6418329 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompile.cs @@ -0,0 +1,362 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Buffers.Binary; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using Nethermind.Core; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.GmpBindings; +using Nethermind.Int256; + +namespace Nethermind.Evm.Precompiles; + +/// +/// https://github.com/ethereum/EIPs/blob/vbuterin-patch-2/EIPS/bigint_modexp.md +/// +public class ModExpPrecompile : IPrecompile +{ + public static readonly ModExpPrecompile Instance = new(); + /// + /// Maximum input size (in bytes) for the modular exponentiation operation under EIP-7823. + /// This constant defines the upper limit for the size of the input data that can be processed. + /// For more details, see: https://eips.ethereum.org/EIPS/eip-7823 + /// + public const uint ModExpMaxInputSizeEip7823 = 1024; + + private const int LengthSize = 32; + private const int StartBaseLength = 0; + private const int StartExpLength = 32; + private const int StartModLength = 64; + private const int LengthsLengths = StartModLength + LengthSize; + + private ModExpPrecompile() + { + } + + public static Address Address { get; } = Address.FromNumber(5); + + public static string Name => "MODEXP"; + + public long BaseGasCost(IReleaseSpec releaseSpec) => 0L; + + /// + /// https://github.com/ethereum/EIPs/pull/2892 + /// ADJUSTED_EXPONENT_LENGTH is defined as follows. + /// If length_of_EXPONENT <= 32, and all bits in EXPONENT are 0, return 0 + /// If length_of_EXPONENT <= 32, then return the index of the highest bit in EXPONENT (eg. 1 -> 0, 2 -> 1, 3 -> 1, 255 -> 7, 256 -> 8). + /// If length_of_EXPONENT > 32, then return 8 * (length_of_EXPONENT - 32) plus the index of the highest bit in the first 32 bytes of EXPONENT (eg. if EXPONENT = \x00\x00\x01\x00.....\x00, with one hundred bytes, then the result is 8 * (100 - 32) + 253 = 797). If all of the first 32 bytes of EXPONENT are zero, return exactly 8 * (length_of_EXPONENT - 32). + /// + /// + /// + /// Gas cost of the MODEXP operation in the context of EIP2565 + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + if (!releaseSpec.IsEip2565Enabled) + { +#pragma warning disable 618 + return ModExpPrecompilePreEip2565.Instance.DataGasCost(inputData, releaseSpec); +#pragma warning restore 618 + } + + try + { + ReadOnlySpan span = inputData.Span; + return span.Length >= LengthsLengths + ? DataGasCostInternal(span, releaseSpec) + : DataGasCostShortInternal(span, releaseSpec); + } + catch (OverflowException) + { + return long.MaxValue; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static long DataGasCostShortInternal(ReadOnlySpan inputData, IReleaseSpec releaseSpec) + { + Debug.Assert(inputData.Length < LengthsLengths); + + Span extendedInput = stackalloc byte[LengthsLengths]; + inputData.CopyTo(extendedInput); + + return DataGasCostInternal(extendedInput, releaseSpec); + } + + private static long DataGasCostInternal(ReadOnlySpan inputData, IReleaseSpec releaseSpec) + { + (uint baseLength, uint expLength, uint modulusLength) = GetInputLengths(inputData); + if (ExceedsMaxInputSize(releaseSpec, baseLength, expLength, modulusLength)) + { + return long.MaxValue; + } + + ulong complexity = MultComplexity(baseLength, modulusLength, releaseSpec.IsEip7883Enabled); + + uint expLengthUpTo32 = Math.Min(LengthSize, expLength); + uint startIndex = LengthsLengths + baseLength; //+ expLength - expLengthUpTo32; // Geth takes head here, why? + UInt256 exp = new(inputData.SliceWithZeroPaddingEmptyOnError((int)startIndex, (int)expLengthUpTo32), isBigEndian: true); + UInt256 iterationCount = CalculateIterationCount(expLength, exp, releaseSpec.IsEip7883Enabled); + + bool overflow = UInt256.MultiplyOverflow(complexity, iterationCount, out UInt256 result); + result /= 3; + return result > long.MaxValue || overflow + ? long.MaxValue + : Math.Max(releaseSpec.IsEip7883Enabled ? GasCostOf.MinModExpEip7883 : GasCostOf.MinModExpEip2565, (long)result); + } + + private static bool ExceedsMaxInputSize(IReleaseSpec releaseSpec, uint baseLength, uint expLength, uint modulusLength) + { + return releaseSpec.IsEip7823Enabled + ? (baseLength > ModExpMaxInputSizeEip7823 | expLength > ModExpMaxInputSizeEip7823 | modulusLength > ModExpMaxInputSizeEip7823) + : (baseLength | modulusLength) > int.MaxValue; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private (uint baseLength, uint expLength, uint modulusLength) GetInputLengthsShort(ReadOnlySpan inputData) + { + Debug.Assert(inputData.Length < LengthsLengths); + + Span extendedInput = stackalloc byte[LengthsLengths]; + inputData.CopyTo(extendedInput); + + return GetInputLengths(extendedInput); + } + + private static (uint baseLength, uint expLength, uint modulusLength) GetInputLengths(ReadOnlySpan inputData) + { + // Test if too high + if (Vector256.IsSupported) + { + ref var firstByte = ref MemoryMarshal.GetReference(inputData); + Vector256 mask = ~Vector256.Create(0, 0, 0, 0, 0, 0, 0, uint.MaxValue).AsByte(); + if (Vector256.BitwiseAnd( + Vector256.BitwiseOr( + Vector256.BitwiseOr( + Unsafe.ReadUnaligned>(ref firstByte), + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, StartExpLength))), + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, 64))), + mask) != Vector256.Zero) + { + return GetInputLengthsMayOverflow(inputData); + } + } + else if (Vector128.IsSupported) + { + ref var firstByte = ref MemoryMarshal.GetReference(inputData); + Vector128 mask = ~Vector128.Create(0, 0, 0, uint.MaxValue).AsByte(); + if (Vector128.BitwiseOr( + Vector128.BitwiseOr( + Vector128.BitwiseOr( + Unsafe.ReadUnaligned>(ref firstByte), + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, StartExpLength))), + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, 64))), + Vector128.BitwiseAnd( + Vector128.BitwiseOr( + Vector128.BitwiseOr( + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, 16)), + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, StartExpLength + 16))), + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, StartModLength + 16))), + mask) + ) != Vector128.Zero) + { + return GetInputLengthsMayOverflow(inputData); + } + } + else if (inputData.Slice(StartBaseLength, LengthSize - sizeof(uint)).IndexOfAnyExcept((byte)0) >= 0 || + inputData.Slice(StartExpLength, LengthSize - sizeof(uint)).IndexOfAnyExcept((byte)0) >= 0 || + inputData.Slice(StartModLength, LengthSize - sizeof(uint)).IndexOfAnyExcept((byte)0) >= 0) + { + return GetInputLengthsMayOverflow(inputData); + } + + uint baseLength = BinaryPrimitives.ReadUInt32BigEndian(inputData.Slice(32 - sizeof(uint), sizeof(uint))); + uint expLength = BinaryPrimitives.ReadUInt32BigEndian(inputData.Slice(64 - sizeof(uint), sizeof(uint))); + uint modulusLength = BinaryPrimitives.ReadUInt32BigEndian(inputData.Slice(96 - sizeof(uint), sizeof(uint))); + return (baseLength, expLength, modulusLength); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static (uint baseLength, uint expLength, uint modulusLength) GetInputLengthsMayOverflow(ReadOnlySpan inputData) + { + // Only valid if baseLength and modulusLength are zero; when expLength doesn't matter + if (Vector256.IsSupported) + { + ref var firstByte = ref MemoryMarshal.GetReference(inputData); + if (Vector256.BitwiseOr( + Unsafe.ReadUnaligned>(ref firstByte), + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, StartModLength))) + != Vector256.Zero) + { + // Overflow + return (uint.MaxValue, uint.MaxValue, uint.MaxValue); + } + } + else if (Vector128.IsSupported) + { + ref var firstByte = ref MemoryMarshal.GetReference(inputData); + if (Vector128.BitwiseOr( + Vector128.BitwiseOr( + Unsafe.ReadUnaligned>(ref firstByte), + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, 16))), + Vector128.BitwiseOr( + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, StartModLength)), + Unsafe.ReadUnaligned>(ref Unsafe.Add(ref firstByte, StartModLength + 16))) + ) != Vector128.Zero) + { + // Overflow + return (uint.MaxValue, uint.MaxValue, uint.MaxValue); + } + } + else if (inputData.Slice(StartBaseLength, LengthSize).IndexOfAnyExcept((byte)0) >= 0 || + inputData.Slice(StartModLength, LengthSize).IndexOfAnyExcept((byte)0) >= 0) + { + // Overflow + return (uint.MaxValue, uint.MaxValue, uint.MaxValue); + } + + return (0, uint.MaxValue, 0); + } + + public unsafe (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + Metrics.ModExpPrecompile++; + + ReadOnlySpan inputSpan = inputData.Span; + (uint baseLength, uint expLength, uint modulusLength) = inputSpan.Length >= LengthsLengths + ? GetInputLengths(inputSpan) + : GetInputLengthsShort(inputSpan); + + if (ExceedsMaxInputSize(releaseSpec, baseLength, expLength, modulusLength)) + return IPrecompile.Failure; + + // if both are 0, then expLength can be huge, which leads to a potential buffer too big exception + if (baseLength == 0 && modulusLength == 0) + return (Bytes.Empty, true); + + using var modulusInt = mpz_t.Create(); + + ReadOnlySpan modulusDataSpan = inputSpan.SliceWithZeroPaddingEmptyOnError(96 + (int)baseLength + (int)expLength, (int)modulusLength); + if (modulusDataSpan.Length > 0) + { + fixed (byte* modulusData = &MemoryMarshal.GetReference(modulusDataSpan)) + Gmp.mpz_import(modulusInt, modulusLength, 1, 1, 1, nuint.Zero, (nint)modulusData); + } + + if (Gmp.mpz_sgn(modulusInt) == 0) + return (new byte[modulusLength], true); + + using var baseInt = mpz_t.Create(); + using var expInt = mpz_t.Create(); + using var powmResult = mpz_t.Create(); + + ReadOnlySpan baseDataSpan = inputSpan.SliceWithZeroPaddingEmptyOnError(96, (int)baseLength); + if (baseDataSpan.Length > 0) + { + fixed (byte* baseData = &MemoryMarshal.GetReference(baseDataSpan)) + Gmp.mpz_import(baseInt, baseLength, 1, 1, 1, nuint.Zero, (nint)baseData); + } + + ReadOnlySpan expDataSpan = inputSpan.SliceWithZeroPaddingEmptyOnError(96 + (int)baseLength, (int)expLength); + if (expDataSpan.Length > 0) + { + fixed (byte* expData = &MemoryMarshal.GetReference(expDataSpan)) + Gmp.mpz_import(expInt, expLength, 1, 1, 1, nuint.Zero, (nint)expData); + } + + Gmp.mpz_powm(powmResult, baseInt, expInt, modulusInt); + + nint powmResultLen = (nint)(Gmp.mpz_sizeinbase(powmResult, 2) + 7) / 8; + nint offset = (int)modulusLength - powmResultLen; + + byte[] result = new byte[modulusLength]; + fixed (byte* ptr = &MemoryMarshal.GetArrayDataReference(result)) + Gmp.mpz_export((nint)(ptr + offset), out _, 1, 1, 1, nuint.Zero, powmResult); + + return (result, true); + } + + /// + /// def calculate_multiplication_complexity(base_length, modulus_length): + /// max_length = max(base_length, modulus_length) + /// words = math.ceil(max_length / 8) + /// return words**2 + /// + /// + private static ulong MultComplexity(uint baseLength, uint modulusLength, bool isEip7883Enabled) + { + // Pick the larger of the two + uint max = baseLength > modulusLength ? baseLength : modulusLength; + + // Compute ceil(max/8) via a single add + shift + // (max + 7) >> 3 == (max + 7) / 8, rounding up + ulong words = ((ulong)max + 7u) >> 3; + + // Square it once + ulong sq = words * words; + + // If EIP-7883 => small-case = 16, else 2*sq when max>32 + if (isEip7883Enabled) + { + return max > LengthSize + ? (sq << 1) // 2 * words * words + : 16UL; // constant floor + } + + // Otherwise plain square + return sq; + } + + static readonly ulong IterationCountMultiplierEip2565 = 8; + + static readonly ulong IterationCountMultiplierEip7883 = 16; + + /// + /// def calculate_iteration_count(exponent_length, exponent): + /// iteration_count = 0 + /// if exponent_length <= 32 and exponent == 0: iteration_count = 0 + /// elif exponent_length <= 32: iteration_count = exponent.bit_length() - 1 + /// elif exponent_length > 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) + /// return max(iteration_count, 1) + /// + /// + /// + /// + /// + private static UInt256 CalculateIterationCount(uint exponentLength, UInt256 exponent, bool isEip7883Enabled) + { + ulong iterationCount; + uint overflow = 0; + if (exponentLength <= LengthSize) + { + iterationCount = (uint)Math.Max(1, exponent.BitLen - 1); + } + else + { + uint bitLength = (uint)exponent.BitLen; + if (bitLength > 0) + { + bitLength--; + } + + ulong multiplicationResult = (exponentLength - LengthSize) * (isEip7883Enabled ? IterationCountMultiplierEip7883 : IterationCountMultiplierEip2565); + iterationCount = multiplicationResult + bitLength; + if (iterationCount < multiplicationResult) + { + // Overflowed + overflow = 1; + } + else if (iterationCount < 1) + { + // Min 1 iteration + iterationCount = 1; + } + } + + return new UInt256(iterationCount, overflow); + } +} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompilePreEip2565.cs b/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompilePreEip2565.cs new file mode 100644 index 00000000000..c646b8b40a6 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/ModExpPrecompilePreEip2565.cs @@ -0,0 +1,133 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Numerics; +using Nethermind.Core; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Int256; + +namespace Nethermind.Evm.Precompiles; + +/// +/// https://github.com/ethereum/EIPs/blob/vbuterin-patch-2/EIPS/bigint_modexp.md +/// +[Obsolete("Pre-eip2565 implementation")] +public class ModExpPrecompilePreEip2565 : IPrecompile +{ + public static ModExpPrecompilePreEip2565 Instance = new(); + private static readonly UInt256 Eight = 8; + + private ModExpPrecompilePreEip2565() + { + } + + public static Address Address { get; } = Address.FromNumber(5); + + public static string Name => "MODEXP"; + + public long BaseGasCost(IReleaseSpec releaseSpec) => 0L; + + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + try + { + return inputData.Length >= 96 + ? DataGasCostInternal(inputData.Span.Slice(0, 96), inputData, releaseSpec) + : DataGasCostInternal(inputData, releaseSpec); + } + catch (OverflowException) + { + return long.MaxValue; + } + } + + private static long DataGasCostInternal(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + Span extendedInput = stackalloc byte[96]; + inputData[..Math.Min(96, inputData.Length)].Span + .CopyTo(extendedInput[..Math.Min(96, inputData.Length)]); + + return DataGasCostInternal(extendedInput, inputData, releaseSpec); + } + + private static long DataGasCostInternal(ReadOnlySpan extendedInput, ReadOnlyMemory inputData, + IReleaseSpec releaseSpec) + { + UInt256 baseLength = new(extendedInput[..32], true); + UInt256 expLength = new(extendedInput.Slice(32, 32), true); + UInt256 modulusLength = new(extendedInput.Slice(64, 32), true); + + UInt256 complexity = MultComplexity(UInt256.Max(baseLength, modulusLength)); + + ReadOnlySpan expSignificantBytes = + inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + (int)baseLength, (int)UInt256.Min(expLength, 32)); + + UInt256 lengthOver32 = expLength <= 32 ? 0 : expLength - 32; + UInt256 adjusted = AdjustedExponentLength(lengthOver32, expSignificantBytes); + UInt256 gas = complexity * UInt256.Max(adjusted, UInt256.One) / 20; + return gas > long.MaxValue ? long.MaxValue : (long)gas; + } + + public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + Metrics.ModExpPrecompile++; + + int baseLength = (int)inputData.Span.SliceWithZeroPaddingEmptyOnError(0, 32).ToUnsignedBigInteger(); + BigInteger expLengthBig = inputData.Span.SliceWithZeroPaddingEmptyOnError(32, 32).ToUnsignedBigInteger(); + int expLength = expLengthBig > int.MaxValue ? int.MaxValue : (int)expLengthBig; + int modulusLength = (int)inputData.Span.SliceWithZeroPaddingEmptyOnError(64, 32).ToUnsignedBigInteger(); + + BigInteger modulusInt = inputData.Span + .SliceWithZeroPaddingEmptyOnError(96 + baseLength + expLength, modulusLength).ToUnsignedBigInteger(); + + if (modulusInt.IsZero) + { + return (new byte[modulusLength], true); + } + + BigInteger baseInt = inputData.Span.SliceWithZeroPaddingEmptyOnError(96, baseLength).ToUnsignedBigInteger(); + BigInteger expInt = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength, expLength) + .ToUnsignedBigInteger(); + return (BigInteger.ModPow(baseInt, expInt, modulusInt).ToBigEndianByteArray(modulusLength), true); + } + + private static UInt256 MultComplexity(in UInt256 adjustedExponentLength) + { + if (adjustedExponentLength <= 64) + { + return adjustedExponentLength * adjustedExponentLength; + } + + if (adjustedExponentLength <= 1024) + { + return adjustedExponentLength * adjustedExponentLength / 4 + 96 * adjustedExponentLength - 3072; + } + + return adjustedExponentLength * adjustedExponentLength / 16 + 480 * adjustedExponentLength - 199680; + } + + private static UInt256 AdjustedExponentLength(in UInt256 lengthOver32, ReadOnlySpan exponent) + { + bool overflow = false; + bool underflow = false; + UInt256 result; + + int leadingZeros = exponent.LeadingZerosCount(); + if (leadingZeros == exponent.Length) + { + overflow |= UInt256.MultiplyOverflow(lengthOver32, Eight, out result); + return overflow ? UInt256.MaxValue : result; + } + + overflow |= UInt256.AddOverflow(lengthOver32, (UInt256)exponent.Length, out result); + underflow |= UInt256.SubtractUnderflow(result, (UInt256)leadingZeros, out result); + underflow |= UInt256.SubtractUnderflow(result, UInt256.One, out result); + overflow |= UInt256.MultiplyOverflow(result, Eight, out result); + overflow |= UInt256.AddOverflow(result, (UInt256)exponent[leadingZeros].GetHighestSetBitIndex(), out result); + underflow |= UInt256.SubtractUnderflow(result, UInt256.One, out result); + + return overflow ? UInt256.MaxValue : underflow ? UInt256.MinValue : result; + } +} diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Nethermind.Evm.Precompiles.csproj b/src/Nethermind/Nethermind.Evm.Precompiles/Nethermind.Evm.Precompiles.csproj new file mode 100644 index 00000000000..88e8f0f7f18 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Nethermind.Evm.Precompiles.csproj @@ -0,0 +1,20 @@ + + + true + enable + + + + + + + + + + + + + + + + diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/PointEvaluationPrecompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/PointEvaluationPrecompile.cs similarity index 95% rename from src/Nethermind/Nethermind.Evm/Precompiles/PointEvaluationPrecompile.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/PointEvaluationPrecompile.cs index a392885d1ca..534113b911f 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/PointEvaluationPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/PointEvaluationPrecompile.cs @@ -8,6 +8,7 @@ using Nethermind.Core; using Nethermind.Core.Specs; using Nethermind.Crypto; +using Nethermind.Evm.Precompiles; using Nethermind.Int256; namespace Nethermind.Evm.Precompiles; @@ -23,6 +24,8 @@ public class PointEvaluationPrecompile : IPrecompile public static Address Address { get; } = Address.FromNumber(0x0a); + public static string Name => "KZG_POINT_EVALUATION"; + public long BaseGasCost(IReleaseSpec releaseSpec) => 50000L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0; diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs new file mode 100644 index 00000000000..b4c3751bee6 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Ripemd160Precompile.cs @@ -0,0 +1,43 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Core; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Crypto; +using Nethermind.Evm; +using Nethermind.Evm.Precompiles; + +namespace Nethermind.Evm.Precompiles; + +public class Ripemd160Precompile : IPrecompile +{ + public static readonly Ripemd160Precompile Instance = new(); + + // missing in .NET Core + // private static RIPEMD160 _ripemd; + + private Ripemd160Precompile() + { + // missing in .NET Core + // _ripemd = RIPEMD160.Create(); + // _ripemd.Initialize(); + } + + public static Address Address { get; } = Address.FromNumber(3); + + public static string Name => "RIPEMD160"; + + public long BaseGasCost(IReleaseSpec releaseSpec) => 600L; + + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => + 120L * EvmInstructions.Div32Ceiling((ulong)inputData.Length); + + public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + Metrics.Ripemd160Precompile++; + + return (Ripemd.Compute(inputData.ToArray()).PadLeft(32), true); + } +} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Secp256r1Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Secp256r1Precompile.cs similarity index 92% rename from src/Nethermind/Nethermind.Evm/Precompiles/Secp256r1Precompile.cs rename to src/Nethermind/Nethermind.Evm.Precompiles/Secp256r1Precompile.cs index 069161091f6..ee198302462 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Secp256r1Precompile.cs +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Secp256r1Precompile.cs @@ -6,6 +6,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Crypto; +using Nethermind.Evm.Precompiles; namespace Nethermind.Evm.Precompiles; @@ -16,6 +17,8 @@ public class Secp256r1Precompile : IPrecompile public static readonly Secp256r1Precompile Instance = new(); public static Address Address { get; } = Address.FromNumber(0x100); + public static string Name => "P256VERIFY"; + public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip7951Enabled ? 6900L : 3450L; public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; diff --git a/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs b/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs new file mode 100644 index 00000000000..5954820a265 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Precompiles/Sha256Precompile.cs @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Security.Cryptography; +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Evm; +using Nethermind.Evm.Precompiles; + +namespace Nethermind.Evm.Precompiles; + +public class Sha256Precompile : IPrecompile +{ + public static readonly Sha256Precompile Instance = new(); + + private Sha256Precompile() + { + } + + public static Address Address { get; } = Address.FromNumber(2); + + public static string Name => "SHA256"; + + public long BaseGasCost(IReleaseSpec releaseSpec) => 60L; + + public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => + 12L * EvmInstructions.Div32Ceiling((ulong)inputData.Length); + + public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) + { + Metrics.Sha256Precompile++; + + byte[] output = new byte[SHA256.HashSizeInBytes]; + bool success = SHA256.TryHashData(inputData.Span, output, out int bytesWritten); + + return (output, success && bytesWritten == SHA256.HashSizeInBytes); + } +} diff --git a/src/Nethermind/Nethermind.Evm.Test/BN254AddPrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/BN254AddPrecompileTests.cs new file mode 100644 index 00000000000..e33e0122ec9 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Test/BN254AddPrecompileTests.cs @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Evm.Precompiles; +using Nethermind.Specs.Forks; +using NUnit.Framework; +using System; + +namespace Nethermind.Evm.Test; + +public class BN254AddPrecompileTests +{ + [TestCase("089142debb13c461f61523586a60732d8b69c5b38a3380a74da7b2961d867dbf2d5fc7bbc013c16d7945f190b232eacc25da675c0eb093fe6b9f1b4b4e107b3625f8c89ea3437f44f8fc8b6bfbb6312074dc6f983809a5e809ff4e1d076dd5850b38c7ced6e4daef9c4347f370d6d8b58f4b1d8dc61a3c59d651a0644a2a27cf", "0a6678fd675aa4d8f0d03a1feb921a27f38ebdcb860cc083653519655acd6d79172fd5b3b2bfdd44e43bcec3eace9347608f9f0a16f1e184cb3f52e6f259cbeb", true)] + [TestCase("23f16f1bcc31bd002746da6fa3825209af9a356ccd99cf79604a430dd592bcd90a03caeda9c5aa40cdc9e4166e083492885dad36c72714e3697e34a4bc72ccaa21315394462f1a39f87462dbceb92718b220e4f80af516f727ad85380fadefbc2e4f40ea7bbe2d4d71f13c84fd2ae24a4a24d9638dd78349d0dee8435a67cca6", "013f227997b410cbd96b137a114f5b12d5a3a53d7482797bcd1f116ff30ff1931effebc79dee208d036553beae8ca71afb3b4c00979560db3991c7e67c49103c", true)] + [TestCase("0341b65d1b32805aedf29c4704ae125b98bb9b736d6e05bd934320632bf46bb60d22bc985718acbcf51e3740c1565f66ff890dfd2302fc51abc999c83d8774ba08ed1b33fe3cd3b1ac11571999e8f451f5bb28dd4019e58b8d24d91cf73dc38f11be2878bb118612a7627f022aa19a17b6eb599bba4185df357f81d052fff90b", "0e9e24a218333ed19a90051efabe246146a6d5017810140ef7e448030539038a230598b7d4127f5b4fd971820084c632ca940b29fcf30139cd1513bbbbf3a3dc", true)] + [TestCase("279e2a1eee50ae1e3fe441dcd58475c40992735644de5c8f6299b6f0c1fe41af21b37bd13a881181d56752e31cf494003a9d396eb908452718469bc5c75aa8071c35e297f7c55363cd2fd00d916c67fad3bdea15487bdc5cc7b720f3a2c8b776106c2a4cf61ab73f91f2258f1846b9be9d28b9a7e83503fa4f4b322bfc07223c", "22f8aa414eb0b9b296bed3fb355804e92ec0af419d9906335f50f032d87a8bf82643f41b228310b816c784c2c54dcfadeaa328b792dbe0d0e04741cd61dac155", true)] + [TestCase("0af6f1fd0b29a4f055c91a472f285e919d430a2b73912ae659224e24a458c65e2c1a52f5abf3e86410b9a603159b0bf51abf4d72cbd5e8161a7b5c47d60dfe571f752f85cf5cc01b2dfe279541032da61c2fcc8ae0dfc6d4253ba9b5d3c858231d03a84afe2a9f595ab03007400ccd36a2c0bc31203d881011dfc450c39b5abe", "1e51b9f09d8fc2e4ca11602326c2cfe191c6c6a47874526e80051197e9f6af842282e508ca489bf881e25cf9590151ff5cf94fa523683a0718d87abcc4d4a16f", true)] + [TestCase("0e6eab4103302750b22364bd1ec80e5edfb3ad06fa175ff2517ca49489f728e9050a17b5a594d0fd6fafed7fe5c447793fe9b617f0f97c3ee6dd29638f6c9232038de98419e242685862c118253ab7df7358f863a59170c37e606d5bd23c742f076ff3443f4e01b7d7ace1315fe50cf77c365d8d289c65303bcc11ba7961ab95", "2231ab2eee93d63596f718533ddbb95a86b13d39e1162897d791566e797f82952f39ea566bede8e7ba15f3c61b0e96275b2fc51800ee2baf2f9bd7acfa874f0a", true)] + [TestCase("1920c53c756f1ec1a40e0264e5f65808eafaeaa7b0885f89852297bc2186ac9d09416cc536a27b6d5616f74dd2bbbfb463b9961752e0aa38d47b5213994959ab015296293a5a1bb5e15a7d019787422cb3409e075e122c6fc5867f0c3f3715731782b870b6641d8d55323e27ebaea17909499877fda62e3ac1e2b2310cad5f9c", "0fa3236565b78b283f3ce63ca62bafb87c33407b11a077e39230ff37c054cf712a38174368bf872f80f78fb5222e95717183242b9d4da75c66243f043aed2fc5", true)] + [TestCase("001faaf97b965ffa633612b7c8f9f4be0b286b19662e5cbe6878019d8ba1382b16567ced7a7ee5c272bbc378a95c2436fb0c6133649c77e55a708b28419b5cac0750d51706ced69621c8e4ba1758ba90c39ba8b3b50507bfa545ace1737e360e283d609cd67a291fc3d720c5b1113eececba4ca31d58a1319d6a5a2fa89608f9", "044fe3c480840e5a8f544efd28a8bf3246f0741a8c61c3116e93d84773399c8b26c5b695120cd724aa2a5f4dfd3042c07f752be4c4a8b750398109d80f4772eb", true)] + [TestCase("128b65cb80257f3006fc20dbb6af6781da7e0f9213d2b909fd113ee0f2d2bb52251e288387db7be742fe67261f36a4f09eeb4763bbbaa1bb13af3dec65302a4115f64edf27478045bf45eded285544acaa7f2b3a2a36176acefc1a3d7181a73219d4344489688c2a2f16caf1141bc42021738339431b3a64cfbc293a73c1eddc", "0a20db61d2b74384ca184f20455ad1f380ba081f89e41c87ceb3fdbbba63c7aa1fbda20003ec799f306f70df7f53f91721e59353013ebf1647f5130903fff482", true)] + [TestCase("16a9fe4620e58d70109d6995fe5f9eb8b3d533280cc604a333dcf0fa688b62e20b972bf2daef6c10a41db685c2417b6f4362032421c8466277d3271b6e8706a809ad61a8a83df55f6cd293cd674338c35dbb32722e9db2d1a3371b43496c05fa09c73b138499e36453d67a2c9b543c2188918287c4eef2c3ccc9ebe1d6142d01", "005a68cc13a108287aa3ca0bd8bef95096ef22668e15c87f7cbe0167cd1cdc930359b9b2dd28843838cf74cb4af2cfd656690a7f73de771b891142db22fa61fb", true)] + [TestCase("0ef704cd9e3c0b10fbfdadae2fb02b1b8679d24684b9a8ced52d2890fb61453e20edded55ab925e685ff207c41edb00ea85eaf74918864a97d75924beb3e5d1c3431d14cfbe9a5a1244e88ada99303090b48f7580ae1e3aa0c82cd92025c03e41b1c9200304be38b893bd18ca5b528bb34fbcd8126c1104f0465a7ae1bf44556", "", false)] + public void Test(string input, string output, bool status) + { + byte[] inputData = Convert.FromHexString(input); + (byte[] outputData, bool outcome) = BN254AddPrecompile.Instance.Run(inputData, MuirGlacier.Instance); + + using (Assert.EnterMultipleScope()) + { + Assert.That(outcome, Is.EqualTo(status)); + Assert.That(outputData, Is.EquivalentTo(Convert.FromHexString(output))); + } + } +} diff --git a/src/Nethermind/Nethermind.Evm.Test/BN254MulPrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/BN254MulPrecompileTests.cs new file mode 100644 index 00000000000..6a473ce52ce --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Test/BN254MulPrecompileTests.cs @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Evm.Precompiles; +using Nethermind.Specs.Forks; +using NUnit.Framework; +using System; + +namespace Nethermind.Evm.Test; + +public class BN254MulPrecompileTests +{ + [TestCase("089142debb13c461f61523586a60732d8b69c5b38a3380a74da7b2961d867dbf2d5fc7bbc013c16d7945f190b232eacc25da675c0eb093fe6b9f1b4b4e107b36ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0bf982b98a2757878c051bfe7eee228b12bc69274b918f08d9fcb21e9184ddc10b17c77cbf3c19d5d27e18cbd4a8c336afb488d0e92c18d56e64dd4ea5c437e6", true)] + [TestCase("25f8c89ea3437f44f8fc8b6bfbb6312074dc6f983809a5e809ff4e1d076dd5850b38c7ced6e4daef9c4347f370d6d8b58f4b1d8dc61a3c59d651a0644a2a27cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "18a902ac147b2951531770c7c18a25e3dd87765e23f7e0c4e9d62b624a6e37450288473776e7e99b2aaa27e8f4656ea9ce5e634fd1ca1aab45315199ecaced2e", true)] + [TestCase("23f16f1bcc31bd002746da6fa3825209af9a356ccd99cf79604a430dd592bcd90a03caeda9c5aa40cdc9e4166e083492885dad36c72714e3697e34a4bc72ccaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0c6a880ffdd0737c53bfec9b65c9098a3298747bd4e5fd07026661b4cb804331116aeec88e11f49753df224c60c4bd8b8bc0a98b8d50f24ce64475268d227f4c", true)] + [TestCase("21315394462f1a39f87462dbceb92718b220e4f80af516f727ad85380fadefbc2e4f40ea7bbe2d4d71f13c84fd2ae24a4a24d9638dd78349d0dee8435a67cca6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "1d7985d51e53cdfbd73b051e9a74ab6e621b6b664a7efed00e30c1264f5623d02808eee3baec187160d2499b4aedbc665a532d245212a1be61e0d4b9b36f3075", true)] + [TestCase("0341b65d1b32805aedf29c4704ae125b98bb9b736d6e05bd934320632bf46bb60d22bc985718acbcf51e3740c1565f66ff890dfd2302fc51abc999c83d8774baffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "15bd6ea71fd264e1bfb04eb6d97b4f3686c5bf36f91356fc13ddde3494e172d90b3f8392fd4cdd5d542887ea4ee0274835bf37b58edf927ef242b8704af52e92", true)] + [TestCase("08ed1b33fe3cd3b1ac11571999e8f451f5bb28dd4019e58b8d24d91cf73dc38f11be2878bb118612a7627f022aa19a17b6eb599bba4185df357f81d052fff90bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "26ec73a6134f8ebce33d675e1f2e6ff3ec066e8d255ffca6eb55ef2ab7c5c51d06500cfcd6950c92de24b90ca09be110f8f9c2fb4d9cb2a9f9677dd81c1c0607", true)] + [TestCase("279e2a1eee50ae1e3fe441dcd58475c40992735644de5c8f6299b6f0c1fe41af21b37bd13a881181d56752e31cf494003a9d396eb908452718469bc5c75aa807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "06894837c70570eac651dae1a443b830c292c1801340ca4150c9d339177965e509ad8d4839bc83bd1852e6a8b71dcf01a1f7d6b6b174858ca02893bd5ace3eee", true)] + [TestCase("1c35e297f7c55363cd2fd00d916c67fad3bdea15487bdc5cc7b720f3a2c8b776106c2a4cf61ab73f91f2258f1846b9be9d28b9a7e83503fa4f4b322bfc07223cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0e56eeb3f168767b21bce1489d9657f694951b25ea8a081f4ebf68469a1eb1e0293446d763ea9c40e52286f2ac504cfabb364b1f899b874b13d78879d25a5ec5", true)] + [TestCase("0af6f1fd0b29a4f055c91a472f285e919d430a2b73912ae659224e24a458c65e2c1a52f5abf3e86410b9a603159b0bf51abf4d72cbd5e8161a7b5c47d60dfe57ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "2f63f5f1275c401356e94adfbe5e8cff21485a9281e55d378a51eb93263a40802a817491a84e40c584481df4a5085b301c6fd66cb97856de55cd04df85a6a1d3", true)] + [TestCase("1f752f85cf5cc01b2dfe279541032da61c2fcc8ae0dfc6d4253ba9b5d3c858231d03a84afe2a9f595ab03007400ccd36a2c0bc31203d881011dfc450c39b5abeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0aa7b6fda656f23eab50e36db0519cdf79f4624d417253085907ebfd9aef38a414cdd2edce2b313fc6dd390628ac9fac910841706d55f9af2a064548694dc05c", true)] + [TestCase("3431d14cfbe9a5a1244e88ada99303090b48f7580ae1e3aa0c82cd92025c03e41b1c9200304be38b893bd18ca5b528bb34fbcd8126c1104f0465a7ae1bf44556ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "", false)] + public void Test(string input, string output, bool status) + { + byte[] inputData = Convert.FromHexString(input); + (byte[] outputData, bool outcome) = BN254MulPrecompile.Instance.Run(inputData, MuirGlacier.Instance); + + using (Assert.EnterMultipleScope()) + { + Assert.That(outcome, Is.EqualTo(status)); + Assert.That(outputData, Is.EquivalentTo(Convert.FromHexString(output))); + } + } +} diff --git a/src/Nethermind/Nethermind.Evm.Test/BN254PairingPrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/BN254PairingPrecompileTests.cs new file mode 100644 index 00000000000..13bdfa73f6a --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Test/BN254PairingPrecompileTests.cs @@ -0,0 +1,68 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Nethermind.Evm.Precompiles; +using Nethermind.Specs.Forks; +using NUnit.Framework; +using System; + +namespace Nethermind.Evm.Test; + +public class BN254PairingPrecompileTests +{ + [TestCase("2722ae33a1d80f67a5da37ef2b7489dd39b1c98287fc408eb416e37de71bba1c3054f7ce76b782aa80254ce991fd5f115810e8f8f57ed0a12f30278112157c11165fa63e0d077c2b406c1001da54664d756636d6018616841c5b0d942519fecb1090ad3ca54838d2b89c0d2e3db3c2aff811d58bc32881d2ec947f473a8308a615b9fb021f60b7604ef07863fc6449504708718eaf59bd00f3620a9da16ed8830a95e72b8b56d1850126d77ddbdbd376e3b19f07a75071f0b958bd40471fe6900738bd659eab6973c3416b9e7c9660d341e8eee184c0f9c5ec59696f220903401e37dd4714f68da2a6affcf65a8cd26c7ae3fa0c0e5a3394887ceaebe4f49de90b501640d9ca26d1b466a9ea005b942b047fb519865b3413ccd90533d9902a85187c1fe325590f77ef42af537664469fa950986ce82c31eeaf1f6b348a3de3c6202ae189a9bf004bd80b9d8bdaa9b395a5263735242766aca3679ec3e547171b2a06ce9550542e6246331cbf852383c14830931cd63ededb0f21621b71e7f981", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("0eefcc4248b67e40298c48e0ed47dca1dbf6f6e377506899430b11bf03b17ede10c71a49ccfb43f8475de84b581eef9ab283c1238e172bf48150f29e1e56201204c9eaee6321d6ee36b8670498aa1c73665f3ecc7350c8ee09a573e692d26320171450a989ebe50e365b92d24c311fd830972e7b16a2523e634175c4e24c884a1a6bf429331081e6e930bd36e23bdf91bb8180a6e4129c11655cb9468093ceba0e9d0caa4d47983e49ee253051aaefd86cc6dd367384f89e2d166bd721c658122a55d1dc0b4bd2f33984f0099a6d44c85baa10aaca32d0ec89e494d24514a68c2d43c0e6576ec46f88dbdcc7c57d685a3eb9342ba7c71b62de9e6373bd9094ff0a716e218f8e4174821a7dc090fa93b7683e2a6e363afe3eb7287a7dcbf9ea090dada034b037e05a7c8b232b8c691b7f0c3b9a870d786e913d936f8256f2e8c0131bdc0ab71a147cb4d91bba85941c00ec91994d2e9e53b1929a14ee2e876dff021d8b2738aed0201234d3919498c918fd5340541ec616542d92d955df4c182902237ac6c6802585c60640eefde7c05fbdf206a5ec25dc3411a4e9b4e6b57be611bbc865815ccfb7c666b117834cbf2a7edd9c2baa691ee3d453c3652c49761b234be3f502cdf3d1e6258eb846afca7acb0fe13577e226ddd277daf32d1d0c5c25e39a0be0435820302ccb2763016b10d0dbde867c745fe86cfba8cc925a2eb72d4bb48beada74cddc1c791a980d9bf7601ce0aec444354a5c02185d392f66f50e4860e017fc0453fd1bb0453197ff5abfacd35b90e7d9b03ff0900cc857ef7f2f0ccd45b2e137fd53d99d027b79aa390ac021bf4d6aa95cc96bacd6a071386e21f73cf3d42f0ed82ca6f673bb89223e16386c7328385edb01eadd4ce28e5ab418861414b0b511cc6300bd0cc6c95538014be8a4a20d8cf56d74f4a63225302b1f065e5ce6c676af04344de377f580aad377dab935d532f2dce9daeb0f31d6900af84aeeab7ebb4390e6bbb4218558fba894959f2cc2fef8af5d1c16998a38c6076f86dbd858db5b0b15ca2cddb0092ef861188e0434f4232d7e3e884fa42bba", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("2685aea6edddbd98ca03c2df477608e71c613e56d9817eb504fd4646d5699f8c266d709c3621b8da9d775d325bd8b916e112f456067cc94c3cdaefd1363ae58d0f238e6e421f1e1a80659b3f3d53c82da29dcd92c8f3e7f5cd6d144264c962e60f0e5f7beee4ab3ca6c225dfcd70cb1dacea4fb1c11efcd92a9bfd000f20385d0c507168460ff0ae1f4a3f4d4d40c2bac5f44e18eb22f961d62817a542ff63111ec38e34e8c84f6b8aeb81ab4d04f44178977880ad50136de60a1d62f3b4fc9407245d2ec4baf533022981fbe51d195b64d3fbc15db7d356f6bd96e425672fa3183cba898f86a37b5f236e41e4938fb5badbfcb19a929fb0b0a945d557d9ba4f0bfae5037583fed3a2d1b726b9f5352a512d1c35ee7e8997aa57b0be6a07b3220aeb130f7f24d035942c0b51ae34ad675041dd89d49c0854aa29036687872f9f105a80888c3259e1ab38ac878b95449da892c2424c0b73a32a4bfd6c1fc2b035166da5e9e14dd821a2bda674e8fbc7edb1c8e1edf32a7fc1a57c5a0583f888460ae28b4c49f27952ca34d10e87fba821e197b891224167a5accfff0a2d6835ca0517e1a590ba9c9f6a14a0b105a34bb5d38df06fe6c87ad79b5902445dcec7d824ac886acc6b9e4405b69d9650e76e92eafd8cd4c670d0eaf4b87894b775221c105c4529534d44bfc6df876cd3f64b459730aaa58f02daabfd425016db382dd12c241b2ae39e4730028739a266d7428bb0f186b0177a5151d821aba508d907ac1ba083d662d28d081508cc46353bd659898905e68ba2d8291da61ab408ac83462f96a39797f8f6957f9994c9e83022ffcb23487eeb10fa010f62467449b1db9b29cf62c0d6b266473eb0bd57accde054bec7804cd87c63b4cea3d9ef688c2076300d74c7b5d90044fed0a3e144ca22f49fd0f519d7f9133f4afe84ed531b8e5c151fba2c92ef82b4974906eaed202eca91413bbef2c19408110d86ab097369a8128a72e0ee836a38fe369c34ab28832467ca7e7da305c7f1734db29dbf5ddd1d2eff09551ac5d3fe228c9cab77da07fbaecb7a4344847b7172858963a81c1cc92ba8f8505e4001622b17c3324a74f572f7905655a37c63dbf2b1e178378c9fb31468feaeb5aef9dd81159a28c201ec816b0bf2358d5eaaf2994f79d945e9f9f22f5b9427cf97e32fbbc4ce9f9bc8b203b5ce92a13388719701140ab94b927d261e807c4698e5ae5b179fd8bb17ee8ac91d6a071c09885c5fbf27529cec212fe8075e75c52a3598f787a261bb7281750b87fe125ea914a2ad8bd77ad60b5994101456c38d0b29c7c9d5251dee44c53ce5c1e06ec623041469154939fca1497a2b24aa5766645e993d87c143ac92f67bd241ee71f36fad6359b04ef25d1e106003161e7e243a350dddd4e5e71f3d260498acfe2da15ac92e024ec7f420dc323b111c0704235cea83ef84cbf533f0b559302ebaf637df3f4d8b68328fad9501355b00a96d3df4f329e4cfcb81daefa893d65caa287cdb330844d31fdc35aa824f8f01b9d722f2ca441ed789275d21ceca9f8b4ad5a2c64d1467519e364ef77bec63054ce19859936c36a5c396cedfae169291b3a2d8d005fed1e4b104f991914fc61b0215a5d38e3bad0ace8354013e8b6ebe73d96fdce88d550953235643111bde05ec8fd2737015151f523cb38a6baa918a4c98e6f955eb2805ede92b82292986061700c3e0189d210d3fb0b4a3bd09bfa0a00241b386394b4e10fe3d480f6c4922823fd2cf9d6134fa302cab2b1fab5957bf6fc7dc4268d5ec0fdab9bf854cf01b07d712153db5c2cef41f822eedb1ec8b86528fb59a12b9362f406c784c55c32b3d0294f737850b94d2ae395964456e19e826fb958730c06e01de0f7f4c3ba9243d95d6a537132236597b565b60453d6ea32c75afb2d875c305661b30ca22f615014ffd20951f8ad3096b7f66eadb520ff3dcab6c86f8fa58f8d486fb0e7c1c2386a1d6047b8807b70d436be59291dd8263a1f3ae9813355f2fbe58010f67d20f576105e2efb422ca422c015e9394e16e484b6ba6da85746f121888b43159d61b793d3497a73545b2e74d525a1a67a201a3a0b9926a2b94d33ed7aa5b0158ff20af4b861226ba9a2c474ab446c2c9eb22f77fe0d45b8b2a810689970885f88b", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("20b961c884a0ad42964edc3b580f607681058a33aee25d60f7dae9f060217ec119d77c703d1a93059a1baf9c17319ca9f1c5fb4a04855d6aedc308d9070f9769103dd1a1691e5fd39ff70241d7569c17764a3824e49664f5145f956abdd559af262f0e5677944e1834c3b5459e0bfb126d41a8afd73bfa12ee3ef45f17e81ca62dc7a825213952eb841f8942a113a5cbda01359751726ef26ce05491815806cb2bbefb942c709bb4fd01181e99ae1716ee28d0453ef725cb8ea45f7a4f93c6b3203b2360ffca610432f4d1053e633004d7a822ebd940e9a546a7d0f2038728921f1aa6348e2cb062d5e193a49d60214f2f0752fd32b57319b877958ef0f7eb9c1b32607b1f0ce57571b1c609260f757911ed8bcc3896e6c95a13655d11b6a7f929b9eabda75ba7d16a31ae4b7af7d0eb1bb349169df32fa20f4cfc959e722e0f24d21c9b7e68ef0e4e941aaffc472a7fa0b9d03b7097df3c993d108fa69d0a8b189dc5d953fcae14f53a800fa624429d2bbb94ec56f371e65dce393dc602ea2a04b4e2312aacb2061b9d55e615845b085696a908d76944bc822ca909212ac6bd05bb2fd64a97c2dd2e76b9ed90febf4fc236d4c466ab7afa4050101828fa67a02b0d987e9d5d717c8be7757e34354fc9a57198e5d8e867a8ff08b3e3020c84cc015904ec31cea03557ca10f0b7f5ea8b5215c80c01f5cc47bcac78c0d2f1f312135154f38704a2b7db3dc7c86be733e8880e07aa0712c2050627bdf56acd40482f36f73badb30e320c12bb66096c8bd7b978410dd5449f250519c6a122ceda572357aea961fec54427a6a1e6cb2d509210e0a6c049d39eefcf09191b561f361a2d372ecd78676d8180b6120c432178bf969e889d2e386ceb20642a0ab00f1c28263dfd316e344e8f9c1380b0fc5b3ce5bf524cae2978f53e6dff5c6cdf0743ee0c68b4b256d924d9635a4cfe45948e1f5c137369b47439912b113818d26e766d0ccf83a1e2015a3ac6f355345d4ab03f710bda2bf76f42eb7ae70aff6f955184031af5d2333c1dfca388231e1d78a53749973f0a6a01f8ad0018704c7db134592cdc9744ad7b88e407d0eb04696b62fd57be16c249043f670d881e8fb7573f9d0cc54a632cf9de52ee862a07e0d9dc11a3f4df8c9fcde0bc80f9fda1b8a84efb0b67884d640c14cc63211267d15a405fe9d03f9713fc79cb787934a778928b1f244b2e84e926f2d5a7e6d9a154873abd1899a7b20df25ae018279ed525e939da2333d4121573982541bb5fdd5d6570676ca6a2979f92a21a563924eaf1b2cc3c16190560061e4eaf988b117bbef2a7380429021d7190eee78b725bc42613725d2a2e3d1167ad6d74508c5322df36e614e10eedb067f8cfcb9573e9281b0b827e282d3416ccc69d13090246f223e743d077d3d167af6558cd17b8110b422b70462dfe3d677fe5a72c5125c9e67534c06a4070f0bcbd8f6a5d93a7691d63a2811e1908a4f98042938fec22a2372ff55c50d679bdb4dcef9a1ecc1dba4fbb54f6ba153aff2b0ba9da968ff1b07f22e95f4404a924ce1d68c9d4cddb10aa9680cdc2064aacfd45913bcc620e4cf277913eaa093e4b3ce25f40d1ac255f863fcf59c2066e98d7ecc5219edfdec9bdb718416fc65e1b48f3a5e33f40a459600bdf13c8144d022ace69574477c864aaa2cf989a862940f80b2c85e5737926e3fd1e18411d06df3079e19f11b85b2634cb2788caa2fa53cfca5de8888091dbd8cb73b3651e0c60e28b318329e56ce5cc18581966834f960344fe9645682b800bc138e5670f8f23befa1ac5f9caba7fca7179167d2df6ea237dee29bccc80eacabd5a51dc06f245eb13c8ba185388b1de78b300308010a551df2b5311f3ae838318d20297179bbf83449adaf1360b0b10494e299a9cc71672ce5774394144435ed65a061b230c57e56d08af54493bae064a3d94aba34faeab22b8056c9d1fd0b499bdade429c428761820248450189abe14f51cf3274aae5e2d65644e9866e1e5342faff915cc65f72d8210c6aab304b14ce4036862bef5e03cc6269ec755cad0f1bf285f0a67d6a9e5be0d4fe6e50b707331076cd11d96ea9c1c98575d21ca59083964fc06691da6e6e12b833b3b126f159d4fe2619b89bd86423b6cb9bfcb34480fa78c", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("0341b65d1b32805aedf29c4704ae125b98bb9b736d6e05bd934320632bf46bb60d22bc985718acbcf51e3740c1565f66ff890dfd2302fc51abc999c83d8774ba0d2c492bf135ed45b0d6265c274d145d35b73afd41ee95d3f1da4bc8761038800251d138db1b9748ffc257b147a1aea66413b14df767f98f7ba02489c617eae51065ff2bd9a5b167db36225a35fd712d781309f4e2c8541a335b2c42bd2bcae4191cd528d749c52f3e198e534868d537867109419a32314886f6bb2bcd337773", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("03d310db98253bb4a3aaff90eeb790d236cbc5698d5a9a6014965acff56e759a1edc5e9ae29193d6e5deed5c3ac4171cae2da155880cf6058848318de6859ea21ee564b4d91e10d3c3a34787dc163a79bf9d571eeb67ff072609cbe19ff25fc7270e094c2467dcf6ecf8c97a09ef643cfff359cbec1426c5eb01864b5cf3c27309f432f65daced7c895c3748fa0b0dfc430584e419442a25b98e74400789801210fa7bc208e286ebea1f5c342a96782b563a0bc4cdb4c42ba151b9cb76eea93d0abcdaf6ffdf0cbf20235077c7bb3908b74b9a8252083f4b01dcbe84cab90fc71a9681988a15b7eea9ae8cb0c2210b870eec2366e0531c414abb65c668c6eb3e21d0be81c5698882ee63cb729ed3f5b725d7a670b76941ddffff9ddca50cf9af21e61a0ac51a17c0128baa2cda8f212b13943959cf26a7578342c93dd2de7deb194e408b546197d9ee99d643e5385dcb8d5904854d8a836763ab8ce20f9b5027222aced81c808247572971b490eef1515a49f651f7df254de2b35310bb5b78c218b2345c40036ea331bfcfb8536739a5e5530027709adae6632a3613cd0838cd204121beebd54ec6bb063ba5a6d84eeceda2a733260066c90d332425e992ef6c2b0f794d64952d560a422a7ff549a58bfaa0cf791ab6dfad1c4941e19078040324bad1c848f2d8efcd716f7d814c46e2632e74a5b8d455a64c55917b220aab982ed4bbed5f80fac726f4a95789fee7905eef0a241596acbea4268ec3f2b87f3129563b69a30c11a856f68c72f129988e8636c86f57467cba299cdb4917469b49137a989e5d714b4b882d4a455600940ab63b14f23e7934ddd62cf5181099c63b2f57525eb3d19451024a4e71ee09c72c5b7e0dff925001acaee126bcd29db5f600d8ff46230e348d08dcbcdb1f85a5a43aa7b4f51841f1d4f98c18bbb57651982cabdf6326194120727367bdae0b081aa7da12c8f8c6af0ce27d2f8d0f059fe1240c9c5a6993d344744d77bbb855960b6704e91846cf362444bff1ccaf45a7c217873a5d7834d0c1d7d9bab5f9934d7ac218834aa916d459d8ceafc280d59efb", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("198f03850c2c5df1bd5601c0a5cdae3cc955026dba50a79dd00aeefe49c48c252ee3bce85e4c7bb10fee21428a8b0c1328d662e152f36a6c62caaac2fe097c0b0c91b38273eedbc873b2172cce9eaf7af1463cb3fb064a49cff2dc95f0b5bc1224a1a5e52496677b5dfa29a4e314d7b32bd22c0f437679e12d0c49c9d84e988014d4d06a717737c0e36767b06809bba6bcda2707bd652b3f922c3a652dfc90b325d0de555188106e9c4bd93171a8377b9d53eeb93b0b259a91c7ba570591f4010f2dbb4dfc16b4fe806d2ed28daf51530d6b88a81c2ffb98d3a6c1153db9239421b7f52300ab7b6eb9d9ef4bd7d58811909cf4c4ad7a9f8546f56099eb6ae1370224ecd4af7d5ec18e5b0c8eb46a8bc774fc4ac6c4233aafe9bf22420ddea4752bff288e58f4bc80b1bb91b450652c120db2ece783788b8ff3beb20b2e8d3c7a2d90a5dc703456ffb854fe3a746143e82bd8e4aae8321ab59a93e5da9d615ede07f9f33a0a234486c63562fd9b27ee6615655b6880bd511475059ab40395d23c", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("08808ba03b1abc4b870cd2e50b3960e85ea4ffde76e97ea70e62feb5712ac68823f1f949786f8cf8a18323bbad75bc71afac4e2419181fee3a627a8980f5d36f243b9ecee8d6c2f2f1b91980e4f7136d16f70c94c5fdc21354adb977bc66d748207322b7980616a6e4f4ddc3f223c52a9a11b785298b69f4075349274adeebb21226d7ded357133a1e9a8472f9c0f23e248c1ca1974ae336f4316731f1f473bf00b29428be1694c86da00b5cfe677c1b3332c93105d18df718f9ff0053bcb7a620adf7f96265baa9a9b1512eb1d59834eb931491d360408061135a8b30ddbfdc284fb8dde65089a6359a11fc8d2725409e2bc1e52141f1dd38bd56d10015346d0aad6b6b34672e8ffda5085e97e2a7f82ff4e3e6660b83e151b778e2dfd1ef3f14b07ac31c0927a5cb27b0447051f1ea39baa7ef12572b9b5dc535ffa28341a220dc6c1d760064168c59b36eae9560df6433eb96acd58aa88499ac5f081eed30245b974d3078709e037860b2970943659596a88d529a36275b34b38c51ced169", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("09fa51b9f1972a041220b86a762c252262d942474d9c2ddaa8d292c79d34b8132771b3f3a480320bc7c9963dda5f4e8120b8f06a0cbc6095d37e0dbbf0b6f9ce23d0c74ab9b983b35311ad334580ad3e9b8ac6eb0ccd69a5097884056c8310e01317cbe87801a1bad8f362bfa07f65f4e6f0df7f1d3681cab1995df75f3caa2516abf6c2348309a172dfb07485e59d4b149d20741c740c9379f5d235c8b7dd922fc0496ddcb63fea074ce4aca7f9a91884b8f3158970ba3f03fd58608b50b7d511857f4a462fb73fa92204c79e81824de2825b74103238b4f8e601a2cb37121303b531c48bcf5c8ddf8e608cd16eef92bec33929ef4d8fe57572214999746567129e8547b1d2f8103bfab8af9a8849ef950c020c2a24c235c889dc65d54c6f00036688a10447a1ca50ecb46b9c77042a3e0959de2919eb62e55e08f94b3b491b05f4e65becdda13865c79072d38ca4a35cd934ccda724348e68631deb874a62d2bec9369394e4b5d549558b030a5b8681d23a67cb9d95465f531a39ae61782b729fc71bd60da082f1dd43572c15900fe35d03e10201fe93668c6e31e0e4330212b0fe78b06800bc1a549cdd0ff91ea7ada763609799901b63a1d3ecb446ad1110847890bfd62a9ad72ad058345167d3716969f4f0c1861e532fcf5dbcbdeec04018770d45b235156f127dc39b55ce54daaccb9b2bffaa9692591647fb85112a622ec7b25af397ed0c3738c242d8c7d98753b0a64f826ad284412b93decd25a091a8d6e03829186f4f33185c75bae823e2840d04ca583753b9ba7b9a215de06ce04ca57858bb1cf75033675d652331e737f7d98400ea1b42102273e74f75ec4a41716a588640c92a28e2d4bf4ca5a6c8fb6fb2d910ce2c882fee639f5e16f11cb1967f6d1826b83b4197e628bf36eead712652ea75027a48148059fb422bf03550f60639bae9064af3ee671b9168eef729fa30153c89843827a9991da684d72ef07e000a8e29e909b06936cc43d82c5bd6f7a4108014532483f674ed28df007232003493fff270b3289b402ba1eab4bf90cbbbdddaec3e70fd0eb648c0fa61b2c", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("1a4db8abfea95acd4ac4bdf3d9082de13dcb9b2a73d6aa98a296a7d7d1009a8a1e8a143f9ed8661a223e211c4f70b1ac1d5057d71e31f182637b6f26de9a59190e817e9fb476d397b0f09aa07d290cc830ceac3ef815c5b8f45caf2cdafd90e209888f93aab917c7b6a9f8ee7174ff889961ff3509256873a774926c0c5b9a0f1005b845c9f53465d9371efb0eb934ecc8db144d466eaf06614e89c77305c35501951dfd5ce7f374b05b2b2a0737a5251ce4d9f53f0ee7fe79399aa09d6bfe9414e57a7979f8f2d78a1c7dc790476265240fff65e18344caa11b0698a574d4412bb862b7c0f8283e05e10a9b6e3bd19e5b69f6988b3f470692f26c379c33132126a4d85b3499d830033f0388c18b8e7b824b5b0b57db1fe366a435b0c1a53c6000ed1afda982e3f8d71da60ede43dd562ae63597ec91b1cba21e1c9fd5b8fbd81795c6b9f6debf45b77638122c7333a59aaa2e7511f526f496feb84c20f651552581dd3c6f3d05c78234b559d784f502fa5dc0900ae7475ba88716e5ac3d499d", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("05fa7cb22fb8809abb745dc167279147fa174e0444cfc99a38f23f2b93e49ad62f7f94d2d206264a9358b54fc96ac31921948cf3c13d121c923991f0b47c04291b2582586c93d23816aac8ce2f90eb913e554211251bc9a2d64dd2efb9a905b80f73f8ca76c166aa5735d9370cf944306abfcac5a5874cc95b00b569f7eba01a1d92dac05e6fe60b5131a0d2e9c459d4b3deaf1a462332b285f90a25e5b61c211467961e060894bc8111abdbb66365b9da4a6700f2d530ae69289d2cc32185d004951597c8a0547ea22859b97dd87a37a8b4125bfcb513eff29e0bcae7a7dab00cb314388716efc2bee7b4294811db5bacaa3bcf720932e253f002b53e968f930bfa9409e358a1370c298a8cb622a0079bd7bf1a0e32e8f8dde7a0f56877945d2f95f233ceb61db914a2fc789bd35b3df37f62329a886194450ccc9e708d900c1fec898ed485e2970646f939313b33a6d3416476fcb249a96f6f11d030093f890621cd7af05f335e3514d7f10972f2b56614e917d9c4cb85178cce40f09a2291211e5387ed32f8c6f90d4c90d60fb08844a0fe0786717113aaf8060208331d3a03558a26134672a33a540774a5a994c549f2ec4e048e99c45f6f44692fa09ecf2d625e843fb3c186d9502acb5c9c3e6d0402ed815d76cf081e3ed847bdf8b0db0caddcd63f8dbab0b1ffdd45ae118ad1dcd7c1306c75a1f448a0e610994e5f300c058a66f63de3e94c81e96dd0cba0182c1371f61006d4cf9c9e24cc439d0cac280db62277ae92b4403f31d0bef2674900f1c21a0fb715b5cad4689154bbf53c2430b990502a5231b79e63246d15293a37918adf641bc8f8b18462909c8d1eea14434c1a33eb5a3b425729a7885db91c54240d3e8049c3d10811709dc86e71ed08d9b41714cb20a4d28f608d83b541cf998bef0ea0257f477e00c180b4e8ae4a0698e1e77ae24715eddf432eb950c3e26972a08521c31c484a733ce217b944f6190db804087bf4786ccbde4b6e149f2471121b29b6cb21d1f7baa6be1ad6ef18295d7425b744106a6fefb550e079074b1933af2bcf989c833a5f133f8e1c490e", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("001faaf97b965ffa633612b7c8f9f4be0b286b19662e5cbe6878019d8ba1382b16567ced7a7ee5c272bbc378a95c2436fb0c6133649c77e55a708b28419b5cac0c37556712bc94140738212a1372a4720ff269102f3f0dad4493b675a85463021e03f350aa8213bd6ce54987e7b32275bcead9a9096897b5c7dcd5964a17e07a2550f45b84e947f8e46267041f661de0ced333f91af090435c4bd6d9cecb4836096855fbc396b73c589e66ad989d7851c08bb55755f5771987d91925ffb40c2f", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("08a66cc423317e9d9560c307c7918b87672f3d99effd28b1d2bd2877e09fbba41a58977974f56dc522d159bffd0099791d207d2da49ee217055f5d0806e2dd0417b523e87e1d03b9498facd5df95cd85affaa681c2a43e51497997aa916318391835cc25b6a0979581ff7042a390a7315d8f5e938ea40dfdcb24822889e494cc18dcd8bedefa1c477913634203aa21a5a926595f62f4010eb3959d51acc430fa23ff858e75bc56f4d5054035aee0fb7264ecc4861ba1c44db81868108dcdc4dd099b58d1c3d880dda20c24def1b2c54cbb20ed9da85265983a00c1cf1facfcf903e39662a649ddbc4fa6927ed85694167b49ee5787bd755a5e4ff6fb82c32a9f20b8ce350fdb30744dc3dd1829ce8e7365a9ca56bfa4f79831355157a73fe99a17a534a927ed0e6cdfe9ae9befe94f581d20a4f19aa54c93149c95d53714c5a70771d55a8c477c0ebdde254d19e591fc3ecf011848276731a12a96a3267c5c710c76eb36abc43ab4d4b5a7a82770304fc2e9487512493dc5fd59aa6eb30402d0", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("1fc8f5de35d75e7446ef5703dcd7e07ad682030dd525b7620e1f7f36908d535e151d3453db1029bf894b5bded388d6a3fcf97d573bcccf93d27456ec79d9337d23ec8c4d66276cb927175d7bc25e3bf5a2252c4f83de5eabd695181834c67273017bea94aade8279f9b646a2e7f570a88aea7eb8bd51aaf40dbfe070a7228a5d06652252d3e68fc6fd6d76cd726513f0f757783f415762ecf16fb288ea9b10252a6ba1abfff1bf53aef31d24fc7d7c18d452ff529a04bb97e2aeaab748cc19762032882547249177d5cc51a46852ebc90ac17f098a3deb8dd8a37fd007bc2baf28714b756b948ac2b606fe0c4c1c3572423892040e5518f9e6abe89e7b1875bc25cd06956892564bd5e9e8557ba6c719e2ecedb4a4996817a8e77593af1321050b2488820e023afa5734ceab7072083831db2f7063cc57cd9852deab6918ca9b00b22e3956983827a599218890be78a3c0ac7f30d3a35d464a9cd4d4ef552576221f5a9cbdba030df39ed692fe2274fe2a99fda883aa4e724d54d6a0f74e0a89", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("273cc7b93b70bbfde8748d62210c033579947802560fd05dad9d65003482995b1b7379946dee0b15e90720dfff72cbb60b60b5aaa8490ed2b77e8f57a8906d1816836ad1a19ace6e0feaa4195ee6006280ce178b5987341221c6ae618794c10603ea811d60c99786835aff3871ef0163cdceec010fd806bd11adeae2a91f4cb6179a512e9627d2af3dfc8a36850e144c7255568b3154d41797e2ac4782234925047ecbe78073575c62a32129476a6456c61545eb98bbf925ae1d673a32d680e71f20ccd414fe03613ff7a3d330ab8bf8964cba66cdf3af8bb955cdc729014e692ef7c335beb80626f05301278f5e3b228bcc981736a258ea6bc4802392f081de265db5dda279bf034808ed23c8613341b31d3d29a2f65a367024af1376d1bb9907b7ed2f35386382b00fb0afa6c5643c170010e35824d8fc84d3604690fa18b404685df83549a5573c7228b29a7dde8679d8771a19e8af709ca46c60f8126e4b033a388adb6c574f85524ff523bc7c44b49c8731b763836e0a4ebf054f0008492b60683ad457d04d91f082e169606c6e5d6e172845fe586925db00a8e6a242c409a8c11d9bd07c2ebbdd653519e9a0f5d29576033ebab9a564e1b07d8909b014232fdeb565d57fecdf556f1b9753361e8d7ceaef0d4778b4669643a8f980ed9107e310cfb6db05062d60b0810fa4aa6ff9825ebc58ae839c844f82ad08d9a273161549f2d3778e678f8167640fde4f43d30f2f60d7ec8cc83673d0e5100235e405c743fcac26a09a44bfb9bbd6f767ccf6dd030879dae04027353dcbfc9a89af0f566f9e06f1a6035c08bd9873e41dc3bf009005f905fc0b9b74ea57a16c5a2411c984cf6d6d274f79bec9cea6021001d0729f412858eda5c909d8bdce6a24980d28d7ff8a6bc01cf9ba50e6613c5495f13a39ced02158862b29579c4cb0e947142fa8592c012a3038fe1178bcb515a016a06651e387087a9110ac43ea9548a520537d116ead0e2498e487613ebb81ef0f6f5210cb448e92f2cda4a4f57013ed1f922e1c90d8e8891a308adec863c0b48faf4b7581e0565ded5a8ac6bccdee08", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("23f16f1bcc31bd002746da6fa3825209af9a356ccd99cf79604a430dd592bcd90a03caeda9c5aa40cdc9e4166e083492885dad36c72714e3697e34a4bc72ccaa2e832e2bd419280d247658bb64323d59bbf47df41aa729d2168a272d66e306ff18ab999098bc5b30758183a160fcca776562d9a9370278aee9e6f71053e9358f0edd6252e0584efe53db6b3c40d1976d3849f08db15d39a0d7a6e327fc67f45e24925638e68e59cc22218917c61d2934c4e6353e2f62178a09627aed68c4e57a", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("0069c0c3d6aa9ca250e5bd3e2826e47936b6e479ad7c776caa5ac801dd5a1c2115226a94941ba68cd74c5b982235773c3a9cf6a71b1dc9d4d8307251f1d031c630316709df5c7f6af25fc5f698db87b1170fdf63bd2917bc21b5037452053dd30bec8492774364ac6ceca4b56b9b8d1aec0bcda12943dd1437e515fa7fe5bf8000c0e3fd9719382c09eded028cf0c9f866d0fec2fab515f6aa60249557270f2e25f0d2cf69c495554a426914354b553f3f6f269e0d5340b2593a5793138189ae214aa7d305903ecbdbc10d564e1ebc9455bf0e8aa3ba3321f8b9023b911cecab19239edfaa2efe905d8a5d6884da42815cc84b13d9c4fb3c304cd99d3d27b61e15063c61103bc76e80aadf05a3ae6a36f90013bce43fdb48bfc8e3e2e09f838d1dcd88fe88d48dcb4d6401442b46fd713c41d36dfbc50d8dad834a9615fc01581377baf2e5ec86b4bfe2123c9f1d5cac10fe0a79fff333ac86ebffe1aabb98252316b9995e22925907421897f44ffffa963b730c7edad138f41f54652ddd8c30", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("2761d967b3f2481435189a94502260dff1044c8cb24ea3809d0eec28cfdbf6c72c87711eaab02bf1f9940d504be3727789efbbb1c48370f61e2e4daad31be6de08a73a943ab3a7ea19633a4ef9e9bc1de68a51d778e41589504b8fb0818cdf88064eb3b5d1a63404e247cd5118a695b3b85d63e89c8512309d591701596f172a210f847e73452b29da165f6c76462f2ee76ff301b534bb0d2f0f7374b041e15612a910ab4044ec261965b917059383b5d5f5c9eb201eb61a6909fb5a610849aa1f4535e9a8bf16a4a4435004b8ab3a84bb6495a0d748ccfc25388832356732910e2936a799b55efa690fd821a3cb4d352cbb3f22ed5fe865f984e289329ca6591e4e4510639258f836e30c422e3a18fb76bdc121fd28ed77306a05b8a3299fec09decd53dc1620f84154fd333da06556e87fae4463cf02459964412fa50d4b082e0120af9b40957fb7ff0dd412f59cc0acc01c49021389cd470dec453e92faa3221680f87a61c96fefc9ada16473b853c4c92a03e1e38211a9487a2812f830760f4841710cf252069ea39d70793aac9b2f769a3954310546fc15a109f6d057d30f01c88e34c9ec83f28674534aa8ad16f61b744b293b63ae3c2fcb178a08408a1780e9ff8f2973152194ebd44ef8b158470d3f67d08425c7a9d99a4f1ee9502704bc22f9c0177342d11e54a0940cd9b51caa04c762f060d5262b5f31c66d088729dcf02930b56cf1a3bcdd147cab2fcfe913c53bf5456dc19edd706ad2122be5129ff68c503fcbe10cef00f314919b033000f43ca563f92e95a8a9dc19a867e400d5a976132900579ff4d8e1f64d86a453d7576e16459b641d574d2d9af32c0707107329853a55152341e8142e6bd97b51118d4777e44d347a3add4f6e73a6d52c0175507a0d4432b6a72508a8fe5838a14c953bb0a8834366aa0ace3a1c12a005e64fcf94cadbc98cb78a5f768409a1cda219c504f3c0e99d1e8de93601046528ceafcc22a3649dd0270094b4b3fbe55fae668028e67a8dc3378fb726cec2fd0c3322db4dccfde2f638c9e7cde93246102e9539f5ea6bf23e57bb3f60e8690e", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("28d6423856311fe86c30fcd983dfa63c95bc5adc1dee6fe0ad715dbe7bba3c091165ad57bbd71dba3d734f446b3a11cbfe5e02051f6898a677bdda5134738d5709661289bdac8badf175790f8e406755b33e54bcd8149e1e469de37447185f110efd4f6454886db697584e85127bf4826304d0d9559195b6d3f875cad607958903e94e1ca8dd25c626e31daf9cd26b3caa7ca2615690127aa11647cba037c92a20179a34c869f27fe9783e133f50fcc38bfb81200b9c635d0b9bbbbc789f4cb60511e5e1561aad84bba3d2495e4853046ae1972e687ccab832f34f19fe9b55db11d42ecbbbf14d945c29319a9a945f64610a2bb9059c0c89911556232bdc6c4b1e92ef35b5ecc024193888d764218828778507233cda5076633acd49986023ba1c0110745aacf972ffd66add373241c8285dc6c96928a6ca012b4e572f1897540deab5945fc017e575d40284abc7356a20bb85330533be288d0a14159da44efd1fc7bd3676093afa2c2d809cb5a14b913c5914c77b341f018f391cfecf0029a2090010e0c084f8c16f8496f1c6db02902cccc6cb8d58118e8dee1baaea679a370075a1886efcc99523c8abf69974f742c7d2de3e12598a963713b9bbc31a9f0a14b98584a1aaebc7649c481668a54d9da6fcb308f3dec33e0965775624f2f904298d6b7a0d04b3a217099a7daf390d5a7edfd72b1c8aab02e6f5cb440cd4a84214772064081adcf6e36148eec3bcbbbd12d363b4a76e7018159f559c2ff1c0d8051f9f9abbafb9032e3c95ebde21931a554fab74bfd7f3d61c939268c46ff9c82ffc5143ba27c7aacca19326cd8522f9d55e6b6d17d4b0586b81d86e76dfb9730782e23592d8d735517d63b6b51313e09681bfb6e66cee098ebb60ca3ebb18f80ddd80135c76e5e26ec2d004f572d267f940a5d5b82e35f4df366312e39387662343e67b7783310ea825278a262dea12bd5b1fa71735819e3e360f467d0af5f522234b4bd70b251d63a8dc9bc9e63117ca8342c3dbb3068df38229b5b34f2bd21097b0a55ece871e554a89aa97a7ecb95cd9e1f5ecea94274019d17b9943de13", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("15848a9e99c4a0719df209a705edfa52bdca729d0b73a9835880da9dc0cd2ace108b1a4ceabe6a8ba3dea041bb0dff513e7b99057d4b3c2aa378807de47dbc3627515ea8ee84feadb86577a1b7553b2016cc63807de89fcbc05bc3d53b0f23332872f837e4cde9fbf64bdd170d6488a3155bcd5b1fef4fa7ad10089bec8ea7b803713c878e32a49ff95dc2bbe7b1491c38258835dbca14ab343e88dc64004dae0f9ec7e3c20939b84e40bf66864e8129742feed7e1291d752c76bdf28e02d03b2c48bfe10367b611f37ab5847542df1d30baed8abc5380d6d80032d0e04af0d10e119d730f867b4e286a3c1c4cd04236999b9bb94d9001a4f144982d72df407d059e6ea753e84de7e8b41b2d0dca1cfb6b12afeb2564a5e24a2064f1b662a1a912e0bdf2470e896d7fda45c39a66c5c4a5297b4f19810ee37e33f7f50499326b1f70831beccc3eb5fb719d27f111e5c731cbeb4002519a4b3831ba896cffb608157b59ceb6f7a0518df929eac70c7bac9ef9c196ba21266ff47cee9bb0c60864", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("279e2a1eee50ae1e3fe441dcd58475c40992735644de5c8f6299b6f0c1fe41af21b37bd13a881181d56752e31cf494003a9d396eb908452718469bc5c75aa80728695310187ac477bdf3d7fb472e6374b1222f8ebcfcae72a8b1dc714ec853461fde556a4ef408d4a2ce89143674e9985eff87fa3df3ce6e7483c3a2f9b82bcb18df8612ef09775ec815b602e35eb6ec71ea6f7acebdc23667a60eb465e76d590500f7d19190ee1090bffe087045e97c913f7c5730110559665b3e8a9e0a526e", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("03d333c171b569f9721355f4b5f9569c18006d55ea805d0ab72f392e6e6be88e230688a302d20e6934bc1151bf8a0af65d4294568f5af0b041197aaec74aabea1aae25b6edb4994684b2877875575b74c14a19eb068d429accd0bbbcd4de1d110b2f112b63197fcaa10a2afb08cd221bd509c829efecdd4a3bade00bf947cc3911796bc946a8148ce73aa901e2e1f4dcb259b11ee880e088ddff65f5f6f05d441ae8c9a28a7ee1d483dc47235e16e19303455ee1b7c6c29fdff01d3eab2c4e77284e25e7b8203b7b40dbf1bfcdb4fbdedea474fd44ed67dab27a031959453e9b0010adb1d55c492437f0bab7e1b63a56467681f06a29aca6ab95d29d5fd23c3529e107847478c3dd0aeb69d6c4345dd0239ba105a1bddc699512e027bbb34b81111903892d003d32111610c7ccd4c529f75cc8bf33a894f40756510ec8b9bcfd0402b66e82c6b8fd6de9652d5c81821f69445b0dca7cd052e1811760803f778a1ae8318c37a3652bdcab122282e95dd3f7393b3214e8ce290c01c9345ce81d1c09304eb9899baa26aa963503f8a55ed2a5d0cc2d5d0fbdfae81c3a823790d2371874cf1b2e447a896844c5338098f2ad9dea545e40d5f5a4369125d95fcd5acf0c0ffafa0ba1c1053fdc155d63329f5d8540fe5c6a876793e04913a1e6a7c88815fe284d364a500612c376e7bd39a466e1b9c4c0a85b105d15a973db33a0f1d42ee64373074312ec2147daed5fbc660ff99664dcb993750af8f192ee51b849a51d9a24c4dbe4f69715d00e8ede2f32c2a54c5e8f8a57487cf80dad49915cdc18239b7847b2fe9c17f926ad11e5161802872b6607265d5bf10c737d9eb157506c05725034e5c2a941efb693478b4401e684afba8af20cfc14c53f66652c737ab71657a4156fc5dc9ddf2b07d05c72395c7bb98f97743c6a81dcc11d25dcf313890effb8dceb430ae9009afe11d1f00e0ec2ca627ce9c4919287a319590dfba56d1d76f3288b570588497d0e5cc88341ba9b40b8fee65f042836161d718ebba12203bab8927db4e4b4dcf9ca7f4250c61d0a055985996d04e0c76d49bc83bad37e0a1a1f642a16d95eaddfb9b7a403bdd032f07c9222813df4dda4aa3054716d7622a999ac90eaa7bbc4ec78bb5d47736aaf04f706ddcc4724776a5dc0bc39cd1a0c9c5fb89113f93dc81db66c1ca13534f16518fb0347056c08bac62a1bcd1b201516a4f52fca78d9d140d40687b093176eb90fb236c03cad3ebf57027afc11742095f3a98a957815f7b13e263a5f11bccea9f6e716e219915e9075d9c0c2a8e0260e553a1182aa35b5d8d710c9705010e1350c02b6a217ec61245bee22c8509810027b242574ec29b652f249774d7320612dde5ca36f20f42bb169352a568e4c14a972b4ef4a1ca49f0e4b095f77ec5929486d1a051ed3b766a40d442e8e7d3b04ebc527aedcdd807d94774c23dbf3bf2841a2a0e3272e10431a056b1fb1224d16565b2f5350a0c8bcdcc6a3a2d189cc488c6c88cf9a0bd213248f73095f4ac0116d2a932043b527cb2a7c42e329a00310c9418da803179a099418ddb9ed859b06035b9b8fa5ebdbcc460641e8af2bd20e68e62d50563672a52294cc0e94cb331287c3cc9c9b8f389de88ed033ca26234d38089a712dfac171b8c8d743c5a2560b1f5c5d64fb31d6830a6c982fc8daafcc6b2ac02ac20685e11cf211edadf2bc01f9b7d3b716110dbfcda9974d00a0e90721e9aae490f3e0ba84b55cefa94919197ef9a4b21ccef5186f0d9801a25cbb77227b2d8488fa8da35e8c70495fb6861997575cfbbc644daf21868564be6a9fbfd216b252271f08fce405355d84d49028f6c5397686e765c5157034c2ed2f92e2d11c7411613f5c60b5ee50540df6fc025a3e1aee7b30e3113afca04fa7e3949a54f65a25aa8241d5056f289c3378a72d4730731a6659294dfe163718d63cc6239d09033ba48004c52a9d55d66317b62493908d3215efe3d2cb77ff6447a971599b2df711a59395515c4cac93a0f2211fada2e1799efd65247699ffbc3b35cce7d210a61e868d3bd8abb37e20bd5afe2a628ffe54a17a274af70c3584b4f9a2e567c6ae5d5a00d14ac7ffc12d04e06a03d1fee23fa99c63fb8a760fe4794af4221f7bb7ceb194c7df2c63859c8b0329", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("1920c53c756f1ec1a40e0264e5f65808eafaeaa7b0885f89852297bc2186ac9d09416cc536a27b6d5616f74dd2bbbfb463b9961752e0aa38d47b5213994959ab081c536b7d9a27636d0af7d4c8dad2e380cb2996a1d650a2e6123224294a6c86039e75a4a93bcc2798aec714e37b9b2602760e7ec7c6f3342e44018f2986da9b2d1ceb9ba9f7b923459d8b4701dfae12b3efd4174fa3705747fba6bce14a87720c15d04d2bd099f86ccaf9834b9588e88fdec8d04bba329d4fed580884f4b2bb", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("16a9fe4620e58d70109d6995fe5f9eb8b3d533280cc604a333dcf0fa688b62e20b972bf2daef6c10a41db685c2417b6f4362032421c8466277d3271b6e8706a8034c462aaaa7a3b4ed1266d755867524258c64b9553c46b2bd4d5c26aaedc66524e9d39a8749083573a1b84662c08ae15f16b75b9fd40089ee412f5e58dfad350e28b1c6e881a288290c7e9e12d23f122e61e89c43619f902c48d300ffe1734b014f125c1960a64127a16c8a17da5f21721e47b17575a94802a78711f45fe988", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("1fa11f66353f7a956254f3b98892d9c0f81a654f6609e0f0af13c2f8766c6f16194657ac1800e822825a05aa50d889e603dbbf4fc8e954f3b6f25fb23d5a5479142bf7baf53de4fc8668bbd4c019c0f6b7af0fec0c17ab0b107c83d25e4d18a52ef429052a9b35b41d51163583d57d79c420be96a1554051174b9ea1698878f11b36ee817c1b97813172a6418fb2937898fe7847dde90b6ff50b6b2a34cded942f593eeabb3b9d60300b894b05f78594a82af66d9117ea00224b4a21d7cf9ff51f70c6b295fa70454024594501c593b3aa26e4a93e66a0f38c3fa1d28c1612e91d631437bb2c0b4c9848a8fd19a1f8e3ac50ae338c9b516cc4049310ba4df21f287c33f63043e7e6ab5a1d13f7e759924743b9e46ded795c2c5ab93a909a3f7315530c731d9ba3398de10f401474f70944267f7ae20d0721edb0c0d48aacdfb501132d8f620cf839dfb326b07e46879ef281630486e202f6a5b3ee25d7bfa5d80e850b940cb4236be15cff7fa6f0afe97d4074d08cc84e9fc2c3af23892d61b63026dba27ff40c376fbe12ba44f231cb58178d22dcdf94e555a0fde0266d30002dab14694741bbac573bd15720b01915261df1442a03b424fbeea31b9f525c090ba172060641818b4c8221b8e01aab9788bb736e262e18f179221f6db532bae8058c38b8572443b8e87233d95e71b98acb2c946f149becc8ce8f259a89bffe962917050d74536bb197c472473578db35d84baa6c6ae9f9b436f0be637300423f198a1c23d945422603b6867cc421baac70d469d72d81380292e07297df63b5c01d61214817267145a6b0aea09a9bf2159d7360c4a7eb0a8c28a7e455c8ea3b540b5fc38fa57a56e8987689e52dc7ca0342c83789b8cb5717473014e1802469d01ca6d73befee617ad1012a1aeec56bc4d85e5f9fa8c98a49640c3543752250e921ef6447d718c318e7375b8903222b36ca85554932dcde661bd0e757a2037f4a1ab9425315926458a4e98d280cc10ed597c6c1af13de72471b52bc15d998d3232d2d849b0f73599c8ef253dda011b06a0f5c7fca436be16db5a6c389fb9cebbe0cf834015436d91dee19a986853c38160ad423bf52b4131487b5dafabece4d352e5dd076ceae35ef158c4b8016d3e4358c5e00a6d6fba7b3e319af57cfb7eeab1b64d4fd598ff6ebc85bf4e00445567736905d23864b42926019dcb0d924e90113ab53b025ba35c881dcf5a659f07632d4afae70d36c2cc547fb18898eca81401dba824b34f4ca6aef0edafa43b22378182199c62f74664f8bd35ab7836b318526669195ff4f5ce7fbad03d22789113e2328e4c4e49e3d81c78384315490295817075dbe3988e067faf0e1b4a9341a202e2616676282e029960b4ca852f528ed0e3f852bd6074625bfd6f46948973ac6ddf8fd1fa87a304eae65a6b2a53d50ea05db05521cfe31ec72869bcdfeb019276208720a0d33ee2ca8ab00ec09099e9c235971953f2ad06d4df01028cbe0f6449758345cb1d4ae4bedb642f84ca9e69e21eb1b1d639939504d29f7649423a34e9ddd3fc1e1648d3a6f717af7efd47f841696819248f6d189b54becec21119346431546391cba18e4badd3660cfba53a91c3b2218293d03778fafeff37c2ea71c3bb6823a1eeef64065f4b45cff7169a02a9934fda95861ec8d0768bc5cad58f79d854bd32503a3c72fe40417cee1d4d81a9d1e78f93cf5cafd2362809d788176ab88c1007a69f234a60a50cd0c00857600e144962a0dd987d284313a55210246ec51f3975707719aaa3f8cf6ef757c47226a5907f5019a2d5a82cea4b790e0deb00f70646c7124b8202b5f29f26dc20a12f4430158da8c567ff51da95b9e26ec39bbaac5e32f6a3cede1f933a8b76aa805201d3367d76248671d8412345ecaf89c599e5a88b93d347ad99a6e249af4a322a73a9d41b0d5350111018c3d9987926037a027101683dc814ec07f07daa46d103731cfa07557be53f12153ae35de17d65274fcc4bd4e15ac961d837a8e68ad24b542fa29ffca7fa5d883d1413e6c8183aff268ab0b4c516d88088a0102e2fb2999edcab90a5efc1a3f78ef830660161c361cf699eab00341565881f1c374f50b5012db4af00642b53ec15a66a315cfcbeac29674c3e619870d04810bea6268", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("128b65cb80257f3006fc20dbb6af6781da7e0f9213d2b909fd113ee0f2d2bb52251e288387db7be742fe67261f36a4f09eeb4763bbbaa1bb13af3dec65302a4125ed8b2035e437f057cb45003f1c25510d7e232c7587581bdc3035064a96d2e32293733bfad88afa5adabcf320f055e3fe0d1ae733dc21f5e08fc234029be16a18414155506a4c287ac374bc28635be3e6b8fd0097554db051a45138f0b6140410f8c1e8992d53017580b1b806cd23729f9a2aefc6e60bb82606551c1393750b", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("089142debb13c461f61523586a60732d8b69c5b38a3380a74da7b2961d867dbf2d5fc7bbc013c16d7945f190b232eacc25da675c0eb093fe6b9f1b4b4e107b3629f2c1dbcc614745f242077001ec9edd475acdab9ab435770d456bd22bbd2abf268683f9b1be0bde4508e2e25e51f6b44da3546e87524337d506fd03c4ff7ce01851abe58ef4e08916bec8034ca62c04cd08340ab6cc525e61706340926221651b71422869c92e49465200ca19033a8aa425f955be3d8329c4475503e45c00e1", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("18db259896bf7a55fbd739049dcd87bab41bca06dbe6ba477bd91293ecc7b72a080f9707ac098f3ac7a06fc4cddf9de9024723d7803df1e832f23facc344e09f1f0a58aa3d929cf73ef5fb29717b46818570f8acc287057a61f1bf19952d5d870a985a1377ac0068c32090c4f61af49e438888371fa281863746ad9c4505839a1635829f9dc1168b264dc1b35951410b3f509179a86259cd1bc219e0d9fb6571282e9a7a2784db855d8fc301a21574e67751c63574f552b5075cf0d54feb2ee7086ac4e5ca51c4e84405e5310187119e9283a8e1d4b9be261bea666f724501c302d9e8305711e2081373125393ea672966c2b7931d9de75640aacce9bdd8ff8109610ee10faabfae8ddd3bae29f8644762b842a90a4baca50bd37c4c8e346cdf2c0a29ba08d26cd5e2ea3ac028f2c13854b997da5de4020810d8d1df0b5ede16181628b1a3d5936ef9414119e8bc454d0209022d6c3b6722ed63bd3be9fd11ef16a94dc0c53b0283290c9189b46b2b2e727ac54299b70b73ccd31eadbbbce239183aa0627c185bbed1b35c46d0d2ab1e248f7a4ab6d1896afcb8cecd471911ef208db0fcb30c4d601aecc21ad3457e4a636a2bb289712a98153589c3674a774f08c0f49c7c290fab83aa67c3ed645856531b1e537e060fddb3b722849819cbfe04336ad8c78b7ecd068f1f543b4cf09a510bed3f39c8afd71b549b957d5b4fdd0f2251c9278bb30892b0ea4fbc771380481fdad33dfe0e9f49916e476823feed199cdc78bf86665cfec1b451e92bb8122597a0b28bdd5d380024756fe070aa101deeac40a4d371c0154aecdddb082f6891c7c3a5074e1b5c1b30e4b3ffcca6980bab17266f609f8c1616cf6c23c51e60b24d2ebcff2c7e486abd11f878ad231b2e69a5773f6986e289b67c70b92da16c0c8f2a8dcced737641061312f5fe17952151ca3275c32561490b233e7284a4690a777da485efacab5557307c6d8e588608aa1e46b4edfd86ff457f0ab244e624488e4563be1a0ee35df8b547c43e4e0411b1dce99279dab100f4137847c3bac64342dc95b9cdc2e5880ae61f898181d8", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("1891e8689d81bec3dadf1f9604c15044cf827e14e75defde61944ff7bcd6030b1c9d52e52a1ec18146b4eb9dfee11579a281998ec99c3828854c69edffc5cc1a1c2be993abe1a808d8adcfbb9fb05aa82c12ac5aabe25f1e45638d8f522f06c005d8941ad434d5775f021bf825f48b90d106afdc75383fb209244d52f1320ea706ea0f67d737534e83b4c371e90088517aaa2f2a663d8e20ee66fa5d96d9335f28f837eee92c44da5329976752d99b1490668677a12f6957a24e87cf06f9bf14277937b372c4dee270475b2c3950a50dd506c82a326944fb1faf73392ec5a54c22ce783eccf8f06cce6ba0c21fb0b4dc405879b8c4e8e8971df765815f9878a41c8ef188c94fed5973836a452d4d365003c8e56af3fc6effda3362c29201741005f4f78eb380df7e435060e8ca35c6453d8e4bda391e23e47d8bad4d28921a5606d86dfc9574f67d7334c2e73ddae937a36c8c59a81c3f25a3ff7336c024cfe21b86dcf0c54a5ede73ad5c313d5cf5438a1e6745b3b61b18635d3d3d5f51df5d2bc6c558c5f3346e9a400595186a9c9ded299367cfb3a0674f23f1ad0350cd251f268d166c85bca4eb0b3cf3c53bce15abcdd22e22ce0e9758a23c6ca5dc7bf9183144119ebb7d667bf302b4039bbad10ed360d3e0ed47ea273c22083d7fc62f1f5ee2f7167b517eff34f496919da38c6c35093638ec958dc251e7ffa9c173a00809cf94fada7d2fa86013db39978eb153f48c11003b37b0b772700047f4f2531895fc8b4f8b0b884014f229aa5d3f71da7438ef65c446e0b427de019cb6f37b18b768d980b9e6f007a41802ca6903b9c02894bad35e0a40c0b857ca9d9d36fa301afd2c4a0e09c76b8c2cf6e39bfb2ed74f709f4f0108f13b111a04b2411e3515b772fcc87fd59b28bb73361c203c9fcaec94adb10c921a4af2f72e5c8be6ad1626d2029044cefbcee5973de8f419f525704d7558e86bdd34502c56da56cde6282c36358df918f4065f03d107144d581ec4d0d4ded89a81f0c276e5653ab7712b2a995c15310672ba6b4431362266dc719d5cfe3b23dd83a2a34b086c18e02b045ebfda6fbb64a22a1d7709ef5f2b065ee20265d4900d004eb1936ddc3fe60f130649fb7b2ec9103636131656a7a47d161e53af88ec99797c4e8e7051d1732607d5ae2eddd9ff4b12ee5823285651ecc4cf5e6241392f72234e5e6b240575900e21d3821d0ac2c6ed2f0e0b615bf1dc36e365bd69d182733f951be4ac6fcc44116425c28405a420df7e495650d5d0f74ea7dc27ee928d8c7d5907a13416384b15eaf7c8c478da036be27d1498ae0d5beb855aae2620577d9c541e36d2ba1ea62043c1911c37372e86bd8530a0ed3dc407c769f8f248a502e719428fb9706de6289e167378b6422d0155dbbd7bd3d1b677c64746ec51316ab8f37a836110ea3e2c62da428e3a53f8e90b0cd00523d05dcb5b1c1f00bc4c66f4e8ffe62842dc26273a383e45c3e23433bdaaee67b5f685a21cb5e85f331880fe736c4642f972ff17a4a947747c14f722f3136da4a6ef86769176b96a30ac6a3d11fe16860200fe29c194cb2630c988439903421dd883caf0e05e3f82e12fd09bc0415e0814c41d1ca9c349188b686207c5acf04a3ca7c62357ac5a36edffe672b5c7856f29fba11455c3a42f6b1615d934140f1125e8f3d0a813580c49e6f668e5b7078d6b3389145fa1296893fec25354e91427e890658f8e2c558b5f22499a5afc66f8106a8d1af7bd16c15088cbb53c0f95ee9222efdb4c3ade4c08ed74d0747077bc87b86a028e52618b80c87fd7819da4433ef2d6232011f94be93a335d44854e0051008f2bb43f5e84934e286032ffbe10716fac0266c7361df4464a26a832697780089c258e55ac985a00cdb2800aa4126b748825466e4bc0dc02f2b44da5217e6f628413d728dde6aab9d4d8ac72e8eebfa6d70cc8ba05532c707dc8ad0d151e7645dd1a35debd99c840c3c31f3b9c17b7d804c1463e41e9e8d5bc2434d3e863d4893a2fd7432b507d5d1a63d09c555d506799665c144b84d13301aa04d2c68a8069c628c6747241f57eb659356042cf5ecb6f917a6ea88bf2e01a70bfcb317c7a21cd20dec788c2a74ab921d7b14fc855204725acba5cec08a5ff8e3fbc44a95c1493", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("1ee25d5450b2735be0093c130b7448d1e411e1e8b7913fcb232598dddfaaa687027cdf0955348f4e55caa9d82fd5bbb38b92f60579a83ac709966683f0d9793321506909285bb1b77ba279f0490a97f2161fe1ab39f7f049c1313a9c8811884e15a20e6fcaf1c0bb0715db97d4626fcc02f7ba2ca64b784b2d4f6f51ee71a03b24732d58be9c0dc31b21e1a719031094660c11a00221284d4163228d8c3cab2e1588d6aa85a6f8ae92b8f3cba309971208f66b4d0863ee99d1d5e8fc4c96cff02dcfc369cc91404a1b8309a63ce750324264c2a70c62ff062762ffd9cac5b91a03571ba65a25d22dc4b4313271c8dd74a99fecf08d6dc8e6b51333a428984b1d1129479779b4c500a4200354648d7fbfa67c9a0cb13a3d0e6137e31ba7ff47d207e78fa56ce0c8f6f4e5f31f678a1868f2c7054f796cadb4bd888681492ebc750bec8d2972a70ed03036210e367258f5cf446378f1a21029a48b152fda72fdb6141196031b0f6bff06f6500d7813f8e2dc009f3abf8c9f9160a9cf29fe29b7c11a3d61bc9163aa0403faa3151c0830b043408955dea0cd7e9af20095f4f5763d2acc09a5367d70eb2f0ae60297138f91ab9df8f73a32690ba35abfd521c0e7ce010d36307a14a7b50309a5a73da3fc8e5b6260531b90ade6a08c01cb6ab7c933102527adf2e3b149232e6870a91fe9a0824cad125ea9f88a531a4c39e6e3860b1c2f1e41fbe9e39f018bdd240daa5e7d050b1d72a31fcbd3c57af3fe7623ff3d194460469ef83ed14d5a5dcd75533364b4c3925bb576850e8abcba7e06441f4e2839f9e57171e29052d593183c38c820ec1f54569a5739f8f028321b725b8d6c001822e194f48d5f008f5ac96d24eb40d7bae35c1f7a87bce889392201b7753924aa964b9b82cc1ed724314f55fd3bfe84a79984448e0a309dbec6f202e707000167456b1aeff780eaf36fe6e74450efcb52c0bb8dd225ce291ea32afd792d4726de9cab205db543a5a385432ca762ea52e445402e3f8532377d89b1d99e17c2272e0742d0904dc8076735cac193377a3534a15229e89605c870331e8c4a325c1ae9f4f66b3f9f6744978a7e689fcfc60691e30e53aa60076b17d09c84624a4b19392f9dfda38b2a543220172bd50eb5ec710884855168a7072e2859252a58c82706373a30c0bf2aa918c2870d43c410f52d116fcc691df9b4c4d9f15a10494e10aa74c6d7e9351528814c724757c648365a3585981200e312fd1d5609b9a49702c6cfa5525ec1bb6df19cd838bdc322938b233c080c3e4885d608028ba06b6d2865e834807335d255e605fd759b0bb6834f946a31ec742859a3d72a6da48d9803095c0ab65997de12a21edb99c4892a6c316dfea1a30c4bb8cc601ecc32f1cd2073ac7bbf3e87be5b54b946001b7ac91092cef11b3b2b0e5163c3a605876c2d0628b3e51cb8edae03423b9bddd8e83315bc96135b725525f42965d283cdd3a0184b6465341456b5ebf3885665459aed84e3cbe071324f5016a9ea977561031719dde6c423f21beeaabb44124d104c07e52ac303b44119fab1262b31b90d47ce14fc4af949f7d3e70387fb7a06f7605665c600fdf6e42017a446621fb351e91b130a080b0636f94376096d780ae1123ddb2a7c474da4028e1585206dd9e2c20a075d52d462d5a10121f7dc323a7bc0c5183f79f337b863fbe0680b158ecf81402958c671823cfdd8f2a372fb01ab9a62d2e9926a7eaca029d96672a0cdaa60591e352d8b7b64557a1f8752efd985adfadc50cb8d84a7757521961bbf43aad9b9216148f860853968329a3712dbe936eb643ee767c8c57c1c39819832e7ee4aa920c013bce746641635ea715962af491bec1d478f1164b1daff3800998ebb24c011b9731675637ecfd7282ad4e7703dffccd386472f84af4bfd1613fa124894ae006f44be7e61d498ff3d57006afe82d3255fff68c4dbc0e3ae72b961061069d3140d573447252faa1bbf6628974a8f127cc2540c6fe651c1a4537b85843bce340f8d932a56ff47605daa21e2bea8bc07ebfe9152548fba7bde2664df992583a221a9678e3e3213636f1ea195108c161f3fa7c46d09b4b64918714c33ddf8087a2fd9da39ae9f5ab723fd232f646615af7682dc44bc2a7ef3e1665fd6db5246b6", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("09d599a8c97251e5d1447076792891b8de719e3fc5b7b245e35c6a8af97dbe1b1cefb6a792c978414992b8c88ead994e8fc972bd8018a40e306eb0e5578b25ca21312203a90480fc7174fba1bb4b9802c930c38aff91399e78e2c76768daff422bbd652137299ba4ebda8016f7501bbfeb6de219561d3f924693efa9acfca2b81618159fd6039f1ee36963eedec8154312d592e6e1dba89d1747c4251bdb725a0c6d546f20a8b44f4517290a078310fd1af065e8ef20ed4ff94c0fd7b7c662be143e5a3414336749caf364eefdc5e30ee73d34d9462a44e90e085851eb93c9b6206426d020f657f36fec865bfa09bc619746c238c4cfa643529eea42aff19dc52abc81b078bdca796d77c4ac57e6a248fdf370d3cd12163c474aaa46eac2cec103b3cc21c58b94796153850268f274376dd6f1a36103e6f870a4eafa452923802c6ca8c36c4a0225e4d80bb8e62aaad963cc39bf9db92e1a0f45a353c82039dd1821a59d0fd59b5d0a0362128b95414fd2479542e1afab6e8fb23e06e9a547210cab4c461a3179e2f0a15c1a20e0569590bc30c8c7344a73db5fe76341efbd2c1d24f43820586b1449eaed8c7063d4e481a1a52d0c5a318f9b69e97c35a6393b016dcb50ee485d31c090cfffa92e709dd5bdf6b94dea9a7310f0c824ba78151003ae718fdd5682ae467b0f776cfdd02db3be8d2aa9d42c88638bffdf154920121c3580c8ff773cdab1bd6a9449d8f4d0dcfd5d3e1bd55acdaed1afb96e40c0dd233eee0523e0a36b7cbba083eb2919ab0a66836dabc699f6f5864d284090cba90d02024b706a23f6d6f84681ab223b9975aa15bfc6c37c1e1d43bcf8de71b10f2321d3e00d52c53f18415f2e87cd00940a6a3234e7400e170297db9b214a596d2a6ca0984a6e1aa1433eb239c30efb32093022dc1ec379567ebe899606324afd22052844ad5cb4241203b35d930334fdcb22754475653cf6138f51677c5759d0034a7400dc24da45b5d4c63576a83f299cc60b43b186de9d8d5120d36596299502031424a44c5970eeb1090ce35d7379a0654db261594a27b7ccec8bab8db83b26534bc2216a34a20a506366d22111acbf059df2198654cd69f1e4db9cf7d4801d135d29f2973a802ab859a35550a844ecde62bdb95e86bb6e974453b5bf2d031a4f3c2aa1d0be4af8f9013414719e7b75536b3e0dbd8250fa3feacd17416de420df18f7491d891ce8c01acf25ed54d37433830a1bb5f169716b07aeb67e4e6a05ce2b0d962f82ebcc36bca7c238f9e0d83f4b731b4447b2fb6f24636aee57260f1a72ebde3694aed548f7d8e20b3f9e119260b66d095e9992ca8645292eb45b01cb4b475f8cdb3126bd428b18745e504371be364d94d482648251a0ae1bb9ae2e976e6fd23476a9181e42a874a734f7efd1dc25037765e35a92885559ef4da81af8fe9ef0615a50760d000b68bff0f102771b9cf46bed9d5ce8565a558e41700bd46d271edbcac6a253a859cb7a172a3176fe6f9eebaf752417603efde4bda114f8788c8608a32c27fb3087189d92464788c4b62525f616c8725f6abf9d4dce07b8399a0e69860301eefd202480a12e054a920ea3dca3844f6309232c61fcfb17c43e311e336f593615004ed5a4b8be2ebde42af53d5fa32a7790ca80fc234a3034f9151c43f2eea7585049b4aad29392d9e9285b011b73cf2c6af955bb236b15857fb2789ec0149c253b23f8232627bd48f36ce4e8bea688d8b64d7469b2072912fb4719cb6894a14986fc875c84c220649f3c48e3a662f4c4f8b0c259529e2b6d3696c45cd1b11f02bd752022b0e7a2599bbca90cb8290789d71bd990d18418bba1e7fca94de8833d95851c88876c42fe817d3025a5076307c85b59add5f81771cbccfaaff14f7fb8807bf88902cdc39ca0a398f8bec67971cf8b771d941204515478d4c8dd014aa27e099cad61aa267ee25fb61d23e5d33ed0e2ad08bfd60c2af2b362d35851adaf161bf289d100b65ccf2050aab6c951e44a010140914e18ceed56ed6655d046f37dd75198590f95200ada816be88cff9fb1ed2aba308c1e556fa4987309f9d3c380432429cc72e8e146a24c339c989d2266c0f1503737075913b800fedc3b85ed5060567231334467aa6104824b79ca8f99ff263fff52", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("2f5a89469bfe012ba76459c35dc24c1aaddec05eee130879f7258d71c97f03072a93777508a68599449e21e16cf2b640f0ac5256231548f2c9e50ae4ab5e2ab7164dab50c5945811423d8717b2f08c524dca34fe055110059a5bb8efefef74e41c89dcffa0b3df9389dbab8f04a89cc52d76485eb690c5a80978f41c33be93f42a7f7a7181c0431613af56e9c2d461a71c0dca94aa3e19736d8cbc3467d841db2815f183c8fb13e36b83a9a6dd99238975ee7578b4dcd316c82818ce012092902aea97784a5249ed59850e30f1d7eb74e9526ad94f5c32af18124ae5913cf456064aae479b94db0dda94455282d2a5bcffd99d5e7749d631125dee0f33c3c0c1288aae58ea8eb4202f12883fc0fcdd68822e03f63a12d6242b0087a8a1495f7c1be646ac485c0d2b972185613095e4d65cc62bcf5b3913de994b430027ea5baf0e30fec7ffcd23b4d7a6adca3c8c994e17f94c76042af6b48441963bd5b478ab11aba040f130739fce83eb9c79c4a86eb251f79152f92afe5d81602744259567095129ca02f619571508cd4f14e669bc759afdf2a98f105ee1d19cc5c8666a7b2059b1d1d6524ebee64551aff3c1c058bc84ba359a85153c6840f9fb99406e4400750e00181c4c86d88d338f58ddd60e5a5b80f83d1926b199951fd27012377c28f1e937b0867a30e1617c85e1dc0a867aa5807b719aa1496cd41acd4a3cb2991018dfefe4eb662fa1a8c892d1971077cb3b81e43c75f412bf4ff67fa9e815cd179228ad0e86867ebd465e80e0523cae366cccf230dd02b58b4dc334f76d8efc1c1657225ab3c04d3e48ef50feb4b1133655c54465ace6d5f4d9222997430e302028fe47b83ec99feb177ddd4def70f8d7c3d774e6198476216ee7d9409b159426b7fcfe50427a47af55719f445ce0ac65f6b444825fa7fb4aa602fa343ae8040e62f09e7e4fd1db2662c0087ca9782f37626d91df409123399dd5c2823268f725da972ca1fae6732cfbf12bd9e5869b5dd7ade24e58d1914de52a6e6c24df6e25c64ab46e4bc7f94167fbe9daa225946046a1261b42fa6d1de0d471ec68aa9f22401b525d3f7e9847bd13103aa28e4bf2e1f47a545f3f7cdcf1621fd9c50cc10f0a2bb7c52925b718b23d79422d7990c7273427262817896b3aaaca889ded820c917c1610cdfcc5821b58b4aea58c86d5793d520d9d8da0a26503fed44591a409f0a9eb7fe6a724ac3f3f7e156c549fa4b51fd0a05231f3fc26b3754ef8aa031a9235db06ff5857739b5ac772d671f809e865cd6d9549bb2f4372f194ee2db50e8e538da6c93dc08c2e85e029c1bfaf6132f18723c06bda51310ef1b746078a2a81296acde9cd3c2de9c5085d319a33d367fb2d19db1b610a376087d1d4596b22909b27282665c97809407bce99fea04e3ebb87e95e0df79e41d67857447f71018c7682174152456cd66cdd61175e8d139985b502ef4a4730334311d794a9a219b49ef5a08c7d3e6b4142a36591873fe04e3f6c218982bb9a7892d8edfb33d90c10f844fde21c32be49991aff39b1c5d5a0875f0ca696b016821fde000d76711b26c07ccd8f5fb96f3a5a5be4d92116c5a786f1f0f762029fb04ad749802df01b91fe1767d07ad8d6fc7b12dacc12c1e0dd32301b60f5579b2e13d751ea08d620421abc8a1bf2246e62468498a1550687dffd7e15c5e7a74fa55b81d5bdeeb6236265d34c29d7d7ff5cbdf071e6489a784e75ed652aba5814530dc2fe2a065c299c3011037f4aec635d14bd3c9a6113b7411d745cdbe920133008642310a3231c7acee4ae528f9cbd2aa8e73f7fdc37067fa7eac6ba22d4bb9b40b96fde7d371d47cd1b8dbc4d5d4a8bf2b60721b9c1b21cb53e268751ec7212804ad98355dc12f7c8d64a99628ac80dac6acbe0b16220fa9ddba015ba16f06c8c57ccfd506418ebdf0ce1738762d3505949ffea9427406d55605b54d05e1c8f1f63cc760f7818f76c8f1552dd6e7572c2e2e84e7ecc83febedf5a789977325ab2fea33a61140baaa1f9d64fb647b4ed54db970b32eb9aec6aba90e6e8ad68b2293e39ef6768074635c4e095ae39e6374b99a6abc4e89155d6e1c5a0a135703c5be082fd44d715060535996f9642fecc139d06a140f8f78b100099740dc0325156b43727224a", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("0bc588b9295424a643de2b40a69c9daff62305085e893ac5c5d404ad565cb89f064f181b7f3fa23a51b829fc7965ddba879c6fb6eb4935ae33756fd01a603ff006bf88db9882537afc39611a5da601b4461f23b8bcd724de1602d10ddf2400e1103d4162b724a3f59c1dde973ecd3086f599fc3fba3092a392b247ae0e555352086554bc12b5b21906ff1f5cbb8ea8065b8384364f1d75dc43fefd5be2ba6e2b1db55d47bb0e96bc45248f7d8e3576f91e6c7db1ba7bd60c36faa62286ae7b7120f8942c679c45219b38e8eacc365bca7dd43e7a5c72457b6c4ccffe1ed38fff28676ef29b9330535753b41464f583af98d87d9af5e453e26e5ae2b5b8900d6a2273ec96dd5d5ae35442d2a401aec95af380f6b94594495f7db684a7bd21cc7115756d01443923350e0f55d5a4572478e5bfd895af1671355dc71962d475d97e0fcbf9663bc4a5135ec00c0275fd629e2c671486523ac3cb274f3c021e434f230e9f37feb748aac515c58c6ada11cd7668939a75cfc4a641c82a88dd642fb39c1b901ae71fb85cc4a5990d19fbe23eb4ea7aeef7a07b5bd9a8628ee7eda77bbe150a9c622deca8c8505253cc14e2908bbbbf8e5cc2e812e8f7a93ef3f3b7c37f1d5fa37baeed342068aecd69557b859a833938de0192b80bb345648eb1af85481421f8a6cfe15954d7c45e82e8c192368f817e1de8a01803d6ded2d258b889c92424fe2cd68ba3328ac7b2042640ed0f9107499dad072a1170bdfc11e3999b7a177288e296a9e13a230d6d2ac704f62abd9af434cc7172468268a27b058cc6822b911b724343991820ddeb0507ba1efc64b6da9bbfb66bcc6dc1968334e59e991987ca0264f9c8da5964afb471dfcee45009ac14dd37520ec63f022ea4ecbb522c466e5b405cdca061c8e56af4864f93fc16271978deadc7bfb667b940186527218b1308f19b5f78e38826e8c0edfcb7bac067f8c412dea480afe0699e1bce28306386adad44c4dcead96aba3c6ac2b511c2050fc36c108842dc68adc692b46006c7437845b91104ce9492712dd05eddebb786e9e50965a87ad9388d375d014b162aa118ed010d6fac2133e46dacd279605ad141d548ce5f6df47f2af040c689127705a6dcefda95143ce3f33a8f1e2bb5d3a6023d7a8bb405337d07bad6e9982b7521e4e177303deba61b19a3c11675b6180e29a79f720c56c1ddc77771969918ecc306d7cf8f2d996ed438b22234436042472402e589dcebe4d4ebd56f54971f7cef6a8b3e1b08248d3f42d957cb5d73d7680167d985cd5a71d91b1e8bd5601262d2cc8102679d1e3765d15df5f020ddac2b2745b108b0d7291700dee47b7b13d6d567250f967755036b3aab4fc48fd80efed33154469ed1deeb843622138723655e3bc692b8b6c508dbd5a6b02cf7f7818224636792dc569f8b5098062fcb1343dc85466867ea7c3f0afc7e45520cbfd8fdf56a3a3679aed086a391b6af57216d573faf61d6405f3d65a897ab4a5a77d94507d8ec790300157dd57b46fe3916316960cecdef7d1af1aa631a1b74da59e4ec618405bcffc885059c3c74585b1b87f2762ee8618a229bd0da5cc35d3d3e920e1863c2babb0ca59bc19597b8200f579d17c5c51094be0e8c425f3cce12e814ca719411c869863d14e1750bba991e0f1d9766b2dc000b3c7451093e5f3293a3c9d36bcafd092d5a19224484ce9100d9659a9571a96dbedb8073a218101ed8f5d224d0b11ca2c898a2b05368adbf2f27181e8fc713173cc3655a599ba70f25ffaf2f29a803d2f58145b6e25327851b55391c39fb460487972b6c817e566c9bc35cbdfa6a89c4643ec632000828ba17530c62524376df313c12934b1745e14167666d4147764280ae0f6ab03c2d4f04f0f5d5ff2e39df860b936e87569da2287a7fcc00e9eca8c9860ece79ddced50c566c803192d5f6863d56d83d10e49dcd60d34555b23d7ef607bbb9a5531b390d9b2016ec136313cb56354fc69c2c97cbf5afd99bff85948e6e730cd37f6cf819fcb2230faca93dc6de50b15aa3dcde0f7d0864056c7ccc11c01b61058a483109171498c1064ca213a3305f1ff0a2861aaff3646bc6a8c8c71804874714881f2a8aefc2aa3e7c8fce2741f292cdac86484aa567e188ee8a908aa5acfaf0dbbc", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("2bc49f4d8134cf72ce0883c589f4f6f0636db174b6176e063b3effdd57e3404309f61eba66408ad541dac082701734d6e6d4cf6f90bc0e65d6578f2d18563e221eb59aa8d8a9187b0857ab89a453fc53209855b300377bbca411998bdf9aa6730bd2384fa0ad96fcd1fc6c1a1a1fb80d4859770ca91b9559281736cfd6745d011cb39aee49da07d70b0f579101c412f1068ea82671859f09c4c1cb3ae74f8cc103fb73a573c8f147ae15610e4f97e291bcfe16556842e00e88ad70db0df2dc3a05430e574064f2d1de68795706bf99b1b6079a99bda3e5ec266567f2f9246e090f5976710762dfa75253c53ae1c2c88523ff08d0c2523d9409033aa2b7e4392000036daaeef66504945efa89111745e29d39ac317d798bbb1d14f84bdf5bfac91134d59ae245678087748ccfd3c65ecf2db2d05595cd6ed8452346713768c7411ab6efb518910157009fdc818e5d4e082da02f0618f4a3d6166f830b81a4e683023ad24b09b49bfd967c7adbe895811172f04a2b90b1379dac89a6fa1a91d8cb", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("240517a373fda7a2fef6ee9e9895505545c354433af3d3548b8537abb10d445c12e45a8b8c4d7a82ae27f0ffe3dd976b1242b040b96043ad31ce9f2ffa5bc707275ec5565ec4ccde5088b40c57c946be5d48b9ba34f956611ec87ed33d47500116f3ff1c54f920a4ba438c43501d2ef59e7c7eb2f8ebde852309bbfbc087af1b1742abd3e12ea49804bc4e8e59ecb9da6789392b1e12958ad653ad49f3d4d8450a1190ddff2fe9afa9dbea1e42222afe9715e1bced4e7ac4c20d89476ed6253c0bcfe3f03313340fd392b32bccfcab83f942f6b13d71e2a3159239c61c50c7bb199c36728784b46d5607ebd7cf5a055a3db4458ad6f0fb7e826d6a280daf625d1db3a467a1de6f3b848da16893902bb07fd0b63f6509dacae6693c7975fe09940b291b95276b136f58cf6f899cbb5a6f4009a4d069be6c0f8f0d6bfd7c38991f0e46dd20f14881ed44b216b44ba054b1f32c61d01f33326ec7f6c2ace3c8901414f211e03a121fcbb34f328205223d7f7ddff484efdd5d06e8886f2781f8e549", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("22f2e1830cea84486d7ff320365a5ead50d356379d7bc4f2b9d77dd298f36fd8087baa2aad4fd8bbca8cc0b525041e1b17aeb3ecc63086cdc6fd1ec2310bb8db243fe8ce837f106ef17e387f9d78df833811427d5338c83f0622f92a65101da31ab23d2eb26b70ff15decd58baf91a68ec85f149012d481da67f806b0571c9471928767c9a5576ba5fbd7cee08203e6de3d9dd36a756fc621700031081a80b7e1aee70334cfaeec2f7551368818353fbd5810266c7d1ba49de47cec9b81b6e82007aed597093879d894ea438d094f3373b51f31bd5993e026e76502bcb1334e32189a92e9df00c0b5c21811462933dd17a5328075b472a53ca61bd9e136701571e529e7c4912cb565a3819473e8cb2c45e0a7b17a63f11e509d80472921e86f92fabe095002240b012e60bc9159383bdbf515def6c41acf180adde6913625a7b11d22c04a21962ecdcb1b679168cc14899e2912f233ed37d116cbde2110af4861ca847018951f8d71a369874541390d23df3cf9e5031655d4e7af4affdda5ec50fb5b633ac619c06ff0312901dc9d949ddb443ded5f59662788c101859ed0cab1782bd118c15612ab18ecaeeb9226a0145c0c1d01428987b8a5523c6da78e015261c22b6d73323e863964a003fb93594743f70e9248ed6898776780a7f3ae7a41b07a0d873b1ece5c55c6c942a7c7249c3d9026fcc607a68fe6e73cd4a76a6821f86065d5e87ffecc2c47bbd85658eb21bbdacdb79f23b031a8c6df93e64574c06eb93cb065183692c4ae4dff2efd51615d926782da50054e4a280c5bafb913d02369aa17493b4fccafbe637b1b7c9e1225e7b6fb24720f778548e304e7617b407e83fd6e3da09599850d6399059fadd57c4fadb492f59ad3adb4783ccda65272f190a9ca862a6d9508d9b2513edecf47aaa4fdc7a64127dcccbe64b7f206d400148ee9fc305099c6a7334452f25473a58edc7161895ab52e3590ea600e2e885010b062ce0df9974072bf87f5a1c8072df23e612b254b688084b5958314efe190bb6fb66657b45e6f81fa7c5fd41004f815ffd08ec00cb46ced2b1f97b04e69b", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("0e6eab4103302750b22364bd1ec80e5edfb3ad06fa175ff2517ca49489f728e9050a17b5a594d0fd6fafed7fe5c447793fe9b617f0f97c3ee6dd29638f6c9232068b38fd28978b73b64592127317a542e084ea8291e404b88d3a731207104f9624d1ae64196a7d3b8e9fdcf72f9dce16d649fa3971daaca56405a0d331e2aa92210a32dfe27a36ca740e4d668066f7559acddea850fee4ebf9c9a241b337e771191a60da23a028dfc3b3b82c3d15802615f6386f29194e088936e3ffe96809eb", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("0af6f1fd0b29a4f055c91a472f285e919d430a2b73912ae659224e24a458c65e2c1a52f5abf3e86410b9a603159b0bf51abf4d72cbd5e8161a7b5c47d60dfe5712fa10f98bc3c4faa2a9729408e92a8b4e6d304abc539cc396820f696f23ecbb2b30d01fe71a3550fa6780e70305d28ea686b72aff7d23cd550f886fcd60f6b30d1142c81b9b27e329c498e4b241fa2ab0e0c62170cbe2a1e642589e4ff6ca54069ec036f519726e40596ede6cd47577c5cc24746754280add50bf87fe7404c8", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("1688243c91950e540e5acdc41b84ee9d2b1c0ecc84dc373d6fd5959baebb33df140c8a9c0ae42792290c177a97425bfbfaf7ef008b7656e906c2df69fbdce89a029c4ee67b639e4b6f7cf0536ba1f24bf61837351b5c74f12fb6cb0887aac3ea1d3c75ef1b03ad925b1b223901a8e7a4e16ef2bf6600e7c175529c18ba8008350aa0f1fd72acfd2bc3c50664eba62133ea85341f0b4ec0c3618f3738401a42ce1fc3592b9642716c47152c9e52881fac74773f705c15b7737e0831ced7a0f8371245c36152deacfd18a947b3f3c83a30652958dd9614b7beef8aa8b5cdb157462ac85cca98a10e6ec5efafdd593179f2f56c4febb1ae6f1d72a9661fd8ed51032b98467d16a6e8e6bfb427838659b8df567ca38ec17c979560bee66d1ab72f372d38efa3e51e7ad3ab06b5610e0631db0a385101b45d0fe47c25610213aa023208289e3f0845bc2197d57ac44b4a808b30aef09a344f80062bd75a1844715d3d0cf55d95f2fefda6a1bab5796626fbb6345796ef134109de55bd61654f54c71f16eb795694ab923473ee66eaa59bbf61de8f8dfa94c481cb4f224b3ba90ec87318c3ec099e1aeb3d63840ccba2159386cb3d71481ef18b5466901b71cdc6e75e1ce807182d1b89fcbaff954b80d8a58d49c953c05a64e2a326cb3ae4802a0f9f29719e2b60002727f32b49638ac3c1d4addc61cb260c4ac99307ba24a7743ad52f325d4f32b8477cbd99a218c2e4ecb3171cab016c51cd800663bec05624f1072775db17ff93e8b807067572c97cbc7321e9690b8fc4f193eb0f1a93ce96a5c20cf7cc3dbf579b54af41204b2451098724e9d8940bd4cabff1605f33592e5f002817dd14edab5e60dde89c66b3c93dc057c53b926b2077d63d2dbbf9316bd64c2bb1b35df3f9ce28954fbe15eb52a08aa70453112cc94ad923616aec0553dfce0d5e44001e7b139917b4cd2d32bca418f24f44bd7ffa16edc47ff8178efee06f28630c2816b74f232864deeea9073bdc2128d704d2375431c7bb196825b0ba890b5ecd90caa2107b346a40472b9972bdca3e388e38a2914e2c1f022a82d49b4f", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("19ca1f96e3289c5656d4c10352144f657c2a89428b7d4330f1e888e3b5b4c15f0de956aa5db71cb39c88cc5ff11e8df5787040891ffab3e2322331fe4e6201b02ffe5b0350192676ee46b31b41c8eaab8ff9122487b9a86b2147b709e37824d02d129f764acabf37e490ce7db53ce2b4209312ca1ad424ebe4eb2ffdaf952a1c1d2063094e546d7e3cbdd07683995f7cbeea09048a904620710923326bf480bd2ee7a2404a0ab6a5b20587081e2f0f630fcc68a139dc635f8207585b699423471ebb4494c2132e960ecee3fefe726c9e8eb207ec6fb922848c20f07f3b6d7ba82ed48a102edf74b6c2a0c3c00047d6678cbbb864407f6760c775ab1266a81c9f2af3cb009291b217d880b7ecf3b88892fde66c985b2b35301d57d9d318401d601e6a4284a43791de04f5c26f29e2e25cb24947adca7e56e1a1ba03cbcba210873004b001fee1e9c6bcd17fdc287f3fd7d4fb0e7f9bc7cd8913037bbb6cd274c21e18b879ae003f24a516097ab114e576c31fc502205e73c1683e0cbaf5fccfe4227f0999fa8cd65d01d281d748ead19540ad1357f3d274b9436d0613bb6482ca2e483b36141dd465a809d324e89a886b3f2a5ba534b0ed5cdead910976659e400f9f0c6e1f4818f8f3ece446e040cda8d27f2f4cfa38e5afb0ca691ab8d113912bd785bb3e736b6a7afacad81a158a57da7a97b1ee82552a94dc17ea082248871902e71297e8e6e985600d8f1deecdc5451f3479e26eea5b396c5352135dc756290ef2305fd43f9275f9b6178180c0ebf3491805239d48e69098c098bde9b6b020f6e519b7863257805e6ffd912294a88711da15864cb78e502c5b7b1c634549155ac0155509b12aaba95cdd1fceb1b5495d5939ea66d3eb606d69f55f22129717993d14d3e9ff2d2f28a318be897d946db05f16e0a705846da2456158d7b98516435dab869cae65a3c9ac4014e52bff7cf183dc4d82706c2ca79104e79aa37b04c3eac831729d837db141e3c7240a766af3fefd712513d9b7704e296ba3c66d2f5546d9a6e362e67593a4ff76ced1767499f61a0aaa35c9adc86e38c046fb0c1d550a18938b0b632ea33b06861bf18aa759f7d19948f4c24789908e40109c6d0ee52be9aa3f2c00131231041c97b788f3d548f8b28bad245a8d744a57bf5c9b137ca7b30ae3f2c8ae8fd3e84e2b8a4ccfe1904994adea9749f55ba7a9bdfef206d28044f2efdcce3ebfc443ae1d8052147eb6d42d0343c206e39292aea132250de83503b212199cf0bf67e3c2a54a54a30afe637ad5f6d74c7e0e0f4f881c1d1e05f6e8cec4135b5c008a1bb843dc3e857d52fcee2a520298bab9282ac416d30ee84e99ee78dfc286b28e60b703136a332de95908117b63c477f309b2ae97022ed6f1a54b994516164004cf5145fc37e8c4871a7055dd1668f797e6609b6d881f6794947b847bc4798f90f274abe605139ed0a8c08afdbe5fb842d7e0ad4e772cf7cb838b23413b68a82a4fd4cfd1f150cd6182df388bb9bfea8cb902ad77e108d7e448a55857369705cbe23efa58bcb60731c977443b7f3b7d78a144579b710ad1010ca4cb30c2d8e9f44f401461baf57093514172eec86e1f018971e28c8d2dd5b5b43873bc63509d967e2b30bd4bb162db4745faf47a64593bcb04c4dc342e7031b0e887aab9abfbe75f761421d85d00fa7a862eb129a79bc9a3dff1345b17b5e7516f4aabf9a49dcf75d6a53ad9420a22f793dd68d9c3aa7c942b6131fb01222d75b7a5d00f267c9bf23d1da0891520489adc3ba71e158d06e2b936a42915a91b7f99341ecbcd5f65b99e100a5d3f01031383ec05efa2ca4e8f8770283922c588ddd38c3efd160bdf296ae4aa7ba35c958fd9e2d77ab1774ec91a252906147e4d85e1493457ff7eaebb505f8522b556c4b6f487680fe918699737fc2dac2c517bf5f945c38479ceedab8ad69dfad8818d7f6986cdc40c40c7f254d837aa190518980d7b47c3078000f8fef69839a3946f26bcddce283c172a481ed4add416f39f0f0fe9c767d85d2c362ab71b74782c1cdb836a060da40adbdd3a401ee80727125b95da0ba13ce26d2dcf5e685924fca207e9600a9cdeb4a6e569638258300e435d19bca9105c292e6b1d3f4faa9c9640c014bbf0e537156e1140954609", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d", "0000000000000000000000000000000000000000000000000000000000000001", true)] + [TestCase("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000001", true)] + [TestCase("192c207ae0491ac1b74673d0f05126dc5a3c4fa0e6d277492fe6f3f6ebb4880c168b043bbbd7ae8e60606a7adf85c3602d0cd195af875ad061b5a6b1ef19b64507caa9e61fc843cf2f3769884e7467dd341a07fac1374f901d6e0da3f47fd2ec2b31ee53ccd0449de5b996cb8159066ba398078ec282102f016265ddec59c3541b38870e413a29c6b0b709e0705b55ab61ccc2ce24bbee322f97bb40b1732a4b28d255308f12e81dc16363f0f4f1410e1e9dd297ccc79032c0379aeb707822f9", "0000000000000000000000000000000000000000000000000000000000000000", true)] + [TestCase("3431d14cfbe9a5a1244e88ada99303090b48f7580ae1e3aa0c82cd92025c03e41b1c9200304be38b893bd18ca5b528bb34fbcd8126c1104f0465a7ae1bf4455607caa9e61fc843cf2f3769884e7467dd341a07fac1374f901d6e0da3f47fd2ec2b31ee53ccd0449de5b996cb8159066ba398078ec282102f016265ddec59c3541b38870e413a29c6b0b709e0705b55ab61ccc2ce24bbee322f97bb40b1732a4b28d255308f12e81dc16363f0f4f1410e1e9dd297ccc79032c0379aeb707822f9", "", false)] + public void Test(string input, string output, bool status) + { + byte[] inputData = Convert.FromHexString(input); + (byte[] outputData, bool outcome) = BN254PairingPrecompile.Instance.Run(inputData, MuirGlacier.Instance); + + using (Assert.EnterMultipleScope()) + { + Assert.That(outcome, Is.EqualTo(status)); + Assert.That(outputData, Is.EquivalentTo(Convert.FromHexString(output))); + } + } +} diff --git a/src/Nethermind/Nethermind.Evm.Test/BlsG1AddPrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/BlsG1AddPrecompileTests.cs index 24f70ffb0dd..7d79873921d 100644 --- a/src/Nethermind/Nethermind.Evm.Test/BlsG1AddPrecompileTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/BlsG1AddPrecompileTests.cs @@ -4,9 +4,9 @@ using System; using System.Collections.Generic; using FluentAssertions; +using Nethermind.Evm.Precompiles.Bls; using Nethermind.Core.Extensions; using Nethermind.Evm.Precompiles; -using Nethermind.Evm.Precompiles.Bls; using Nethermind.Specs.Forks; using NUnit.Framework; diff --git a/src/Nethermind/Nethermind.Evm.Test/BlsG2AddPrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/BlsG2AddPrecompileTests.cs index aa3d89c0fd3..560e4845af1 100644 --- a/src/Nethermind/Nethermind.Evm.Test/BlsG2AddPrecompileTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/BlsG2AddPrecompileTests.cs @@ -4,9 +4,9 @@ using System; using System.Collections.Generic; using FluentAssertions; +using Nethermind.Evm.Precompiles.Bls; using Nethermind.Core.Extensions; using Nethermind.Evm.Precompiles; -using Nethermind.Evm.Precompiles.Bls; using Nethermind.Specs.Forks; using NUnit.Framework; diff --git a/src/Nethermind/Nethermind.Evm.Test/BnAddPrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/BnAddPrecompileTests.cs deleted file mode 100644 index a22cd643b4f..00000000000 --- a/src/Nethermind/Nethermind.Evm.Test/BnAddPrecompileTests.cs +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Core.Extensions; -using Nethermind.Evm.Precompiles; -using Nethermind.Evm.Precompiles.Snarks; -using Nethermind.Specs.Forks; -using NUnit.Framework; - -namespace Nethermind.Evm.Test; - -public class BnAddPrecompileTests -{ - [Test] - public void Test() - { - byte[][] inputs = - { - Bytes.FromHexString("089142debb13c461f61523586a60732d8b69c5b38a3380a74da7b2961d867dbf2d5fc7bbc013c16d7945f190b232eacc25da675c0eb093fe6b9f1b4b4e107b3625f8c89ea3437f44f8fc8b6bfbb6312074dc6f983809a5e809ff4e1d076dd5850b38c7ced6e4daef9c4347f370d6d8b58f4b1d8dc61a3c59d651a0644a2a27cf"), - Bytes.FromHexString("23f16f1bcc31bd002746da6fa3825209af9a356ccd99cf79604a430dd592bcd90a03caeda9c5aa40cdc9e4166e083492885dad36c72714e3697e34a4bc72ccaa21315394462f1a39f87462dbceb92718b220e4f80af516f727ad85380fadefbc2e4f40ea7bbe2d4d71f13c84fd2ae24a4a24d9638dd78349d0dee8435a67cca6"), - Bytes.FromHexString("0341b65d1b32805aedf29c4704ae125b98bb9b736d6e05bd934320632bf46bb60d22bc985718acbcf51e3740c1565f66ff890dfd2302fc51abc999c83d8774ba08ed1b33fe3cd3b1ac11571999e8f451f5bb28dd4019e58b8d24d91cf73dc38f11be2878bb118612a7627f022aa19a17b6eb599bba4185df357f81d052fff90b"), - Bytes.FromHexString("279e2a1eee50ae1e3fe441dcd58475c40992735644de5c8f6299b6f0c1fe41af21b37bd13a881181d56752e31cf494003a9d396eb908452718469bc5c75aa8071c35e297f7c55363cd2fd00d916c67fad3bdea15487bdc5cc7b720f3a2c8b776106c2a4cf61ab73f91f2258f1846b9be9d28b9a7e83503fa4f4b322bfc07223c"), - Bytes.FromHexString("0af6f1fd0b29a4f055c91a472f285e919d430a2b73912ae659224e24a458c65e2c1a52f5abf3e86410b9a603159b0bf51abf4d72cbd5e8161a7b5c47d60dfe571f752f85cf5cc01b2dfe279541032da61c2fcc8ae0dfc6d4253ba9b5d3c858231d03a84afe2a9f595ab03007400ccd36a2c0bc31203d881011dfc450c39b5abe"), - Bytes.FromHexString("0e6eab4103302750b22364bd1ec80e5edfb3ad06fa175ff2517ca49489f728e9050a17b5a594d0fd6fafed7fe5c447793fe9b617f0f97c3ee6dd29638f6c9232038de98419e242685862c118253ab7df7358f863a59170c37e606d5bd23c742f076ff3443f4e01b7d7ace1315fe50cf77c365d8d289c65303bcc11ba7961ab95"), - Bytes.FromHexString("1920c53c756f1ec1a40e0264e5f65808eafaeaa7b0885f89852297bc2186ac9d09416cc536a27b6d5616f74dd2bbbfb463b9961752e0aa38d47b5213994959ab015296293a5a1bb5e15a7d019787422cb3409e075e122c6fc5867f0c3f3715731782b870b6641d8d55323e27ebaea17909499877fda62e3ac1e2b2310cad5f9c"), - Bytes.FromHexString("001faaf97b965ffa633612b7c8f9f4be0b286b19662e5cbe6878019d8ba1382b16567ced7a7ee5c272bbc378a95c2436fb0c6133649c77e55a708b28419b5cac0750d51706ced69621c8e4ba1758ba90c39ba8b3b50507bfa545ace1737e360e283d609cd67a291fc3d720c5b1113eececba4ca31d58a1319d6a5a2fa89608f9"), - Bytes.FromHexString("128b65cb80257f3006fc20dbb6af6781da7e0f9213d2b909fd113ee0f2d2bb52251e288387db7be742fe67261f36a4f09eeb4763bbbaa1bb13af3dec65302a4115f64edf27478045bf45eded285544acaa7f2b3a2a36176acefc1a3d7181a73219d4344489688c2a2f16caf1141bc42021738339431b3a64cfbc293a73c1eddc"), - Bytes.FromHexString("16a9fe4620e58d70109d6995fe5f9eb8b3d533280cc604a333dcf0fa688b62e20b972bf2daef6c10a41db685c2417b6f4362032421c8466277d3271b6e8706a809ad61a8a83df55f6cd293cd674338c35dbb32722e9db2d1a3371b43496c05fa09c73b138499e36453d67a2c9b543c2188918287c4eef2c3ccc9ebe1d6142d01") - }; - - for (int i = 0; i < inputs.Length; i++) - { - IPrecompile precompile = Bn254AddPrecompile.Instance; - _ = precompile.Run(inputs[i], MuirGlacier.Instance); - } - } -} diff --git a/src/Nethermind/Nethermind.Evm.Test/BnMulPrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/BnMulPrecompileTests.cs deleted file mode 100644 index be40da630d1..00000000000 --- a/src/Nethermind/Nethermind.Evm.Test/BnMulPrecompileTests.cs +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Core.Extensions; -using Nethermind.Evm.Precompiles; -using Nethermind.Evm.Precompiles.Snarks; -using Nethermind.Specs.Forks; -using NUnit.Framework; - -namespace Nethermind.Evm.Test; - -public class BnMulPrecompileTests -{ - [Test] - public void Test() - { - byte[][] inputs = - { - Bytes.FromHexString("089142debb13c461f61523586a60732d8b69c5b38a3380a74da7b2961d867dbf2d5fc7bbc013c16d7945f190b232eacc25da675c0eb093fe6b9f1b4b4e107b36ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - Bytes.FromHexString("25f8c89ea3437f44f8fc8b6bfbb6312074dc6f983809a5e809ff4e1d076dd5850b38c7ced6e4daef9c4347f370d6d8b58f4b1d8dc61a3c59d651a0644a2a27cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - Bytes.FromHexString("23f16f1bcc31bd002746da6fa3825209af9a356ccd99cf79604a430dd592bcd90a03caeda9c5aa40cdc9e4166e083492885dad36c72714e3697e34a4bc72ccaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - Bytes.FromHexString("21315394462f1a39f87462dbceb92718b220e4f80af516f727ad85380fadefbc2e4f40ea7bbe2d4d71f13c84fd2ae24a4a24d9638dd78349d0dee8435a67cca6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - Bytes.FromHexString("0341b65d1b32805aedf29c4704ae125b98bb9b736d6e05bd934320632bf46bb60d22bc985718acbcf51e3740c1565f66ff890dfd2302fc51abc999c83d8774baffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - Bytes.FromHexString("08ed1b33fe3cd3b1ac11571999e8f451f5bb28dd4019e58b8d24d91cf73dc38f11be2878bb118612a7627f022aa19a17b6eb599bba4185df357f81d052fff90bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - Bytes.FromHexString("279e2a1eee50ae1e3fe441dcd58475c40992735644de5c8f6299b6f0c1fe41af21b37bd13a881181d56752e31cf494003a9d396eb908452718469bc5c75aa807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - Bytes.FromHexString("1c35e297f7c55363cd2fd00d916c67fad3bdea15487bdc5cc7b720f3a2c8b776106c2a4cf61ab73f91f2258f1846b9be9d28b9a7e83503fa4f4b322bfc07223cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - Bytes.FromHexString("0af6f1fd0b29a4f055c91a472f285e919d430a2b73912ae659224e24a458c65e2c1a52f5abf3e86410b9a603159b0bf51abf4d72cbd5e8161a7b5c47d60dfe57ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - Bytes.FromHexString("1f752f85cf5cc01b2dfe279541032da61c2fcc8ae0dfc6d4253ba9b5d3c858231d03a84afe2a9f595ab03007400ccd36a2c0bc31203d881011dfc450c39b5abeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - }; - - for (int i = 0; i < inputs.Length; i++) - { - IPrecompile precompile = Bn254MulPrecompile.Instance; - _ = precompile.Run(inputs[i], MuirGlacier.Instance); - } - } -} diff --git a/src/Nethermind/Nethermind.Evm.Test/BnPairPrecompileTests.cs b/src/Nethermind/Nethermind.Evm.Test/BnPairPrecompileTests.cs deleted file mode 100644 index 6f5d09ddd58..00000000000 --- a/src/Nethermind/Nethermind.Evm.Test/BnPairPrecompileTests.cs +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using Nethermind.Core.Extensions; -using Nethermind.Evm.Precompiles; -using Nethermind.Evm.Precompiles.Snarks; -using Nethermind.Specs.Forks; -using NUnit.Framework; - -namespace Nethermind.Evm.Test; - -public class BnPairPrecompileTests -{ - [Test] - public void Test() - { - byte[][] inputs = - { - Bytes.FromHexString("089142debb13c461f61523586a60732d8b69c5b38a3380a74da7b2961d867dbf2d5fc7bbc013c16d7945f190b232eacc25da675c0eb093fe6b9f1b4b4e107b3629f2c1dbcc614745f242077001ec9edd475acdab9ab435770d456bd22bbd2abf268683f9b1be0bde4508e2e25e51f6b44da3546e87524337d506fd03c4ff7ce01851abe58ef4e08916bec8034ca62c04cd08340ab6cc525e61706340926221651b71422869c92e49465200ca19033a8aa425f955be3d8329c4475503e45c00e1"), - Bytes.FromHexString("23f16f1bcc31bd002746da6fa3825209af9a356ccd99cf79604a430dd592bcd90a03caeda9c5aa40cdc9e4166e083492885dad36c72714e3697e34a4bc72ccaa2e832e2bd419280d247658bb64323d59bbf47df41aa729d2168a272d66e306ff18ab999098bc5b30758183a160fcca776562d9a9370278aee9e6f71053e9358f0edd6252e0584efe53db6b3c40d1976d3849f08db15d39a0d7a6e327fc67f45e24925638e68e59cc22218917c61d2934c4e6353e2f62178a09627aed68c4e57a"), - Bytes.FromHexString("0341b65d1b32805aedf29c4704ae125b98bb9b736d6e05bd934320632bf46bb60d22bc985718acbcf51e3740c1565f66ff890dfd2302fc51abc999c83d8774ba0d2c492bf135ed45b0d6265c274d145d35b73afd41ee95d3f1da4bc8761038800251d138db1b9748ffc257b147a1aea66413b14df767f98f7ba02489c617eae51065ff2bd9a5b167db36225a35fd712d781309f4e2c8541a335b2c42bd2bcae4191cd528d749c52f3e198e534868d537867109419a32314886f6bb2bcd337773"), - Bytes.FromHexString("279e2a1eee50ae1e3fe441dcd58475c40992735644de5c8f6299b6f0c1fe41af21b37bd13a881181d56752e31cf494003a9d396eb908452718469bc5c75aa80728695310187ac477bdf3d7fb472e6374b1222f8ebcfcae72a8b1dc714ec853461fde556a4ef408d4a2ce89143674e9985eff87fa3df3ce6e7483c3a2f9b82bcb18df8612ef09775ec815b602e35eb6ec71ea6f7acebdc23667a60eb465e76d590500f7d19190ee1090bffe087045e97c913f7c5730110559665b3e8a9e0a526e"), - Bytes.FromHexString("0af6f1fd0b29a4f055c91a472f285e919d430a2b73912ae659224e24a458c65e2c1a52f5abf3e86410b9a603159b0bf51abf4d72cbd5e8161a7b5c47d60dfe5712fa10f98bc3c4faa2a9729408e92a8b4e6d304abc539cc396820f696f23ecbb2b30d01fe71a3550fa6780e70305d28ea686b72aff7d23cd550f886fcd60f6b30d1142c81b9b27e329c498e4b241fa2ab0e0c62170cbe2a1e642589e4ff6ca54069ec036f519726e40596ede6cd47577c5cc24746754280add50bf87fe7404c8"), - Bytes.FromHexString("0e6eab4103302750b22364bd1ec80e5edfb3ad06fa175ff2517ca49489f728e9050a17b5a594d0fd6fafed7fe5c447793fe9b617f0f97c3ee6dd29638f6c9232068b38fd28978b73b64592127317a542e084ea8291e404b88d3a731207104f9624d1ae64196a7d3b8e9fdcf72f9dce16d649fa3971daaca56405a0d331e2aa92210a32dfe27a36ca740e4d668066f7559acddea850fee4ebf9c9a241b337e771191a60da23a028dfc3b3b82c3d15802615f6386f29194e088936e3ffe96809eb"), - Bytes.FromHexString("1920c53c756f1ec1a40e0264e5f65808eafaeaa7b0885f89852297bc2186ac9d09416cc536a27b6d5616f74dd2bbbfb463b9961752e0aa38d47b5213994959ab081c536b7d9a27636d0af7d4c8dad2e380cb2996a1d650a2e6123224294a6c86039e75a4a93bcc2798aec714e37b9b2602760e7ec7c6f3342e44018f2986da9b2d1ceb9ba9f7b923459d8b4701dfae12b3efd4174fa3705747fba6bce14a87720c15d04d2bd099f86ccaf9834b9588e88fdec8d04bba329d4fed580884f4b2bb"), - Bytes.FromHexString("001faaf97b965ffa633612b7c8f9f4be0b286b19662e5cbe6878019d8ba1382b16567ced7a7ee5c272bbc378a95c2436fb0c6133649c77e55a708b28419b5cac0c37556712bc94140738212a1372a4720ff269102f3f0dad4493b675a85463021e03f350aa8213bd6ce54987e7b32275bcead9a9096897b5c7dcd5964a17e07a2550f45b84e947f8e46267041f661de0ced333f91af090435c4bd6d9cecb4836096855fbc396b73c589e66ad989d7851c08bb55755f5771987d91925ffb40c2f"), - Bytes.FromHexString("128b65cb80257f3006fc20dbb6af6781da7e0f9213d2b909fd113ee0f2d2bb52251e288387db7be742fe67261f36a4f09eeb4763bbbaa1bb13af3dec65302a4125ed8b2035e437f057cb45003f1c25510d7e232c7587581bdc3035064a96d2e32293733bfad88afa5adabcf320f055e3fe0d1ae733dc21f5e08fc234029be16a18414155506a4c287ac374bc28635be3e6b8fd0097554db051a45138f0b6140410f8c1e8992d53017580b1b806cd23729f9a2aefc6e60bb82606551c1393750b"), - Bytes.FromHexString("16a9fe4620e58d70109d6995fe5f9eb8b3d533280cc604a333dcf0fa688b62e20b972bf2daef6c10a41db685c2417b6f4362032421c8466277d3271b6e8706a8034c462aaaa7a3b4ed1266d755867524258c64b9553c46b2bd4d5c26aaedc66524e9d39a8749083573a1b84662c08ae15f16b75b9fd40089ee412f5e58dfad350e28b1c6e881a288290c7e9e12d23f122e61e89c43619f902c48d300ffe1734b014f125c1960a64127a16c8a17da5f21721e47b17575a94802a78711f45fe988"), - Bytes.FromHexString("1a4db8abfea95acd4ac4bdf3d9082de13dcb9b2a73d6aa98a296a7d7d1009a8a1e8a143f9ed8661a223e211c4f70b1ac1d5057d71e31f182637b6f26de9a59190e817e9fb476d397b0f09aa07d290cc830ceac3ef815c5b8f45caf2cdafd90e209888f93aab917c7b6a9f8ee7174ff889961ff3509256873a774926c0c5b9a0f1005b845c9f53465d9371efb0eb934ecc8db144d466eaf06614e89c77305c35501951dfd5ce7f374b05b2b2a0737a5251ce4d9f53f0ee7fe79399aa09d6bfe9414e57a7979f8f2d78a1c7dc790476265240fff65e18344caa11b0698a574d4412bb862b7c0f8283e05e10a9b6e3bd19e5b69f6988b3f470692f26c379c33132126a4d85b3499d830033f0388c18b8e7b824b5b0b57db1fe366a435b0c1a53c6000ed1afda982e3f8d71da60ede43dd562ae63597ec91b1cba21e1c9fd5b8fbd81795c6b9f6debf45b77638122c7333a59aaa2e7511f526f496feb84c20f651552581dd3c6f3d05c78234b559d784f502fa5dc0900ae7475ba88716e5ac3d499d"), - Bytes.FromHexString("1fc8f5de35d75e7446ef5703dcd7e07ad682030dd525b7620e1f7f36908d535e151d3453db1029bf894b5bded388d6a3fcf97d573bcccf93d27456ec79d9337d23ec8c4d66276cb927175d7bc25e3bf5a2252c4f83de5eabd695181834c67273017bea94aade8279f9b646a2e7f570a88aea7eb8bd51aaf40dbfe070a7228a5d06652252d3e68fc6fd6d76cd726513f0f757783f415762ecf16fb288ea9b10252a6ba1abfff1bf53aef31d24fc7d7c18d452ff529a04bb97e2aeaab748cc19762032882547249177d5cc51a46852ebc90ac17f098a3deb8dd8a37fd007bc2baf28714b756b948ac2b606fe0c4c1c3572423892040e5518f9e6abe89e7b1875bc25cd06956892564bd5e9e8557ba6c719e2ecedb4a4996817a8e77593af1321050b2488820e023afa5734ceab7072083831db2f7063cc57cd9852deab6918ca9b00b22e3956983827a599218890be78a3c0ac7f30d3a35d464a9cd4d4ef552576221f5a9cbdba030df39ed692fe2274fe2a99fda883aa4e724d54d6a0f74e0a89"), - Bytes.FromHexString("0069c0c3d6aa9ca250e5bd3e2826e47936b6e479ad7c776caa5ac801dd5a1c2115226a94941ba68cd74c5b982235773c3a9cf6a71b1dc9d4d8307251f1d031c630316709df5c7f6af25fc5f698db87b1170fdf63bd2917bc21b5037452053dd30bec8492774364ac6ceca4b56b9b8d1aec0bcda12943dd1437e515fa7fe5bf8000c0e3fd9719382c09eded028cf0c9f866d0fec2fab515f6aa60249557270f2e25f0d2cf69c495554a426914354b553f3f6f269e0d5340b2593a5793138189ae214aa7d305903ecbdbc10d564e1ebc9455bf0e8aa3ba3321f8b9023b911cecab19239edfaa2efe905d8a5d6884da42815cc84b13d9c4fb3c304cd99d3d27b61e15063c61103bc76e80aadf05a3ae6a36f90013bce43fdb48bfc8e3e2e09f838d1dcd88fe88d48dcb4d6401442b46fd713c41d36dfbc50d8dad834a9615fc01581377baf2e5ec86b4bfe2123c9f1d5cac10fe0a79fff333ac86ebffe1aabb98252316b9995e22925907421897f44ffffa963b730c7edad138f41f54652ddd8c30"), - Bytes.FromHexString("240517a373fda7a2fef6ee9e9895505545c354433af3d3548b8537abb10d445c12e45a8b8c4d7a82ae27f0ffe3dd976b1242b040b96043ad31ce9f2ffa5bc707275ec5565ec4ccde5088b40c57c946be5d48b9ba34f956611ec87ed33d47500116f3ff1c54f920a4ba438c43501d2ef59e7c7eb2f8ebde852309bbfbc087af1b1742abd3e12ea49804bc4e8e59ecb9da6789392b1e12958ad653ad49f3d4d8450a1190ddff2fe9afa9dbea1e42222afe9715e1bced4e7ac4c20d89476ed6253c0bcfe3f03313340fd392b32bccfcab83f942f6b13d71e2a3159239c61c50c7bb199c36728784b46d5607ebd7cf5a055a3db4458ad6f0fb7e826d6a280daf625d1db3a467a1de6f3b848da16893902bb07fd0b63f6509dacae6693c7975fe09940b291b95276b136f58cf6f899cbb5a6f4009a4d069be6c0f8f0d6bfd7c38991f0e46dd20f14881ed44b216b44ba054b1f32c61d01f33326ec7f6c2ace3c8901414f211e03a121fcbb34f328205223d7f7ddff484efdd5d06e8886f2781f8e549"), - Bytes.FromHexString("15848a9e99c4a0719df209a705edfa52bdca729d0b73a9835880da9dc0cd2ace108b1a4ceabe6a8ba3dea041bb0dff513e7b99057d4b3c2aa378807de47dbc3627515ea8ee84feadb86577a1b7553b2016cc63807de89fcbc05bc3d53b0f23332872f837e4cde9fbf64bdd170d6488a3155bcd5b1fef4fa7ad10089bec8ea7b803713c878e32a49ff95dc2bbe7b1491c38258835dbca14ab343e88dc64004dae0f9ec7e3c20939b84e40bf66864e8129742feed7e1291d752c76bdf28e02d03b2c48bfe10367b611f37ab5847542df1d30baed8abc5380d6d80032d0e04af0d10e119d730f867b4e286a3c1c4cd04236999b9bb94d9001a4f144982d72df407d059e6ea753e84de7e8b41b2d0dca1cfb6b12afeb2564a5e24a2064f1b662a1a912e0bdf2470e896d7fda45c39a66c5c4a5297b4f19810ee37e33f7f50499326b1f70831beccc3eb5fb719d27f111e5c731cbeb4002519a4b3831ba896cffb608157b59ceb6f7a0518df929eac70c7bac9ef9c196ba21266ff47cee9bb0c60864"), - Bytes.FromHexString("08a66cc423317e9d9560c307c7918b87672f3d99effd28b1d2bd2877e09fbba41a58977974f56dc522d159bffd0099791d207d2da49ee217055f5d0806e2dd0417b523e87e1d03b9498facd5df95cd85affaa681c2a43e51497997aa916318391835cc25b6a0979581ff7042a390a7315d8f5e938ea40dfdcb24822889e494cc18dcd8bedefa1c477913634203aa21a5a926595f62f4010eb3959d51acc430fa23ff858e75bc56f4d5054035aee0fb7264ecc4861ba1c44db81868108dcdc4dd099b58d1c3d880dda20c24def1b2c54cbb20ed9da85265983a00c1cf1facfcf903e39662a649ddbc4fa6927ed85694167b49ee5787bd755a5e4ff6fb82c32a9f20b8ce350fdb30744dc3dd1829ce8e7365a9ca56bfa4f79831355157a73fe99a17a534a927ed0e6cdfe9ae9befe94f581d20a4f19aa54c93149c95d53714c5a70771d55a8c477c0ebdde254d19e591fc3ecf011848276731a12a96a3267c5c710c76eb36abc43ab4d4b5a7a82770304fc2e9487512493dc5fd59aa6eb30402d0"), - Bytes.FromHexString("08808ba03b1abc4b870cd2e50b3960e85ea4ffde76e97ea70e62feb5712ac68823f1f949786f8cf8a18323bbad75bc71afac4e2419181fee3a627a8980f5d36f243b9ecee8d6c2f2f1b91980e4f7136d16f70c94c5fdc21354adb977bc66d748207322b7980616a6e4f4ddc3f223c52a9a11b785298b69f4075349274adeebb21226d7ded357133a1e9a8472f9c0f23e248c1ca1974ae336f4316731f1f473bf00b29428be1694c86da00b5cfe677c1b3332c93105d18df718f9ff0053bcb7a620adf7f96265baa9a9b1512eb1d59834eb931491d360408061135a8b30ddbfdc284fb8dde65089a6359a11fc8d2725409e2bc1e52141f1dd38bd56d10015346d0aad6b6b34672e8ffda5085e97e2a7f82ff4e3e6660b83e151b778e2dfd1ef3f14b07ac31c0927a5cb27b0447051f1ea39baa7ef12572b9b5dc535ffa28341a220dc6c1d760064168c59b36eae9560df6433eb96acd58aa88499ac5f081eed30245b974d3078709e037860b2970943659596a88d529a36275b34b38c51ced169"), - Bytes.FromHexString("198f03850c2c5df1bd5601c0a5cdae3cc955026dba50a79dd00aeefe49c48c252ee3bce85e4c7bb10fee21428a8b0c1328d662e152f36a6c62caaac2fe097c0b0c91b38273eedbc873b2172cce9eaf7af1463cb3fb064a49cff2dc95f0b5bc1224a1a5e52496677b5dfa29a4e314d7b32bd22c0f437679e12d0c49c9d84e988014d4d06a717737c0e36767b06809bba6bcda2707bd652b3f922c3a652dfc90b325d0de555188106e9c4bd93171a8377b9d53eeb93b0b259a91c7ba570591f4010f2dbb4dfc16b4fe806d2ed28daf51530d6b88a81c2ffb98d3a6c1153db9239421b7f52300ab7b6eb9d9ef4bd7d58811909cf4c4ad7a9f8546f56099eb6ae1370224ecd4af7d5ec18e5b0c8eb46a8bc774fc4ac6c4233aafe9bf22420ddea4752bff288e58f4bc80b1bb91b450652c120db2ece783788b8ff3beb20b2e8d3c7a2d90a5dc703456ffb854fe3a746143e82bd8e4aae8321ab59a93e5da9d615ede07f9f33a0a234486c63562fd9b27ee6615655b6880bd511475059ab40395d23c"), - Bytes.FromHexString("2722ae33a1d80f67a5da37ef2b7489dd39b1c98287fc408eb416e37de71bba1c3054f7ce76b782aa80254ce991fd5f115810e8f8f57ed0a12f30278112157c11165fa63e0d077c2b406c1001da54664d756636d6018616841c5b0d942519fecb1090ad3ca54838d2b89c0d2e3db3c2aff811d58bc32881d2ec947f473a8308a615b9fb021f60b7604ef07863fc6449504708718eaf59bd00f3620a9da16ed8830a95e72b8b56d1850126d77ddbdbd376e3b19f07a75071f0b958bd40471fe6900738bd659eab6973c3416b9e7c9660d341e8eee184c0f9c5ec59696f220903401e37dd4714f68da2a6affcf65a8cd26c7ae3fa0c0e5a3394887ceaebe4f49de90b501640d9ca26d1b466a9ea005b942b047fb519865b3413ccd90533d9902a85187c1fe325590f77ef42af537664469fa950986ce82c31eeaf1f6b348a3de3c6202ae189a9bf004bd80b9d8bdaa9b395a5263735242766aca3679ec3e547171b2a06ce9550542e6246331cbf852383c14830931cd63ededb0f21621b71e7f981"), - Bytes.FromHexString("2bc49f4d8134cf72ce0883c589f4f6f0636db174b6176e063b3effdd57e3404309f61eba66408ad541dac082701734d6e6d4cf6f90bc0e65d6578f2d18563e221eb59aa8d8a9187b0857ab89a453fc53209855b300377bbca411998bdf9aa6730bd2384fa0ad96fcd1fc6c1a1a1fb80d4859770ca91b9559281736cfd6745d011cb39aee49da07d70b0f579101c412f1068ea82671859f09c4c1cb3ae74f8cc103fb73a573c8f147ae15610e4f97e291bcfe16556842e00e88ad70db0df2dc3a05430e574064f2d1de68795706bf99b1b6079a99bda3e5ec266567f2f9246e090f5976710762dfa75253c53ae1c2c88523ff08d0c2523d9409033aa2b7e4392000036daaeef66504945efa89111745e29d39ac317d798bbb1d14f84bdf5bfac91134d59ae245678087748ccfd3c65ecf2db2d05595cd6ed8452346713768c7411ab6efb518910157009fdc818e5d4e082da02f0618f4a3d6166f830b81a4e683023ad24b09b49bfd967c7adbe895811172f04a2b90b1379dac89a6fa1a91d8cb"), - Bytes.FromHexString("03d310db98253bb4a3aaff90eeb790d236cbc5698d5a9a6014965acff56e759a1edc5e9ae29193d6e5deed5c3ac4171cae2da155880cf6058848318de6859ea21ee564b4d91e10d3c3a34787dc163a79bf9d571eeb67ff072609cbe19ff25fc7270e094c2467dcf6ecf8c97a09ef643cfff359cbec1426c5eb01864b5cf3c27309f432f65daced7c895c3748fa0b0dfc430584e419442a25b98e74400789801210fa7bc208e286ebea1f5c342a96782b563a0bc4cdb4c42ba151b9cb76eea93d0abcdaf6ffdf0cbf20235077c7bb3908b74b9a8252083f4b01dcbe84cab90fc71a9681988a15b7eea9ae8cb0c2210b870eec2366e0531c414abb65c668c6eb3e21d0be81c5698882ee63cb729ed3f5b725d7a670b76941ddffff9ddca50cf9af21e61a0ac51a17c0128baa2cda8f212b13943959cf26a7578342c93dd2de7deb194e408b546197d9ee99d643e5385dcb8d5904854d8a836763ab8ce20f9b5027222aced81c808247572971b490eef1515a49f651f7df254de2b35310bb5b78c218b2345c40036ea331bfcfb8536739a5e5530027709adae6632a3613cd0838cd204121beebd54ec6bb063ba5a6d84eeceda2a733260066c90d332425e992ef6c2b0f794d64952d560a422a7ff549a58bfaa0cf791ab6dfad1c4941e19078040324bad1c848f2d8efcd716f7d814c46e2632e74a5b8d455a64c55917b220aab982ed4bbed5f80fac726f4a95789fee7905eef0a241596acbea4268ec3f2b87f3129563b69a30c11a856f68c72f129988e8636c86f57467cba299cdb4917469b49137a989e5d714b4b882d4a455600940ab63b14f23e7934ddd62cf5181099c63b2f57525eb3d19451024a4e71ee09c72c5b7e0dff925001acaee126bcd29db5f600d8ff46230e348d08dcbcdb1f85a5a43aa7b4f51841f1d4f98c18bbb57651982cabdf6326194120727367bdae0b081aa7da12c8f8c6af0ce27d2f8d0f059fe1240c9c5a6993d344744d77bbb855960b6704e91846cf362444bff1ccaf45a7c217873a5d7834d0c1d7d9bab5f9934d7ac218834aa916d459d8ceafc280d59efb"), - Bytes.FromHexString("2761d967b3f2481435189a94502260dff1044c8cb24ea3809d0eec28cfdbf6c72c87711eaab02bf1f9940d504be3727789efbbb1c48370f61e2e4daad31be6de08a73a943ab3a7ea19633a4ef9e9bc1de68a51d778e41589504b8fb0818cdf88064eb3b5d1a63404e247cd5118a695b3b85d63e89c8512309d591701596f172a210f847e73452b29da165f6c76462f2ee76ff301b534bb0d2f0f7374b041e15612a910ab4044ec261965b917059383b5d5f5c9eb201eb61a6909fb5a610849aa1f4535e9a8bf16a4a4435004b8ab3a84bb6495a0d748ccfc25388832356732910e2936a799b55efa690fd821a3cb4d352cbb3f22ed5fe865f984e289329ca6591e4e4510639258f836e30c422e3a18fb76bdc121fd28ed77306a05b8a3299fec09decd53dc1620f84154fd333da06556e87fae4463cf02459964412fa50d4b082e0120af9b40957fb7ff0dd412f59cc0acc01c49021389cd470dec453e92faa3221680f87a61c96fefc9ada16473b853c4c92a03e1e38211a9487a2812f830760f4841710cf252069ea39d70793aac9b2f769a3954310546fc15a109f6d057d30f01c88e34c9ec83f28674534aa8ad16f61b744b293b63ae3c2fcb178a08408a1780e9ff8f2973152194ebd44ef8b158470d3f67d08425c7a9d99a4f1ee9502704bc22f9c0177342d11e54a0940cd9b51caa04c762f060d5262b5f31c66d088729dcf02930b56cf1a3bcdd147cab2fcfe913c53bf5456dc19edd706ad2122be5129ff68c503fcbe10cef00f314919b033000f43ca563f92e95a8a9dc19a867e400d5a976132900579ff4d8e1f64d86a453d7576e16459b641d574d2d9af32c0707107329853a55152341e8142e6bd97b51118d4777e44d347a3add4f6e73a6d52c0175507a0d4432b6a72508a8fe5838a14c953bb0a8834366aa0ace3a1c12a005e64fcf94cadbc98cb78a5f768409a1cda219c504f3c0e99d1e8de93601046528ceafcc22a3649dd0270094b4b3fbe55fae668028e67a8dc3378fb726cec2fd0c3322db4dccfde2f638c9e7cde93246102e9539f5ea6bf23e57bb3f60e8690e"), - Bytes.FromHexString("28d6423856311fe86c30fcd983dfa63c95bc5adc1dee6fe0ad715dbe7bba3c091165ad57bbd71dba3d734f446b3a11cbfe5e02051f6898a677bdda5134738d5709661289bdac8badf175790f8e406755b33e54bcd8149e1e469de37447185f110efd4f6454886db697584e85127bf4826304d0d9559195b6d3f875cad607958903e94e1ca8dd25c626e31daf9cd26b3caa7ca2615690127aa11647cba037c92a20179a34c869f27fe9783e133f50fcc38bfb81200b9c635d0b9bbbbc789f4cb60511e5e1561aad84bba3d2495e4853046ae1972e687ccab832f34f19fe9b55db11d42ecbbbf14d945c29319a9a945f64610a2bb9059c0c89911556232bdc6c4b1e92ef35b5ecc024193888d764218828778507233cda5076633acd49986023ba1c0110745aacf972ffd66add373241c8285dc6c96928a6ca012b4e572f1897540deab5945fc017e575d40284abc7356a20bb85330533be288d0a14159da44efd1fc7bd3676093afa2c2d809cb5a14b913c5914c77b341f018f391cfecf0029a2090010e0c084f8c16f8496f1c6db02902cccc6cb8d58118e8dee1baaea679a370075a1886efcc99523c8abf69974f742c7d2de3e12598a963713b9bbc31a9f0a14b98584a1aaebc7649c481668a54d9da6fcb308f3dec33e0965775624f2f904298d6b7a0d04b3a217099a7daf390d5a7edfd72b1c8aab02e6f5cb440cd4a84214772064081adcf6e36148eec3bcbbbd12d363b4a76e7018159f559c2ff1c0d8051f9f9abbafb9032e3c95ebde21931a554fab74bfd7f3d61c939268c46ff9c82ffc5143ba27c7aacca19326cd8522f9d55e6b6d17d4b0586b81d86e76dfb9730782e23592d8d735517d63b6b51313e09681bfb6e66cee098ebb60ca3ebb18f80ddd80135c76e5e26ec2d004f572d267f940a5d5b82e35f4df366312e39387662343e67b7783310ea825278a262dea12bd5b1fa71735819e3e360f467d0af5f522234b4bd70b251d63a8dc9bc9e63117ca8342c3dbb3068df38229b5b34f2bd21097b0a55ece871e554a89aa97a7ecb95cd9e1f5ecea94274019d17b9943de13"), - Bytes.FromHexString("09fa51b9f1972a041220b86a762c252262d942474d9c2ddaa8d292c79d34b8132771b3f3a480320bc7c9963dda5f4e8120b8f06a0cbc6095d37e0dbbf0b6f9ce23d0c74ab9b983b35311ad334580ad3e9b8ac6eb0ccd69a5097884056c8310e01317cbe87801a1bad8f362bfa07f65f4e6f0df7f1d3681cab1995df75f3caa2516abf6c2348309a172dfb07485e59d4b149d20741c740c9379f5d235c8b7dd922fc0496ddcb63fea074ce4aca7f9a91884b8f3158970ba3f03fd58608b50b7d511857f4a462fb73fa92204c79e81824de2825b74103238b4f8e601a2cb37121303b531c48bcf5c8ddf8e608cd16eef92bec33929ef4d8fe57572214999746567129e8547b1d2f8103bfab8af9a8849ef950c020c2a24c235c889dc65d54c6f00036688a10447a1ca50ecb46b9c77042a3e0959de2919eb62e55e08f94b3b491b05f4e65becdda13865c79072d38ca4a35cd934ccda724348e68631deb874a62d2bec9369394e4b5d549558b030a5b8681d23a67cb9d95465f531a39ae61782b729fc71bd60da082f1dd43572c15900fe35d03e10201fe93668c6e31e0e4330212b0fe78b06800bc1a549cdd0ff91ea7ada763609799901b63a1d3ecb446ad1110847890bfd62a9ad72ad058345167d3716969f4f0c1861e532fcf5dbcbdeec04018770d45b235156f127dc39b55ce54daaccb9b2bffaa9692591647fb85112a622ec7b25af397ed0c3738c242d8c7d98753b0a64f826ad284412b93decd25a091a8d6e03829186f4f33185c75bae823e2840d04ca583753b9ba7b9a215de06ce04ca57858bb1cf75033675d652331e737f7d98400ea1b42102273e74f75ec4a41716a588640c92a28e2d4bf4ca5a6c8fb6fb2d910ce2c882fee639f5e16f11cb1967f6d1826b83b4197e628bf36eead712652ea75027a48148059fb422bf03550f60639bae9064af3ee671b9168eef729fa30153c89843827a9991da684d72ef07e000a8e29e909b06936cc43d82c5bd6f7a4108014532483f674ed28df007232003493fff270b3289b402ba1eab4bf90cbbbdddaec3e70fd0eb648c0fa61b2c"), - Bytes.FromHexString("18db259896bf7a55fbd739049dcd87bab41bca06dbe6ba477bd91293ecc7b72a080f9707ac098f3ac7a06fc4cddf9de9024723d7803df1e832f23facc344e09f1f0a58aa3d929cf73ef5fb29717b46818570f8acc287057a61f1bf19952d5d870a985a1377ac0068c32090c4f61af49e438888371fa281863746ad9c4505839a1635829f9dc1168b264dc1b35951410b3f509179a86259cd1bc219e0d9fb6571282e9a7a2784db855d8fc301a21574e67751c63574f552b5075cf0d54feb2ee7086ac4e5ca51c4e84405e5310187119e9283a8e1d4b9be261bea666f724501c302d9e8305711e2081373125393ea672966c2b7931d9de75640aacce9bdd8ff8109610ee10faabfae8ddd3bae29f8644762b842a90a4baca50bd37c4c8e346cdf2c0a29ba08d26cd5e2ea3ac028f2c13854b997da5de4020810d8d1df0b5ede16181628b1a3d5936ef9414119e8bc454d0209022d6c3b6722ed63bd3be9fd11ef16a94dc0c53b0283290c9189b46b2b2e727ac54299b70b73ccd31eadbbbce239183aa0627c185bbed1b35c46d0d2ab1e248f7a4ab6d1896afcb8cecd471911ef208db0fcb30c4d601aecc21ad3457e4a636a2bb289712a98153589c3674a774f08c0f49c7c290fab83aa67c3ed645856531b1e537e060fddb3b722849819cbfe04336ad8c78b7ecd068f1f543b4cf09a510bed3f39c8afd71b549b957d5b4fdd0f2251c9278bb30892b0ea4fbc771380481fdad33dfe0e9f49916e476823feed199cdc78bf86665cfec1b451e92bb8122597a0b28bdd5d380024756fe070aa101deeac40a4d371c0154aecdddb082f6891c7c3a5074e1b5c1b30e4b3ffcca6980bab17266f609f8c1616cf6c23c51e60b24d2ebcff2c7e486abd11f878ad231b2e69a5773f6986e289b67c70b92da16c0c8f2a8dcced737641061312f5fe17952151ca3275c32561490b233e7284a4690a777da485efacab5557307c6d8e588608aa1e46b4edfd86ff457f0ab244e624488e4563be1a0ee35df8b547c43e4e0411b1dce99279dab100f4137847c3bac64342dc95b9cdc2e5880ae61f898181d8"), - Bytes.FromHexString("1688243c91950e540e5acdc41b84ee9d2b1c0ecc84dc373d6fd5959baebb33df140c8a9c0ae42792290c177a97425bfbfaf7ef008b7656e906c2df69fbdce89a029c4ee67b639e4b6f7cf0536ba1f24bf61837351b5c74f12fb6cb0887aac3ea1d3c75ef1b03ad925b1b223901a8e7a4e16ef2bf6600e7c175529c18ba8008350aa0f1fd72acfd2bc3c50664eba62133ea85341f0b4ec0c3618f3738401a42ce1fc3592b9642716c47152c9e52881fac74773f705c15b7737e0831ced7a0f8371245c36152deacfd18a947b3f3c83a30652958dd9614b7beef8aa8b5cdb157462ac85cca98a10e6ec5efafdd593179f2f56c4febb1ae6f1d72a9661fd8ed51032b98467d16a6e8e6bfb427838659b8df567ca38ec17c979560bee66d1ab72f372d38efa3e51e7ad3ab06b5610e0631db0a385101b45d0fe47c25610213aa023208289e3f0845bc2197d57ac44b4a808b30aef09a344f80062bd75a1844715d3d0cf55d95f2fefda6a1bab5796626fbb6345796ef134109de55bd61654f54c71f16eb795694ab923473ee66eaa59bbf61de8f8dfa94c481cb4f224b3ba90ec87318c3ec099e1aeb3d63840ccba2159386cb3d71481ef18b5466901b71cdc6e75e1ce807182d1b89fcbaff954b80d8a58d49c953c05a64e2a326cb3ae4802a0f9f29719e2b60002727f32b49638ac3c1d4addc61cb260c4ac99307ba24a7743ad52f325d4f32b8477cbd99a218c2e4ecb3171cab016c51cd800663bec05624f1072775db17ff93e8b807067572c97cbc7321e9690b8fc4f193eb0f1a93ce96a5c20cf7cc3dbf579b54af41204b2451098724e9d8940bd4cabff1605f33592e5f002817dd14edab5e60dde89c66b3c93dc057c53b926b2077d63d2dbbf9316bd64c2bb1b35df3f9ce28954fbe15eb52a08aa70453112cc94ad923616aec0553dfce0d5e44001e7b139917b4cd2d32bca418f24f44bd7ffa16edc47ff8178efee06f28630c2816b74f232864deeea9073bdc2128d704d2375431c7bb196825b0ba890b5ecd90caa2107b346a40472b9972bdca3e388e38a2914e2c1f022a82d49b4f"), - Bytes.FromHexString("0eefcc4248b67e40298c48e0ed47dca1dbf6f6e377506899430b11bf03b17ede10c71a49ccfb43f8475de84b581eef9ab283c1238e172bf48150f29e1e56201204c9eaee6321d6ee36b8670498aa1c73665f3ecc7350c8ee09a573e692d26320171450a989ebe50e365b92d24c311fd830972e7b16a2523e634175c4e24c884a1a6bf429331081e6e930bd36e23bdf91bb8180a6e4129c11655cb9468093ceba0e9d0caa4d47983e49ee253051aaefd86cc6dd367384f89e2d166bd721c658122a55d1dc0b4bd2f33984f0099a6d44c85baa10aaca32d0ec89e494d24514a68c2d43c0e6576ec46f88dbdcc7c57d685a3eb9342ba7c71b62de9e6373bd9094ff0a716e218f8e4174821a7dc090fa93b7683e2a6e363afe3eb7287a7dcbf9ea090dada034b037e05a7c8b232b8c691b7f0c3b9a870d786e913d936f8256f2e8c0131bdc0ab71a147cb4d91bba85941c00ec91994d2e9e53b1929a14ee2e876dff021d8b2738aed0201234d3919498c918fd5340541ec616542d92d955df4c182902237ac6c6802585c60640eefde7c05fbdf206a5ec25dc3411a4e9b4e6b57be611bbc865815ccfb7c666b117834cbf2a7edd9c2baa691ee3d453c3652c49761b234be3f502cdf3d1e6258eb846afca7acb0fe13577e226ddd277daf32d1d0c5c25e39a0be0435820302ccb2763016b10d0dbde867c745fe86cfba8cc925a2eb72d4bb48beada74cddc1c791a980d9bf7601ce0aec444354a5c02185d392f66f50e4860e017fc0453fd1bb0453197ff5abfacd35b90e7d9b03ff0900cc857ef7f2f0ccd45b2e137fd53d99d027b79aa390ac021bf4d6aa95cc96bacd6a071386e21f73cf3d42f0ed82ca6f673bb89223e16386c7328385edb01eadd4ce28e5ab418861414b0b511cc6300bd0cc6c95538014be8a4a20d8cf56d74f4a63225302b1f065e5ce6c676af04344de377f580aad377dab935d532f2dce9daeb0f31d6900af84aeeab7ebb4390e6bbb4218558fba894959f2cc2fef8af5d1c16998a38c6076f86dbd858db5b0b15ca2cddb0092ef861188e0434f4232d7e3e884fa42bba"), - Bytes.FromHexString("05fa7cb22fb8809abb745dc167279147fa174e0444cfc99a38f23f2b93e49ad62f7f94d2d206264a9358b54fc96ac31921948cf3c13d121c923991f0b47c04291b2582586c93d23816aac8ce2f90eb913e554211251bc9a2d64dd2efb9a905b80f73f8ca76c166aa5735d9370cf944306abfcac5a5874cc95b00b569f7eba01a1d92dac05e6fe60b5131a0d2e9c459d4b3deaf1a462332b285f90a25e5b61c211467961e060894bc8111abdbb66365b9da4a6700f2d530ae69289d2cc32185d004951597c8a0547ea22859b97dd87a37a8b4125bfcb513eff29e0bcae7a7dab00cb314388716efc2bee7b4294811db5bacaa3bcf720932e253f002b53e968f930bfa9409e358a1370c298a8cb622a0079bd7bf1a0e32e8f8dde7a0f56877945d2f95f233ceb61db914a2fc789bd35b3df37f62329a886194450ccc9e708d900c1fec898ed485e2970646f939313b33a6d3416476fcb249a96f6f11d030093f890621cd7af05f335e3514d7f10972f2b56614e917d9c4cb85178cce40f09a2291211e5387ed32f8c6f90d4c90d60fb08844a0fe0786717113aaf8060208331d3a03558a26134672a33a540774a5a994c549f2ec4e048e99c45f6f44692fa09ecf2d625e843fb3c186d9502acb5c9c3e6d0402ed815d76cf081e3ed847bdf8b0db0caddcd63f8dbab0b1ffdd45ae118ad1dcd7c1306c75a1f448a0e610994e5f300c058a66f63de3e94c81e96dd0cba0182c1371f61006d4cf9c9e24cc439d0cac280db62277ae92b4403f31d0bef2674900f1c21a0fb715b5cad4689154bbf53c2430b990502a5231b79e63246d15293a37918adf641bc8f8b18462909c8d1eea14434c1a33eb5a3b425729a7885db91c54240d3e8049c3d10811709dc86e71ed08d9b41714cb20a4d28f608d83b541cf998bef0ea0257f477e00c180b4e8ae4a0698e1e77ae24715eddf432eb950c3e26972a08521c31c484a733ce217b944f6190db804087bf4786ccbde4b6e149f2471121b29b6cb21d1f7baa6be1ad6ef18295d7425b744106a6fefb550e079074b1933af2bcf989c833a5f133f8e1c490e"), - Bytes.FromHexString("273cc7b93b70bbfde8748d62210c033579947802560fd05dad9d65003482995b1b7379946dee0b15e90720dfff72cbb60b60b5aaa8490ed2b77e8f57a8906d1816836ad1a19ace6e0feaa4195ee6006280ce178b5987341221c6ae618794c10603ea811d60c99786835aff3871ef0163cdceec010fd806bd11adeae2a91f4cb6179a512e9627d2af3dfc8a36850e144c7255568b3154d41797e2ac4782234925047ecbe78073575c62a32129476a6456c61545eb98bbf925ae1d673a32d680e71f20ccd414fe03613ff7a3d330ab8bf8964cba66cdf3af8bb955cdc729014e692ef7c335beb80626f05301278f5e3b228bcc981736a258ea6bc4802392f081de265db5dda279bf034808ed23c8613341b31d3d29a2f65a367024af1376d1bb9907b7ed2f35386382b00fb0afa6c5643c170010e35824d8fc84d3604690fa18b404685df83549a5573c7228b29a7dde8679d8771a19e8af709ca46c60f8126e4b033a388adb6c574f85524ff523bc7c44b49c8731b763836e0a4ebf054f0008492b60683ad457d04d91f082e169606c6e5d6e172845fe586925db00a8e6a242c409a8c11d9bd07c2ebbdd653519e9a0f5d29576033ebab9a564e1b07d8909b014232fdeb565d57fecdf556f1b9753361e8d7ceaef0d4778b4669643a8f980ed9107e310cfb6db05062d60b0810fa4aa6ff9825ebc58ae839c844f82ad08d9a273161549f2d3778e678f8167640fde4f43d30f2f60d7ec8cc83673d0e5100235e405c743fcac26a09a44bfb9bbd6f767ccf6dd030879dae04027353dcbfc9a89af0f566f9e06f1a6035c08bd9873e41dc3bf009005f905fc0b9b74ea57a16c5a2411c984cf6d6d274f79bec9cea6021001d0729f412858eda5c909d8bdce6a24980d28d7ff8a6bc01cf9ba50e6613c5495f13a39ced02158862b29579c4cb0e947142fa8592c012a3038fe1178bcb515a016a06651e387087a9110ac43ea9548a520537d116ead0e2498e487613ebb81ef0f6f5210cb448e92f2cda4a4f57013ed1f922e1c90d8e8891a308adec863c0b48faf4b7581e0565ded5a8ac6bccdee08"), - Bytes.FromHexString("22f2e1830cea84486d7ff320365a5ead50d356379d7bc4f2b9d77dd298f36fd8087baa2aad4fd8bbca8cc0b525041e1b17aeb3ecc63086cdc6fd1ec2310bb8db243fe8ce837f106ef17e387f9d78df833811427d5338c83f0622f92a65101da31ab23d2eb26b70ff15decd58baf91a68ec85f149012d481da67f806b0571c9471928767c9a5576ba5fbd7cee08203e6de3d9dd36a756fc621700031081a80b7e1aee70334cfaeec2f7551368818353fbd5810266c7d1ba49de47cec9b81b6e82007aed597093879d894ea438d094f3373b51f31bd5993e026e76502bcb1334e32189a92e9df00c0b5c21811462933dd17a5328075b472a53ca61bd9e136701571e529e7c4912cb565a3819473e8cb2c45e0a7b17a63f11e509d80472921e86f92fabe095002240b012e60bc9159383bdbf515def6c41acf180adde6913625a7b11d22c04a21962ecdcb1b679168cc14899e2912f233ed37d116cbde2110af4861ca847018951f8d71a369874541390d23df3cf9e5031655d4e7af4affdda5ec50fb5b633ac619c06ff0312901dc9d949ddb443ded5f59662788c101859ed0cab1782bd118c15612ab18ecaeeb9226a0145c0c1d01428987b8a5523c6da78e015261c22b6d73323e863964a003fb93594743f70e9248ed6898776780a7f3ae7a41b07a0d873b1ece5c55c6c942a7c7249c3d9026fcc607a68fe6e73cd4a76a6821f86065d5e87ffecc2c47bbd85658eb21bbdacdb79f23b031a8c6df93e64574c06eb93cb065183692c4ae4dff2efd51615d926782da50054e4a280c5bafb913d02369aa17493b4fccafbe637b1b7c9e1225e7b6fb24720f778548e304e7617b407e83fd6e3da09599850d6399059fadd57c4fadb492f59ad3adb4783ccda65272f190a9ca862a6d9508d9b2513edecf47aaa4fdc7a64127dcccbe64b7f206d400148ee9fc305099c6a7334452f25473a58edc7161895ab52e3590ea600e2e885010b062ce0df9974072bf87f5a1c8072df23e612b254b688084b5958314efe190bb6fb66657b45e6f81fa7c5fd41004f815ffd08ec00cb46ced2b1f97b04e69b"), - Bytes.FromHexString("03d333c171b569f9721355f4b5f9569c18006d55ea805d0ab72f392e6e6be88e230688a302d20e6934bc1151bf8a0af65d4294568f5af0b041197aaec74aabea1aae25b6edb4994684b2877875575b74c14a19eb068d429accd0bbbcd4de1d110b2f112b63197fcaa10a2afb08cd221bd509c829efecdd4a3bade00bf947cc3911796bc946a8148ce73aa901e2e1f4dcb259b11ee880e088ddff65f5f6f05d441ae8c9a28a7ee1d483dc47235e16e19303455ee1b7c6c29fdff01d3eab2c4e77284e25e7b8203b7b40dbf1bfcdb4fbdedea474fd44ed67dab27a031959453e9b0010adb1d55c492437f0bab7e1b63a56467681f06a29aca6ab95d29d5fd23c3529e107847478c3dd0aeb69d6c4345dd0239ba105a1bddc699512e027bbb34b81111903892d003d32111610c7ccd4c529f75cc8bf33a894f40756510ec8b9bcfd0402b66e82c6b8fd6de9652d5c81821f69445b0dca7cd052e1811760803f778a1ae8318c37a3652bdcab122282e95dd3f7393b3214e8ce290c01c9345ce81d1c09304eb9899baa26aa963503f8a55ed2a5d0cc2d5d0fbdfae81c3a823790d2371874cf1b2e447a896844c5338098f2ad9dea545e40d5f5a4369125d95fcd5acf0c0ffafa0ba1c1053fdc155d63329f5d8540fe5c6a876793e04913a1e6a7c88815fe284d364a500612c376e7bd39a466e1b9c4c0a85b105d15a973db33a0f1d42ee64373074312ec2147daed5fbc660ff99664dcb993750af8f192ee51b849a51d9a24c4dbe4f69715d00e8ede2f32c2a54c5e8f8a57487cf80dad49915cdc18239b7847b2fe9c17f926ad11e5161802872b6607265d5bf10c737d9eb157506c05725034e5c2a941efb693478b4401e684afba8af20cfc14c53f66652c737ab71657a4156fc5dc9ddf2b07d05c72395c7bb98f97743c6a81dcc11d25dcf313890effb8dceb430ae9009afe11d1f00e0ec2ca627ce9c4919287a319590dfba56d1d76f3288b570588497d0e5cc88341ba9b40b8fee65f042836161d718ebba12203bab8927db4e4b4dcf9ca7f4250c61d0a055985996d04e0c76d49bc83bad37e0a1a1f642a16d95eaddfb9b7a403bdd032f07c9222813df4dda4aa3054716d7622a999ac90eaa7bbc4ec78bb5d47736aaf04f706ddcc4724776a5dc0bc39cd1a0c9c5fb89113f93dc81db66c1ca13534f16518fb0347056c08bac62a1bcd1b201516a4f52fca78d9d140d40687b093176eb90fb236c03cad3ebf57027afc11742095f3a98a957815f7b13e263a5f11bccea9f6e716e219915e9075d9c0c2a8e0260e553a1182aa35b5d8d710c9705010e1350c02b6a217ec61245bee22c8509810027b242574ec29b652f249774d7320612dde5ca36f20f42bb169352a568e4c14a972b4ef4a1ca49f0e4b095f77ec5929486d1a051ed3b766a40d442e8e7d3b04ebc527aedcdd807d94774c23dbf3bf2841a2a0e3272e10431a056b1fb1224d16565b2f5350a0c8bcdcc6a3a2d189cc488c6c88cf9a0bd213248f73095f4ac0116d2a932043b527cb2a7c42e329a00310c9418da803179a099418ddb9ed859b06035b9b8fa5ebdbcc460641e8af2bd20e68e62d50563672a52294cc0e94cb331287c3cc9c9b8f389de88ed033ca26234d38089a712dfac171b8c8d743c5a2560b1f5c5d64fb31d6830a6c982fc8daafcc6b2ac02ac20685e11cf211edadf2bc01f9b7d3b716110dbfcda9974d00a0e90721e9aae490f3e0ba84b55cefa94919197ef9a4b21ccef5186f0d9801a25cbb77227b2d8488fa8da35e8c70495fb6861997575cfbbc644daf21868564be6a9fbfd216b252271f08fce405355d84d49028f6c5397686e765c5157034c2ed2f92e2d11c7411613f5c60b5ee50540df6fc025a3e1aee7b30e3113afca04fa7e3949a54f65a25aa8241d5056f289c3378a72d4730731a6659294dfe163718d63cc6239d09033ba48004c52a9d55d66317b62493908d3215efe3d2cb77ff6447a971599b2df711a59395515c4cac93a0f2211fada2e1799efd65247699ffbc3b35cce7d210a61e868d3bd8abb37e20bd5afe2a628ffe54a17a274af70c3584b4f9a2e567c6ae5d5a00d14ac7ffc12d04e06a03d1fee23fa99c63fb8a760fe4794af4221f7bb7ceb194c7df2c63859c8b0329"), - Bytes.FromHexString("0bc588b9295424a643de2b40a69c9daff62305085e893ac5c5d404ad565cb89f064f181b7f3fa23a51b829fc7965ddba879c6fb6eb4935ae33756fd01a603ff006bf88db9882537afc39611a5da601b4461f23b8bcd724de1602d10ddf2400e1103d4162b724a3f59c1dde973ecd3086f599fc3fba3092a392b247ae0e555352086554bc12b5b21906ff1f5cbb8ea8065b8384364f1d75dc43fefd5be2ba6e2b1db55d47bb0e96bc45248f7d8e3576f91e6c7db1ba7bd60c36faa62286ae7b7120f8942c679c45219b38e8eacc365bca7dd43e7a5c72457b6c4ccffe1ed38fff28676ef29b9330535753b41464f583af98d87d9af5e453e26e5ae2b5b8900d6a2273ec96dd5d5ae35442d2a401aec95af380f6b94594495f7db684a7bd21cc7115756d01443923350e0f55d5a4572478e5bfd895af1671355dc71962d475d97e0fcbf9663bc4a5135ec00c0275fd629e2c671486523ac3cb274f3c021e434f230e9f37feb748aac515c58c6ada11cd7668939a75cfc4a641c82a88dd642fb39c1b901ae71fb85cc4a5990d19fbe23eb4ea7aeef7a07b5bd9a8628ee7eda77bbe150a9c622deca8c8505253cc14e2908bbbbf8e5cc2e812e8f7a93ef3f3b7c37f1d5fa37baeed342068aecd69557b859a833938de0192b80bb345648eb1af85481421f8a6cfe15954d7c45e82e8c192368f817e1de8a01803d6ded2d258b889c92424fe2cd68ba3328ac7b2042640ed0f9107499dad072a1170bdfc11e3999b7a177288e296a9e13a230d6d2ac704f62abd9af434cc7172468268a27b058cc6822b911b724343991820ddeb0507ba1efc64b6da9bbfb66bcc6dc1968334e59e991987ca0264f9c8da5964afb471dfcee45009ac14dd37520ec63f022ea4ecbb522c466e5b405cdca061c8e56af4864f93fc16271978deadc7bfb667b940186527218b1308f19b5f78e38826e8c0edfcb7bac067f8c412dea480afe0699e1bce28306386adad44c4dcead96aba3c6ac2b511c2050fc36c108842dc68adc692b46006c7437845b91104ce9492712dd05eddebb786e9e50965a87ad9388d375d014b162aa118ed010d6fac2133e46dacd279605ad141d548ce5f6df47f2af040c689127705a6dcefda95143ce3f33a8f1e2bb5d3a6023d7a8bb405337d07bad6e9982b7521e4e177303deba61b19a3c11675b6180e29a79f720c56c1ddc77771969918ecc306d7cf8f2d996ed438b22234436042472402e589dcebe4d4ebd56f54971f7cef6a8b3e1b08248d3f42d957cb5d73d7680167d985cd5a71d91b1e8bd5601262d2cc8102679d1e3765d15df5f020ddac2b2745b108b0d7291700dee47b7b13d6d567250f967755036b3aab4fc48fd80efed33154469ed1deeb843622138723655e3bc692b8b6c508dbd5a6b02cf7f7818224636792dc569f8b5098062fcb1343dc85466867ea7c3f0afc7e45520cbfd8fdf56a3a3679aed086a391b6af57216d573faf61d6405f3d65a897ab4a5a77d94507d8ec790300157dd57b46fe3916316960cecdef7d1af1aa631a1b74da59e4ec618405bcffc885059c3c74585b1b87f2762ee8618a229bd0da5cc35d3d3e920e1863c2babb0ca59bc19597b8200f579d17c5c51094be0e8c425f3cce12e814ca719411c869863d14e1750bba991e0f1d9766b2dc000b3c7451093e5f3293a3c9d36bcafd092d5a19224484ce9100d9659a9571a96dbedb8073a218101ed8f5d224d0b11ca2c898a2b05368adbf2f27181e8fc713173cc3655a599ba70f25ffaf2f29a803d2f58145b6e25327851b55391c39fb460487972b6c817e566c9bc35cbdfa6a89c4643ec632000828ba17530c62524376df313c12934b1745e14167666d4147764280ae0f6ab03c2d4f04f0f5d5ff2e39df860b936e87569da2287a7fcc00e9eca8c9860ece79ddced50c566c803192d5f6863d56d83d10e49dcd60d34555b23d7ef607bbb9a5531b390d9b2016ec136313cb56354fc69c2c97cbf5afd99bff85948e6e730cd37f6cf819fcb2230faca93dc6de50b15aa3dcde0f7d0864056c7ccc11c01b61058a483109171498c1064ca213a3305f1ff0a2861aaff3646bc6a8c8c71804874714881f2a8aefc2aa3e7c8fce2741f292cdac86484aa567e188ee8a908aa5acfaf0dbbc"), - Bytes.FromHexString("2685aea6edddbd98ca03c2df477608e71c613e56d9817eb504fd4646d5699f8c266d709c3621b8da9d775d325bd8b916e112f456067cc94c3cdaefd1363ae58d0f238e6e421f1e1a80659b3f3d53c82da29dcd92c8f3e7f5cd6d144264c962e60f0e5f7beee4ab3ca6c225dfcd70cb1dacea4fb1c11efcd92a9bfd000f20385d0c507168460ff0ae1f4a3f4d4d40c2bac5f44e18eb22f961d62817a542ff63111ec38e34e8c84f6b8aeb81ab4d04f44178977880ad50136de60a1d62f3b4fc9407245d2ec4baf533022981fbe51d195b64d3fbc15db7d356f6bd96e425672fa3183cba898f86a37b5f236e41e4938fb5badbfcb19a929fb0b0a945d557d9ba4f0bfae5037583fed3a2d1b726b9f5352a512d1c35ee7e8997aa57b0be6a07b3220aeb130f7f24d035942c0b51ae34ad675041dd89d49c0854aa29036687872f9f105a80888c3259e1ab38ac878b95449da892c2424c0b73a32a4bfd6c1fc2b035166da5e9e14dd821a2bda674e8fbc7edb1c8e1edf32a7fc1a57c5a0583f888460ae28b4c49f27952ca34d10e87fba821e197b891224167a5accfff0a2d6835ca0517e1a590ba9c9f6a14a0b105a34bb5d38df06fe6c87ad79b5902445dcec7d824ac886acc6b9e4405b69d9650e76e92eafd8cd4c670d0eaf4b87894b775221c105c4529534d44bfc6df876cd3f64b459730aaa58f02daabfd425016db382dd12c241b2ae39e4730028739a266d7428bb0f186b0177a5151d821aba508d907ac1ba083d662d28d081508cc46353bd659898905e68ba2d8291da61ab408ac83462f96a39797f8f6957f9994c9e83022ffcb23487eeb10fa010f62467449b1db9b29cf62c0d6b266473eb0bd57accde054bec7804cd87c63b4cea3d9ef688c2076300d74c7b5d90044fed0a3e144ca22f49fd0f519d7f9133f4afe84ed531b8e5c151fba2c92ef82b4974906eaed202eca91413bbef2c19408110d86ab097369a8128a72e0ee836a38fe369c34ab28832467ca7e7da305c7f1734db29dbf5ddd1d2eff09551ac5d3fe228c9cab77da07fbaecb7a4344847b7172858963a81c1cc92ba8f8505e4001622b17c3324a74f572f7905655a37c63dbf2b1e178378c9fb31468feaeb5aef9dd81159a28c201ec816b0bf2358d5eaaf2994f79d945e9f9f22f5b9427cf97e32fbbc4ce9f9bc8b203b5ce92a13388719701140ab94b927d261e807c4698e5ae5b179fd8bb17ee8ac91d6a071c09885c5fbf27529cec212fe8075e75c52a3598f787a261bb7281750b87fe125ea914a2ad8bd77ad60b5994101456c38d0b29c7c9d5251dee44c53ce5c1e06ec623041469154939fca1497a2b24aa5766645e993d87c143ac92f67bd241ee71f36fad6359b04ef25d1e106003161e7e243a350dddd4e5e71f3d260498acfe2da15ac92e024ec7f420dc323b111c0704235cea83ef84cbf533f0b559302ebaf637df3f4d8b68328fad9501355b00a96d3df4f329e4cfcb81daefa893d65caa287cdb330844d31fdc35aa824f8f01b9d722f2ca441ed789275d21ceca9f8b4ad5a2c64d1467519e364ef77bec63054ce19859936c36a5c396cedfae169291b3a2d8d005fed1e4b104f991914fc61b0215a5d38e3bad0ace8354013e8b6ebe73d96fdce88d550953235643111bde05ec8fd2737015151f523cb38a6baa918a4c98e6f955eb2805ede92b82292986061700c3e0189d210d3fb0b4a3bd09bfa0a00241b386394b4e10fe3d480f6c4922823fd2cf9d6134fa302cab2b1fab5957bf6fc7dc4268d5ec0fdab9bf854cf01b07d712153db5c2cef41f822eedb1ec8b86528fb59a12b9362f406c784c55c32b3d0294f737850b94d2ae395964456e19e826fb958730c06e01de0f7f4c3ba9243d95d6a537132236597b565b60453d6ea32c75afb2d875c305661b30ca22f615014ffd20951f8ad3096b7f66eadb520ff3dcab6c86f8fa58f8d486fb0e7c1c2386a1d6047b8807b70d436be59291dd8263a1f3ae9813355f2fbe58010f67d20f576105e2efb422ca422c015e9394e16e484b6ba6da85746f121888b43159d61b793d3497a73545b2e74d525a1a67a201a3a0b9926a2b94d33ed7aa5b0158ff20af4b861226ba9a2c474ab446c2c9eb22f77fe0d45b8b2a810689970885f88b"), - Bytes.FromHexString("1891e8689d81bec3dadf1f9604c15044cf827e14e75defde61944ff7bcd6030b1c9d52e52a1ec18146b4eb9dfee11579a281998ec99c3828854c69edffc5cc1a1c2be993abe1a808d8adcfbb9fb05aa82c12ac5aabe25f1e45638d8f522f06c005d8941ad434d5775f021bf825f48b90d106afdc75383fb209244d52f1320ea706ea0f67d737534e83b4c371e90088517aaa2f2a663d8e20ee66fa5d96d9335f28f837eee92c44da5329976752d99b1490668677a12f6957a24e87cf06f9bf14277937b372c4dee270475b2c3950a50dd506c82a326944fb1faf73392ec5a54c22ce783eccf8f06cce6ba0c21fb0b4dc405879b8c4e8e8971df765815f9878a41c8ef188c94fed5973836a452d4d365003c8e56af3fc6effda3362c29201741005f4f78eb380df7e435060e8ca35c6453d8e4bda391e23e47d8bad4d28921a5606d86dfc9574f67d7334c2e73ddae937a36c8c59a81c3f25a3ff7336c024cfe21b86dcf0c54a5ede73ad5c313d5cf5438a1e6745b3b61b18635d3d3d5f51df5d2bc6c558c5f3346e9a400595186a9c9ded299367cfb3a0674f23f1ad0350cd251f268d166c85bca4eb0b3cf3c53bce15abcdd22e22ce0e9758a23c6ca5dc7bf9183144119ebb7d667bf302b4039bbad10ed360d3e0ed47ea273c22083d7fc62f1f5ee2f7167b517eff34f496919da38c6c35093638ec958dc251e7ffa9c173a00809cf94fada7d2fa86013db39978eb153f48c11003b37b0b772700047f4f2531895fc8b4f8b0b884014f229aa5d3f71da7438ef65c446e0b427de019cb6f37b18b768d980b9e6f007a41802ca6903b9c02894bad35e0a40c0b857ca9d9d36fa301afd2c4a0e09c76b8c2cf6e39bfb2ed74f709f4f0108f13b111a04b2411e3515b772fcc87fd59b28bb73361c203c9fcaec94adb10c921a4af2f72e5c8be6ad1626d2029044cefbcee5973de8f419f525704d7558e86bdd34502c56da56cde6282c36358df918f4065f03d107144d581ec4d0d4ded89a81f0c276e5653ab7712b2a995c15310672ba6b4431362266dc719d5cfe3b23dd83a2a34b086c18e02b045ebfda6fbb64a22a1d7709ef5f2b065ee20265d4900d004eb1936ddc3fe60f130649fb7b2ec9103636131656a7a47d161e53af88ec99797c4e8e7051d1732607d5ae2eddd9ff4b12ee5823285651ecc4cf5e6241392f72234e5e6b240575900e21d3821d0ac2c6ed2f0e0b615bf1dc36e365bd69d182733f951be4ac6fcc44116425c28405a420df7e495650d5d0f74ea7dc27ee928d8c7d5907a13416384b15eaf7c8c478da036be27d1498ae0d5beb855aae2620577d9c541e36d2ba1ea62043c1911c37372e86bd8530a0ed3dc407c769f8f248a502e719428fb9706de6289e167378b6422d0155dbbd7bd3d1b677c64746ec51316ab8f37a836110ea3e2c62da428e3a53f8e90b0cd00523d05dcb5b1c1f00bc4c66f4e8ffe62842dc26273a383e45c3e23433bdaaee67b5f685a21cb5e85f331880fe736c4642f972ff17a4a947747c14f722f3136da4a6ef86769176b96a30ac6a3d11fe16860200fe29c194cb2630c988439903421dd883caf0e05e3f82e12fd09bc0415e0814c41d1ca9c349188b686207c5acf04a3ca7c62357ac5a36edffe672b5c7856f29fba11455c3a42f6b1615d934140f1125e8f3d0a813580c49e6f668e5b7078d6b3389145fa1296893fec25354e91427e890658f8e2c558b5f22499a5afc66f8106a8d1af7bd16c15088cbb53c0f95ee9222efdb4c3ade4c08ed74d0747077bc87b86a028e52618b80c87fd7819da4433ef2d6232011f94be93a335d44854e0051008f2bb43f5e84934e286032ffbe10716fac0266c7361df4464a26a832697780089c258e55ac985a00cdb2800aa4126b748825466e4bc0dc02f2b44da5217e6f628413d728dde6aab9d4d8ac72e8eebfa6d70cc8ba05532c707dc8ad0d151e7645dd1a35debd99c840c3c31f3b9c17b7d804c1463e41e9e8d5bc2434d3e863d4893a2fd7432b507d5d1a63d09c555d506799665c144b84d13301aa04d2c68a8069c628c6747241f57eb659356042cf5ecb6f917a6ea88bf2e01a70bfcb317c7a21cd20dec788c2a74ab921d7b14fc855204725acba5cec08a5ff8e3fbc44a95c1493"), - Bytes.FromHexString("20b961c884a0ad42964edc3b580f607681058a33aee25d60f7dae9f060217ec119d77c703d1a93059a1baf9c17319ca9f1c5fb4a04855d6aedc308d9070f9769103dd1a1691e5fd39ff70241d7569c17764a3824e49664f5145f956abdd559af262f0e5677944e1834c3b5459e0bfb126d41a8afd73bfa12ee3ef45f17e81ca62dc7a825213952eb841f8942a113a5cbda01359751726ef26ce05491815806cb2bbefb942c709bb4fd01181e99ae1716ee28d0453ef725cb8ea45f7a4f93c6b3203b2360ffca610432f4d1053e633004d7a822ebd940e9a546a7d0f2038728921f1aa6348e2cb062d5e193a49d60214f2f0752fd32b57319b877958ef0f7eb9c1b32607b1f0ce57571b1c609260f757911ed8bcc3896e6c95a13655d11b6a7f929b9eabda75ba7d16a31ae4b7af7d0eb1bb349169df32fa20f4cfc959e722e0f24d21c9b7e68ef0e4e941aaffc472a7fa0b9d03b7097df3c993d108fa69d0a8b189dc5d953fcae14f53a800fa624429d2bbb94ec56f371e65dce393dc602ea2a04b4e2312aacb2061b9d55e615845b085696a908d76944bc822ca909212ac6bd05bb2fd64a97c2dd2e76b9ed90febf4fc236d4c466ab7afa4050101828fa67a02b0d987e9d5d717c8be7757e34354fc9a57198e5d8e867a8ff08b3e3020c84cc015904ec31cea03557ca10f0b7f5ea8b5215c80c01f5cc47bcac78c0d2f1f312135154f38704a2b7db3dc7c86be733e8880e07aa0712c2050627bdf56acd40482f36f73badb30e320c12bb66096c8bd7b978410dd5449f250519c6a122ceda572357aea961fec54427a6a1e6cb2d509210e0a6c049d39eefcf09191b561f361a2d372ecd78676d8180b6120c432178bf969e889d2e386ceb20642a0ab00f1c28263dfd316e344e8f9c1380b0fc5b3ce5bf524cae2978f53e6dff5c6cdf0743ee0c68b4b256d924d9635a4cfe45948e1f5c137369b47439912b113818d26e766d0ccf83a1e2015a3ac6f355345d4ab03f710bda2bf76f42eb7ae70aff6f955184031af5d2333c1dfca388231e1d78a53749973f0a6a01f8ad0018704c7db134592cdc9744ad7b88e407d0eb04696b62fd57be16c249043f670d881e8fb7573f9d0cc54a632cf9de52ee862a07e0d9dc11a3f4df8c9fcde0bc80f9fda1b8a84efb0b67884d640c14cc63211267d15a405fe9d03f9713fc79cb787934a778928b1f244b2e84e926f2d5a7e6d9a154873abd1899a7b20df25ae018279ed525e939da2333d4121573982541bb5fdd5d6570676ca6a2979f92a21a563924eaf1b2cc3c16190560061e4eaf988b117bbef2a7380429021d7190eee78b725bc42613725d2a2e3d1167ad6d74508c5322df36e614e10eedb067f8cfcb9573e9281b0b827e282d3416ccc69d13090246f223e743d077d3d167af6558cd17b8110b422b70462dfe3d677fe5a72c5125c9e67534c06a4070f0bcbd8f6a5d93a7691d63a2811e1908a4f98042938fec22a2372ff55c50d679bdb4dcef9a1ecc1dba4fbb54f6ba153aff2b0ba9da968ff1b07f22e95f4404a924ce1d68c9d4cddb10aa9680cdc2064aacfd45913bcc620e4cf277913eaa093e4b3ce25f40d1ac255f863fcf59c2066e98d7ecc5219edfdec9bdb718416fc65e1b48f3a5e33f40a459600bdf13c8144d022ace69574477c864aaa2cf989a862940f80b2c85e5737926e3fd1e18411d06df3079e19f11b85b2634cb2788caa2fa53cfca5de8888091dbd8cb73b3651e0c60e28b318329e56ce5cc18581966834f960344fe9645682b800bc138e5670f8f23befa1ac5f9caba7fca7179167d2df6ea237dee29bccc80eacabd5a51dc06f245eb13c8ba185388b1de78b300308010a551df2b5311f3ae838318d20297179bbf83449adaf1360b0b10494e299a9cc71672ce5774394144435ed65a061b230c57e56d08af54493bae064a3d94aba34faeab22b8056c9d1fd0b499bdade429c428761820248450189abe14f51cf3274aae5e2d65644e9866e1e5342faff915cc65f72d8210c6aab304b14ce4036862bef5e03cc6269ec755cad0f1bf285f0a67d6a9e5be0d4fe6e50b707331076cd11d96ea9c1c98575d21ca59083964fc06691da6e6e12b833b3b126f159d4fe2619b89bd86423b6cb9bfcb34480fa78c"), - Bytes.FromHexString("1ee25d5450b2735be0093c130b7448d1e411e1e8b7913fcb232598dddfaaa687027cdf0955348f4e55caa9d82fd5bbb38b92f60579a83ac709966683f0d9793321506909285bb1b77ba279f0490a97f2161fe1ab39f7f049c1313a9c8811884e15a20e6fcaf1c0bb0715db97d4626fcc02f7ba2ca64b784b2d4f6f51ee71a03b24732d58be9c0dc31b21e1a719031094660c11a00221284d4163228d8c3cab2e1588d6aa85a6f8ae92b8f3cba309971208f66b4d0863ee99d1d5e8fc4c96cff02dcfc369cc91404a1b8309a63ce750324264c2a70c62ff062762ffd9cac5b91a03571ba65a25d22dc4b4313271c8dd74a99fecf08d6dc8e6b51333a428984b1d1129479779b4c500a4200354648d7fbfa67c9a0cb13a3d0e6137e31ba7ff47d207e78fa56ce0c8f6f4e5f31f678a1868f2c7054f796cadb4bd888681492ebc750bec8d2972a70ed03036210e367258f5cf446378f1a21029a48b152fda72fdb6141196031b0f6bff06f6500d7813f8e2dc009f3abf8c9f9160a9cf29fe29b7c11a3d61bc9163aa0403faa3151c0830b043408955dea0cd7e9af20095f4f5763d2acc09a5367d70eb2f0ae60297138f91ab9df8f73a32690ba35abfd521c0e7ce010d36307a14a7b50309a5a73da3fc8e5b6260531b90ade6a08c01cb6ab7c933102527adf2e3b149232e6870a91fe9a0824cad125ea9f88a531a4c39e6e3860b1c2f1e41fbe9e39f018bdd240daa5e7d050b1d72a31fcbd3c57af3fe7623ff3d194460469ef83ed14d5a5dcd75533364b4c3925bb576850e8abcba7e06441f4e2839f9e57171e29052d593183c38c820ec1f54569a5739f8f028321b725b8d6c001822e194f48d5f008f5ac96d24eb40d7bae35c1f7a87bce889392201b7753924aa964b9b82cc1ed724314f55fd3bfe84a79984448e0a309dbec6f202e707000167456b1aeff780eaf36fe6e74450efcb52c0bb8dd225ce291ea32afd792d4726de9cab205db543a5a385432ca762ea52e445402e3f8532377d89b1d99e17c2272e0742d0904dc8076735cac193377a3534a15229e89605c870331e8c4a325c1ae9f4f66b3f9f6744978a7e689fcfc60691e30e53aa60076b17d09c84624a4b19392f9dfda38b2a543220172bd50eb5ec710884855168a7072e2859252a58c82706373a30c0bf2aa918c2870d43c410f52d116fcc691df9b4c4d9f15a10494e10aa74c6d7e9351528814c724757c648365a3585981200e312fd1d5609b9a49702c6cfa5525ec1bb6df19cd838bdc322938b233c080c3e4885d608028ba06b6d2865e834807335d255e605fd759b0bb6834f946a31ec742859a3d72a6da48d9803095c0ab65997de12a21edb99c4892a6c316dfea1a30c4bb8cc601ecc32f1cd2073ac7bbf3e87be5b54b946001b7ac91092cef11b3b2b0e5163c3a605876c2d0628b3e51cb8edae03423b9bddd8e83315bc96135b725525f42965d283cdd3a0184b6465341456b5ebf3885665459aed84e3cbe071324f5016a9ea977561031719dde6c423f21beeaabb44124d104c07e52ac303b44119fab1262b31b90d47ce14fc4af949f7d3e70387fb7a06f7605665c600fdf6e42017a446621fb351e91b130a080b0636f94376096d780ae1123ddb2a7c474da4028e1585206dd9e2c20a075d52d462d5a10121f7dc323a7bc0c5183f79f337b863fbe0680b158ecf81402958c671823cfdd8f2a372fb01ab9a62d2e9926a7eaca029d96672a0cdaa60591e352d8b7b64557a1f8752efd985adfadc50cb8d84a7757521961bbf43aad9b9216148f860853968329a3712dbe936eb643ee767c8c57c1c39819832e7ee4aa920c013bce746641635ea715962af491bec1d478f1164b1daff3800998ebb24c011b9731675637ecfd7282ad4e7703dffccd386472f84af4bfd1613fa124894ae006f44be7e61d498ff3d57006afe82d3255fff68c4dbc0e3ae72b961061069d3140d573447252faa1bbf6628974a8f127cc2540c6fe651c1a4537b85843bce340f8d932a56ff47605daa21e2bea8bc07ebfe9152548fba7bde2664df992583a221a9678e3e3213636f1ea195108c161f3fa7c46d09b4b64918714c33ddf8087a2fd9da39ae9f5ab723fd232f646615af7682dc44bc2a7ef3e1665fd6db5246b6"), - Bytes.FromHexString("09d599a8c97251e5d1447076792891b8de719e3fc5b7b245e35c6a8af97dbe1b1cefb6a792c978414992b8c88ead994e8fc972bd8018a40e306eb0e5578b25ca21312203a90480fc7174fba1bb4b9802c930c38aff91399e78e2c76768daff422bbd652137299ba4ebda8016f7501bbfeb6de219561d3f924693efa9acfca2b81618159fd6039f1ee36963eedec8154312d592e6e1dba89d1747c4251bdb725a0c6d546f20a8b44f4517290a078310fd1af065e8ef20ed4ff94c0fd7b7c662be143e5a3414336749caf364eefdc5e30ee73d34d9462a44e90e085851eb93c9b6206426d020f657f36fec865bfa09bc619746c238c4cfa643529eea42aff19dc52abc81b078bdca796d77c4ac57e6a248fdf370d3cd12163c474aaa46eac2cec103b3cc21c58b94796153850268f274376dd6f1a36103e6f870a4eafa452923802c6ca8c36c4a0225e4d80bb8e62aaad963cc39bf9db92e1a0f45a353c82039dd1821a59d0fd59b5d0a0362128b95414fd2479542e1afab6e8fb23e06e9a547210cab4c461a3179e2f0a15c1a20e0569590bc30c8c7344a73db5fe76341efbd2c1d24f43820586b1449eaed8c7063d4e481a1a52d0c5a318f9b69e97c35a6393b016dcb50ee485d31c090cfffa92e709dd5bdf6b94dea9a7310f0c824ba78151003ae718fdd5682ae467b0f776cfdd02db3be8d2aa9d42c88638bffdf154920121c3580c8ff773cdab1bd6a9449d8f4d0dcfd5d3e1bd55acdaed1afb96e40c0dd233eee0523e0a36b7cbba083eb2919ab0a66836dabc699f6f5864d284090cba90d02024b706a23f6d6f84681ab223b9975aa15bfc6c37c1e1d43bcf8de71b10f2321d3e00d52c53f18415f2e87cd00940a6a3234e7400e170297db9b214a596d2a6ca0984a6e1aa1433eb239c30efb32093022dc1ec379567ebe899606324afd22052844ad5cb4241203b35d930334fdcb22754475653cf6138f51677c5759d0034a7400dc24da45b5d4c63576a83f299cc60b43b186de9d8d5120d36596299502031424a44c5970eeb1090ce35d7379a0654db261594a27b7ccec8bab8db83b26534bc2216a34a20a506366d22111acbf059df2198654cd69f1e4db9cf7d4801d135d29f2973a802ab859a35550a844ecde62bdb95e86bb6e974453b5bf2d031a4f3c2aa1d0be4af8f9013414719e7b75536b3e0dbd8250fa3feacd17416de420df18f7491d891ce8c01acf25ed54d37433830a1bb5f169716b07aeb67e4e6a05ce2b0d962f82ebcc36bca7c238f9e0d83f4b731b4447b2fb6f24636aee57260f1a72ebde3694aed548f7d8e20b3f9e119260b66d095e9992ca8645292eb45b01cb4b475f8cdb3126bd428b18745e504371be364d94d482648251a0ae1bb9ae2e976e6fd23476a9181e42a874a734f7efd1dc25037765e35a92885559ef4da81af8fe9ef0615a50760d000b68bff0f102771b9cf46bed9d5ce8565a558e41700bd46d271edbcac6a253a859cb7a172a3176fe6f9eebaf752417603efde4bda114f8788c8608a32c27fb3087189d92464788c4b62525f616c8725f6abf9d4dce07b8399a0e69860301eefd202480a12e054a920ea3dca3844f6309232c61fcfb17c43e311e336f593615004ed5a4b8be2ebde42af53d5fa32a7790ca80fc234a3034f9151c43f2eea7585049b4aad29392d9e9285b011b73cf2c6af955bb236b15857fb2789ec0149c253b23f8232627bd48f36ce4e8bea688d8b64d7469b2072912fb4719cb6894a14986fc875c84c220649f3c48e3a662f4c4f8b0c259529e2b6d3696c45cd1b11f02bd752022b0e7a2599bbca90cb8290789d71bd990d18418bba1e7fca94de8833d95851c88876c42fe817d3025a5076307c85b59add5f81771cbccfaaff14f7fb8807bf88902cdc39ca0a398f8bec67971cf8b771d941204515478d4c8dd014aa27e099cad61aa267ee25fb61d23e5d33ed0e2ad08bfd60c2af2b362d35851adaf161bf289d100b65ccf2050aab6c951e44a010140914e18ceed56ed6655d046f37dd75198590f95200ada816be88cff9fb1ed2aba308c1e556fa4987309f9d3c380432429cc72e8e146a24c339c989d2266c0f1503737075913b800fedc3b85ed5060567231334467aa6104824b79ca8f99ff263fff52"), - Bytes.FromHexString("19ca1f96e3289c5656d4c10352144f657c2a89428b7d4330f1e888e3b5b4c15f0de956aa5db71cb39c88cc5ff11e8df5787040891ffab3e2322331fe4e6201b02ffe5b0350192676ee46b31b41c8eaab8ff9122487b9a86b2147b709e37824d02d129f764acabf37e490ce7db53ce2b4209312ca1ad424ebe4eb2ffdaf952a1c1d2063094e546d7e3cbdd07683995f7cbeea09048a904620710923326bf480bd2ee7a2404a0ab6a5b20587081e2f0f630fcc68a139dc635f8207585b699423471ebb4494c2132e960ecee3fefe726c9e8eb207ec6fb922848c20f07f3b6d7ba82ed48a102edf74b6c2a0c3c00047d6678cbbb864407f6760c775ab1266a81c9f2af3cb009291b217d880b7ecf3b88892fde66c985b2b35301d57d9d318401d601e6a4284a43791de04f5c26f29e2e25cb24947adca7e56e1a1ba03cbcba210873004b001fee1e9c6bcd17fdc287f3fd7d4fb0e7f9bc7cd8913037bbb6cd274c21e18b879ae003f24a516097ab114e576c31fc502205e73c1683e0cbaf5fccfe4227f0999fa8cd65d01d281d748ead19540ad1357f3d274b9436d0613bb6482ca2e483b36141dd465a809d324e89a886b3f2a5ba534b0ed5cdead910976659e400f9f0c6e1f4818f8f3ece446e040cda8d27f2f4cfa38e5afb0ca691ab8d113912bd785bb3e736b6a7afacad81a158a57da7a97b1ee82552a94dc17ea082248871902e71297e8e6e985600d8f1deecdc5451f3479e26eea5b396c5352135dc756290ef2305fd43f9275f9b6178180c0ebf3491805239d48e69098c098bde9b6b020f6e519b7863257805e6ffd912294a88711da15864cb78e502c5b7b1c634549155ac0155509b12aaba95cdd1fceb1b5495d5939ea66d3eb606d69f55f22129717993d14d3e9ff2d2f28a318be897d946db05f16e0a705846da2456158d7b98516435dab869cae65a3c9ac4014e52bff7cf183dc4d82706c2ca79104e79aa37b04c3eac831729d837db141e3c7240a766af3fefd712513d9b7704e296ba3c66d2f5546d9a6e362e67593a4ff76ced1767499f61a0aaa35c9adc86e38c046fb0c1d550a18938b0b632ea33b06861bf18aa759f7d19948f4c24789908e40109c6d0ee52be9aa3f2c00131231041c97b788f3d548f8b28bad245a8d744a57bf5c9b137ca7b30ae3f2c8ae8fd3e84e2b8a4ccfe1904994adea9749f55ba7a9bdfef206d28044f2efdcce3ebfc443ae1d8052147eb6d42d0343c206e39292aea132250de83503b212199cf0bf67e3c2a54a54a30afe637ad5f6d74c7e0e0f4f881c1d1e05f6e8cec4135b5c008a1bb843dc3e857d52fcee2a520298bab9282ac416d30ee84e99ee78dfc286b28e60b703136a332de95908117b63c477f309b2ae97022ed6f1a54b994516164004cf5145fc37e8c4871a7055dd1668f797e6609b6d881f6794947b847bc4798f90f274abe605139ed0a8c08afdbe5fb842d7e0ad4e772cf7cb838b23413b68a82a4fd4cfd1f150cd6182df388bb9bfea8cb902ad77e108d7e448a55857369705cbe23efa58bcb60731c977443b7f3b7d78a144579b710ad1010ca4cb30c2d8e9f44f401461baf57093514172eec86e1f018971e28c8d2dd5b5b43873bc63509d967e2b30bd4bb162db4745faf47a64593bcb04c4dc342e7031b0e887aab9abfbe75f761421d85d00fa7a862eb129a79bc9a3dff1345b17b5e7516f4aabf9a49dcf75d6a53ad9420a22f793dd68d9c3aa7c942b6131fb01222d75b7a5d00f267c9bf23d1da0891520489adc3ba71e158d06e2b936a42915a91b7f99341ecbcd5f65b99e100a5d3f01031383ec05efa2ca4e8f8770283922c588ddd38c3efd160bdf296ae4aa7ba35c958fd9e2d77ab1774ec91a252906147e4d85e1493457ff7eaebb505f8522b556c4b6f487680fe918699737fc2dac2c517bf5f945c38479ceedab8ad69dfad8818d7f6986cdc40c40c7f254d837aa190518980d7b47c3078000f8fef69839a3946f26bcddce283c172a481ed4add416f39f0f0fe9c767d85d2c362ab71b74782c1cdb836a060da40adbdd3a401ee80727125b95da0ba13ce26d2dcf5e685924fca207e9600a9cdeb4a6e569638258300e435d19bca9105c292e6b1d3f4faa9c9640c014bbf0e537156e1140954609"), - Bytes.FromHexString("1fa11f66353f7a956254f3b98892d9c0f81a654f6609e0f0af13c2f8766c6f16194657ac1800e822825a05aa50d889e603dbbf4fc8e954f3b6f25fb23d5a5479142bf7baf53de4fc8668bbd4c019c0f6b7af0fec0c17ab0b107c83d25e4d18a52ef429052a9b35b41d51163583d57d79c420be96a1554051174b9ea1698878f11b36ee817c1b97813172a6418fb2937898fe7847dde90b6ff50b6b2a34cded942f593eeabb3b9d60300b894b05f78594a82af66d9117ea00224b4a21d7cf9ff51f70c6b295fa70454024594501c593b3aa26e4a93e66a0f38c3fa1d28c1612e91d631437bb2c0b4c9848a8fd19a1f8e3ac50ae338c9b516cc4049310ba4df21f287c33f63043e7e6ab5a1d13f7e759924743b9e46ded795c2c5ab93a909a3f7315530c731d9ba3398de10f401474f70944267f7ae20d0721edb0c0d48aacdfb501132d8f620cf839dfb326b07e46879ef281630486e202f6a5b3ee25d7bfa5d80e850b940cb4236be15cff7fa6f0afe97d4074d08cc84e9fc2c3af23892d61b63026dba27ff40c376fbe12ba44f231cb58178d22dcdf94e555a0fde0266d30002dab14694741bbac573bd15720b01915261df1442a03b424fbeea31b9f525c090ba172060641818b4c8221b8e01aab9788bb736e262e18f179221f6db532bae8058c38b8572443b8e87233d95e71b98acb2c946f149becc8ce8f259a89bffe962917050d74536bb197c472473578db35d84baa6c6ae9f9b436f0be637300423f198a1c23d945422603b6867cc421baac70d469d72d81380292e07297df63b5c01d61214817267145a6b0aea09a9bf2159d7360c4a7eb0a8c28a7e455c8ea3b540b5fc38fa57a56e8987689e52dc7ca0342c83789b8cb5717473014e1802469d01ca6d73befee617ad1012a1aeec56bc4d85e5f9fa8c98a49640c3543752250e921ef6447d718c318e7375b8903222b36ca85554932dcde661bd0e757a2037f4a1ab9425315926458a4e98d280cc10ed597c6c1af13de72471b52bc15d998d3232d2d849b0f73599c8ef253dda011b06a0f5c7fca436be16db5a6c389fb9cebbe0cf834015436d91dee19a986853c38160ad423bf52b4131487b5dafabece4d352e5dd076ceae35ef158c4b8016d3e4358c5e00a6d6fba7b3e319af57cfb7eeab1b64d4fd598ff6ebc85bf4e00445567736905d23864b42926019dcb0d924e90113ab53b025ba35c881dcf5a659f07632d4afae70d36c2cc547fb18898eca81401dba824b34f4ca6aef0edafa43b22378182199c62f74664f8bd35ab7836b318526669195ff4f5ce7fbad03d22789113e2328e4c4e49e3d81c78384315490295817075dbe3988e067faf0e1b4a9341a202e2616676282e029960b4ca852f528ed0e3f852bd6074625bfd6f46948973ac6ddf8fd1fa87a304eae65a6b2a53d50ea05db05521cfe31ec72869bcdfeb019276208720a0d33ee2ca8ab00ec09099e9c235971953f2ad06d4df01028cbe0f6449758345cb1d4ae4bedb642f84ca9e69e21eb1b1d639939504d29f7649423a34e9ddd3fc1e1648d3a6f717af7efd47f841696819248f6d189b54becec21119346431546391cba18e4badd3660cfba53a91c3b2218293d03778fafeff37c2ea71c3bb6823a1eeef64065f4b45cff7169a02a9934fda95861ec8d0768bc5cad58f79d854bd32503a3c72fe40417cee1d4d81a9d1e78f93cf5cafd2362809d788176ab88c1007a69f234a60a50cd0c00857600e144962a0dd987d284313a55210246ec51f3975707719aaa3f8cf6ef757c47226a5907f5019a2d5a82cea4b790e0deb00f70646c7124b8202b5f29f26dc20a12f4430158da8c567ff51da95b9e26ec39bbaac5e32f6a3cede1f933a8b76aa805201d3367d76248671d8412345ecaf89c599e5a88b93d347ad99a6e249af4a322a73a9d41b0d5350111018c3d9987926037a027101683dc814ec07f07daa46d103731cfa07557be53f12153ae35de17d65274fcc4bd4e15ac961d837a8e68ad24b542fa29ffca7fa5d883d1413e6c8183aff268ab0b4c516d88088a0102e2fb2999edcab90a5efc1a3f78ef830660161c361cf699eab00341565881f1c374f50b5012db4af00642b53ec15a66a315cfcbeac29674c3e619870d04810bea6268"), - Bytes.FromHexString("2f5a89469bfe012ba76459c35dc24c1aaddec05eee130879f7258d71c97f03072a93777508a68599449e21e16cf2b640f0ac5256231548f2c9e50ae4ab5e2ab7164dab50c5945811423d8717b2f08c524dca34fe055110059a5bb8efefef74e41c89dcffa0b3df9389dbab8f04a89cc52d76485eb690c5a80978f41c33be93f42a7f7a7181c0431613af56e9c2d461a71c0dca94aa3e19736d8cbc3467d841db2815f183c8fb13e36b83a9a6dd99238975ee7578b4dcd316c82818ce012092902aea97784a5249ed59850e30f1d7eb74e9526ad94f5c32af18124ae5913cf456064aae479b94db0dda94455282d2a5bcffd99d5e7749d631125dee0f33c3c0c1288aae58ea8eb4202f12883fc0fcdd68822e03f63a12d6242b0087a8a1495f7c1be646ac485c0d2b972185613095e4d65cc62bcf5b3913de994b430027ea5baf0e30fec7ffcd23b4d7a6adca3c8c994e17f94c76042af6b48441963bd5b478ab11aba040f130739fce83eb9c79c4a86eb251f79152f92afe5d81602744259567095129ca02f619571508cd4f14e669bc759afdf2a98f105ee1d19cc5c8666a7b2059b1d1d6524ebee64551aff3c1c058bc84ba359a85153c6840f9fb99406e4400750e00181c4c86d88d338f58ddd60e5a5b80f83d1926b199951fd27012377c28f1e937b0867a30e1617c85e1dc0a867aa5807b719aa1496cd41acd4a3cb2991018dfefe4eb662fa1a8c892d1971077cb3b81e43c75f412bf4ff67fa9e815cd179228ad0e86867ebd465e80e0523cae366cccf230dd02b58b4dc334f76d8efc1c1657225ab3c04d3e48ef50feb4b1133655c54465ace6d5f4d9222997430e302028fe47b83ec99feb177ddd4def70f8d7c3d774e6198476216ee7d9409b159426b7fcfe50427a47af55719f445ce0ac65f6b444825fa7fb4aa602fa343ae8040e62f09e7e4fd1db2662c0087ca9782f37626d91df409123399dd5c2823268f725da972ca1fae6732cfbf12bd9e5869b5dd7ade24e58d1914de52a6e6c24df6e25c64ab46e4bc7f94167fbe9daa225946046a1261b42fa6d1de0d471ec68aa9f22401b525d3f7e9847bd13103aa28e4bf2e1f47a545f3f7cdcf1621fd9c50cc10f0a2bb7c52925b718b23d79422d7990c7273427262817896b3aaaca889ded820c917c1610cdfcc5821b58b4aea58c86d5793d520d9d8da0a26503fed44591a409f0a9eb7fe6a724ac3f3f7e156c549fa4b51fd0a05231f3fc26b3754ef8aa031a9235db06ff5857739b5ac772d671f809e865cd6d9549bb2f4372f194ee2db50e8e538da6c93dc08c2e85e029c1bfaf6132f18723c06bda51310ef1b746078a2a81296acde9cd3c2de9c5085d319a33d367fb2d19db1b610a376087d1d4596b22909b27282665c97809407bce99fea04e3ebb87e95e0df79e41d67857447f71018c7682174152456cd66cdd61175e8d139985b502ef4a4730334311d794a9a219b49ef5a08c7d3e6b4142a36591873fe04e3f6c218982bb9a7892d8edfb33d90c10f844fde21c32be49991aff39b1c5d5a0875f0ca696b016821fde000d76711b26c07ccd8f5fb96f3a5a5be4d92116c5a786f1f0f762029fb04ad749802df01b91fe1767d07ad8d6fc7b12dacc12c1e0dd32301b60f5579b2e13d751ea08d620421abc8a1bf2246e62468498a1550687dffd7e15c5e7a74fa55b81d5bdeeb6236265d34c29d7d7ff5cbdf071e6489a784e75ed652aba5814530dc2fe2a065c299c3011037f4aec635d14bd3c9a6113b7411d745cdbe920133008642310a3231c7acee4ae528f9cbd2aa8e73f7fdc37067fa7eac6ba22d4bb9b40b96fde7d371d47cd1b8dbc4d5d4a8bf2b60721b9c1b21cb53e268751ec7212804ad98355dc12f7c8d64a99628ac80dac6acbe0b16220fa9ddba015ba16f06c8c57ccfd506418ebdf0ce1738762d3505949ffea9427406d55605b54d05e1c8f1f63cc760f7818f76c8f1552dd6e7572c2e2e84e7ecc83febedf5a789977325ab2fea33a61140baaa1f9d64fb647b4ed54db970b32eb9aec6aba90e6e8ad68b2293e39ef6768074635c4e095ae39e6374b99a6abc4e89155d6e1c5a0a135703c5be082fd44d715060535996f9642fecc139d06a140f8f78b100099740dc0325156b43727224a"), - }; - - for (int i = 0; i < inputs.Length; i++) - { - byte[] cloned = inputs[i].Clone() as byte[]; - IPrecompile precompile = Bn254PairingPrecompile.Instance; - _ = precompile.Run(cloned, MuirGlacier.Instance); - } - } -} diff --git a/src/Nethermind/Nethermind.Evm.Test/CodeInfoRepositoryTests.cs b/src/Nethermind/Nethermind.Evm.Test/CodeInfoRepositoryTests.cs index 8f651891ea6..a4f13f23deb 100644 --- a/src/Nethermind/Nethermind.Evm.Test/CodeInfoRepositoryTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/CodeInfoRepositoryTests.cs @@ -3,23 +3,18 @@ using Nethermind.Core.Crypto; using Nethermind.Core; -using Nethermind.Crypto; -using Nethermind.Logging; -using Nethermind.Serialization.Rlp; using NSubstitute; using NUnit.Framework; -using System; using System.Collections.Generic; using Nethermind.Core.Test.Builders; using FluentAssertions; +using Nethermind.Blockchain; using Nethermind.Evm.State; using Nethermind.Core.Specs; using Nethermind.Evm.CodeAnalysis; using Nethermind.Core.Extensions; using Nethermind.Core.Test; -using Nethermind.Db; using Nethermind.State; -using Nethermind.Trie.Pruning; namespace Nethermind.Evm.Test; @@ -69,7 +64,7 @@ public void TryGetDelegation_CodeIsNotDelegation_ReturnsFalse(byte[] code) IWorldState stateProvider = worldStateManager.GlobalWorldState; stateProvider.CreateAccount(TestItem.AddressA, 0); stateProvider.InsertCode(TestItem.AddressA, code, Substitute.For()); - CodeInfoRepository sut = new(); + EthereumCodeInfoRepository sut = new(); sut.TryGetDelegation(stateProvider, TestItem.AddressA, Substitute.For(), out _).Should().Be(false); } @@ -97,7 +92,7 @@ public void TryGetDelegation_CodeTryGetDelegation_ReturnsTrue(byte[] code) IWorldState stateProvider = worldStateManager.GlobalWorldState; stateProvider.CreateAccount(TestItem.AddressA, 0); stateProvider.InsertCode(TestItem.AddressA, code, Substitute.For()); - CodeInfoRepository sut = new(); + EthereumCodeInfoRepository sut = new(); sut.TryGetDelegation(stateProvider, TestItem.AddressA, Substitute.For(), out _).Should().Be(true); } @@ -109,7 +104,7 @@ public void TryGetDelegation_CodeTryGetDelegation_CorrectDelegationAddressIsSet( IWorldState stateProvider = worldStateManager.GlobalWorldState; stateProvider.CreateAccount(TestItem.AddressA, 0); stateProvider.InsertCode(TestItem.AddressA, code, Substitute.For()); - CodeInfoRepository sut = new(); + EthereumCodeInfoRepository sut = new(); Address result; sut.TryGetDelegation(stateProvider, TestItem.AddressA, Substitute.For(), out result); @@ -129,7 +124,7 @@ public void GetExecutableCodeHash_CodeTryGetDelegation_ReturnsHashOfDelegated(by stateProvider.CreateAccount(delegationAddress, 0); stateProvider.InsertCode(delegationAddress, delegationCode, Substitute.For()); - CodeInfoRepository sut = new(); + EthereumCodeInfoRepository sut = new(); sut.GetExecutableCodeHash(stateProvider, TestItem.AddressA, Substitute.For()).Should().Be(Keccak.Compute(code).ValueHash256); } @@ -142,7 +137,7 @@ public void GetExecutableCodeHash_CodeIsNotDelegation_ReturnsCodeHashOfAddress(b stateProvider.CreateAccount(TestItem.AddressA, 0); stateProvider.InsertCode(TestItem.AddressA, code, Substitute.For()); - CodeInfoRepository sut = new(); + EthereumCodeInfoRepository sut = new(); sut.GetExecutableCodeHash(stateProvider, TestItem.AddressA, Substitute.For()).Should().Be(Keccak.Compute(code).ValueHash256); } @@ -158,7 +153,7 @@ public void GetCachedCodeInfo_CodeTryGetDelegation_ReturnsCodeOfDelegation(byte[ stateProvider.CreateAccount(delegationAddress, 0); byte[] delegationCode = new byte[32]; stateProvider.InsertCode(delegationAddress, delegationCode, Substitute.For()); - CodeInfoRepository sut = new(); + EthereumCodeInfoRepository sut = new(); ICodeInfo cached = sut.GetCachedCodeInfo(stateProvider, TestItem.AddressA, Substitute.For()); cached.CodeSpan.ToArray().Should().BeEquivalentTo(delegationCode); @@ -172,7 +167,7 @@ public void GetCachedCodeInfo_CodeIsNotDelegation_ReturnsCodeOfAddress(byte[] co stateProvider.CreateAccount(TestItem.AddressA, 0); stateProvider.InsertCode(TestItem.AddressA, code, Substitute.For()); - CodeInfoRepository sut = new(); + EthereumCodeInfoRepository sut = new(); ICodeInfo cached = sut.GetCachedCodeInfo(stateProvider, TestItem.AddressA, Substitute.For()); cached.CodeSpan.ToArray().Should().BeEquivalentTo(code); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs index 3a41d38d74d..12724009977 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip1108Tests.cs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Specs; -using Nethermind.Evm.Precompiles.Snarks; using NUnit.Framework; +using Nethermind.Evm.Precompiles; namespace Nethermind.Evm.Test; @@ -26,7 +26,7 @@ public void Test_add_before_istanbul() { _blockNumberAdjustment = -1; byte[] code = Prepare.EvmCode - .CallWithInput(Bn254AddPrecompile.Address, 1000L, new byte[128]) + .CallWithInput(BN254AddPrecompile.Address, 1000L, new byte[128]) .Done; TestAllTracerWithOutput result = Execute(code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); @@ -37,7 +37,7 @@ public void Test_add_before_istanbul() public void Test_add_after_istanbul() { byte[] code = Prepare.EvmCode - .CallWithInput(Bn254AddPrecompile.Address, 1000L, new byte[128]) + .CallWithInput(BN254AddPrecompile.Address, 1000L, new byte[128]) .Done; TestAllTracerWithOutput result = Execute(code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); @@ -49,7 +49,7 @@ public void Test_mul_before_istanbul() { _blockNumberAdjustment = -1; byte[] code = Prepare.EvmCode - .CallWithInput(Bn254MulPrecompile.Address, 50000L, new byte[128]) + .CallWithInput(BN254MulPrecompile.Address, 50000L, new byte[128]) .Done; TestAllTracerWithOutput result = Execute(code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); @@ -60,7 +60,7 @@ public void Test_mul_before_istanbul() public void Test_mul_after_istanbul() { byte[] code = Prepare.EvmCode - .CallWithInput(Bn254MulPrecompile.Address, 10000L, new byte[128]) + .CallWithInput(BN254MulPrecompile.Address, 10000L, new byte[128]) .Done; TestAllTracerWithOutput result = Execute(code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); @@ -72,7 +72,7 @@ public void Test_pairing_before_istanbul() { _blockNumberAdjustment = -1; byte[] code = Prepare.EvmCode - .CallWithInput(Bn254PairingPrecompile.Address, 200000L, new byte[192]) + .CallWithInput(BN254PairingPrecompile.Address, 200000L, new byte[192]) .Done; TestAllTracerWithOutput result = Execute(BlockNumber, 1000000L, code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); @@ -83,7 +83,7 @@ public void Test_pairing_before_istanbul() public void Test_pairing_after_istanbul() { byte[] code = Prepare.EvmCode - .CallWithInput(Bn254PairingPrecompile.Address, 200000L, new byte[192]) + .CallWithInput(BN254PairingPrecompile.Address, 200000L, new byte[192]) .Done; TestAllTracerWithOutput result = Execute(BlockNumber, 1000000L, code); Assert.That(result.StatusCode, Is.EqualTo(StatusCode.Success)); diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip2537Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip2537Tests.cs index 90936510c1a..9a079cd770c 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip2537Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip2537Tests.cs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: LGPL-3.0-only using NUnit.Framework; -using Nethermind.Evm.Precompiles; using Nethermind.Evm.Precompiles.Bls; +using Nethermind.Evm.Precompiles; using Nethermind.Specs; namespace Nethermind.Evm.Test; diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip2565Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip2565Tests.cs index afc87008b9a..14e715eb990 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip2565Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip2565Tests.cs @@ -3,10 +3,12 @@ using System; using System.Linq; +using System.Numerics; using FluentAssertions; using MathNet.Numerics.Random; using Nethermind.Core.Extensions; using Nethermind.Evm.Precompiles; +using Nethermind.Int256; using Nethermind.Specs.Forks; using NUnit.Framework; @@ -25,13 +27,12 @@ public void Simple_routine([Random(int.MinValue, int.MaxValue, 100)] int seed) string randomInput = string.Format("{0}{0}{0}{1}", Length64, data.ToHexString()); Prepare input = Prepare.EvmCode.FromCode(randomInput); + byte[] inputData = input.Done.ToArray(); - (ReadOnlyMemory, bool) gmpPair = ModExpPrecompile.Instance.Run(input.Done.ToArray(), Berlin.Instance); -#pragma warning disable 618 - (ReadOnlyMemory, bool) bigIntPair = ModExpPrecompile.OldRun(input.Done.ToArray()); -#pragma warning restore 618 + (ReadOnlyMemory, bool) gmpPair = ModExpPrecompile.Instance.Run(inputData, Berlin.Instance); + (ReadOnlyMemory, bool) bigIntPair = BigIntegerModExp(inputData); - Assert.That(bigIntPair.Item1.ToArray(), Is.EqualTo(gmpPair.Item1.ToArray())); + Assert.That(gmpPair.Item1.ToArray(), Is.EqualTo(bigIntPair.Item1.ToArray())); } [Test] @@ -51,5 +52,37 @@ public void ModExp_run_should_not_throw_exception(string inputStr) long gas = ModExpPrecompile.Instance.DataGasCost(input.Done, London.Instance); gas.Should().Be(200); } + + private static (byte[], bool) BigIntegerModExp(byte[] inputData) + { + (int baseLength, int expLength, int modulusLength) = GetInputLengths(inputData); + + BigInteger modulusInt = inputData + .SliceWithZeroPaddingEmptyOnError(96 + baseLength + expLength, modulusLength).ToUnsignedBigInteger(); + + if (modulusInt.IsZero) + { + return (new byte[modulusLength], true); + } + + BigInteger baseInt = inputData.SliceWithZeroPaddingEmptyOnError(96, baseLength).ToUnsignedBigInteger(); + BigInteger expInt = inputData.SliceWithZeroPaddingEmptyOnError(96 + baseLength, expLength) + .ToUnsignedBigInteger(); + return (BigInteger.ModPow(baseInt, expInt, modulusInt).ToBigEndianByteArray(modulusLength), true); + } + + private static (int baseLength, int expLength, int modulusLength) GetInputLengths(ReadOnlySpan inputData) + { + Span extendedInput = stackalloc byte[96]; + inputData[..Math.Min(96, inputData.Length)] + .CopyTo(extendedInput[..Math.Min(96, inputData.Length)]); + + int baseLength = (int)new UInt256(extendedInput[..32], true); + UInt256 expLengthUint256 = new(extendedInput.Slice(32, 32), true); + int expLength = expLengthUint256 > Array.MaxLength ? Array.MaxLength : (int)expLengthUint256; + int modulusLength = (int)new UInt256(extendedInput.Slice(64, 32), true); + + return (baseLength, expLength, modulusLength); + } } } diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7823Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7823Tests.cs index 9da085fea3c..578e214fbbf 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Eip7823Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Eip7823Tests.cs @@ -6,9 +6,9 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Nethermind.Evm.Precompiles; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; -using Nethermind.Evm.Precompiles; using Nethermind.Int256; using Nethermind.Specs.Forks; using NUnit.Framework; @@ -60,8 +60,8 @@ public void TestInvalid(string inputHex) byte[] input = Bytes.FromHexString(inputHex); - Assert.Throws(() => TestSuccess(input, specDisabled)); - Assert.Throws(() => TestSuccess(input, specEnabled)); + Assert.That(TestSuccess(input, specDisabled), Is.EqualTo(false)); + Assert.That(TestSuccess(input, specEnabled), Is.EqualTo(false)); Assert.That(TestGas(input, specDisabled), Is.EqualTo(long.MaxValue)); Assert.That(TestGas(input, specEnabled), Is.EqualTo(long.MaxValue)); diff --git a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs index 443ec8916b4..5039a34eb8c 100644 --- a/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/EvmPooledMemoryTests.cs @@ -9,7 +9,6 @@ using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; -using Nethermind.Db; using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; using Nethermind.Int256; @@ -17,8 +16,8 @@ using Nethermind.Specs; using Nethermind.Specs.Forks; using Nethermind.Evm.State; -using Nethermind.Trie.Pruning; using FluentAssertions; +using Nethermind.Blockchain; using Nethermind.Core.Test; using Nethermind.State; using NUnit.Framework; @@ -152,7 +151,7 @@ private static string Run(byte[] input) IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); IWorldState stateProvider = worldStateManager.GlobalWorldState; ISpecProvider specProvider = new TestSpecProvider(London.Instance); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new( new TestBlockhashProvider(specProvider), specProvider, diff --git a/src/Nethermind/Nethermind.Evm.Test/ILEVM/IlEvmTests.cs b/src/Nethermind/Nethermind.Evm.Test/ILEVM/IlEvmTests.cs index 31e1eaade1c..a116bffc7a6 100644 --- a/src/Nethermind/Nethermind.Evm.Test/ILEVM/IlEvmTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/ILEVM/IlEvmTests.cs @@ -1862,6 +1862,7 @@ public void Execution_Swap_Happens_When_Compilation_Occurs() IlEvmEnabledMode = ILMode.AOT_MODE, IlEvmAnalysisThreshold = 1, IlEvmAnalysisQueueMaxSize = 1, + IlEvmAllowedContracts = [], }, Prague.Instance); byte[] bytecode = diff --git a/src/Nethermind/Nethermind.Evm.Test/ILEVM/PrimFibbTests.cs b/src/Nethermind/Nethermind.Evm.Test/ILEVM/PrimFibbTests.cs index e4ac562419c..bdada4f17cd 100644 --- a/src/Nethermind/Nethermind.Evm.Test/ILEVM/PrimFibbTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/ILEVM/PrimFibbTests.cs @@ -199,7 +199,11 @@ public void EquivalenceTest(UInt256 number) { var bytecode = ResolveBytecode(Number); - IlVirtualMachineTestsBase standardChain = new IlVirtualMachineTestsBase(new VMConfig(), Prague.Instance); + IlVirtualMachineTestsBase standardChain = new IlVirtualMachineTestsBase(new VMConfig() + { + IsILEvmEnabled = false, + IlEvmEnabledMode = ILMode.NO_ILVM + }, Prague.Instance); Path.Combine(Directory.GetCurrentDirectory(), "GeneratedContracts.dll"); IlVirtualMachineTestsBase enhancedChain = new IlVirtualMachineTestsBase(new VMConfig diff --git a/src/Nethermind/Nethermind.Evm.Test/ILEVM/RealContractTestsBase.cs b/src/Nethermind/Nethermind.Evm.Test/ILEVM/RealContractTestsBase.cs index ac3ff85b283..f2ca6f2a0a4 100644 --- a/src/Nethermind/Nethermind.Evm.Test/ILEVM/RealContractTestsBase.cs +++ b/src/Nethermind/Nethermind.Evm.Test/ILEVM/RealContractTestsBase.cs @@ -60,7 +60,11 @@ protected RealContractTestsBase(bool useIlEVM) } else { - _config = new VMConfig(); + _config = new VMConfig + { + IsILEvmEnabled = false, + IlEvmEnabledMode = ILMode.NO_ILVM + }; } } diff --git a/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=FibbBytecode_number=43_result=701408733.verified.txt b/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=FibbBytecode_number=43_result=701408733.verified.txt index 2e74095c61e..b7881b10ce7 100644 --- a/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=FibbBytecode_number=43_result=701408733.verified.txt +++ b/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=FibbBytecode_number=43_result=701408733.verified.txt @@ -20,8 +20,6 @@ brtrue.s j3 ldarg.1 call Boolean get_ShouldJump() brtrue.s j1 - -j7: ldarg.0 ldarg.1 call Segment[17::31] @@ -30,7 +28,7 @@ ldarg.1 call Boolean get_ShouldJump() brtrue.s j1 -j8: +j7: ldarg.0 ldfld Nethermind.Evm.EvmState EvmState call Boolean get_IsStatic() @@ -77,11 +75,8 @@ ldloc.0 ldc.i4.s 11 beq.s j6 ldloc.0 -ldc.i4.s 17 -beq.s j7 -ldloc.0 ldc.i4.s 32 -beq.s j8 +beq.s j7 br.s InvalidJumpDestination StaticCallViolation: diff --git a/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=FibbBytecode_number=5_result=8.verified.txt b/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=FibbBytecode_number=5_result=8.verified.txt index 2e74095c61e..b7881b10ce7 100644 --- a/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=FibbBytecode_number=5_result=8.verified.txt +++ b/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=FibbBytecode_number=5_result=8.verified.txt @@ -20,8 +20,6 @@ brtrue.s j3 ldarg.1 call Boolean get_ShouldJump() brtrue.s j1 - -j7: ldarg.0 ldarg.1 call Segment[17::31] @@ -30,7 +28,7 @@ ldarg.1 call Boolean get_ShouldJump() brtrue.s j1 -j8: +j7: ldarg.0 ldfld Nethermind.Evm.EvmState EvmState call Boolean get_IsStatic() @@ -77,11 +75,8 @@ ldloc.0 ldc.i4.s 11 beq.s j6 ldloc.0 -ldc.i4.s 17 -beq.s j7 -ldloc.0 ldc.i4.s 32 -beq.s j8 +beq.s j7 br.s InvalidJumpDestination StaticCallViolation: diff --git a/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=PrimBytecode_number=40001263_result=1.verified.txt b/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=PrimBytecode_number=40001263_result=1.verified.txt index 2e74095c61e..b7881b10ce7 100644 --- a/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=PrimBytecode_number=40001263_result=1.verified.txt +++ b/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=PrimBytecode_number=40001263_result=1.verified.txt @@ -20,8 +20,6 @@ brtrue.s j3 ldarg.1 call Boolean get_ShouldJump() brtrue.s j1 - -j7: ldarg.0 ldarg.1 call Segment[17::31] @@ -30,7 +28,7 @@ ldarg.1 call Boolean get_ShouldJump() brtrue.s j1 -j8: +j7: ldarg.0 ldfld Nethermind.Evm.EvmState EvmState call Boolean get_IsStatic() @@ -77,11 +75,8 @@ ldloc.0 ldc.i4.s 11 beq.s j6 ldloc.0 -ldc.i4.s 17 -beq.s j7 -ldloc.0 ldc.i4.s 32 -beq.s j8 +beq.s j7 br.s InvalidJumpDestination StaticCallViolation: diff --git a/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=PrimBytecode_number=8000010_result=0.verified.txt b/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=PrimBytecode_number=8000010_result=0.verified.txt index 2e74095c61e..b7881b10ce7 100644 --- a/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=PrimBytecode_number=8000010_result=0.verified.txt +++ b/src/Nethermind/Nethermind.Evm.Test/ILEVM/SyntheticTest.Verify_useIlEvm=True_benchmarkName=PrimBytecode_number=8000010_result=0.verified.txt @@ -20,8 +20,6 @@ brtrue.s j3 ldarg.1 call Boolean get_ShouldJump() brtrue.s j1 - -j7: ldarg.0 ldarg.1 call Segment[17::31] @@ -30,7 +28,7 @@ ldarg.1 call Boolean get_ShouldJump() brtrue.s j1 -j8: +j7: ldarg.0 ldfld Nethermind.Evm.EvmState EvmState call Boolean get_IsStatic() @@ -77,11 +75,8 @@ ldloc.0 ldc.i4.s 11 beq.s j6 ldloc.0 -ldc.i4.s 17 -beq.s j7 -ldloc.0 ldc.i4.s 32 -beq.s j8 +beq.s j7 br.s InvalidJumpDestination StaticCallViolation: diff --git a/src/Nethermind/Nethermind.Evm.Test/ILEVM/USDCProxyTests.Verify_useIlEvm=True.verified.txt b/src/Nethermind/Nethermind.Evm.Test/ILEVM/USDCProxyTests.Verify_useIlEvm=True.verified.txt index eb84eb0d19a..b7881b10ce7 100644 --- a/src/Nethermind/Nethermind.Evm.Test/ILEVM/USDCProxyTests.Verify_useIlEvm=True.verified.txt +++ b/src/Nethermind/Nethermind.Evm.Test/ILEVM/USDCProxyTests.Verify_useIlEvm=True.verified.txt @@ -2,966 +2,42 @@ ldobj Nethermind.Evm.CodeAnalysis.IL.ILChunkExecutionState ldfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState ldc.i4.2 -beq j2 +beq.s j2 j4: j5: ldarg.0 ldarg.1 -call Segment[0::12] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j6: -ldarg.0 -ldarg.1 -call Segment[13::64] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j7: -ldarg.0 -ldarg.1 -call Segment[65::75] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j8: -ldarg.0 -ldarg.1 -call Segment[76::86] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j9: -ldarg.0 -ldarg.1 -call Segment[87::97] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j10: -ldarg.0 -ldarg.1 -call Segment[98::108] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j11: -ldarg.0 -ldarg.1 -call Segment[109::116] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j12: -ldarg.0 -ldarg.1 -call Segment[117::118] -brtrue j3 - -j13: -ldarg.0 -ldarg.1 -call Segment[119::126] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j14: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j15 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j15: -ldarg.0 -ldarg.1 -call Segment[127::130] -brtrue j3 - -j17: -ldarg.0 -ldarg.1 -call Segment[131::183] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j18: -ldarg.0 -ldarg.1 -call Segment[184::185] -brtrue j3 - -j19: -ldarg.0 -ldarg.1 -call Segment[186::261] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j20: -ldarg.0 -ldarg.1 -call Segment[262::263] -brtrue j3 - -j21: -ldarg.0 -ldarg.1 -call Segment[264::271] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j22: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j23 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j23: -ldarg.0 -ldarg.1 -call Segment[272::275] -brtrue j3 - -j25: -ldarg.0 -ldarg.1 -call Segment[276::284] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j26: -ldarg.0 -ldarg.1 -call Segment[285::350] -brtrue j3 - -j27: -ldarg.0 -ldarg.1 -call Segment[351::358] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j28: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j29 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j29: -ldarg.0 -ldarg.1 -call Segment[359::362] -brtrue j3 - -j31: -ldarg.0 -ldarg.1 -call Segment[363::415] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j32: -ldarg.0 -ldarg.1 -call Segment[416::417] -brtrue j3 - -j33: -ldarg.0 -ldarg.1 -call Segment[418::425] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j34: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j35 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j35: -ldarg.0 -ldarg.1 -call Segment[426::429] -brtrue j3 - -j37: -ldarg.0 -ldarg.1 -call Segment[430::438] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j38: -ldarg.0 -ldarg.1 -call Segment[439::504] -brtrue j3 - -j39: -ldarg.0 -ldarg.1 -call Segment[505::512] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j40: -ldarg.0 -ldarg.1 -call Segment[513::523] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j41: -ldarg.0 -ldarg.1 -call Segment[524::528] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j42: -ldarg.0 -ldarg.1 -call Segment[529::530] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j43: -ldarg.0 -ldarg.1 -call Segment[531::538] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j44: -ldarg.0 -ldarg.1 -call Segment[539::590] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j45: -ldarg.0 -ldarg.1 -call Segment[591::598] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j46: -ldarg.0 -ldarg.1 -call Segment[599::603] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j47: -ldarg.0 -ldarg.1 -call Segment[604::611] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j48: -ldarg.0 -ldarg.1 -call Segment[612::612] -brtrue j3 - -j49: -ldarg.0 -ldarg.1 -call Segment[613::615] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j50: -ldarg.0 -ldarg.1 -call Segment[616::623] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j51: -ldarg.0 -ldarg.1 -call Segment[624::675] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j52: -ldarg.0 -ldarg.1 -call Segment[676::683] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j53: -ldarg.0 -ldarg.1 -call Segment[684::742] -brtrue j3 -ldarg.1 -call Boolean get_ShouldHalt() -brtrue j3 - -j54: - -j55: -ldarg.0 -ldarg.1 -call Segment[743::752] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j56: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j57 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j57: -ldarg.0 -ldarg.1 -call Segment[753::756] -brtrue j3 - -j59: -ldarg.0 -ldarg.1 -call Segment[757::761] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j60: -ldarg.0 -ldarg.1 -call Segment[762::769] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j61: -ldarg.0 -ldarg.1 -call Segment[770::770] -brtrue j3 - -j62: -ldarg.0 -ldarg.1 -call Segment[771::775] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j63: -ldarg.0 -ldarg.1 -call Segment[776::785] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j64: -ldarg.0 -ldarg.1 -call Segment[786::837] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j65: -ldarg.0 -ldarg.1 -call Segment[838::844] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j66: -ldarg.0 -ldarg.1 -call Segment[845::851] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j67: -ldarg.0 -ldarg.1 -call Segment[852::859] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j68: -ldarg.0 -ldarg.1 -call Segment[860::860] -brtrue j3 - -j69: -ldarg.0 -ldarg.1 -call Segment[861::863] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j70: -ldarg.0 -ldarg.1 -call Segment[864::871] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j71: -ldarg.0 -ldarg.1 -call Segment[872::923] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j72: -ldarg.0 -ldarg.1 -call Segment[924::978] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j73: -ldloca.s 54 -call Boolean get_HasValue() -brtrue.s j74 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 54 - -j74: -ldarg.0 -ldarg.1 -call Segment[979::1125] -brtrue j3 - -j76: -ldarg.0 -ldarg.1 -call Segment[1126::1166] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j77: -ldarg.0 -ldfld Nethermind.Evm.EvmState EvmState -call Boolean get_IsStatic() -brtrue StaticCallViolation -ldarg.0 -ldarg.1 -call Segment[1167::1292] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j78: -ldarg.0 -ldarg.1 -call Segment[1293::1297] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j79: -ldarg.0 -ldarg.1 -call Segment[1298::1305] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j80: -ldarg.0 -ldarg.1 -call Segment[1306::1306] -brtrue j3 - -j81: -ldarg.0 -ldarg.1 -call Segment[1307::1309] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j82: -ldarg.0 -ldarg.1 -call Segment[1310::1319] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j83: -ldarg.0 -ldarg.1 -call Segment[1320::1371] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j84: -ldarg.0 -ldarg.1 -call Segment[1372::1378] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j85: -ldarg.0 -ldarg.1 -call Segment[1379::1385] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j86: -ldarg.0 -ldarg.1 -call Segment[1386::1393] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j87: -ldarg.0 -ldarg.1 -call Segment[1394::1394] -brtrue j3 - -j88: -ldarg.0 -ldarg.1 -call Segment[1395::1397] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j89: -ldarg.0 -ldarg.1 -call Segment[1398::1405] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j90: -ldarg.0 -ldarg.1 -call Segment[1406::1459] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j91: -ldloca.s 54 -call Boolean get_HasValue() -brtrue.s j92 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 54 - -j92: -ldarg.0 -ldarg.1 -call Segment[1460::1606] -brtrue j3 - -j94: -ldarg.0 -ldarg.1 -call Segment[1607::1614] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j95: -ldarg.0 -ldarg.1 -call Segment[1615::1616] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j96: -ldarg.0 -ldarg.1 -call Segment[1617::1665] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j97: -ldloca.s 58 -call Boolean get_HasValue() -brtrue.s j98 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 244 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 58 - -j98: -ldarg.0 -ldarg.1 -call Segment[1666::1680] -brtrue j3 -ldarg.1 -call Boolean get_ShouldHalt() -brtrue j3 - -j100: - -j101: -ldloca.s 59 -call Boolean get_HasValue() -brtrue.s j102 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4.s 61 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4.s 62 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 59 - -j102: -ldarg.0 -ldarg.1 -call Segment[1681::1694] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j104: -ldloca.s 60 -call Boolean get_HasValue() -brtrue.s j105 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4.s 61 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 60 - -j105: -ldarg.0 -ldarg.1 -call Segment[1695::1698] -brtrue j3 - -j107: -ldloca.s 61 -call Boolean get_HasValue() -brtrue.s j108 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4.s 61 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 61 - -j108: -ldarg.0 -ldarg.1 -call Segment[1699::1703] -brtrue j3 - -j110: -ldarg.0 -ldarg.1 -call Segment[1704::1752] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j111: -ldarg.0 -ldarg.1 -call Segment[1753::1761] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j112: -ldarg.0 -ldfld Nethermind.Evm.EvmState EvmState -call Boolean get_IsStatic() -brtrue StaticCallViolation -ldarg.0 -ldarg.1 -call Segment[1762::1863] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j113: -ldarg.0 -ldfld Nethermind.Evm.EvmState EvmState -call Boolean get_IsStatic() -brtrue StaticCallViolation -ldarg.0 -ldarg.1 -call Segment[1864::1910] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j114: -ldarg.0 -ldarg.1 -call Segment[1911::1912] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j115: -ldarg.0 -ldarg.1 -call Segment[1913::1923] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 +call Segment[0::10] +brtrue.s j3 -j116: +j6: ldarg.0 ldarg.1 -call Segment[1924::1930] -brtrue j3 +call Segment[11::16] +brtrue.s j3 ldarg.1 call Boolean get_ShouldJump() -brtrue j1 - -j117: -ldloca.s 54 -call Boolean get_HasValue() -brtrue.s j118 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 54 - -j118: -ldarg.0 -ldarg.1 -call Segment[1931::2077] -brtrue.s j3 - -j120: -ldarg.0 -ldfld Nethermind.Evm.EvmState EvmState -call Boolean get_IsStatic() -brtrue StaticCallViolation +brtrue.s j1 ldarg.0 ldarg.1 -call Segment[2078::2122] +call Segment[17::31] brtrue.s j3 ldarg.1 call Boolean get_ShouldJump() brtrue.s j1 -j121: +j7: +ldarg.0 +ldfld Nethermind.Evm.EvmState EvmState +call Boolean get_IsStatic() +brtrue.s StaticCallViolation ldarg.0 ldarg.1 -call Segment[2123::2141] +call Segment[32::39] brtrue.s j3 ldarg.1 -call Boolean get_ShouldJump() -brtrue.s j1 -ldarg.1 ldc.i4.4 stfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState @@ -981,694 +57,28 @@ ldarg.1 ldc.i4.1 stfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState ldloc.0 -ldc.i4 2186 +ldc.i4.s 40 bge.s j3 ldloc.0 ldc.i4.0 -beq j4 -ldloc.0 -ldc.i4 743 -beq j54 -ldloc.0 -ldc.i4 1681 -beq j100 -br InvalidJumpDestination +beq.s j4 +br.s InvalidJumpDestination j1: ldarg.1 ldfld Int32 JumpDestination stloc.0 ldloc.0 -ldc.i4.s 127 -and -switch j122, j123, j124, j125, j126, j127, j128, j129, j130, j131, j132, j133, j134, j135, j136, j137, j138, j139, j140, j141, j142, j143, j144, j145, j146, j147, j148, j149, j150, j151, j152, j153, j154, j155, j156, j157, j158, j159, j160, j161, j162, j163, j164, j165, j166, j167, j168, j169, j170, j171, j172, j173, j174, j175, j176, j177, j178, j179, j180, j181, j182, j183, j184, j185, j186, j187, j188, j189, j190, j191, j192, j193, j194, j195, j196, j197, j198, j199, j200, j201, j202, j203, j204, j205, j206, j207, j208, j209, j210, j211, j212, j213, j214, j215, j216, j217, j218, j219, j220, j221, j222, j223, j224, j225, j226, j227, j228, j229, j230, j231, j232, j233, j234, j235, j236, j237, j238, j239, j240, j241, j242, j243, j244, j245, j246, j247, j248, j249 - -j122: -ldloc.0 ldc.i4.0 -beq j5 -br InvalidJumpDestination - -j123: -ldloc.0 -ldc.i4 513 -beq j40 -br InvalidJumpDestination - -j124: -ldloc.0 -ldc.i4 770 -beq j61 -ldloc.0 -ldc.i4 1666 -beq j97 -br InvalidJumpDestination - -j125: -ldloc.0 -ldc.i4 131 -beq j17 -ldloc.0 -ldc.i4 771 -beq j62 -br InvalidJumpDestination - -j126: -ldloc.0 -ldc.i4 1924 -beq j116 -br InvalidJumpDestination - -j127: -br InvalidJumpDestination - -j128: -ldloc.0 -ldc.i4 262 -beq j20 -br InvalidJumpDestination - -j129: -br InvalidJumpDestination - -j130: -ldloc.0 -ldc.i4 264 -beq j21 -ldloc.0 -ldc.i4 776 -beq j63 -br InvalidJumpDestination - -j131: -br InvalidJumpDestination - -j132: -br InvalidJumpDestination - -j133: -ldloc.0 -ldc.i4 1931 -beq j117 -br InvalidJumpDestination - -j134: -ldloc.0 -ldc.i4 524 -beq j41 -br InvalidJumpDestination - -j135: -ldloc.0 -ldc.i4.s 13 -beq j6 -ldloc.0 -ldc.i4 1293 -beq j78 -br InvalidJumpDestination - -j136: -br InvalidJumpDestination - -j137: -ldloc.0 -ldc.i4 1167 -beq j77 -br InvalidJumpDestination - -j138: -ldloc.0 -ldc.i4 272 -beq j22 -br InvalidJumpDestination - -j139: -ldloc.0 -ldc.i4 529 -beq j42 -ldloc.0 -ldc.i4 1681 -beq j101 -br InvalidJumpDestination - -j140: -ldloc.0 -ldc.i4 786 -beq j64 -ldloc.0 -ldc.i4 1298 -beq j79 -br InvalidJumpDestination - -j141: -ldloc.0 -ldc.i4 531 -beq j43 -br InvalidJumpDestination - -j142: -ldloc.0 -ldc.i4 276 -beq j25 -br InvalidJumpDestination - -j143: -br InvalidJumpDestination - -j144: -br InvalidJumpDestination - -j145: -br InvalidJumpDestination - -j146: -br InvalidJumpDestination - -j147: -br InvalidJumpDestination - -j148: -ldloc.0 -ldc.i4 1306 -beq j80 -br InvalidJumpDestination - -j149: -ldloc.0 -ldc.i4 539 -beq j44 -ldloc.0 -ldc.i4 1307 -beq j81 -br InvalidJumpDestination - -j150: -ldloc.0 -ldc.i4 924 -beq j72 -br InvalidJumpDestination - -j151: -ldloc.0 -ldc.i4 285 -beq j26 -br InvalidJumpDestination - -j152: -ldloc.0 -ldc.i4 1310 -beq j82 -ldloc.0 -ldc.i4 2078 -beq j120 -br InvalidJumpDestination - -j153: -ldloc.0 -ldc.i4 1695 -beq j104 -br InvalidJumpDestination - -j154: -ldloc.0 -ldc.i4 416 -beq j32 -br InvalidJumpDestination - -j155: -br InvalidJumpDestination - -j156: -ldloc.0 -ldc.i4 418 -beq j33 -br InvalidJumpDestination - -j157: -ldloc.0 -ldc.i4 1699 -beq j107 -br InvalidJumpDestination - -j158: -ldloc.0 -ldc.i4 676 -beq j52 -br InvalidJumpDestination - -j159: -br InvalidJumpDestination - -j160: -br InvalidJumpDestination - -j161: -br InvalidJumpDestination - -j162: -ldloc.0 -ldc.i4 1320 -beq j83 -ldloc.0 -ldc.i4 1704 -beq j110 -br InvalidJumpDestination - -j163: -br InvalidJumpDestination - -j164: -ldloc.0 -ldc.i4 426 -beq j34 -br InvalidJumpDestination - -j165: -br InvalidJumpDestination - -j166: -ldloc.0 -ldc.i4 684 -beq j53 -br InvalidJumpDestination - -j167: -br InvalidJumpDestination - -j168: -ldloc.0 -ldc.i4 430 -beq j37 -br InvalidJumpDestination - -j169: -br InvalidJumpDestination - -j170: -br InvalidJumpDestination - -j171: -br InvalidJumpDestination - -j172: -br InvalidJumpDestination - -j173: -br InvalidJumpDestination - -j174: -ldloc.0 -ldc.i4 1460 -beq j91 -br InvalidJumpDestination - -j175: -br InvalidJumpDestination - -j176: -br InvalidJumpDestination - -j177: -ldloc.0 -ldc.i4 439 -beq j38 -br InvalidJumpDestination - -j178: -ldloc.0 -ldc.i4 184 -beq j18 -br InvalidJumpDestination - -j179: -br InvalidJumpDestination - -j180: -ldloc.0 -ldc.i4 186 -beq j19 -br InvalidJumpDestination - -j181: -br InvalidJumpDestination - -j182: -br InvalidJumpDestination - -j183: -br InvalidJumpDestination - -j184: -br InvalidJumpDestination - -j185: -br InvalidJumpDestination - -j186: -br InvalidJumpDestination - -j187: -ldloc.0 -ldc.i4.s 65 -beq j7 -br InvalidJumpDestination - -j188: -br InvalidJumpDestination - -j189: -br InvalidJumpDestination - -j190: -br InvalidJumpDestination - -j191: -br InvalidJumpDestination - -j192: -ldloc.0 -ldc.i4 838 -beq j65 -br InvalidJumpDestination - -j193: -ldloc.0 -ldc.i4 1607 -beq j94 -br InvalidJumpDestination - -j194: -ldloc.0 -ldc.i4 1864 -beq j113 -br InvalidJumpDestination - -j195: -br InvalidJumpDestination - -j196: -br InvalidJumpDestination - -j197: -ldloc.0 -ldc.i4 2123 -beq j121 -br InvalidJumpDestination - -j198: -ldloc.0 -ldc.i4.s 76 -beq j8 -br InvalidJumpDestination - -j199: -ldloc.0 -ldc.i4 845 -beq j66 -br InvalidJumpDestination - -j200: -br InvalidJumpDestination - -j201: -ldloc.0 -ldc.i4 591 -beq j45 -ldloc.0 -ldc.i4 1615 -beq j95 -br InvalidJumpDestination - -j202: -br InvalidJumpDestination - -j203: -ldloc.0 -ldc.i4 1617 -beq j96 -br InvalidJumpDestination - -j204: -br InvalidJumpDestination - -j205: -ldloc.0 -ldc.i4 979 -beq j73 -br InvalidJumpDestination - -j206: -ldloc.0 -ldc.i4 852 -beq j67 -br InvalidJumpDestination - -j207: -br InvalidJumpDestination - -j208: -br InvalidJumpDestination - -j209: -ldloc.0 -ldc.i4.s 87 -beq j9 -ldloc.0 -ldc.i4 599 -beq j46 -br InvalidJumpDestination - -j210: -br InvalidJumpDestination - -j211: -ldloc.0 -ldc.i4 1753 -beq j111 -br InvalidJumpDestination - -j212: -br InvalidJumpDestination - -j213: -br InvalidJumpDestination - -j214: -ldloc.0 -ldc.i4 604 -beq j47 -ldloc.0 -ldc.i4 860 -beq j68 -ldloc.0 -ldc.i4 1372 -beq j84 -br InvalidJumpDestination - -j215: -ldloc.0 -ldc.i4 861 -beq j69 -br InvalidJumpDestination - -j216: -br InvalidJumpDestination - -j217: -ldloc.0 -ldc.i4 351 -beq j27 -br InvalidJumpDestination - -j218: -ldloc.0 -ldc.i4 864 -beq j70 -br InvalidJumpDestination - -j219: -br InvalidJumpDestination - -j220: -ldloc.0 -ldc.i4.s 98 -beq j10 -ldloc.0 -ldc.i4 1762 -beq j112 -br InvalidJumpDestination - -j221: -ldloc.0 -ldc.i4 1379 -beq j85 -br InvalidJumpDestination - -j222: +beq.s j5 ldloc.0 -ldc.i4 612 -beq j48 -br InvalidJumpDestination - -j223: -ldloc.0 -ldc.i4 613 -beq j49 -br InvalidJumpDestination - -j224: -ldloc.0 -ldc.i4 1126 -beq j76 -br InvalidJumpDestination - -j225: -ldloc.0 -ldc.i4 359 -beq j28 -ldloc.0 -ldc.i4 743 -beq j55 -br InvalidJumpDestination - -j226: -ldloc.0 -ldc.i4 616 -beq j50 -ldloc.0 -ldc.i4 872 -beq j71 -br InvalidJumpDestination - -j227: -br InvalidJumpDestination - -j228: -ldloc.0 -ldc.i4 1386 -beq j86 -br InvalidJumpDestination - -j229: -ldloc.0 -ldc.i4 363 -beq j31 -br InvalidJumpDestination - -j230: -br InvalidJumpDestination - -j231: -ldloc.0 -ldc.i4.s 109 -beq j11 -br InvalidJumpDestination - -j232: -br InvalidJumpDestination - -j233: -br InvalidJumpDestination - -j234: -ldloc.0 -ldc.i4 624 -beq j51 -br InvalidJumpDestination - -j235: -ldloc.0 -ldc.i4 753 -beq j56 -br InvalidJumpDestination - -j236: -ldloc.0 -ldc.i4 1394 -beq j87 -br InvalidJumpDestination - -j237: -ldloc.0 -ldc.i4 1395 -beq j88 -br InvalidJumpDestination - -j238: -br InvalidJumpDestination - -j239: -ldloc.0 -ldc.i4.s 117 -beq j12 -ldloc.0 -ldc.i4 757 -beq j59 -br InvalidJumpDestination - -j240: -ldloc.0 -ldc.i4 1398 -beq j89 -br InvalidJumpDestination - -j241: -ldloc.0 -ldc.i4.s 119 -beq j13 -ldloc.0 -ldc.i4 1911 -beq j114 -br InvalidJumpDestination - -j242: -br.s InvalidJumpDestination - -j243: -ldloc.0 -ldc.i4 505 -beq j39 -ldloc.0 -ldc.i4 1913 -beq j115 -br.s InvalidJumpDestination - -j244: -ldloc.0 -ldc.i4 762 -beq j60 -br.s InvalidJumpDestination - -j245: -br.s InvalidJumpDestination - -j246: -br.s InvalidJumpDestination - -j247: -br.s InvalidJumpDestination - -j248: -ldloc.0 -ldc.i4 1406 -beq j90 -br.s InvalidJumpDestination - -j249: +ldc.i4.s 11 +beq.s j6 ldloc.0 -ldc.i4.s 127 -beq j14 +ldc.i4.s 32 +beq.s j7 br.s InvalidJumpDestination -BadInstruction: -ldarg.1 -dup -ldc.i4.1 -stfld Nethermind.Evm.EvmExceptionType ExceptionType -ldc.i4.8 -stfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState -br j3 - StaticCallViolation: ldarg.1 dup @@ -1676,7 +86,7 @@ ldc.i4.s 11 stfld Nethermind.Evm.EvmExceptionType ExceptionType ldc.i4.8 stfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState -br j3 +br.s j3 InvalidJumpDestination: ldarg.1 @@ -1685,4 +95,4 @@ ldc.i4.8 stfld Nethermind.Evm.EvmExceptionType ExceptionType ldc.i4.8 stfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState -br j3 +br.s j3 diff --git a/src/Nethermind/Nethermind.Evm.Test/ILEVM/WrappedEthTests.Verify_useIlEvm=True.verified.txt b/src/Nethermind/Nethermind.Evm.Test/ILEVM/WrappedEthTests.Verify_useIlEvm=True.verified.txt index 2d948384abe..b7881b10ce7 100644 --- a/src/Nethermind/Nethermind.Evm.Test/ILEVM/WrappedEthTests.Verify_useIlEvm=True.verified.txt +++ b/src/Nethermind/Nethermind.Evm.Test/ILEVM/WrappedEthTests.Verify_useIlEvm=True.verified.txt @@ -2,1107 +2,40 @@ ldobj Nethermind.Evm.CodeAnalysis.IL.ILChunkExecutionState ldfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState ldc.i4.2 -beq j2 +beq.s j2 j4: j5: ldarg.0 ldarg.1 -call Segment[0::12] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 +call Segment[0::10] +brtrue.s j3 j6: ldarg.0 ldarg.1 -call Segment[13::64] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j7: -ldarg.0 -ldarg.1 -call Segment[65::75] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j8: -ldarg.0 -ldarg.1 -call Segment[76::86] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j9: -ldarg.0 -ldarg.1 -call Segment[87::97] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j10: -ldarg.0 -ldarg.1 -call Segment[98::108] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j11: -ldarg.0 -ldarg.1 -call Segment[109::119] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j12: -ldarg.0 -ldarg.1 -call Segment[120::130] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j13: -ldarg.0 -ldarg.1 -call Segment[131::141] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j14: -ldarg.0 -ldarg.1 -call Segment[142::152] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j15: -ldarg.0 -ldarg.1 -call Segment[153::163] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j16: -ldarg.0 -ldarg.1 -call Segment[164::174] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j17: -ldarg.0 -ldarg.1 -call Segment[175::182] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j18: -ldarg.0 -ldarg.1 -call Segment[183::184] -brtrue j3 - -j19: -ldarg.0 -ldarg.1 -call Segment[185::191] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j20: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j21 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j21: -ldarg.0 -ldarg.1 -call Segment[192::195] -brtrue j3 - -j23: -ldarg.0 -ldarg.1 -call Segment[196::203] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j24: -ldarg.0 -ldarg.1 -call Segment[204::240] -brtrue j3 - -j25: -ldarg.0 -ldarg.1 -call Segment[241::249] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j26: -ldarg.0 -ldarg.1 -call Segment[250::267] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j27: -ldarg.0 -ldarg.1 -call Segment[268::287] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j28: -ldarg.0 -ldarg.1 -call Segment[288::312] -brtrue j3 - -j29: -ldarg.0 -ldarg.1 -call Segment[313::326] -brtrue j3 - -j30: -ldarg.0 -ldarg.1 -call Segment[327::333] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j31: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j32 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j32: -ldarg.0 -ldarg.1 -call Segment[334::337] -brtrue j3 - -j34: -ldarg.0 -ldarg.1 -call Segment[338::390] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j35: -ldarg.0 -ldarg.1 -call Segment[391::416] -brtrue j3 - -j36: -ldarg.0 -ldarg.1 -call Segment[417::423] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j37: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j38 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j38: -ldarg.0 -ldarg.1 -call Segment[424::427] -brtrue j3 - -j40: -ldarg.0 -ldarg.1 -call Segment[428::435] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j41: -ldarg.0 -ldarg.1 -call Segment[436::457] -brtrue j3 - -j42: -ldarg.0 -ldarg.1 -call Segment[458::464] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j43: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j44 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j44: -ldarg.0 -ldarg.1 -call Segment[465::468] -brtrue j3 - -j46: -ldarg.0 -ldarg.1 -call Segment[469::552] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j47: -ldarg.0 -ldarg.1 -call Segment[553::578] -brtrue j3 - -j48: -ldarg.0 -ldarg.1 -call Segment[579::585] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j49: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j50 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j50: -ldarg.0 -ldarg.1 -call Segment[586::589] -brtrue j3 - -j52: -ldarg.0 -ldarg.1 -call Segment[590::611] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j53: -ldarg.0 -ldarg.1 -call Segment[612::613] -brtrue j3 - -j54: -ldarg.0 -ldarg.1 -call Segment[614::620] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j55: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j56 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j56: -ldarg.0 -ldarg.1 -call Segment[621::624] -brtrue j3 - -j58: -ldarg.0 -ldarg.1 -call Segment[625::632] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j59: -ldarg.0 -ldarg.1 -call Segment[633::660] -brtrue j3 - -j60: -ldarg.0 -ldarg.1 -call Segment[661::667] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j61: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j62 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j62: -ldarg.0 -ldarg.1 -call Segment[668::671] -brtrue j3 - -j64: -ldarg.0 -ldarg.1 -call Segment[672::715] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j65: -ldarg.0 -ldarg.1 -call Segment[716::737] -brtrue j3 - -j66: -ldarg.0 -ldarg.1 -call Segment[738::744] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j67: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j68 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j68: -ldarg.0 -ldarg.1 -call Segment[745::748] -brtrue j3 - -j70: -ldarg.0 -ldarg.1 -call Segment[749::756] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j71: -ldarg.0 -ldarg.1 -call Segment[757::793] -brtrue j3 - -j72: -ldarg.0 -ldarg.1 -call Segment[794::802] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j73: -ldarg.0 -ldarg.1 -call Segment[803::820] -brtrue j3 +call Segment[11::16] +brtrue.s j3 ldarg.1 call Boolean get_ShouldJump() -brtrue j1 - -j74: +brtrue.s j1 ldarg.0 ldarg.1 -call Segment[821::840] -brtrue j3 +call Segment[17::31] +brtrue.s j3 ldarg.1 call Boolean get_ShouldJump() -brtrue j1 - -j75: -ldarg.0 -ldarg.1 -call Segment[841::865] -brtrue j3 - -j76: -ldarg.0 -ldarg.1 -call Segment[866::879] -brtrue j3 - -j77: -ldarg.0 -ldarg.1 -call Segment[880::886] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j78: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j79 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j79: -ldarg.0 -ldarg.1 -call Segment[887::890] -brtrue j3 - -j81: -ldarg.0 -ldarg.1 -call Segment[891::943] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j82: -ldarg.0 -ldarg.1 -call Segment[944::969] -brtrue j3 - -j83: -ldarg.0 -ldarg.1 -call Segment[970::977] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j84: -ldarg.0 -ldarg.1 -call Segment[978::979] -brtrue j3 - -j85: -ldarg.0 -ldarg.1 -call Segment[980::986] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j86: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j87 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j87: -ldarg.0 -ldarg.1 -call Segment[987::990] -brtrue j3 - -j89: -ldarg.0 -ldarg.1 -call Segment[991::1065] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j90: -ldarg.0 -ldarg.1 -call Segment[1066::1087] -brtrue j3 - -j91: -ldarg.0 -ldfld Nethermind.Evm.EvmState EvmState -call Boolean get_IsStatic() -brtrue StaticCallViolation -ldarg.0 -ldarg.1 -call Segment[1088::1244] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j92: -ldarg.0 -ldarg.1 -call Segment[1245::1324] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j93: -ldarg.0 -ldarg.1 -call Segment[1325::1332] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j94: -ldarg.0 -ldarg.1 -call Segment[1333::1351] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j95: -ldarg.0 -ldarg.1 -call Segment[1352::1365] -brtrue j3 - -j96: -ldarg.0 -ldarg.1 -call Segment[1366::1385] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j97: -ldarg.0 -ldarg.1 -call Segment[1386::1394] -brtrue j3 - -j98: -ldarg.0 -ldarg.1 -call Segment[1395::1402] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j99: -ldarg.0 -ldfld Nethermind.Evm.EvmState EvmState -call Boolean get_IsStatic() -brtrue StaticCallViolation -ldarg.0 -ldarg.1 -call Segment[1403::1644] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j100: -ldarg.0 -ldarg.1 -call Segment[1645::1675] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j101: -ldarg.0 -ldarg.1 -call Segment[1676::1751] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j102: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j103 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j103: -ldarg.0 -ldarg.1 -call Segment[1752::1755] -brtrue j3 - -j105: -ldarg.0 -ldarg.1 -call Segment[1756::1810] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j106: -ldarg.0 -ldarg.1 -call Segment[1811::1971] -brtrue j3 - -j107: -ldarg.0 -ldarg.1 -call Segment[1972::1977] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j108: -ldarg.0 -ldarg.1 -call Segment[1978::2111] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j109: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j110 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j110: -ldarg.0 -ldarg.1 -call Segment[2112::2115] -brtrue j3 - -j112: -ldarg.0 -ldfld Nethermind.Evm.EvmState EvmState -call Boolean get_IsStatic() -brtrue StaticCallViolation -ldarg.0 -ldarg.1 -call Segment[2116::2254] -brtrue j3 - -j113: -ldarg.0 -ldfld Nethermind.Evm.EvmState EvmState -call Boolean get_IsStatic() -brtrue StaticCallViolation -ldarg.0 -ldarg.1 -call Segment[2255::2520] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j114: -ldarg.0 -ldarg.1 -call Segment[2521::2594] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j115: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j116 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j116: -ldarg.0 -ldarg.1 -call Segment[2595::2598] -brtrue j3 - -j118: -ldarg.0 -ldfld Nethermind.Evm.EvmState EvmState -call Boolean get_IsStatic() -brtrue StaticCallViolation -ldarg.0 -ldarg.1 -call Segment[2599::2724] -brtrue j3 -ldarg.1 -call Boolean get_ShouldHalt() -brtrue j3 - -j119: - -j120: -ldarg.0 -ldarg.1 -call Segment[2725::2735] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j121: -ldloca.s 36 -call Boolean get_HasValue() -brtrue.s j122 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 253 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 36 - -j122: -ldarg.0 -ldarg.1 -call Segment[2736::2739] -brtrue j3 - -j124: -ldarg.0 -ldfld Nethermind.Evm.EvmState EvmState -call Boolean get_IsStatic() -brtrue StaticCallViolation -ldarg.0 -ldarg.1 -call Segment[2740::2820] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j125: -ldarg.0 -ldarg.1 -call Segment[2821::2839] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j126: -ldarg.0 -ldarg.1 -call Segment[2840::2863] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j127: -ldarg.0 -ldarg.1 -call Segment[2864::2943] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j128: -ldarg.0 -ldarg.1 -call Segment[2944::2951] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j129: -ldarg.0 -ldarg.1 -call Segment[2952::2970] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j130: -ldarg.0 -ldarg.1 -call Segment[2971::2984] -brtrue j3 - -j131: -ldarg.0 -ldarg.1 -call Segment[2985::3004] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j132: -ldarg.0 -ldarg.1 -call Segment[3005::3013] -brtrue j3 - -j133: -ldarg.0 -ldarg.1 -call Segment[3014::3021] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j134: -ldarg.0 -ldarg.1 -call Segment[3022::3034] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j135: -ldarg.0 -ldarg.1 -call Segment[3035::3042] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j136: -ldarg.0 -ldarg.1 -call Segment[3043::3079] -brtrue j3 -ldarg.1 -call Boolean get_ShouldJump() -brtrue j1 - -j137: - -j138: -ldloca.s 74 -call Boolean get_HasValue() -brtrue.s j139 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 250 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 74 - -j139: -ldarg.0 -ldarg.1 -call Segment[3102::3111] -brtrue.s j3 -ldarg.1 -call Boolean get_ShouldHalt() -brtrue.s j3 - -j141: - -j142: -ldloca.s 75 -call Boolean get_HasValue() -brtrue.s j143 -ldarg.0 -ldfld Nethermind.Evm.VirtualMachine Vm -call Nethermind.Core.Specs.IReleaseSpec get_Spec() -ldc.i4 250 -call Boolean IsEnabled(Nethermind.Core.Specs.IReleaseSpec, Nethermind.Evm.Instruction) -brfalse BadInstruction -ldc.i4.1 -newobj Void .ctor(Boolean) -stloc.s 75 - -j143: -ldarg.0 -ldarg.1 -call Segment[3112::3112] -brtrue.s j3 -ldarg.1 -call Boolean get_ShouldHalt() -brtrue.s j3 - -j145: +brtrue.s j1 -j146: +j7: +ldarg.0 +ldfld Nethermind.Evm.EvmState EvmState +call Boolean get_IsStatic() +brtrue.s StaticCallViolation ldarg.0 ldarg.1 -call Segment[3113::3122] +call Segment[32::39] brtrue.s j3 ldarg.1 ldc.i4.4 @@ -1124,745 +57,28 @@ ldarg.1 ldc.i4.1 stfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState ldloc.0 -ldc.i4 3124 +ldc.i4.s 40 bge.s j3 ldloc.0 ldc.i4.0 -beq j4 -ldloc.0 -ldc.i4 2725 -beq j119 -ldloc.0 -ldc.i4 3102 -beq j137 -ldloc.0 -ldc.i4 3112 -beq j141 -ldloc.0 -ldc.i4 3113 -beq.s j145 -br InvalidJumpDestination +beq.s j4 +br.s InvalidJumpDestination j1: ldarg.1 ldfld Int32 JumpDestination stloc.0 ldloc.0 -ldc.i4.s 127 -and -switch j147, j148, j149, j150, j151, j152, j153, j154, j155, j156, j157, j158, j159, j160, j161, j162, j163, j164, j165, j166, j167, j168, j169, j170, j171, j172, j173, j174, j175, j176, j177, j178, j179, j180, j181, j182, j183, j184, j185, j186, j187, j188, j189, j190, j191, j192, j193, j194, j195, j196, j197, j198, j199, j200, j201, j202, j203, j204, j205, j206, j207, j208, j209, j210, j211, j212, j213, j214, j215, j216, j217, j218, j219, j220, j221, j222, j223, j224, j225, j226, j227, j228, j229, j230, j231, j232, j233, j234, j235, j236, j237, j238, j239, j240, j241, j242, j243, j244, j245, j246, j247, j248, j249, j250, j251, j252, j253, j254, j255, j256, j257, j258, j259, j260, j261, j262, j263, j264, j265, j266, j267, j268, j269, j270, j271, j272, j273, j274 - -j147: -ldloc.0 ldc.i4.0 -beq j5 -ldloc.0 -ldc.i4 2944 -beq j128 -br InvalidJumpDestination - -j148: -br InvalidJumpDestination - -j149: -br InvalidJumpDestination - -j150: -ldloc.0 -ldc.i4 131 -beq j13 -br InvalidJumpDestination - -j151: -br InvalidJumpDestination - -j152: -ldloc.0 -ldc.i4 2821 -beq j125 -br InvalidJumpDestination - -j153: -br InvalidJumpDestination - -j154: -ldloc.0 -ldc.i4 391 -beq j35 -br InvalidJumpDestination - -j155: -ldloc.0 -ldc.i4 2952 -beq j129 -br InvalidJumpDestination - -j156: -br InvalidJumpDestination - -j157: -br InvalidJumpDestination - -j158: -br InvalidJumpDestination - -j159: -ldloc.0 -ldc.i4 268 -beq j27 -ldloc.0 -ldc.i4 1676 -beq j101 -br InvalidJumpDestination - -j160: -ldloc.0 -ldc.i4.s 13 -beq j6 -br InvalidJumpDestination - -j161: -ldloc.0 -ldc.i4 142 -beq j14 -br InvalidJumpDestination - -j162: -br InvalidJumpDestination - -j163: -br InvalidJumpDestination - -j164: -br InvalidJumpDestination - -j165: -br InvalidJumpDestination - -j166: -ldloc.0 -ldc.i4 1811 -beq j106 -br InvalidJumpDestination - -j167: -br InvalidJumpDestination - -j168: -ldloc.0 -ldc.i4 661 -beq j60 -br InvalidJumpDestination - -j169: -br InvalidJumpDestination - -j170: -br InvalidJumpDestination - -j171: -ldloc.0 -ldc.i4 2840 -beq j126 -br InvalidJumpDestination - -j172: -ldloc.0 -ldc.i4 153 -beq j15 -br InvalidJumpDestination - -j173: -ldloc.0 -ldc.i4 794 -beq j72 -br InvalidJumpDestination - -j174: -ldloc.0 -ldc.i4 2971 -beq j130 -br InvalidJumpDestination - -j175: -ldloc.0 -ldc.i4 668 -beq j61 -br InvalidJumpDestination - -j176: -br InvalidJumpDestination - -j177: -ldloc.0 -ldc.i4 3102 -beq j138 -br InvalidJumpDestination - -j178: -br InvalidJumpDestination - -j179: -ldloc.0 -ldc.i4 288 -beq j28 -ldloc.0 -ldc.i4 672 -beq j64 -br InvalidJumpDestination - -j180: -ldloc.0 -ldc.i4 417 -beq j36 -br InvalidJumpDestination - -j181: -br InvalidJumpDestination - -j182: -ldloc.0 -ldc.i4 803 -beq j73 -ldloc.0 -ldc.i4 2595 -beq j115 -br InvalidJumpDestination - -j183: -ldloc.0 -ldc.i4 164 -beq j16 -br InvalidJumpDestination - -j184: -ldloc.0 -ldc.i4 2725 -beq j120 -br InvalidJumpDestination - -j185: -br InvalidJumpDestination - -j186: -ldloc.0 -ldc.i4 2599 -beq j118 -br InvalidJumpDestination - -j187: -ldloc.0 -ldc.i4 424 -beq j37 -ldloc.0 -ldc.i4 3112 -beq j142 -br InvalidJumpDestination - -j188: -ldloc.0 -ldc.i4 553 -beq j47 -ldloc.0 -ldc.i4 2985 -beq j131 -ldloc.0 -ldc.i4 3113 -beq j146 -br InvalidJumpDestination - -j189: -ldloc.0 -ldc.i4 1066 -beq j90 -br InvalidJumpDestination - -j190: -br InvalidJumpDestination - -j191: -ldloc.0 -ldc.i4 428 -beq j40 -br InvalidJumpDestination - -j192: -ldloc.0 -ldc.i4 1325 -beq j93 -br InvalidJumpDestination - -j193: -br InvalidJumpDestination - -j194: -ldloc.0 -ldc.i4 175 -beq j17 -br InvalidJumpDestination - -j195: -ldloc.0 -ldc.i4 944 -beq j82 -ldloc.0 -ldc.i4 2736 -beq j121 -ldloc.0 -ldc.i4 2864 -beq j127 -br InvalidJumpDestination - -j196: -br InvalidJumpDestination - -j197: -br InvalidJumpDestination - -j198: -br InvalidJumpDestination - -j199: -ldloc.0 -ldc.i4 436 -beq j41 -ldloc.0 -ldc.i4 1972 -beq j107 -ldloc.0 -ldc.i4 2740 -beq j124 -br InvalidJumpDestination - -j200: -ldloc.0 -ldc.i4 821 -beq j74 -ldloc.0 -ldc.i4 1333 -beq j94 -br InvalidJumpDestination - -j201: -br InvalidJumpDestination - -j202: -ldloc.0 -ldc.i4 183 -beq j18 -br InvalidJumpDestination - -j203: -br InvalidJumpDestination - -j204: -ldloc.0 -ldc.i4 185 -beq j19 -ldloc.0 -ldc.i4 313 -beq j29 -br InvalidJumpDestination - -j205: -ldloc.0 -ldc.i4 1978 -beq j108 -br InvalidJumpDestination - -j206: -br InvalidJumpDestination - -j207: -br InvalidJumpDestination - -j208: -ldloc.0 -ldc.i4 3005 -beq j132 -br InvalidJumpDestination - -j209: -br InvalidJumpDestination - -j210: -br InvalidJumpDestination - -j211: -ldloc.0 -ldc.i4 192 -beq j20 -ldloc.0 -ldc.i4 1088 -beq j91 -ldloc.0 -ldc.i4 2112 -beq j109 -br InvalidJumpDestination - -j212: -ldloc.0 -ldc.i4.s 65 -beq j7 -br InvalidJumpDestination - -j213: -br InvalidJumpDestination - -j214: -ldloc.0 -ldc.i4 579 -beq j48 -br InvalidJumpDestination - -j215: -ldloc.0 -ldc.i4 196 -beq j23 -ldloc.0 -ldc.i4 2116 -beq j112 -br InvalidJumpDestination - -j216: -br InvalidJumpDestination - -j217: -ldloc.0 -ldc.i4 3014 -beq j133 -br InvalidJumpDestination - -j218: -ldloc.0 -ldc.i4 327 -beq j30 -br InvalidJumpDestination - -j219: -ldloc.0 -ldc.i4 1352 -beq j95 -br InvalidJumpDestination - -j220: -ldloc.0 -ldc.i4 841 -beq j75 -br InvalidJumpDestination - -j221: -ldloc.0 -ldc.i4 458 -beq j42 -ldloc.0 -ldc.i4 586 -beq j49 -ldloc.0 -ldc.i4 970 -beq j83 -br InvalidJumpDestination - -j222: -br InvalidJumpDestination - -j223: -ldloc.0 -ldc.i4.s 76 -beq j8 -ldloc.0 -ldc.i4 204 -beq j24 -ldloc.0 -ldc.i4 716 -beq j65 -br InvalidJumpDestination - -j224: -br InvalidJumpDestination - -j225: -ldloc.0 -ldc.i4 334 -beq j31 -ldloc.0 -ldc.i4 590 -beq j52 -ldloc.0 -ldc.i4 3022 -beq j134 -br InvalidJumpDestination - -j226: -ldloc.0 -ldc.i4 2255 -beq j113 -br InvalidJumpDestination - -j227: -br InvalidJumpDestination - -j228: -ldloc.0 -ldc.i4 465 -beq j43 -br InvalidJumpDestination - -j229: -ldloc.0 -ldc.i4 338 -beq j34 -ldloc.0 -ldc.i4 978 -beq j84 -br InvalidJumpDestination - -j230: -br InvalidJumpDestination - -j231: -ldloc.0 -ldc.i4 980 -beq j85 -br InvalidJumpDestination - -j232: -ldloc.0 -ldc.i4 469 -beq j46 -br InvalidJumpDestination - -j233: -ldloc.0 -ldc.i4 1366 -beq j96 -br InvalidJumpDestination - -j234: -ldloc.0 -ldc.i4.s 87 -beq j9 -br InvalidJumpDestination - -j235: -ldloc.0 -ldc.i4 1752 -beq j102 -br InvalidJumpDestination - -j236: -ldloc.0 -ldc.i4 2521 -beq j114 -br InvalidJumpDestination - -j237: -br InvalidJumpDestination - -j238: -ldloc.0 -ldc.i4 987 -beq j86 -ldloc.0 -ldc.i4 3035 -beq j135 -br InvalidJumpDestination - -j239: -ldloc.0 -ldc.i4 1756 -beq j105 -br InvalidJumpDestination - -j240: -ldloc.0 -ldc.i4 1245 -beq j92 -br InvalidJumpDestination - -j241: -br InvalidJumpDestination - -j242: -ldloc.0 -ldc.i4 991 -beq j89 -br InvalidJumpDestination - -j243: -br InvalidJumpDestination - -j244: -br InvalidJumpDestination - -j245: -ldloc.0 -ldc.i4.s 98 -beq j10 +beq.s j5 ldloc.0 -ldc.i4 738 -beq j66 -ldloc.0 -ldc.i4 866 -beq j76 -br InvalidJumpDestination - -j246: -ldloc.0 -ldc.i4 3043 -beq j136 -br InvalidJumpDestination - -j247: -ldloc.0 -ldc.i4 612 -beq j53 -br InvalidJumpDestination - -j248: -br InvalidJumpDestination - -j249: -ldloc.0 -ldc.i4 614 -beq j54 -br InvalidJumpDestination - -j250: -br InvalidJumpDestination - -j251: -br InvalidJumpDestination - -j252: -ldloc.0 -ldc.i4 745 -beq j67 -br InvalidJumpDestination - -j253: -ldloc.0 -ldc.i4 1386 -beq j97 -br InvalidJumpDestination - -j254: -br InvalidJumpDestination - -j255: -br InvalidJumpDestination - -j256: -ldloc.0 -ldc.i4.s 109 -beq j11 -ldloc.0 -ldc.i4 621 -beq j55 -ldloc.0 -ldc.i4 749 -beq j70 -ldloc.0 -ldc.i4 1645 -beq j100 -br InvalidJumpDestination - -j257: -br InvalidJumpDestination - -j258: -br InvalidJumpDestination - -j259: -ldloc.0 -ldc.i4 880 -beq j77 -br InvalidJumpDestination - -j260: -ldloc.0 -ldc.i4 241 -beq j25 -ldloc.0 -ldc.i4 625 -beq j58 -br InvalidJumpDestination - -j261: -br InvalidJumpDestination - -j262: -ldloc.0 -ldc.i4 1395 -beq j98 -br InvalidJumpDestination - -j263: -br InvalidJumpDestination - -j264: -ldloc.0 -ldc.i4 757 -beq j71 -br InvalidJumpDestination - -j265: -br InvalidJumpDestination - -j266: -ldloc.0 -ldc.i4 887 -beq j78 -br InvalidJumpDestination - -j267: -ldloc.0 -ldc.i4.s 120 -beq j12 -br.s InvalidJumpDestination - -j268: -ldloc.0 -ldc.i4 633 -beq j59 -br.s InvalidJumpDestination - -j269: -ldloc.0 -ldc.i4 250 -beq j26 -br.s InvalidJumpDestination - -j270: -ldloc.0 -ldc.i4 891 -beq j81 +ldc.i4.s 11 +beq.s j6 ldloc.0 -ldc.i4 1403 -beq j99 -br.s InvalidJumpDestination - -j271: -br.s InvalidJumpDestination - -j272: -br.s InvalidJumpDestination - -j273: -br.s InvalidJumpDestination - -j274: +ldc.i4.s 32 +beq.s j7 br.s InvalidJumpDestination -BadInstruction: -ldarg.1 -dup -ldc.i4.1 -stfld Nethermind.Evm.EvmExceptionType ExceptionType -ldc.i4.8 -stfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState -br j3 - StaticCallViolation: ldarg.1 dup @@ -1870,7 +86,7 @@ ldc.i4.s 11 stfld Nethermind.Evm.EvmExceptionType ExceptionType ldc.i4.8 stfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState -br j3 +br.s j3 InvalidJumpDestination: ldarg.1 @@ -1879,4 +95,4 @@ ldc.i4.8 stfld Nethermind.Evm.EvmExceptionType ExceptionType ldc.i4.8 stfld Nethermind.Evm.CodeAnalysis.IL.ContractState ContractState -br j3 +br.s j3 diff --git a/src/Nethermind/Nethermind.Evm.Test/TestCodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm.Test/TestCodeInfoRepository.cs index b7f28cc25be..e554a7efb88 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TestCodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TestCodeInfoRepository.cs @@ -9,7 +9,7 @@ using Nethermind.Evm.EvmObjectFormat; using Nethermind.Evm.Precompiles; using Nethermind.Evm.Precompiles.Bls; -using Nethermind.Evm.Precompiles.Snarks; +//using Nethermind.Evm.Precompiles.Snarks; using Nethermind.Evm.State; using Nethermind.State; using System; @@ -28,6 +28,9 @@ public class TestCodeInfoRepository : ICodeInfoRepository private readonly CodeLruCache _codeCache = new(); private readonly FrozenDictionary _localPrecompiles; + public bool IsPrecompile(Address address, IReleaseSpec spec) => + address.IsPrecompile(spec) && _localPrecompiles.ContainsKey(address); + private static FrozenDictionary InitializePrecompiledContracts() { return new Dictionary @@ -37,9 +40,9 @@ private static FrozenDictionary InitializePrecompi [Ripemd160Precompile.Address] = new PrecompileInfo(Ripemd160Precompile.Instance), [IdentityPrecompile.Address] = new PrecompileInfo(IdentityPrecompile.Instance), - [Bn254AddPrecompile.Address] = new PrecompileInfo(Bn254AddPrecompile.Instance), - [Bn254MulPrecompile.Address] = new PrecompileInfo(Bn254MulPrecompile.Instance), - [Bn254PairingPrecompile.Address] = new PrecompileInfo(Bn254PairingPrecompile.Instance), + [BN254AddPrecompile.Address] = new PrecompileInfo(BN254AddPrecompile.Instance), + [BN254MulPrecompile.Address] = new PrecompileInfo(BN254MulPrecompile.Instance), + [BN254PairingPrecompile.Address] = new PrecompileInfo(BN254PairingPrecompile.Instance), [ModExpPrecompile.Address] = new PrecompileInfo(ModExpPrecompile.Instance), [Blake2FPrecompile.Address] = new PrecompileInfo(Blake2FPrecompile.Instance), diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs index 0e9431b1430..ac19bb707e0 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs @@ -3,6 +3,7 @@ using System; using FluentAssertions; +using Nethermind.Blockchain; using Nethermind.Blockchain.Tracing; using Nethermind.Config; using Nethermind.Core; @@ -392,7 +393,7 @@ public TestEnvironment() _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(0); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new(new TestBlockhashProvider(_specProvider), _specProvider, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId); diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs index 89f6468f221..81f2fa555ad 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/ParityLikeTxTracerTests.cs @@ -11,7 +11,6 @@ using Nethermind.Int256; using Nethermind.Evm.Precompiles; using Nethermind.Blockchain.Tracing.ParityStyle; -using Nethermind.Evm.TransactionProcessing; using Nethermind.Evm.State; using NUnit.Framework; diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs index 74714732b2f..d035564f287 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip4844Tests.cs @@ -15,6 +15,7 @@ using Nethermind.Evm.State; using NUnit.Framework; using System.Collections.Generic; +using Nethermind.Blockchain; using Nethermind.Core.Test; using Nethermind.State; @@ -34,7 +35,7 @@ public void Setup() _specProvider = new TestSpecProvider(Cancun.Instance); IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); _stateProvider = worldStateManager.GlobalWorldState; - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new(new TestBlockhashProvider(_specProvider), _specProvider, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId); diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip7623Tests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip7623Tests.cs index ec1d4dedc0f..a68e8dacba3 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip7623Tests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorEip7623Tests.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using Nethermind.Blockchain; using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; @@ -32,7 +33,7 @@ public void Setup() _specProvider = new TestSpecProvider(Prague.Instance); IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); _stateProvider = worldStateManager.GlobalWorldState; - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new(new TestBlockhashProvider(_specProvider), _specProvider, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId); diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs index 253e14ce64c..38e5ebb8a54 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -4,6 +4,7 @@ using System; using System.Threading; using FluentAssertions; +using Nethermind.Blockchain; using Nethermind.Blockchain.Tracing; using Nethermind.Core; using Nethermind.Core.Extensions; @@ -45,7 +46,7 @@ public void Setup() _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(0); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new(new TestBlockhashProvider(_specProvider), _specProvider, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId); diff --git a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs index 4be33c866d9..0bb823ec72c 100644 --- a/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs +++ b/src/Nethermind/Nethermind.Evm.Test/VirtualMachineTestsBase.cs @@ -16,11 +16,11 @@ using Nethermind.Int256; using Nethermind.Evm.Tracing; using Nethermind.Blockchain.Tracing.GethStyle; +using Nethermind.Core.Test.Db; using Nethermind.Evm.TransactionProcessing; using Nethermind.Logging; using Nethermind.Evm.State; using Nethermind.State; -using Nethermind.Trie.Pruning; using NUnit.Framework; namespace Nethermind.Evm.Test; @@ -78,7 +78,7 @@ public virtual void Setup() TestState = worldStateManager.GlobalWorldState; _ethereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId); IBlockhashProvider blockhashProvider = new TestBlockhashProvider(SpecProvider); - CodeInfoRepository = new CodeInfoRepository(); + CodeInfoRepository = new EthereumCodeInfoRepository(); Machine = new VirtualMachine(blockhashProvider, SpecProvider, logManager); _processor = new TransactionProcessor(SpecProvider, TestState, Machine, CodeInfoRepository, logManager); } diff --git a/src/Nethermind/Nethermind.Evm/CodeAnalysis/IL/IlAnalyzer.cs b/src/Nethermind/Nethermind.Evm/CodeAnalysis/IL/IlAnalyzer.cs index f66ff49b969..dc77198e57d 100644 --- a/src/Nethermind/Nethermind.Evm/CodeAnalysis/IL/IlAnalyzer.cs +++ b/src/Nethermind/Nethermind.Evm/CodeAnalysis/IL/IlAnalyzer.cs @@ -77,12 +77,19 @@ private static async Task WorkerLoop(int taskLimit, IVMConfig config, ILogger lo Task[] taskPool = new Task[taskLimit]; Array.Fill(taskPool, Task.CompletedTask); - await foreach (var codeInfo in _channel.Reader.ReadAllAsync(_cts.Token)) + while (await _channel.Reader.WaitToReadAsync(_cts.Token)) { - int index = Task.WaitAny(taskPool); + while (_channel.Reader.TryRead(out CodeInfo? codeInfo)) + { + if (codeInfo is null) + break; + + int index = Task.WaitAny(taskPool); - Metrics.DecrementIlvmAotQueueSize(); - taskPool[index] = Task.Run(() => ProcessCodeInfoAsync(config, logger, codeInfo)); + Metrics.DecrementIlvmAotQueueSize(); + + taskPool[index] = Task.Run(async () => await ProcessCodeInfoAsync(config, logger, codeInfo)); + } } } catch (Exception ex) diff --git a/src/Nethermind/Nethermind.State/CodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs similarity index 65% rename from src/Nethermind/Nethermind.State/CodeInfoRepository.cs rename to src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs index e5d150e2de1..27fba0c65a6 100644 --- a/src/Nethermind/Nethermind.State/CodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/CodeInfoRepository.cs @@ -2,9 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Collections.Concurrent; using System.Collections.Frozen; -using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -12,63 +10,30 @@ using Nethermind.Core.Caching; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; -using Nethermind.Evm; using Nethermind.Evm.CodeAnalysis; using Nethermind.Evm.EvmObjectFormat; using Nethermind.Evm.Precompiles; -using Nethermind.Evm.Precompiles.Bls; -using Nethermind.Evm.Precompiles.Snarks; using Nethermind.Evm.State; -namespace Nethermind.State; +namespace Nethermind.Evm; public class CodeInfoRepository : ICodeInfoRepository { - private static readonly FrozenDictionary _precompiles = InitializePrecompiledContracts(); private static readonly CodeLruCache _codeCache = new(); private readonly FrozenDictionary _localPrecompiles; - private static FrozenDictionary InitializePrecompiledContracts() + protected CodeInfoRepository(FrozenDictionary precompiles) { - return new Dictionary - { - [EcRecoverPrecompile.Address] = new PrecompileInfo(EcRecoverPrecompile.Instance), - [Sha256Precompile.Address] = new PrecompileInfo(Sha256Precompile.Instance), - [Ripemd160Precompile.Address] = new PrecompileInfo(Ripemd160Precompile.Instance), - [IdentityPrecompile.Address] = new PrecompileInfo(IdentityPrecompile.Instance), - - [Bn254AddPrecompile.Address] = new PrecompileInfo(Bn254AddPrecompile.Instance), - [Bn254MulPrecompile.Address] = new PrecompileInfo(Bn254MulPrecompile.Instance), - [Bn254PairingPrecompile.Address] = new PrecompileInfo(Bn254PairingPrecompile.Instance), - [ModExpPrecompile.Address] = new PrecompileInfo(ModExpPrecompile.Instance), - - [Blake2FPrecompile.Address] = new PrecompileInfo(Blake2FPrecompile.Instance), - - [G1AddPrecompile.Address] = new PrecompileInfo(G1AddPrecompile.Instance), - [G1MSMPrecompile.Address] = new PrecompileInfo(G1MSMPrecompile.Instance), - [G2AddPrecompile.Address] = new PrecompileInfo(G2AddPrecompile.Instance), - [G2MSMPrecompile.Address] = new PrecompileInfo(G2MSMPrecompile.Instance), - [PairingCheckPrecompile.Address] = new PrecompileInfo(PairingCheckPrecompile.Instance), - [MapFpToG1Precompile.Address] = new PrecompileInfo(MapFpToG1Precompile.Instance), - [MapFp2ToG2Precompile.Address] = new PrecompileInfo(MapFp2ToG2Precompile.Instance), - - [PointEvaluationPrecompile.Address] = new PrecompileInfo(PointEvaluationPrecompile.Instance), - - [Secp256r1Precompile.Address] = new PrecompileInfo(Secp256r1Precompile.Instance), - }.ToFrozenDictionary(); + _localPrecompiles = precompiles; } - public CodeInfoRepository(ConcurrentDictionary? precompileCache = null) - { - _localPrecompiles = precompileCache is null - ? _precompiles - : _precompiles.ToFrozenDictionary(kvp => kvp.Key, kvp => CreateCachedPrecompile(kvp, precompileCache)); - } + public bool IsPrecompile(Address address, IReleaseSpec spec) => + address.IsPrecompile(spec) && _localPrecompiles.ContainsKey(address); public ICodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, bool followDelegation, IReleaseSpec vmSpec, out Address? delegationAddress) { delegationAddress = null; - if (codeSource.IsPrecompile(vmSpec)) + if (IsPrecompile(codeSource, vmSpec)) { return _localPrecompiles[codeSource]; } @@ -119,7 +84,7 @@ private static ICodeInfo InternalGetCachedCode(IReadOnlyStateProvider worldState } else { - Db.Metrics.IncrementCodeDbCache(); + Metrics.IncrementCodeDbCache(); } return cachedCodeInfo; @@ -197,43 +162,12 @@ private static bool TryGetDelegatedAddress(ReadOnlySpan code, [NotNullWhen return false; } - private static PrecompileInfo CreateCachedPrecompile( - in KeyValuePair originalPrecompile, - ConcurrentDictionary cache) => - new PrecompileInfo(new CachedPrecompile(originalPrecompile.Key.Value, originalPrecompile.Value.Precompile!, cache)); - public bool TryGetDelegation(IReadOnlyStateProvider worldState, Address address, IReleaseSpec spec, [NotNullWhen(true)] out Address? delegatedAddress) => TryGetDelegatedAddress(InternalGetCachedCode(worldState, address, spec).CodeSpan, out delegatedAddress); public bool TryGetDelegation(IReadOnlyStateProvider worldState, in ValueHash256 codeHash, IReleaseSpec spec, [NotNullWhen(true)] out Address? delegatedAddress) => TryGetDelegatedAddress(InternalGetCachedCode(worldState, in codeHash, spec).CodeSpan, out delegatedAddress); - private class CachedPrecompile( - Address address, - IPrecompile precompile, - ConcurrentDictionary cache) : IPrecompile - { - public static Address Address => Address.Zero; - - public long BaseGasCost(IReleaseSpec releaseSpec) => precompile.BaseGasCost(releaseSpec); - - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => precompile.DataGasCost(inputData, releaseSpec); - - public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - PreBlockCaches.PrecompileCacheKey key = new(address, inputData); - if (!cache.TryGetValue(key, out (byte[], bool) result)) - { - result = precompile.Run(inputData, releaseSpec); - // we need to rebuild the key with data copy as the data can be changed by VM processing - key = new PreBlockCaches.PrecompileCacheKey(address, inputData.ToArray()); - cache.TryAdd(key, result); - } - - return result; - } - } - private sealed class CodeLruCache { private const int CacheCount = 16; diff --git a/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs b/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs index 244b27961fd..0156a2ef723 100644 --- a/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.Evm/ICodeInfoRepository.cs @@ -13,6 +13,7 @@ namespace Nethermind.Evm; public interface ICodeInfoRepository { + bool IsPrecompile(Address address, IReleaseSpec spec); ICodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, bool followDelegation, IReleaseSpec vmSpec, out Address? delegationAddress); ValueHash256 GetExecutableCodeHash(IWorldState worldState, Address address, IReleaseSpec spec); void InsertCode(IWorldState state, ReadOnlyMemory code, Address codeOwner, IReleaseSpec spec); diff --git a/src/Nethermind/Nethermind.Evm/IVirtualMachine.cs b/src/Nethermind/Nethermind.Evm/IVirtualMachine.cs index 3dfc4e3acff..7a11d6c80a3 100644 --- a/src/Nethermind/Nethermind.Evm/IVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/IVirtualMachine.cs @@ -10,8 +10,9 @@ namespace Nethermind.Evm { public interface IVirtualMachine { - TransactionSubstate ExecuteTransaction(EvmState state, IWorldState worldState, ITxTracer txTracer) - where TTracingInst : struct, IFlag; + TransactionSubstate ExecuteTransaction(EvmState state, IWorldState worldState, ITxTracer txTracer) + where TTracingInst : struct, IFlag + where TEnablePrecompilation : struct, IFlag; ref readonly BlockExecutionContext BlockExecutionContext { get; } ref readonly TxExecutionContext TxExecutionContext { get; } void SetBlockExecutionContext(in BlockExecutionContext blockExecutionContext); diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs index 7b617177595..3ee8702f219 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Math2Param.cs @@ -269,7 +269,7 @@ public static EvmExceptionType InstructionExp(VirtualMachine vm, r goto StackUnderflow; // Pop the exponent as a 256-bit word. - Span bytes = stack.PopWord256(); + ReadOnlySpan bytes = stack.PopWord256(); // Determine the effective byte-length of the exponent. int leadingZeros = bytes.LeadingZerosCount(); diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.cs index 6caeeb3d873..693b1ba2aec 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.cs @@ -6,8 +6,8 @@ using System.Runtime.CompilerServices; using Nethermind.Core; using Nethermind.Core.Specs; -using Nethermind.Evm.Precompiles; +[assembly: InternalsVisibleTo("Nethermind.Evm.Precompiles")] namespace Nethermind.Evm; using unsafe OpCode = delegate*; using Int256; @@ -366,7 +366,7 @@ private static bool ChargeAccountAccessGas(ref long gasAvailable, VirtualMachine } // If the account is cold (and not a precompile), charge the cold access cost. - if (!address.IsPrecompile(spec) && vmState.AccessTracker.WarmUp(address)) + if (!vm.CodeInfoRepository.IsPrecompile(address, spec) && vmState.AccessTracker.WarmUp(address)) { result = UpdateGas(GasCostOf.ColdAccountAccess, ref gasAvailable); } diff --git a/src/Nethermind/Nethermind.Evm/Metrics.cs b/src/Nethermind/Nethermind.Evm/Metrics.cs index f3333cd2edd..e820dc3eabd 100644 --- a/src/Nethermind/Nethermind.Evm/Metrics.cs +++ b/src/Nethermind/Nethermind.Evm/Metrics.cs @@ -13,6 +13,13 @@ namespace Nethermind.Evm; public class Metrics { + [CounterMetric] + [Description("Number of Code DB cache reads.")] + public static long CodeDbCache => _codeDbCache.GetTotalValue(); + private static readonly ZeroContentionCounter _codeDbCache = new(); + [Description("Number of Code DB cache reads on thread.")] + internal static long ThreadLocalCodeDbCache => _codeDbCache.ThreadLocalValue; + internal static void IncrementCodeDbCache() => _codeDbCache.Increment(); [CounterMetric] [Description("Number of EVM exceptions thrown by contracts.")] public static long EvmExceptions { get; set; } @@ -61,60 +68,6 @@ public class Metrics [Description("Number of EXP opcodes executed.")] public static long ExpOpcode { get; set; } - [Description("Number of BN254_MUL precompile calls.")] - public static long Bn254MulPrecompile { get; set; } - - [Description("Number of BN254_ADD precompile calls.")] - public static long Bn254AddPrecompile { get; set; } - - [Description("Number of BN254_PAIRING precompile calls.")] - public static long Bn254PairingPrecompile { get; set; } - - [Description("Number of BLS12_G1ADD precompile calls.")] - public static long BlsG1AddPrecompile { get; set; } - - [Description("Number of BLS12_G1MUL precompile calls.")] - public static long BlsG1MulPrecompile { get; set; } - - [Description("Number of BLS12_G1MSM precompile calls.")] - public static long BlsG1MSMPrecompile { get; set; } - - [Description("Number of BLS12_G2ADD precompile calls.")] - public static long BlsG2AddPrecompile { get; set; } - - [Description("Number of BLS12_G2MUL precompile calls.")] - public static long BlsG2MulPrecompile { get; set; } - - [Description("Number of BLS12_G2MSM precompile calls.")] - public static long BlsG2MSMPrecompile { get; set; } - - [Description("Number of BLS12_PAIRING_CHECK precompile calls.")] - public static long BlsPairingCheckPrecompile { get; set; } - - [Description("Number of BLS12_MAP_FP_TO_G1 precompile calls.")] - public static long BlsMapFpToG1Precompile { get; set; } - - [Description("Number of BLS12_MAP_FP2_TO_G2 precompile calls.")] - public static long BlsMapFp2ToG2Precompile { get; set; } - - [Description("Number of EC_RECOVERY precompile calls.")] - public static long EcRecoverPrecompile { get; set; } - - [Description("Number of MODEXP precompile calls.")] - public static long ModExpPrecompile { get; set; } - - [Description("Number of RIPEMD160 precompile calls.")] - public static long Ripemd160Precompile { get; set; } - - [Description("Number of SHA256 precompile calls.")] - public static long Sha256Precompile { get; set; } - - [Description("Number of Secp256r1 precompile calls.")] - public static long Secp256r1Precompile { get; set; } - - [Description("Number of Point Evaluation precompile calls.")] - public static long PointEvaluationPrecompile { get; set; } - public static long _IlvmContractsAnalyzed; [Description("Number of contracts analyzed by ILVM")] // "ILVM" is an abbreviation for "Intermediate Language Virtual Machine public static long IlvmContractsAnalyzed => _IlvmContractsAnalyzed; @@ -216,8 +169,6 @@ public static void IncrementIlvmAotDllSaved() Interlocked.Increment(ref _IlvmAotCacheTouched); } - - [CounterMetric] [Description("Number of calls made to addresses without code.")] public static long EmptyCalls => _emptyCalls.GetTotalValue(); diff --git a/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj b/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj index ada3e4ddfcc..f24ddd0cd1e 100644 --- a/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj +++ b/src/Nethermind/Nethermind.Evm/Nethermind.Evm.csproj @@ -14,12 +14,6 @@ - - - - - - diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/AddressExtensions.cs b/src/Nethermind/Nethermind.Evm/Precompiles/AddressExtensions.cs index eb6392747bb..2ea5c2f3dbb 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/AddressExtensions.cs +++ b/src/Nethermind/Nethermind.Evm/Precompiles/AddressExtensions.cs @@ -24,9 +24,9 @@ public static bool IsPrecompile(this Address address, IReleaseSpec releaseSpec) 0x03 => true, 0x04 => true, 0x05 => releaseSpec.ModExpEnabled, - 0x06 => releaseSpec.Bn128Enabled, - 0x07 => releaseSpec.Bn128Enabled, - 0x08 => releaseSpec.Bn128Enabled, + 0x06 => releaseSpec.BN254Enabled, + 0x07 => releaseSpec.BN254Enabled, + 0x08 => releaseSpec.BN254Enabled, 0x09 => releaseSpec.BlakeEnabled, 0x0a => releaseSpec.IsEip4844Enabled, 0x0b => releaseSpec.Bls381Enabled, diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Blake2FPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Blake2FPrecompile.cs deleted file mode 100644 index 30c83984126..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Blake2FPrecompile.cs +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using Nethermind.Core; -using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; -using Nethermind.Crypto.Blake2; - -namespace Nethermind.Evm.Precompiles -{ - public class Blake2FPrecompile : IPrecompile - { - private const int RequiredInputLength = 213; - - private readonly Blake2Compression _blake = new(); - - public static readonly Blake2FPrecompile Instance = new(); - - public static Address Address { get; } = Address.FromNumber(9); - - public long BaseGasCost(IReleaseSpec releaseSpec) => 0; - - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - if (inputData.Length != RequiredInputLength) - { - return 0; - } - - byte finalByte = inputData.Span[212]; - if (finalByte != 0 && finalByte != 1) - { - return 0; - } - - uint rounds = inputData[..4].Span.ReadEthUInt32(); - - return rounds; - } - - public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - if (inputData.Length != RequiredInputLength) - { - return IPrecompile.Failure; - } - - byte finalByte = inputData.Span[212]; - if (finalByte != 0 && finalByte != 1) - { - return IPrecompile.Failure; - } - - byte[] result = new byte[64]; - _blake.Compress(inputData.Span, result); - - return (result, true); - } - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/Discount.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Bls/Discount.cs deleted file mode 100644 index 3b05ee5ecb1..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Bls/Discount.cs +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -namespace Nethermind.Evm.Precompiles.Bls -{ - /// - /// https://eips.ethereum.org/EIPS/eip-2537 - /// - internal static class Discount - { - public static int ForG1(int k) => k >= 128 ? _maxDiscountG1 : _discountTable[k].g1; - public static int ForG2(int k) => k >= 128 ? _maxDiscountG2 : _discountTable[k].g2; - - private const int _maxDiscountG1 = 519; - private const int _maxDiscountG2 = 524; - - private static readonly (int g1, int g2)[] _discountTable = - { - (0, 0), // 0 - (1000, 1000), // 1 - (949, 1000), // 2 - (848, 923), // 3 - (797, 884), // 4 - (764, 855), // 5 - (750, 832), // 6 - (738, 812), // 7 - (728, 796), // 8 - (719, 782), // 9 - (712, 770), // 10 - (705, 759), // 11 - (698, 749), // 12 - (692, 740), // 13 - (687, 732), // 14 - (682, 724), // 15 - (677, 717), // 16 - (673, 711), // 17 - (669, 704), // 18 - (665, 699), // 19 - (661, 693), // 20 - (658, 688), // 21 - (654, 683), // 22 - (651, 679), // 23 - (648, 674), // 24 - (645, 670), // 25 - (642, 666), // 26 - (640, 663), // 27 - (637, 659), // 28 - (635, 655), // 29 - (632, 652), // 30 - (630, 649), // 31 - (627, 646), // 32 - (625, 643), // 33 - (623, 640), // 34 - (621, 637), // 35 - (619, 634), // 36 - (617, 632), // 37 - (615, 629), // 38 - (613, 627), // 39 - (611, 624), // 40 - (609, 622), // 41 - (608, 620), // 42 - (606, 618), // 43 - (604, 615), // 44 - (603, 613), // 45 - (601, 611), // 46 - (599, 609), // 47 - (598, 607), // 48 - (596, 606), // 49 - (595, 604), // 50 - (593, 602), // 51 - (592, 600), // 52 - (591, 598), // 53 - (589, 597), // 54 - (588, 595), // 55 - (586, 593), // 56 - (585, 592), // 57 - (584, 590), // 58 - (582, 589), // 59 - (581, 587), // 60 - (580, 586), // 61 - (579, 584), // 62 - (577, 583), // 63 - (576, 582), // 64 - (575, 580), // 65 - (574, 579), // 66 - (573, 578), // 67 - (572, 576), // 68 - (570, 575), // 69 - (569, 574), // 70 - (568, 573), // 71 - (567, 571), // 72 - (566, 570), // 73 - (565, 569), // 74 - (564, 568), // 75 - (563, 567), // 76 - (562, 566), // 77 - (561, 565), // 78 - (560, 563), // 79 - (559, 562), // 80 - (558, 561), // 81 - (557, 560), // 82 - (556, 559), // 83 - (555, 558), // 84 - (554, 557), // 85 - (553, 556), // 86 - (552, 555), // 87 - (551, 554), // 88 - (550, 553), // 89 - (549, 552), // 90 - (548, 552), // 91 - (547, 551), // 92 - (547, 550), // 93 - (546, 549), // 94 - (545, 548), // 95 - (544, 547), // 96 - (543, 546), // 97 - (542, 545), // 98 - (541, 545), // 99 - (540, 544), // 100 - (540, 543), // 101 - (539, 542), // 102 - (538, 541), // 103 - (537, 541), // 104 - (536, 540), // 105 - (536, 539), // 106 - (535, 538), // 107 - (534, 537), // 108 - (533, 537), // 109 - (532, 536), // 110 - (532, 535), // 111 - (531, 535), // 112 - (530, 534), // 113 - (529, 533), // 114 - (528, 532), // 115 - (528, 532), // 116 - (527, 531), // 117 - (526, 530), // 118 - (525, 530), // 119 - (525, 529), // 120 - (524, 528), // 121 - (523, 528), // 122 - (522, 527), // 123 - (522, 526), // 124 - (521, 526), // 125 - (520, 525), // 126 - (520, 524), // 127 - (519, 524) // 128 - }; - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/EcRecoverPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/EcRecoverPrecompile.cs deleted file mode 100644 index ab785afd2ce..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/EcRecoverPrecompile.cs +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Runtime.CompilerServices; -using Nethermind.Core; -using Nethermind.Core.Crypto; -using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; -using Nethermind.Crypto; - -namespace Nethermind.Evm.Precompiles -{ - public class EcRecoverPrecompile : IPrecompile - { - public static readonly EcRecoverPrecompile Instance = new(); - - private EcRecoverPrecompile() - { - } - - public static Address Address { get; } = Address.FromNumber(1); - - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; - - public long BaseGasCost(IReleaseSpec releaseSpec) => 3000L; - - private readonly byte[] _zero31 = new byte[31]; - - public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - Metrics.EcRecoverPrecompile++; - return inputData.Length >= 128 ? RunInternal(inputData.Span) : RunInternal(inputData); - } - - private (byte[], bool) RunInternal(ReadOnlyMemory inputData) - { - Span inputDataSpan = stackalloc byte[128]; - inputData.Span[..Math.Min(128, inputData.Length)] - .CopyTo(inputDataSpan[..Math.Min(128, inputData.Length)]); - - return RunInternal(inputDataSpan); - } - - private (byte[], bool) RunInternal(ReadOnlySpan inputDataSpan) - { - ReadOnlySpan vBytes = inputDataSpan.Slice(32, 32); - - // TEST: CALLCODEEcrecoverV_prefixedf0_d0g0v0 - // TEST: CALLCODEEcrecoverV_prefixedf0_d1g0v0 - if (!Bytes.AreEqual(_zero31, vBytes[..31])) - { - return ([], true); - } - - byte v = vBytes[31]; - if (v != 27 && v != 28) - { - return ([], true); - } - - Span publicKey = stackalloc byte[65]; - if (!EthereumEcdsa.RecoverAddressRaw(inputDataSpan.Slice(64, 64), Signature.GetRecoveryId(v), inputDataSpan[..32], publicKey)) - { - return ([], true); - } - - byte[] result = ValueKeccak.Compute(publicKey.Slice(1, 64)).ToByteArray(); - result.AsSpan(0, 12).Clear(); - return (result, true); - } - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Extensions.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Extensions.cs deleted file mode 100644 index 43ba06acdea..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Extensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; - -namespace Nethermind.Evm.Precompiles -{ - public static class Extensions - { - public static void PrepareEthInput(this ReadOnlyMemory inputData, Span inputDataSpan) - { - inputData.Span[..Math.Min(inputDataSpan.Length, inputData.Length)] - .CopyTo(inputDataSpan[..Math.Min(inputDataSpan.Length, inputData.Length)]); - } - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/IPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/IPrecompile.cs index 55536651958..b6f3c929476 100644 --- a/src/Nethermind/Nethermind.Evm/Precompiles/IPrecompile.cs +++ b/src/Nethermind/Nethermind.Evm/Precompiles/IPrecompile.cs @@ -10,6 +10,7 @@ namespace Nethermind.Evm.Precompiles public interface IPrecompile { static virtual Address Address => Address.Zero; + static virtual string Name => string.Empty; long BaseGasCost(IReleaseSpec releaseSpec); diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/IdentityPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/IdentityPrecompile.cs deleted file mode 100644 index 224aa6fd42d..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/IdentityPrecompile.cs +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using Nethermind.Core; -using Nethermind.Core.Specs; - -namespace Nethermind.Evm.Precompiles -{ - public class IdentityPrecompile : IPrecompile - { - public static readonly IdentityPrecompile Instance = new(); - - private IdentityPrecompile() - { - } - - public static Address Address { get; } = Address.FromNumber(4); - - public long BaseGasCost(IReleaseSpec releaseSpec) => 15L; - - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 3L * EvmInstructions.Div32Ceiling((ulong)inputData.Length); - - public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - return (inputData.ToArray(), true); - } - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/ModExpPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/ModExpPrecompile.cs deleted file mode 100644 index ffda26020a5..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/ModExpPrecompile.cs +++ /dev/null @@ -1,260 +0,0 @@ -// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Numerics; -using System.Runtime.InteropServices; -using Nethermind.Core; -using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; -using Nethermind.GmpBindings; -using Nethermind.Int256; - -namespace Nethermind.Evm.Precompiles; - -/// -/// https://github.com/ethereum/EIPs/blob/vbuterin-patch-2/EIPS/bigint_modexp.md -/// -public class ModExpPrecompile : IPrecompile -{ - public static readonly ModExpPrecompile Instance = new(); - /// - /// Maximum input size (in bytes) for the modular exponentiation operation under EIP-7823. - /// This constant defines the upper limit for the size of the input data that can be processed. - /// For more details, see: https://eips.ethereum.org/EIPS/eip-7823 - /// - public const int ModExpMaxInputSizeEip7823 = 1024; - - private ModExpPrecompile() - { - } - - public static Address Address { get; } = Address.FromNumber(5); - - public long BaseGasCost(IReleaseSpec releaseSpec) => 0L; - - /// - /// https://github.com/ethereum/EIPs/pull/2892 - /// ADJUSTED_EXPONENT_LENGTH is defined as follows. - /// If length_of_EXPONENT <= 32, and all bits in EXPONENT are 0, return 0 - /// If length_of_EXPONENT <= 32, then return the index of the highest bit in EXPONENT (eg. 1 -> 0, 2 -> 1, 3 -> 1, 255 -> 7, 256 -> 8). - /// If length_of_EXPONENT > 32, then return 8 * (length_of_EXPONENT - 32) plus the index of the highest bit in the first 32 bytes of EXPONENT (eg. if EXPONENT = \x00\x00\x01\x00.....\x00, with one hundred bytes, then the result is 8 * (100 - 32) + 253 = 797). If all of the first 32 bytes of EXPONENT are zero, return exactly 8 * (length_of_EXPONENT - 32). - /// - /// - /// - /// Gas cost of the MODEXP operation in the context of EIP2565 - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - if (!releaseSpec.IsEip2565Enabled) - { -#pragma warning disable 618 - return ModExpPrecompilePreEip2565.Instance.DataGasCost(inputData, releaseSpec); -#pragma warning restore 618 - } - - try - { - return inputData.Length >= 96 - ? DataGasCostInternal(inputData.Span.Slice(0, 96), inputData, releaseSpec) - : DataGasCostInternal(inputData, releaseSpec); - } - catch (OverflowException) - { - return long.MaxValue; - } - } - - private static long DataGasCostInternal(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - Span extendedInput = stackalloc byte[96]; - inputData[..Math.Min(96, inputData.Length)].Span - .CopyTo(extendedInput[..Math.Min(96, inputData.Length)]); - - return DataGasCostInternal(extendedInput, inputData, releaseSpec); - } - - private static long DataGasCostInternal(ReadOnlySpan extendedInput, ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - UInt256 baseLength = new(extendedInput[..32], true); - UInt256 expLength = new(extendedInput.Slice(32, 32), true); - UInt256 modulusLength = new(extendedInput.Slice(64, 32), true); - - if (ExceedsMaxInputSize(releaseSpec, baseLength, expLength, modulusLength)) - { - return long.MaxValue; - } - - UInt256 complexity = MultComplexity(baseLength, modulusLength, releaseSpec.IsEip7883Enabled); - - UInt256 expLengthUpTo32 = UInt256.Min(32, expLength); - UInt256 startIndex = 96 + baseLength; //+ expLength - expLengthUpTo32; // Geth takes head here, why? - UInt256 exp = new(inputData.Span.SliceWithZeroPaddingEmptyOnError((int)startIndex, (int)expLengthUpTo32), true); - UInt256 iterationCount = CalculateIterationCount(expLength, exp, releaseSpec.IsEip7883Enabled); - bool overflow = UInt256.MultiplyOverflow(complexity, iterationCount, out UInt256 result); - result /= 3; - return result > long.MaxValue || overflow - ? long.MaxValue - : Math.Max(releaseSpec.IsEip7883Enabled ? GasCostOf.MinModExpEip7883 : GasCostOf.MinModExpEip2565, (long)result); - } - - private static bool ExceedsMaxInputSize(IReleaseSpec releaseSpec, UInt256 baseLength, UInt256 expLength, UInt256 modulusLength) - => releaseSpec.IsEip7823Enabled && - (baseLength > ModExpMaxInputSizeEip7823 || expLength > ModExpMaxInputSizeEip7823 || modulusLength > ModExpMaxInputSizeEip7823); - - private static (int, int, int) GetInputLengths(ReadOnlyMemory inputData) - { - Span extendedInput = stackalloc byte[96]; - inputData[..Math.Min(96, inputData.Length)].Span - .CopyTo(extendedInput[..Math.Min(96, inputData.Length)]); - - int baseLength = (int)new UInt256(extendedInput[..32], true); - UInt256 expLengthUint256 = new(extendedInput.Slice(32, 32), true); - int expLength = expLengthUint256 > Array.MaxLength ? Array.MaxLength : (int)expLengthUint256; - int modulusLength = (int)new UInt256(extendedInput.Slice(64, 32), true); - - return (baseLength, expLength, modulusLength); - } - - public unsafe (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - Metrics.ModExpPrecompile++; - - (int baseLength, int expLength, int modulusLength) = GetInputLengths(inputData); - - if (ExceedsMaxInputSize(releaseSpec, (uint)baseLength, (uint)expLength, (uint)modulusLength)) - return IPrecompile.Failure; - - // if both are 0, then expLength can be huge, which leads to a potential buffer too big exception - if (baseLength == 0 && modulusLength == 0) - return (Bytes.Empty, true); - - using var modulusInt = mpz_t.Create(); - - fixed (byte* modulusData = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength + expLength, modulusLength)) - { - if (modulusData is not null) - Gmp.mpz_import(modulusInt, (nuint)modulusLength, 1, 1, 1, nuint.Zero, (nint)modulusData); - } - - if (Gmp.mpz_sgn(modulusInt) == 0) - return (new byte[modulusLength], true); - - using var baseInt = mpz_t.Create(); - using var expInt = mpz_t.Create(); - using var powmResult = mpz_t.Create(); - - fixed (byte* baseData = inputData.Span.SliceWithZeroPaddingEmptyOnError(96, baseLength)) - fixed (byte* expData = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength, expLength)) - { - if (baseData is not null) - Gmp.mpz_import(baseInt, (nuint)baseLength, 1, 1, 1, nuint.Zero, (nint)baseData); - - if (expData is not null) - Gmp.mpz_import(expInt, (nuint)expLength, 1, 1, 1, nuint.Zero, (nint)expData); - } - - Gmp.mpz_powm(powmResult, baseInt, expInt, modulusInt); - - var powmResultLen = (int)(Gmp.mpz_sizeinbase(powmResult, 2) + 7) / 8; - var offset = modulusLength - powmResultLen; - byte[] result = new byte[modulusLength]; - - fixed (byte* ptr = result) - Gmp.mpz_export((nint)(ptr + offset), out _, 1, 1, 1, nuint.Zero, powmResult); - - return (result, true); - } - - [Obsolete("This is a previous implementation using BigInteger instead of GMP")] - public static (byte[], bool) OldRun(byte[] inputData) - { - Metrics.ModExpPrecompile++; - - (int baseLength, int expLength, int modulusLength) = GetInputLengths(inputData); - - BigInteger modulusInt = inputData - .SliceWithZeroPaddingEmptyOnError(96 + baseLength + expLength, modulusLength).ToUnsignedBigInteger(); - - if (modulusInt.IsZero) - { - return (new byte[modulusLength], true); - } - - BigInteger baseInt = inputData.SliceWithZeroPaddingEmptyOnError(96, baseLength).ToUnsignedBigInteger(); - BigInteger expInt = inputData.SliceWithZeroPaddingEmptyOnError(96 + baseLength, expLength) - .ToUnsignedBigInteger(); - return (BigInteger.ModPow(baseInt, expInt, modulusInt).ToBigEndianByteArray(modulusLength), true); - } - - /// - /// def calculate_multiplication_complexity(base_length, modulus_length): - /// max_length = max(base_length, modulus_length) - /// words = math.ceil(max_length / 8) - /// return words**2 - /// - /// - private static UInt256 MultComplexity(in UInt256 baseLength, in UInt256 modulusLength, bool isEip7883Enabled) - { - UInt256 maxLength = UInt256.Max(baseLength, modulusLength); - UInt256.Mod(maxLength, 8, out UInt256 mod8); - UInt256 words = (maxLength / 8) + (mod8.IsZero ? UInt256.Zero : UInt256.One); - - if (isEip7883Enabled) - { - return maxLength > 32 ? 2 * words * words : 16; - } - - return words * words; - } - - static readonly UInt256 IterationCountMultiplierEip2565 = 8; - - static readonly UInt256 IterationCountMultiplierEip7883 = 16; - - /// - /// def calculate_iteration_count(exponent_length, exponent): - /// iteration_count = 0 - /// if exponent_length <= 32 and exponent == 0: iteration_count = 0 - /// elif exponent_length <= 32: iteration_count = exponent.bit_length() - 1 - /// elif exponent_length > 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) - /// return max(iteration_count, 1) - /// - /// - /// - /// - /// - private static UInt256 CalculateIterationCount(UInt256 exponentLength, UInt256 exponent, bool isEip7883Enabled) - { - try - { - UInt256 iterationCount; - if (exponentLength <= 32) - { - iterationCount = exponent.IsZero ? UInt256.Zero : (UInt256)(exponent.BitLen - 1); - } - else - { - int bitLength = (exponent & UInt256.MaxValue).BitLen; - if (bitLength > 0) - { - bitLength--; - } - - bool overflow = UInt256.MultiplyOverflow(exponentLength - 32, - isEip7883Enabled ? IterationCountMultiplierEip7883 : IterationCountMultiplierEip2565, - out UInt256 multiplicationResult); - overflow |= UInt256.AddOverflow(multiplicationResult, (UInt256)bitLength, out iterationCount); - if (overflow) - { - return UInt256.MaxValue; - } - } - - return UInt256.Max(iterationCount, UInt256.One); - } - catch (OverflowException) - { - return UInt256.MaxValue; - } - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/ModExpPrecompilePreEip2565.cs b/src/Nethermind/Nethermind.Evm/Precompiles/ModExpPrecompilePreEip2565.cs deleted file mode 100644 index 71a6a83208b..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/ModExpPrecompilePreEip2565.cs +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Numerics; -using Nethermind.Core; -using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; -using Nethermind.Int256; - -namespace Nethermind.Evm.Precompiles -{ - /// - /// https://github.com/ethereum/EIPs/blob/vbuterin-patch-2/EIPS/bigint_modexp.md - /// - [Obsolete("Pre-eip2565 implementation")] - public class ModExpPrecompilePreEip2565 : IPrecompile - { - public static ModExpPrecompilePreEip2565 Instance = new(); - private static readonly UInt256 Eight = 8; - - private ModExpPrecompilePreEip2565() - { - } - - public static Address Address { get; } = Address.FromNumber(5); - - public long BaseGasCost(IReleaseSpec releaseSpec) => 0L; - - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - try - { - return inputData.Length >= 96 - ? DataGasCostInternal(inputData.Span.Slice(0, 96), inputData, releaseSpec) - : DataGasCostInternal(inputData, releaseSpec); - } - catch (OverflowException) - { - return long.MaxValue; - } - } - - private static long DataGasCostInternal(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - Span extendedInput = stackalloc byte[96]; - inputData[..Math.Min(96, inputData.Length)].Span - .CopyTo(extendedInput[..Math.Min(96, inputData.Length)]); - - return DataGasCostInternal(extendedInput, inputData, releaseSpec); - } - - private static long DataGasCostInternal(ReadOnlySpan extendedInput, ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - UInt256 baseLength = new(extendedInput[..32], true); - UInt256 expLength = new(extendedInput.Slice(32, 32), true); - UInt256 modulusLength = new(extendedInput.Slice(64, 32), true); - - UInt256 complexity = MultComplexity(UInt256.Max(baseLength, modulusLength)); - - byte[] expSignificantBytes = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + (int)baseLength, (int)UInt256.Min(expLength, 32)); - - UInt256 lengthOver32 = expLength <= 32 ? 0 : expLength - 32; - UInt256 adjusted = AdjustedExponentLength(lengthOver32, expSignificantBytes); - UInt256 gas = complexity * UInt256.Max(adjusted, UInt256.One) / 20; - return gas > long.MaxValue ? long.MaxValue : (long)gas; - } - - public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - Metrics.ModExpPrecompile++; - - int baseLength = (int)inputData.Span.SliceWithZeroPaddingEmptyOnError(0, 32).ToUnsignedBigInteger(); - BigInteger expLengthBig = inputData.Span.SliceWithZeroPaddingEmptyOnError(32, 32).ToUnsignedBigInteger(); - int expLength = expLengthBig > int.MaxValue ? int.MaxValue : (int)expLengthBig; - int modulusLength = (int)inputData.Span.SliceWithZeroPaddingEmptyOnError(64, 32).ToUnsignedBigInteger(); - - BigInteger modulusInt = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength + expLength, modulusLength).ToUnsignedBigInteger(); - - if (modulusInt.IsZero) - { - return (new byte[modulusLength], true); - } - - BigInteger baseInt = inputData.Span.SliceWithZeroPaddingEmptyOnError(96, baseLength).ToUnsignedBigInteger(); - BigInteger expInt = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength, expLength).ToUnsignedBigInteger(); - return (BigInteger.ModPow(baseInt, expInt, modulusInt).ToBigEndianByteArray(modulusLength), true); - } - - private static UInt256 MultComplexity(in UInt256 adjustedExponentLength) - { - if (adjustedExponentLength <= 64) - { - return adjustedExponentLength * adjustedExponentLength; - } - - if (adjustedExponentLength <= 1024) - { - return adjustedExponentLength * adjustedExponentLength / 4 + 96 * adjustedExponentLength - 3072; - } - - return adjustedExponentLength * adjustedExponentLength / 16 + 480 * adjustedExponentLength - 199680; - } - - private static UInt256 AdjustedExponentLength(in UInt256 lengthOver32, byte[] exponent) - { - bool overflow = false; - bool underflow = false; - UInt256 result; - - int leadingZeros = exponent.AsSpan().LeadingZerosCount(); - if (leadingZeros == exponent.Length) - { - overflow |= UInt256.MultiplyOverflow(lengthOver32, Eight, out result); - return overflow ? UInt256.MaxValue : result; - } - - overflow |= UInt256.AddOverflow(lengthOver32, (UInt256)exponent.Length, out result); - underflow |= UInt256.SubtractUnderflow(result, (UInt256)leadingZeros, out result); - underflow |= UInt256.SubtractUnderflow(result, UInt256.One, out result); - overflow |= UInt256.MultiplyOverflow(result, Eight, out result); - overflow |= UInt256.AddOverflow(result, (UInt256)exponent[leadingZeros].GetHighestSetBitIndex(), out result); - underflow |= UInt256.SubtractUnderflow(result, UInt256.One, out result); - - return overflow ? UInt256.MaxValue : underflow ? UInt256.MinValue : result; - } - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Ripemd160Precompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Ripemd160Precompile.cs deleted file mode 100644 index 6e2135bfccf..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Ripemd160Precompile.cs +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using Nethermind.Core; -using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; -using Nethermind.Crypto; - -namespace Nethermind.Evm.Precompiles -{ - public class Ripemd160Precompile : IPrecompile - { - public static readonly Ripemd160Precompile Instance = new(); - - // missing in .NET Core - // private static RIPEMD160 _ripemd; - - private Ripemd160Precompile() - { - // missing in .NET Core - // _ripemd = RIPEMD160.Create(); - // _ripemd.Initialize(); - } - - public static Address Address { get; } = Address.FromNumber(3); - - public long BaseGasCost(IReleaseSpec releaseSpec) => 600L; - - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 120L * EvmInstructions.Div32Ceiling((ulong)inputData.Length); - - public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - Metrics.Ripemd160Precompile++; - - return (Ripemd.Compute(inputData.ToArray()).PadLeft(32), true); - } - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Sha256Precompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Sha256Precompile.cs deleted file mode 100644 index 5be824b5311..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Sha256Precompile.cs +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Security.Cryptography; -using System.Threading; -using Nethermind.Core; -using Nethermind.Core.Specs; - -namespace Nethermind.Evm.Precompiles -{ - public class Sha256Precompile : IPrecompile - { - public static readonly Sha256Precompile Instance = new(); - - private Sha256Precompile() { } - - public static Address Address { get; } = Address.FromNumber(2); - - public long BaseGasCost(IReleaseSpec releaseSpec) => 60L; - - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 12L * EvmInstructions.Div32Ceiling((ulong)inputData.Length); - - public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - Metrics.Sha256Precompile++; - - byte[] output = new byte[SHA256.HashSizeInBytes]; - bool success = SHA256.TryHashData(inputData.Span, output, out int bytesWritten); - - return (output, success && bytesWritten == SHA256.HashSizeInBytes); - } - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Snarks/Bn254AddPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Snarks/Bn254AddPrecompile.cs deleted file mode 100644 index 9c8e171836c..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Snarks/Bn254AddPrecompile.cs +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using Nethermind.Core; -using Nethermind.Core.Specs; -using Nethermind.Crypto; - -namespace Nethermind.Evm.Precompiles.Snarks; - -/// -/// https://github.com/matter-labs/eip1962/blob/master/eip196_header.h -/// -public class Bn254AddPrecompile : IPrecompile -{ - public static readonly Bn254AddPrecompile Instance = new(); - - public static Address Address { get; } = Address.FromNumber(6); - - public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 150L : 500L; - - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; - - public unsafe (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - Metrics.Bn254AddPrecompile++; - return inputData.Length == 128 ? RunInternal(inputData.Span) : RunInternal(inputData); - } - - private static (byte[], bool) RunInternal(ReadOnlyMemory inputData) - { - Span inputDataSpan = stackalloc byte[128]; - inputData.PrepareEthInput(inputDataSpan); - return RunInternal(inputDataSpan); - } - - private static (byte[], bool) RunInternal(ReadOnlySpan inputDataSpan) - { - byte[] output = GC.AllocateUninitializedArray(64); - return Pairings.Bn254Add(inputDataSpan, output) ? (output, true) : IPrecompile.Failure; - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Snarks/Bn254MulPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Snarks/Bn254MulPrecompile.cs deleted file mode 100644 index 3a4bf261c95..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Snarks/Bn254MulPrecompile.cs +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using Nethermind.Core; -using Nethermind.Core.Specs; -using Nethermind.Crypto; - -namespace Nethermind.Evm.Precompiles.Snarks; - -/// -/// https://github.com/herumi/mcl/blob/master/api.md -/// -public class Bn254MulPrecompile : IPrecompile -{ - public static readonly Bn254MulPrecompile Instance = new(); - - public static Address Address { get; } = Address.FromNumber(7); - - public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 6000L : 40000L; - - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => 0L; - - public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - Metrics.Bn254MulPrecompile++; - return inputData.Length == 96 ? RunInternal(inputData.Span) : RunInternal(inputData); - } - - private static (byte[], bool) RunInternal(ReadOnlyMemory inputData) - { - Span inputDataSpan = stackalloc byte[96]; - inputData.PrepareEthInput(inputDataSpan); - return RunInternal(inputDataSpan); - } - - private static (byte[], bool) RunInternal(ReadOnlySpan inputDataSpan) - { - byte[] output = GC.AllocateUninitializedArray(64); - return Pairings.Bn254Mul(inputDataSpan, output) ? (output, true) : IPrecompile.Failure; - } -} diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Snarks/Bn254PairingPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Snarks/Bn254PairingPrecompile.cs deleted file mode 100644 index 22847a90c7e..00000000000 --- a/src/Nethermind/Nethermind.Evm/Precompiles/Snarks/Bn254PairingPrecompile.cs +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Buffers; -using Nethermind.Core; -using Nethermind.Core.Specs; -using Nethermind.Crypto; - -namespace Nethermind.Evm.Precompiles.Snarks; - -/// -/// https://github.com/herumi/mcl/blob/master/api.md -/// -public class Bn254PairingPrecompile : IPrecompile -{ - private const int Bn256PairingMaxInputSizeGranite = 112687; - private const int PairSize = 192; - - public static readonly Bn254PairingPrecompile Instance = new(); - - public static Address Address { get; } = Address.FromNumber(8); - - public long BaseGasCost(IReleaseSpec releaseSpec) => releaseSpec.IsEip1108Enabled ? 45000L : 100000L; - - public long DataGasCost(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) => (releaseSpec.IsEip1108Enabled ? 34000L : 80000L) * (inputData.Length / PairSize); - - public (byte[], bool) Run(ReadOnlyMemory inputData, IReleaseSpec releaseSpec) - { - Metrics.Bn254PairingPrecompile++; - if (releaseSpec.IsOpGraniteEnabled && inputData.Length > Bn256PairingMaxInputSizeGranite) - { - return IPrecompile.Failure; - } - if (inputData.Length % PairSize > 0) - { - // note that it will not happen in case of null / 0 length - return IPrecompile.Failure; - } - - byte[] inputDataArray = ArrayPool.Shared.Rent(inputData.Length); - - /* we modify input in place here and this is save for EVM but not - safe in benchmarks so we need to remember to clone */ - Span output = stackalloc byte[64]; - Span inputDataSpanReshuffled = inputDataArray.AsSpan(0, inputData.Length); - ReadOnlySpan inputDataSpan = inputData.Span; - Span inputReshuffled = stackalloc byte[PairSize]; - for (int i = 0; i < inputData.Length / PairSize; i++) - { - inputDataSpan.Slice(i * PairSize + 0, 64).CopyTo(inputReshuffled[..64]); - inputDataSpan.Slice(i * PairSize + 64, 32).CopyTo(inputReshuffled.Slice(96, 32)); - inputDataSpan.Slice(i * PairSize + 96, 32).CopyTo(inputReshuffled.Slice(64, 32)); - inputDataSpan.Slice(i * PairSize + 128, 32).CopyTo(inputReshuffled.Slice(160, 32)); - inputDataSpan.Slice(i * PairSize + 160, 32).CopyTo(inputReshuffled.Slice(128, 32)); - inputReshuffled.CopyTo(inputDataSpanReshuffled.Slice(i * PairSize, PairSize)); - } - - bool result = Pairings.Bn254Pairing(inputDataSpanReshuffled, output); - ArrayPool.Shared.Return(inputDataArray); - return result ? (output[..32].ToArray(), true) : IPrecompile.Failure; - } -} diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index 084d942314e..a7cef60895f 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -150,6 +150,24 @@ public interface ITxTracer : IWorldStateTracer, IDisposable || IsTracingFees || IsTracingLogs; + bool IsIlEvmInCompatible => // only allow reciepts for now, this enables ilevm to be easily tested by the existing setup + IsTracingActions + || IsTracingOpLevelStorage + || IsTracingMemory + || IsTracingInstructions + || IsTracingRefunds + || IsTracingCode + || IsTracingStack + || IsTracingBlockHash + || IsTracingAccess + || IsTracingFees + || IsTracingLogs + || IsTracingState + || IsTracingStorage; + + bool IsIlEvmCompatible => !IsIlEvmInCompatible; + + /// /// Transaction completed successfully /// diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 0e5458317f6..de2add32831 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -637,7 +637,9 @@ private int ExecuteEvmCall( using (EvmState state = EvmState.RentTopLevel(gasAvailable, executionType, in env, in accessedItems, in snapshot)) { - substate = VirtualMachine.ExecuteTransaction(state, WorldState, tracer); + substate = tracer.IsIlEvmCompatible + ? VirtualMachine.ExecuteTransaction(state, WorldState, tracer) + : VirtualMachine.ExecuteTransaction(state, WorldState, tracer); gasAvailable = state.GasAvailable; } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 002e34dce44..540b94042d3 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -135,11 +135,12 @@ public sealed unsafe partial class VirtualMachine( /// /// Thrown when an EVM-specific error occurs during execution. /// - public TransactionSubstate ExecuteTransaction( + public TransactionSubstate ExecuteTransaction( EvmState evmState, IWorldState worldState, ITxTracer txTracer) where TTracingInst : struct, IFlag + where TEnablePrecompilation : struct, IFlag { // Initialize dependencies for transaction tracing and state access. _txTracer = txTracer; @@ -191,9 +192,9 @@ public TransactionSubstate ExecuteTransaction( // Execute the regular EVM call if valid code is present; otherwise, mark as invalid. if (_currentState.Env.CodeInfo is not null) { - callResult = _txTracer.IsTracing - ? ExecuteCall(_previousCallResult, previousCallOutput, _previousCallOutputDestination) - : ExecuteCall(_previousCallResult, previousCallOutput, _previousCallOutputDestination); + callResult = _vmConfig.IsVmOptimizationEnabled + ? ExecuteCall(_previousCallResult, previousCallOutput, _previousCallOutputDestination) + : ExecuteCall(_previousCallResult, previousCallOutput, _previousCallOutputDestination); } else { @@ -974,7 +975,7 @@ private CallResult RunPrecompile(EvmState state) IReleaseSpec spec = BlockExecutionContext.Spec; long baseGasCost = precompile.BaseGasCost(spec); - long blobGasCost = precompile.DataGasCost(callData, spec); + long dataGasCost = precompile.DataGasCost(callData, spec); bool wasCreated = _worldState.AddToBalanceAndCreateIfNotExists(state.Env.ExecutingAccount, transferValue, spec); @@ -994,7 +995,7 @@ private CallResult RunPrecompile(EvmState state) _parityTouchBugAccount.ShouldDelete = true; } - if (!UpdateGas(checked(baseGasCost + blobGasCost), ref gasAvailable)) + if (!UpdateGas(checked(baseGasCost + dataGasCost), ref gasAvailable)) { return new(default, false, 0, true, EvmExceptionType.OutOfGas); } @@ -1056,6 +1057,7 @@ private CallResult ExecuteCall( ZeroPaddedSpan previousCallOutput, scoped in UInt256 previousCallOutputDestination) where TTracingInst : struct, IFlag + where TEnablePrecompilation : struct, IFlag { EvmState vmState = _currentState; // Obtain a reference to the execution environment for convenience. @@ -1076,7 +1078,7 @@ private CallResult ExecuteCall( if(typeof(TEnablePrecompilation) == typeof(OnFlag)) { - // IlAnalyzer.Analyse(env.CodeInfo as CodeInfo, ILMode.AOT_MODE, _vmConfig, _logger); + //if (env.CodeInfo.CodeHash is not null) IlAnalyzer.Analyse(env.CodeInfo as CodeInfo, ILMode.AOT_MODE, _vmConfig, _logger); env.CodeInfo.NoticeExecution(_vmConfig, _logger, Spec); } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs index 77d1c518c71..4777e2f026f 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateVirtualMachine.cs @@ -12,15 +12,18 @@ namespace Nethermind.Facade.Simulate; public class SimulateVirtualMachine(IVirtualMachine virtualMachine) : IVirtualMachine { - public TransactionSubstate ExecuteTransaction(EvmState state, IWorldState worldState, ITxTracer txTracer) + public TransactionSubstate ExecuteTransaction(EvmState state, IWorldState worldState, ITxTracer txTracer) where TTracingInst : struct, IFlag + where TEnablePrecompilation : struct, IFlag { if (txTracer.IsTracingActions && TryGetLogsMutator(txTracer, out ITxLogsMutator logsMutator)) { logsMutator.SetLogsToMutate(state.AccessTracker.Logs); } - return virtualMachine.ExecuteTransaction(state, worldState, txTracer); + return txTracer.IsIlEvmCompatible + ? virtualMachine.ExecuteTransaction(state, worldState, txTracer) + : virtualMachine.ExecuteTransaction(state, worldState, txTracer); } private static bool TryGetLogsMutator(ITxTracer txTracer, [NotNullWhen(true)] out ITxLogsMutator? txLogsMutator) diff --git a/src/Nethermind/Nethermind.Flashbots.Test/Rbuilder/RbuilderRpcModuleTests.cs b/src/Nethermind/Nethermind.Flashbots.Test/Rbuilder/RbuilderRpcModuleTests.cs index e0030f64f47..fe5636f3110 100644 --- a/src/Nethermind/Nethermind.Flashbots.Test/Rbuilder/RbuilderRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.Flashbots.Test/Rbuilder/RbuilderRpcModuleTests.cs @@ -10,6 +10,7 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; +using Nethermind.Core.Test.Db; using Nethermind.Db; using Nethermind.Evm.TransactionProcessing; using Nethermind.Flashbots.Modules.Rbuilder; diff --git a/src/Nethermind/Nethermind.Init.Snapshot/InitDatabaseSnapshot.cs b/src/Nethermind/Nethermind.Init.Snapshot/InitDatabaseSnapshot.cs index f15a56c24c6..6481c384d23 100644 --- a/src/Nethermind/Nethermind.Init.Snapshot/InitDatabaseSnapshot.cs +++ b/src/Nethermind/Nethermind.Init.Snapshot/InitDatabaseSnapshot.cs @@ -19,7 +19,7 @@ public class InitDatabaseSnapshot : InitDatabase private readonly INethermindApi _api; private readonly ILogger _logger; - public InitDatabaseSnapshot(INethermindApi api) : base(api) + public InitDatabaseSnapshot(INethermindApi api) : base() { _api = api; _logger = _api.LogManager.GetClassLogger(); diff --git a/src/Nethermind/Nethermind.Init/Modules/BlockProcessingModule.cs b/src/Nethermind/Nethermind.Init/Modules/BlockProcessingModule.cs index 98588394299..f488ef4f9b2 100644 --- a/src/Nethermind/Nethermind.Init/Modules/BlockProcessingModule.cs +++ b/src/Nethermind/Nethermind.Init/Modules/BlockProcessingModule.cs @@ -40,7 +40,7 @@ protected override void Load(ContainerBuilder builder) // Block processing components common between rpc, validation and production .AddScoped() - .AddScoped() + .AddScoped() .AddScoped() .AddScoped() .AddScoped() diff --git a/src/Nethermind/Nethermind.Init/Modules/ContainerBuilderExtensions.cs b/src/Nethermind/Nethermind.Init/Modules/ContainerBuilderExtensions.cs index 78835d53050..556179e7201 100644 --- a/src/Nethermind/Nethermind.Init/Modules/ContainerBuilderExtensions.cs +++ b/src/Nethermind/Nethermind.Init/Modules/ContainerBuilderExtensions.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Autofac; using Nethermind.Api; using Nethermind.Core; @@ -41,4 +42,28 @@ public static ContainerBuilder AddNetworkStorage(this ContainerBuilder builder, return new NetworkStorage(db, logManager); }); } + + // Note: The convention for `dbName` is that it is camelCase. + // this is not necessarily true for plugins. More importantly, this is also the path. Use the second overload for a more + // explicit param. + public static ContainerBuilder AddDatabase(this ContainerBuilder builder, string dbName) => builder + .AddDatabase(dbName, GetTitleDbName(dbName), dbName); + + public static ContainerBuilder AddDatabase(this ContainerBuilder builder, string keyName, string dbName, string path) => builder + .AddKeyedSingleton(keyName, (ctx) => ctx.Resolve() + .CreateDb(new DbSettings(dbName, path))); + + public static ContainerBuilder AddColumnDatabase(this ContainerBuilder builder, string dbName) where T : struct, Enum => + builder + .AddSingleton>((ctx) => ctx.Resolve() + .CreateColumnsDb(new DbSettings(GetTitleDbName(dbName), dbName))) + + .AddKeyedSingleton(dbName, (ctx) => + { + IColumnsDb db = ctx.Resolve>(); + if (db is ITunableDb tunableDb) return tunableDb; + return new NoopTunableDb(); + }); + + private static string GetTitleDbName(string dbName) => char.ToUpper(dbName[0]) + dbName[1..]; } diff --git a/src/Nethermind/Nethermind.Init/Modules/DbModule.cs b/src/Nethermind/Nethermind.Init/Modules/DbModule.cs new file mode 100644 index 00000000000..e78d9604220 --- /dev/null +++ b/src/Nethermind/Nethermind.Init/Modules/DbModule.cs @@ -0,0 +1,126 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Autofac; +using Nethermind.Api; +using Nethermind.Blockchain.Receipts; +using Nethermind.Blockchain.Synchronization; +using Nethermind.Core; +using Nethermind.Db; +using Nethermind.Db.Rocks; +using Nethermind.Db.Rpc; +using Nethermind.JsonRpc.Client; +using Nethermind.Logging; +using Nethermind.Serialization.Json; + +namespace Nethermind.Init.Modules; + +/// +/// Declares the default database and some classes for utility functions. +/// Additional databases can be added by plugin using the or +/// DSL. These just create a keyed , +/// so plugins can override individual database separately. To override all, replace . +/// These are all lazy as usual and no database is created until a service that require them is created. +/// +/// +/// +/// +public class DbModule( + IInitConfig initConfig, + IReceiptConfig receiptConfig, + ISyncConfig syncConfig +) : Module +{ + protected override void Load(ContainerBuilder builder) + { + builder + .AddSingleton() + .AddSingleton() + .AddScoped((dbProvider) => dbProvider.AsReadOnly(false)) + + // Allow requesting keyed specialization instead of `IDb`. + .AddKeyedAdapter((db) => db) + .AddKeyedAdapter((db) => db) + .AddKeyedAdapter((db) => + { + if (db is ITunableDb tunableDb) return tunableDb; + return new NoopTunableDb(); + }) + .AddKeyedAdapter((kv) => kv) + + // Monitoring use these to track active db. We intercept db factory to keep them lazy. Does not + // track db that is not created by db factory though... + .AddSingleton() + .AddDecorator() + + .AddDatabase(DbNames.State) + .AddDatabase(DbNames.Code) + .AddDatabase(DbNames.Metadata) + .AddDatabase(DbNames.BlockNumbers) + .AddDatabase(DbNames.BadBlocks) + .AddDatabase(DbNames.Blocks) + .AddDatabase(DbNames.Headers) + .AddDatabase(DbNames.BlockInfos) + .AddDatabase(DbNames.BadBlocks) + .AddDatabase(DbNames.Bloom) + .AddDatabase(DbNames.Metadata) + .AddDatabase(DbNames.BlobTransactions) + + .AddColumnDatabase(DbNames.Receipts) + .AddColumnDatabase(DbNames.BlobTransactions) + ; + + switch (initConfig.DiagnosticMode) + { + case DiagnosticMode.MemDb: + builder.AddSingleton(); + break; + case DiagnosticMode.RpcDb: + builder.AddDecorator(CreateRpcDbFactory); + break; + case DiagnosticMode.ReadOnlyDb: + builder.AddDecorator(); + break; + } + + // Change receipt db to readonlycolumndb if receipt is disabled + bool useReceiptsDb = receiptConfig.StoreReceipts || syncConfig.DownloadReceiptsInFastSync; + if (!useReceiptsDb) + { + builder.AddSingleton>((_) => new ReadOnlyColumnsDb(new MemColumnsDb(), false)); + } + + } + + private IDbFactory CreateRpcDbFactory( + IComponentContext ctx, + IDbFactory baseDbFactory) + { + IJsonSerializer jsonSerializer = ctx.Resolve(); + ILogManager logManager = ctx.Resolve(); + + RpcDbFactory rpcDbFactory = new( + baseDbFactory, + jsonSerializer, + new BasicJsonRpcClient( + new Uri(initConfig.RpcDbUrl), + jsonSerializer, + logManager + ), logManager); + return rpcDbFactory; + } + + private class ReadOnlyDbFactory(IDbFactory baseDbFactory) : IDbFactory + { + public IDb CreateDb(DbSettings dbSettings) + { + return baseDbFactory.CreateDb(dbSettings).AsReadOnly(true); + } + + public IColumnsDb CreateColumnsDb(DbSettings dbSettings) where T : struct, Enum + { + return baseDbFactory.CreateColumnsDb(dbSettings).CreateReadOnly(true); + } + } +} diff --git a/src/Nethermind/Nethermind.Init/Modules/NethermindModule.cs b/src/Nethermind/Nethermind.Init/Modules/NethermindModule.cs index 811dd729f4b..5ba9059520d 100644 --- a/src/Nethermind/Nethermind.Init/Modules/NethermindModule.cs +++ b/src/Nethermind/Nethermind.Init/Modules/NethermindModule.cs @@ -8,14 +8,13 @@ using Nethermind.Blockchain.Find; using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Spec; +using Nethermind.Blockchain.Synchronization; using Nethermind.Config; using Nethermind.Core; using Nethermind.Core.ServiceStopper; using Nethermind.Core.Specs; using Nethermind.Crypto; -using Nethermind.Db; using Nethermind.Era1; -using Nethermind.Facade.Simulate; using Nethermind.JsonRpc; using Nethermind.Logging; using Nethermind.Network.Config; @@ -40,17 +39,22 @@ protected override void Load(ContainerBuilder builder) .AddModule(new AppInputModule(chainSpec, configProvider, logManager)) .AddModule(new NetworkModule(configProvider)) .AddModule(new DiscoveryModule(configProvider.GetConfig(), configProvider.GetConfig())) + .AddModule(new DbModule( + configProvider.GetConfig(), + configProvider.GetConfig(), + configProvider.GetConfig() + )) .AddModule(new WorldStateModule(configProvider.GetConfig())) .AddModule(new BuiltInStepsModule()) .AddModule(new RpcModules(configProvider.GetConfig())) .AddModule(new EraModule()) .AddSource(new ConfigRegistrationSource()) - .AddModule(new DbModule()) .AddModule(new BlockProcessingModule()) .AddSingleton() .Bind() .AddSingleton((bt) => bt.AsReadOnly()) + .AddSingleton() .AddKeyedSingleton(IProtectedPrivateKey.NodeKey, (ctx) => ctx.Resolve().NodeKey!) .AddSingleton(Nethermind.Abi.AbiEncoder.Instance) @@ -67,6 +71,11 @@ protected override void Load(ContainerBuilder builder) .AddSingleton() .Add() // Not a singleton so that dispose is registered to correct lifetime ; + + if (!configProvider.GetConfig().BlobsSupport.IsPersistentStorage()) + { + builder.AddSingleton(NullBlobTxStorage.Instance); + } } // Just a wrapper to make it clear, these three are expected to be available at the time of configurations. diff --git a/src/Nethermind/Nethermind.Init/Modules/WorldStateModule.cs b/src/Nethermind/Nethermind.Init/Modules/WorldStateModule.cs index 9f4ddc96c45..64f7db5d99f 100644 --- a/src/Nethermind/Nethermind.Init/Modules/WorldStateModule.cs +++ b/src/Nethermind/Nethermind.Init/Modules/WorldStateModule.cs @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.IO.Abstractions; +using System.Threading; using Autofac; using Nethermind.Api; using Nethermind.Api.Steps; @@ -8,6 +10,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Core; using Nethermind.Db; +using Nethermind.Db.FullPruning; using Nethermind.Evm.State; using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Admin; @@ -23,6 +26,20 @@ protected override void Load(ContainerBuilder builder) { builder + // Special case for state db with pruning trie state. + .AddKeyedSingleton(DbNames.State, (ctx) => + { + DbSettings stateDbSettings = new DbSettings(GetTitleDbName(DbNames.State), DbNames.State); + IFileSystem fileSystem = ctx.Resolve(); + IDbFactory dbFactory = ctx.Resolve(); + return new FullPruningDb( + stateDbSettings, + dbFactory is not MemDbFactory + ? new FullPruningInnerDbFactory(dbFactory, fileSystem, stateDbSettings.DbPath) + : dbFactory, + () => Interlocked.Increment(ref Nethermind.Db.Metrics.StateDbInPruningWrites)); + }) + .AddSingleton(ctx => { IInitConfig initConfig = ctx.Resolve(); @@ -91,4 +108,6 @@ public PruningTrieStateFactoryOutput(PruningTrieStateFactory factory) AdminRpcModule = adminRpc; } } + + private static string GetTitleDbName(string dbName) => char.ToUpper(dbName[0]) + dbName[1..]; } diff --git a/src/Nethermind/Nethermind.Init/Steps/InitDatabase.cs b/src/Nethermind/Nethermind.Init/Steps/InitDatabase.cs index 8b540ac978c..6d737d25d8c 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitDatabase.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitDatabase.cs @@ -1,95 +1,24 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; -using System.IO; -using System.Reflection; using System.Threading; using System.Threading.Tasks; -using Nethermind.Api; using Nethermind.Api.Steps; -using Nethermind.Blockchain.Receipts; -using Nethermind.Blockchain.Synchronization; -using Nethermind.Db; -using Nethermind.Db.Rocks; -using Nethermind.Db.Rocks.Config; -using Nethermind.Db.Rpc; -using Nethermind.JsonRpc.Client; -using Nethermind.Logging; -using Nethermind.Trie; -using Nethermind.TxPool; +using Nethermind.Core.Attributes; namespace Nethermind.Init.Steps { [RunnerStepDependencies(typeof(ApplyMemoryHint))] + [Todo("Remove. Need to move `InitDatabaseSnapshot` to its own step also")] public class InitDatabase : IStep { - private readonly INethermindApi _api; - - public InitDatabase(INethermindApi api) - { - _api = api; - } - - public virtual async Task Execute(CancellationToken _) + public InitDatabase() { - ILogger logger = _api.LogManager.GetClassLogger(); - - /* sync */ - IDbConfig dbConfig = _api.Config(); - ISyncConfig syncConfig = _api.Config(); - IInitConfig initConfig = _api.Config(); - ITxPoolConfig txPoolConfig = _api.Config(); - IReceiptConfig receiptConfig = _api.Config(); - - foreach (PropertyInfo propertyInfo in typeof(IDbConfig).GetProperties()) - { - if (logger.IsDebug) logger.Debug($"DB {propertyInfo.Name}: {propertyInfo.GetValue(dbConfig)}"); - } - - try - { - bool useReceiptsDb = receiptConfig.StoreReceipts || syncConfig.DownloadReceiptsInFastSync; - bool useBlobsDb = txPoolConfig.BlobsSupport.IsPersistentStorage(); - InitDbApi(initConfig, dbConfig, receiptConfig.StoreReceipts || syncConfig.DownloadReceiptsInFastSync); - _api.DisposeStack.Push(_api.DbProvider!); - StandardDbInitializer dbInitializer = new(_api.DbProvider, _api.DbFactory, _api.FileSystem); - await dbInitializer.InitStandardDbsAsync(useReceiptsDb, useBlobsDb); - _api.BlobTxStorage = useBlobsDb - ? new BlobTxStorage(_api.DbProvider!.BlobTransactionsDb) - : NullBlobTxStorage.Instance; - } - catch (TypeInitializationException ex) - { - if (logger.IsError) - logger.Error("Failed loading RocksDB", ex); - } } - private void InitDbApi(IInitConfig initConfig, IDbConfig dbConfig, bool storeReceipts) + public virtual Task Execute(CancellationToken _) { - switch (initConfig.DiagnosticMode) - { - case DiagnosticMode.RpcDb: - _api.DbProvider = new DbProvider(); - RocksDbFactory rocksDbFactory = new(dbConfig, _api.LogManager, Path.Combine(initConfig.BaseDbPath, "debug")); - RpcDbFactory rpcDbFactory = new(rocksDbFactory, _api.EthereumJsonSerializer, new BasicJsonRpcClient(new Uri(initConfig.RpcDbUrl), _api.EthereumJsonSerializer, _api.LogManager), _api.LogManager); - _api.DbFactory = rpcDbFactory; - break; - case DiagnosticMode.ReadOnlyDb: - DbProvider rocksDbProvider = new(); - _api.DbProvider = new ReadOnlyDbProvider(rocksDbProvider, storeReceipts); // ToDo storeReceipts as createInMemoryWriteStore - bug? - _api.DbFactory = new RocksDbFactory(dbConfig, _api.LogManager, Path.Combine(initConfig.BaseDbPath, "debug")); - break; - case DiagnosticMode.MemDb: - _api.DbProvider = new DbProvider(); - _api.DbFactory = new MemDbFactory(); - break; - default: - _api.DbProvider = new DbProvider(); - _api.DbFactory = new RocksDbFactory(dbConfig, _api.LogManager, initConfig.BaseDbPath); - break; - } + return Task.CompletedTask; } } } diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs index eb06e47f99f..0fc7b9dde39 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs @@ -26,7 +26,6 @@ using Nethermind.Consensus.Withdrawals; using Nethermind.Core; using Nethermind.Core.Attributes; -using Nethermind.Core.Crypto; using Nethermind.Core.ServiceStopper; using Nethermind.Evm; using Nethermind.Evm.State; @@ -37,6 +36,7 @@ using Nethermind.State; using Nethermind.TxPool; using Nethermind.Wallet; +using Nethermind.Core.Crypto; namespace Nethermind.Init.Steps { @@ -75,7 +75,7 @@ protected virtual Task InitBlockchain() IStateReader stateReader = setApi.StateReader!; IWorldState mainWorldState = _api.WorldStateManager!.GlobalWorldState; PreBlockCaches? preBlockCaches = (mainWorldState as IPreBlockCaches)?.Caches; - CodeInfoRepository codeInfoRepository = new(preBlockCaches?.PrecompileCache); + EthereumCodeInfoRepository codeInfoRepository = new(preBlockCaches?.PrecompileCache); IChainHeadInfoProvider chainHeadInfoProvider = new ChainHeadInfoProvider(getApi.SpecProvider!, getApi.BlockTree!, stateReader, codeInfoRepository); @@ -89,7 +89,7 @@ protected virtual Task InitBlockchain() SetupAndLoadWhiteListedContracts(vmConfig); WarmupEvm(vmConfig); - VirtualMachine virtualMachine = CreateVirtualMachine(codeInfoRepository, mainWorldState, vmConfig); + VirtualMachine virtualMachine = CreateVirtualMachine(mainWorldState, vmConfig); ITransactionProcessor transactionProcessor = CreateTransactionProcessor(codeInfoRepository, virtualMachine, mainWorldState); if (_api.SealValidator is null) throw new StepDependencyException(nameof(_api.SealValidator)); @@ -170,7 +170,7 @@ private void WarmupEvm(IVMConfig vmConfig) { IWorldState state = _api.WorldStateManager!.CreateResettableWorldState(); state.SetBaseBlock(null); - VirtualMachine.WarmUpEvmInstructions(state, new CodeInfoRepository(), vmConfig); + VirtualMachine.WarmUpEvmInstructions(state, new EthereumCodeInfoRepository(), vmConfig); } protected virtual ITransactionProcessor CreateTransactionProcessor(ICodeInfoRepository codeInfoRepository, IVirtualMachine virtualMachine, IWorldState worldState) @@ -185,7 +185,7 @@ protected virtual ITransactionProcessor CreateTransactionProcessor(ICodeInfoRepo _api.LogManager); } - protected VirtualMachine CreateVirtualMachine(CodeInfoRepository codeInfoRepository, IWorldState worldState, IVMConfig vmConfig) + protected VirtualMachine CreateVirtualMachine(IWorldState worldState, IVMConfig vmConfig) { if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); if (_api.SpecProvider is null) throw new StepDependencyException(nameof(_api.SpecProvider)); @@ -231,7 +231,6 @@ protected virtual BlockProcessor CreateBlockProcessor( ITransactionProcessor transactionProcessor, IWorldState worldState) { - if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider)); if (_api.RewardCalculatorSource is null) throw new StepDependencyException(nameof(_api.RewardCalculatorSource)); if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); if (_api.WorldStateManager is null) throw new StepDependencyException(nameof(_api.WorldStateManager)); diff --git a/src/Nethermind/Nethermind.Init/Steps/StartMonitoring.cs b/src/Nethermind/Nethermind.Init/Steps/StartMonitoring.cs index 92ad942412a..a06dfb91065 100644 --- a/src/Nethermind/Nethermind.Init/Steps/StartMonitoring.cs +++ b/src/Nethermind/Nethermind.Init/Steps/StartMonitoring.cs @@ -10,6 +10,7 @@ using Nethermind.Core.ServiceStopper; using Nethermind.Db; using Nethermind.Facade.Eth; +using Nethermind.Init.Modules; using Nethermind.Logging; using Nethermind.Monitoring; using Nethermind.Monitoring.Config; @@ -21,7 +22,7 @@ namespace Nethermind.Init.Steps; [RunnerStepDependencies(typeof(InitializeBlockTree))] public class StartMonitoring( IEthSyncingInfo ethSyncingInfo, - IDbProvider dbProvider, + DbTracker dbTracker, IPruningConfig pruningConfig, ISyncConfig syncConfig, IServiceStopper serviceStopper, @@ -86,7 +87,7 @@ private void SetupMetrics(IMonitoringService monitoringService) { monitoringService.AddMetricsUpdateAction(() => { - foreach (KeyValuePair kv in dbProvider.GetAllDbMeta()) + foreach (KeyValuePair kv in dbTracker.GetAllDbMeta()) { // Note: At the moment, the metric for a columns db is combined across column. IDbMeta.DbMetric dbMetric = kv.Value.GatherMetric(includeSharedCache: kv.Key == DbNames.State); // Only include shared cache if state db diff --git a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs index fc00eaafe64..31e5bf34e9a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Benchmark/EthModuleBenchmarks.cs @@ -1,64 +1,32 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System.Threading.Tasks; using Autofac; using BenchmarkDotNet.Attributes; using Nethermind.Api; using Nethermind.Blockchain; -using Nethermind.Blockchain.BeaconBlockRoot; -using Nethermind.Blockchain.Blocks; -using Nethermind.Blockchain.Filters; using Nethermind.Blockchain.Find; -using Nethermind.Blockchain.Headers; using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Tracing; using Nethermind.Consensus.Processing; -using Nethermind.Consensus.Rewards; -using Nethermind.Consensus.Validators; using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Specs; using Nethermind.Core.Test.Builders; -using Nethermind.Crypto; -using Nethermind.Db; -using Nethermind.Evm; using Nethermind.Evm.State; -using Nethermind.Evm.Tracing; using Nethermind.Facade; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Logging; using Nethermind.State; -using Nethermind.State.Repositories; -using Nethermind.Db.Blooms; -using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade.Eth; using Nethermind.JsonRpc.Modules.Eth.FeeHistory; using Nethermind.JsonRpc.Modules.Eth.GasPrice; -using Nethermind.Trie.Pruning; using Nethermind.TxPool; using Nethermind.Wallet; -using BlockTree = Nethermind.Blockchain.BlockTree; -using Nethermind.Blockchain.Synchronization; using Nethermind.Config; -using Nethermind.Consensus.ExecutionRequests; -using Nethermind.Consensus; -using Nethermind.Consensus.Scheduler; -using Nethermind.Consensus.Withdrawals; -using Nethermind.Core.Test; using Nethermind.Core.Test.Modules; -using Nethermind.Facade.Find; -using Nethermind.Facade.Simulate; using Nethermind.Network; -using Nethermind.Network.Config; -using Nethermind.Network.P2P.Subprotocols.Eth; -using Nethermind.Network.Rlpx; -using Nethermind.Stats; -using Nethermind.Synchronization; -using Nethermind.Synchronization.ParallelSync; -using Nethermind.Synchronization.Peers; -using NSubstitute; namespace Nethermind.JsonRpc.Benchmark { @@ -112,6 +80,7 @@ public void GlobalSetup() _container.Resolve(), feeHistoryOracle, _container.Resolve(), + _container.Resolve(), new BlocksConfig().SecondsPerSlot); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs index f61e0aad47d..11e1e43e21e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/BoundedModulePoolTests.cs @@ -55,7 +55,8 @@ public Task Initialize() Substitute.For(), Substitute.For(), Substitute.For(), - new BlocksConfig()), + new BlocksConfig(), + Substitute.For()), 1, 1000); return Task.CompletedTask; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/ParityRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/ParityRpcModuleTests.cs index dfaead65e34..b64953e2c84 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/ParityRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/ParityRpcModuleTests.cs @@ -34,7 +34,7 @@ using NSubstitute; using NUnit.Framework; using System; -using Nethermind.Evm; +using Nethermind.Core.Test.Db; using Nethermind.State; namespace Nethermind.JsonRpc.Test.Modules @@ -78,7 +78,7 @@ public void Initialize() _txPool = new TxPool.TxPool(_ethereumEcdsa, new BlobTxStorage(), - new ChainHeadInfoProvider(new FixedForkActivationChainHeadSpecProvider(specProvider), _blockTree, stateProvider, new CodeInfoRepository()) { HasSynced = true }, + new ChainHeadInfoProvider(new FixedForkActivationChainHeadSpecProvider(specProvider), _blockTree, stateProvider, new EthereumCodeInfoRepository()) { HasSynced = true }, new TxPoolConfig(), new TxValidator(specProvider.ChainId), LimboLogs.Instance, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs index e47a97788dc..87e775b08ee 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Proof/ProofRpcModuleTests.cs @@ -30,6 +30,7 @@ using Nethermind.Core.Buffers; using Nethermind.Core.Specs; using Nethermind.Core.Test; +using Nethermind.Core.Test.Db; using Nethermind.Core.Test.Modules; using Nethermind.Evm.Tracing.State; using Nethermind.Facade.Eth.RpcTransaction; diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs index ad8a951819d..cde82c8033a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/SingletonModulePoolTests.cs @@ -54,7 +54,8 @@ public Task Initialize() Substitute.For(), Substitute.For(), Substitute.For(), - new BlocksConfig()); + new BlocksConfig(), + Substitute.For()); return Task.CompletedTask; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs index 315ef62c37f..e9c169c2d31 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TestRpcBlockchain.cs @@ -200,6 +200,7 @@ public async Task Build(Action configurer) @this.FeeHistoryOracle ?? new FeeHistoryOracle(@this.BlockTree, @this.ReceiptStorage, @this.SpecProvider), @this.ProtocolsManager, + @this.ForkInfo, @this.BlocksConfig.SecondsPerSlot); protected override async Task Build(Action? configurer = null) diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/Nethermind.JsonRpc.TraceStore.csproj b/src/Nethermind/Nethermind.JsonRpc.TraceStore/Nethermind.JsonRpc.TraceStore.csproj index f3d846e11e9..d4989e37be3 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/Nethermind.JsonRpc.TraceStore.csproj +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/Nethermind.JsonRpc.TraceStore.csproj @@ -8,6 +8,7 @@ + diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs index f77621415aa..fe69626430a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs @@ -1,23 +1,27 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using Autofac; +using Autofac.Core; using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Db; using Nethermind.Blockchain.Tracing.ParityStyle; +using Nethermind.Core; using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Trace; using Nethermind.Logging; +using Nethermind.Init.Modules; namespace Nethermind.JsonRpc.TraceStore; public class TraceStorePlugin(ITraceStoreConfig traceStoreConfig) : INethermindPlugin { - private const string DbName = "TraceStore"; + public const string DbName = "TraceStore"; + private INethermindApi _api = null!; private IJsonRpcConfig _jsonRpcConfig = null!; private IDb? _db; - private TraceStorePruner? _pruner; private ILogManager _logManager = null!; private ILogger _logger; private ITraceSerializer? _traceSerializer; @@ -37,13 +41,12 @@ public Task Init(INethermindApi nethermindApi) _traceSerializer = new ParityLikeTraceSerializer(_logManager, traceStoreConfig.MaxDepth, traceStoreConfig.VerifySerialized); // Setup DB - _db = _api.DbFactory!.CreateDb(new DbSettings(DbName, DbName.ToLower())); - _api.DbProvider!.RegisterDb(DbName, _db); + _db = _api.Context.ResolveKeyed(DbName); //Setup pruning if configured if (traceStoreConfig.BlocksToKeep != 0) { - _pruner = new TraceStorePruner(_api.BlockTree!, _db, traceStoreConfig.BlocksToKeep, _logManager); + _api.Context.Resolve(); } return Task.CompletedTask; @@ -80,8 +83,15 @@ public Task InitRpcModules() public ValueTask DisposeAsync() { - _pruner?.Dispose(); - _db?.Dispose(); return default; } + + public IModule Module => new TracerStorePluginModule(); + + private class TracerStorePluginModule : Module + { + protected override void Load(ContainerBuilder builder) => builder + .AddDatabase(DbName) + .AddSingleton(); + } } diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs index ce4091abf40..a13f58bf278 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePruner.cs @@ -1,8 +1,10 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using Autofac.Features.AttributeFilters; using Nethermind.Blockchain; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Db; using Nethermind.Logging; @@ -18,6 +20,12 @@ public class TraceStorePruner : IDisposable private readonly int _blockToKeep; private readonly ILogger _logger; + [UseConstructorForDependencyInjection] + public TraceStorePruner(IBlockTree blockTree, [KeyFilter(TraceStorePlugin.DbName)] IDb db, ITraceStoreConfig traceStoreConfig, ILogManager logManager) + : this(blockTree, db, traceStoreConfig.BlocksToKeep, logManager) + { + } + public TraceStorePruner(IBlockTree blockTree, IDb db, int blockToKeep, ILogManager logManager) { _blockTree = blockTree; diff --git a/src/Nethermind/Nethermind.JsonRpc/Data/EthConfigResult.cs b/src/Nethermind/Nethermind.JsonRpc/Data/EthConfigResult.cs new file mode 100644 index 00000000000..5f5b6407043 --- /dev/null +++ b/src/Nethermind/Nethermind.JsonRpc/Data/EthConfigResult.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.Text.Json.Nodes; +using Nethermind.Core; + +namespace Nethermind.JsonRpc.Data; + +public class EthConfig +{ + public required JsonNode Current { get; init; } + public required ulong CurrentHash { get; init; } + public required byte[] CurrentForkId { get; init; } + + public required JsonNode? Next { get; init; } + public required ulong? NextHash { get; init; } + public required byte[]? NextForkId { get; init; } + + public required JsonNode? Last { get; init; } + public required ulong? LastHash { get; init; } + public required byte[]? LastForkId { get; init; } +} + +public class ForkConfig +{ + public int? ActivationTime { get; init; } + public int? ActivationBlock { get; init; } + public required BlobScheduleSettingsForRpc? BlobSchedule { get; init; } + public required ulong ChainId { get; init; } + public required OrderedDictionary Precompiles { get; init; } + public required OrderedDictionary SystemContracts { get; init; } +} + +public class BlobScheduleSettingsForRpc +{ + public required int BaseFeeUpdateFraction { get; init; } + public required int Max { get; init; } + public required int Target { get; init; } +} diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs index 4b499c9e599..d5b6001e4aa 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthModuleFactory.cs @@ -32,7 +32,8 @@ public class EthModuleFactory( IEthSyncingInfo ethSyncingInfo, IFeeHistoryOracle feeHistoryOracle, IProtocolsManager protocolsManager, - IBlocksConfig blocksConfig) + IBlocksConfig blocksConfig, + IForkInfo forkInfo) : ModuleFactoryBase { private readonly ulong _secondsPerSlot = blocksConfig.SecondsPerSlot; @@ -55,6 +56,7 @@ public override IEthRpcModule Create() ethSyncingInfo, feeHistoryOracle, protocolsManager, + forkInfo, _secondsPerSlot); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index c12d642192c..a95cef44870 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -3,12 +3,17 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Security; using System.Text; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using DotNetty.Buffers; +using Force.Crc32; using Nethermind.Blockchain.Filters; using Nethermind.Blockchain.Find; using Nethermind.Blockchain.Receipts; @@ -18,6 +23,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Evm; +using Nethermind.Evm.Precompiles; using Nethermind.Facade; using Nethermind.Facade.Eth; using Nethermind.Facade.Eth.RpcTransaction; @@ -31,6 +37,7 @@ using Nethermind.Logging; using Nethermind.Network; using Nethermind.Network.Contract.P2P; +using Nethermind.Serialization.Json; using Nethermind.Serialization.Rlp; using Nethermind.State; using Nethermind.State.Proofs; @@ -61,6 +68,7 @@ public partial class EthRpcModule( IEthSyncingInfo ethSyncingInfo, IFeeHistoryOracle feeHistoryOracle, IProtocolsManager protocolsManager, + IForkInfo forkInfo, ulong? secondsPerSlot) : IEthRpcModule { protected readonly Encoding _messageEncoding = Encoding.UTF8; @@ -79,6 +87,7 @@ public partial class EthRpcModule( protected readonly IFeeHistoryOracle _feeHistoryOracle = feeHistoryOracle ?? throw new ArgumentNullException(nameof(feeHistoryOracle)); protected readonly IProtocolsManager _protocolsManager = protocolsManager ?? throw new ArgumentNullException(nameof(protocolsManager)); protected readonly ulong _secondsPerSlot = secondsPerSlot ?? throw new ArgumentNullException(nameof(secondsPerSlot)); + readonly JsonSerializerOptions UnchangedDictionaryKeyOptions = new(EthereumJsonSerializer.JsonOptionsIndented) { DictionaryKeyPolicy = null }; public ResultWrapper eth_protocolVersion() { @@ -772,6 +781,65 @@ private ResultWrapper GetStateFailureResult(BlockHeader header }; } + public ResultWrapper eth_config() + { + ForkActivationsSummary forks = forkInfo.GetForkActivationsSummary(_blockFinder.Head?.Header); + + ForkConfig current = GetForkConfig(forks.Current, _specProvider); + ForkConfig? next = GetForkConfig(forks.Next, _specProvider); + ForkConfig? last = GetForkConfig(forks.Last, _specProvider); + + string serializedCurrent = JsonSerializer.Serialize(current, UnchangedDictionaryKeyOptions); + string? serializedNext = next is null ? null : JsonSerializer.Serialize(next, UnchangedDictionaryKeyOptions); + string? serializedLast = last is null ? null : JsonSerializer.Serialize(last, UnchangedDictionaryKeyOptions); + + return ResultWrapper.Success(new EthConfig + { + Current = JsonNode.Parse(serializedCurrent)!, + CurrentHash = GetCrc32FromJson(serializedCurrent).Value, + CurrentForkId = forks.CurrentForkId.HashBytes, + + Next = serializedNext is null ? null : JsonNode.Parse(serializedNext), + NextHash = GetCrc32FromJson(serializedNext), + NextForkId = forks.NextForkId?.HashBytes, + + Last = serializedLast is null ? null : JsonNode.Parse(serializedLast), + LastHash = GetCrc32FromJson(serializedLast), + LastForkId = forks.LastForkId?.HashBytes, + }); + + [return: NotNullIfNotNull(nameof(json))] + static uint? GetCrc32FromJson(string? json) => json is null ? null : Crc32Algorithm.Compute(Encoding.UTF8.GetBytes(RemoveWhitespace().Replace(json, ""))); + + static ForkConfig? GetForkConfig(ForkActivation? forkActivation, ISpecProvider specProvider) + { + if (forkActivation is null) + { + return null; + } + + IReleaseSpec? spec = specProvider.GetSpec(forkActivation.Value.BlockNumber, forkActivation.Value.Timestamp); + + return new ForkConfig + { + ActivationTime = forkActivation.Value.Timestamp is not null ? (int)forkActivation.Value.Timestamp : null, + ActivationBlock = forkActivation.Value.Timestamp is null ? (int)forkActivation.Value.BlockNumber : null, + BlobSchedule = spec.IsEip4844Enabled ? new BlobScheduleSettingsForRpc + { + BaseFeeUpdateFraction = (int)spec.BlobBaseFeeUpdateFraction, + Max = (int)spec.MaxBlobCount, + Target = (int)spec.TargetBlobCount, + } : null, + ChainId = specProvider.ChainId, + Precompiles = spec.ListPrecompiles(), + SystemContracts = spec.ListSystemContracts(), + }; + } + } + private CancellationTokenSource BuildTimeoutCancellationTokenSource() => _rpcConfig.BuildTimeoutCancellationToken(); + + [GeneratedRegex("\\s", RegexOptions.Compiled)] + private static partial Regex RemoveWhitespace(); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index a64170158db..f700581e4a3 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -284,5 +284,8 @@ ResultWrapper eth_getTransactionByBlockNumberAndIndex( [JsonRpcMethod(IsImplemented = true, Description = "Retrieves Accounts via Address and Blocknumber", IsSharable = true)] ResultWrapper eth_getAccount([JsonRpcParameter(ExampleValue = "[\"0xaa00000000000000000000000000000000000000\", \"latest\"]")] Address accountAddress, BlockParameter? blockParameter = null); + + [JsonRpcMethod(IsImplemented = true, Description = "Provides configuration data for the current and next fork", IsSharable = true)] + ResultWrapper eth_config(); } } diff --git a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs index 3fab9da0b28..8b591f6fa0a 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs @@ -144,7 +144,6 @@ protected override ContainerBuilder ConfigureContainer(ContainerBuilder builder, { // Yes getting from `TestBlockchain` itself, since steps are not run // and some of these are not from DI. you know... chicken and egg, but dont forgot about rooster. - api.DbProvider = DbProvider; api.TxPool = TxPool; api.TransactionComparerProvider = TransactionComparerProvider; api.FinalizationManager = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs index 340386ddf01..8f037d54294 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs @@ -71,7 +71,6 @@ private IContainer BuildContainer(IConfigProvider? configProvider = null) Build.MockOutNethermindApi((NethermindApi)api); api.BlockProcessingQueue?.IsEmpty.Returns(true); - api.DbFactory = new MemDbFactory(); }) .Build(); } diff --git a/src/Nethermind/Nethermind.Network.Benchmark/Eth62ProtocolHandlerBenchmarks.cs b/src/Nethermind/Nethermind.Network.Benchmark/Eth62ProtocolHandlerBenchmarks.cs index e3bfc72f98a..a19bd15b664 100644 --- a/src/Nethermind/Nethermind.Network.Benchmark/Eth62ProtocolHandlerBenchmarks.cs +++ b/src/Nethermind/Nethermind.Network.Benchmark/Eth62ProtocolHandlerBenchmarks.cs @@ -62,7 +62,7 @@ public void SetUp() TxPool.TxPool txPool = new TxPool.TxPool( ecdsa, new BlobTxStorage(), - new ChainHeadInfoProvider(new FixedForkActivationChainHeadSpecProvider(MainnetSpecProvider.Instance), tree, stateProvider, new CodeInfoRepository()), + new ChainHeadInfoProvider(new FixedForkActivationChainHeadSpecProvider(MainnetSpecProvider.Instance), tree, stateProvider, new EthereumCodeInfoRepository()), new TxPoolConfig(), new TxValidator(TestBlockchainIds.ChainId), LimboLogs.Instance, diff --git a/src/Nethermind/Nethermind.Network/ForkInfo.cs b/src/Nethermind/Nethermind.Network/ForkInfo.cs index db2eda1e451..f47393f515c 100644 --- a/src/Nethermind/Nethermind.Network/ForkInfo.cs +++ b/src/Nethermind/Nethermind.Network/ForkInfo.cs @@ -1,12 +1,6 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; -using System.Buffers.Binary; -using System.Collections.Generic; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Threading; using Force.Crc32; using Nethermind.Core; using Nethermind.Core.Collections; @@ -14,6 +8,12 @@ using Nethermind.Core.Specs; using Nethermind.Specs; using Nethermind.Synchronization; +using System; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Threading; namespace Nethermind.Network { @@ -138,5 +138,44 @@ public ValidationResult ValidateForkId(ForkId peerId, BlockHeader? head) return ValidationResult.Valid; } + + public ForkActivationsSummary GetForkActivationsSummary(BlockHeader? head) + { + ForkActivation headActivation = new(head?.Number ?? 0, head.Number == 0 ? 0 : head?.Timestamp ?? 0); + + int indexOfActive = 0; + for (; indexOfActive < Forks.Length; indexOfActive++) + { + ForkActivation fork = Forks[indexOfActive].Activation; + + if (fork.Timestamp.HasValue ? fork.Timestamp >= headActivation.Timestamp : + fork.BlockNumber >= headActivation.BlockNumber) + { + break; + } + } + + bool isNextPresent = indexOfActive < Forks.Length - 1; + + // The fix for post-merge genesis + ForkActivation currentForkActivation = Forks[indexOfActive].Activation; + + if (currentForkActivation.BlockNumber is 0) + { + currentForkActivation = new ForkActivation(0, 0); + } + + return new ForkActivationsSummary + { + Current = currentForkActivation, + CurrentForkId = Forks[indexOfActive].Id, + + Next = isNextPresent ? Forks[indexOfActive + 1].Activation : null, + NextForkId = isNextPresent ? Forks[indexOfActive + 1].Id : null, + + Last = isNextPresent ? Forks[^1].Activation : null, + LastForkId = isNextPresent ? Forks[^1].Id : null, + }; + } } } diff --git a/src/Nethermind/Nethermind.Network/IForkInfo.cs b/src/Nethermind/Nethermind.Network/IForkInfo.cs index 4b13c1b4bcb..89988e75902 100644 --- a/src/Nethermind/Nethermind.Network/IForkInfo.cs +++ b/src/Nethermind/Nethermind.Network/IForkInfo.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core; +using Nethermind.Core.Specs; namespace Nethermind.Network; @@ -16,4 +17,16 @@ public interface IForkInfo /// /// ValidationResult ValidateForkId(ForkId peerId, BlockHeader? head); + + ForkActivationsSummary GetForkActivationsSummary(BlockHeader? head); +} + +public readonly ref struct ForkActivationsSummary +{ + public ForkActivation Current { get; init; } + public ForkId CurrentForkId { get; init; } + public ForkActivation? Next { get; init; } + public ForkId? NextForkId { get; init; } + public ForkActivation? Last { get; init; } + public ForkId? LastForkId { get; init; } } diff --git a/src/Nethermind/Nethermind.Optimism.Test/Rpc/OptimismEthRpcModuleTest.cs b/src/Nethermind/Nethermind.Optimism.Test/Rpc/OptimismEthRpcModuleTest.cs index c6e7949b38b..a5e62b6887c 100644 --- a/src/Nethermind/Nethermind.Optimism.Test/Rpc/OptimismEthRpcModuleTest.cs +++ b/src/Nethermind/Nethermind.Optimism.Test/Rpc/OptimismEthRpcModuleTest.cs @@ -555,6 +555,7 @@ public static TestRpcBlockchain.Builder WithOptimismEthRpcMod blockchain.FeeHistoryOracle ?? new FeeHistoryOracle(blockchain.BlockTree, blockchain.ReceiptStorage, blockchain.SpecProvider), blockchain.ProtocolsManager, + blockchain.ForkInfo, new BlocksConfig().SecondsPerSlot, sequencerRpcClient, ecdsa, sealer, opSpecHelper diff --git a/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs b/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs index 82dab7e72d9..737744f7b1c 100644 --- a/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs +++ b/src/Nethermind/Nethermind.Optimism/InitializeBlockchainOptimism.cs @@ -58,7 +58,6 @@ protected override ITransactionProcessor CreateTransactionProcessor(ICodeInfoRep protected override BlockProcessor CreateBlockProcessor(BlockCachePreWarmer? preWarmer, ITransactionProcessor transactionProcessor, IWorldState worldState) { - if (api.DbProvider is null) throw new StepDependencyException(nameof(api.DbProvider)); if (api.RewardCalculatorSource is null) throw new StepDependencyException(nameof(api.RewardCalculatorSource)); if (api.SpecHelper is null) throw new StepDependencyException(nameof(api.SpecHelper)); if (api.SpecProvider is null) throw new StepDependencyException(nameof(api.SpecProvider)); diff --git a/src/Nethermind/Nethermind.Optimism/OptimismEthereumEcdsa.cs b/src/Nethermind/Nethermind.Optimism/OptimismEthereumEcdsa.cs index 44d807cddbd..b72cf8e29fb 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismEthereumEcdsa.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismEthereumEcdsa.cs @@ -19,6 +19,4 @@ public OptimismEthereumEcdsa(IEthereumEcdsa ethereumEcdsa) _ethereumEcdsa = ethereumEcdsa; } public Address? RecoverAddress(Signature signature, in ValueHash256 message) => _ethereumEcdsa.RecoverAddress(signature, in message); - - public Address? RecoverAddress(Span signatureBytes, in ValueHash256 message) => _ethereumEcdsa.RecoverAddress(signatureBytes, in message); } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs index 9ae3cf8f69a..aa6db5df906 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthModuleFactory.cs @@ -43,6 +43,7 @@ public class OptimismEthModuleFactory : ModuleFactoryBase private readonly IReceiptFinder _receiptFinder; private readonly IOptimismSpecHelper _opSpecHelper; private readonly IProtocolsManager _protocolsManager; + private readonly IForkInfo _forkInfo; private readonly ulong? _secondsPerSlot; private readonly IJsonRpcClient? _sequencerRpcClient; @@ -60,6 +61,7 @@ public OptimismEthModuleFactory(IJsonRpcConfig rpcConfig, IEthSyncingInfo ethSyncingInfo, IFeeHistoryOracle feeHistoryOracle, IProtocolsManager protocolsManager, + IForkInfo forkInfo, IBlocksConfig blocksConfig, IEthereumEcdsa ecdsa, IOptimismSpecHelper opSpecHelper, @@ -85,7 +87,7 @@ ITimestamper timestamper _receiptFinder = receiptFinder; _opSpecHelper = opSpecHelper; _protocolsManager = protocolsManager; - + _forkInfo = forkInfo; ILogger logger = logManager.GetClassLogger(); if (config.SequencerUrl is null && logger.IsWarn) { @@ -119,6 +121,7 @@ public override IOptimismEthRpcModule Create() _ethSyncingInfo, _feeHistoryOracle, _protocolsManager, + _forkInfo, _secondsPerSlot, _sequencerRpcClient, diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs index b74f1fbaa5c..11edf540823 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismEthRpcModule.cs @@ -54,6 +54,7 @@ public OptimismEthRpcModule( IEthSyncingInfo ethSyncingInfo, IFeeHistoryOracle feeHistoryOracle, IProtocolsManager protocolsManager, + IForkInfo forkInfo, ulong? secondsPerSlot, IJsonRpcClient? sequencerRpcClient, @@ -74,6 +75,7 @@ public OptimismEthRpcModule( ethSyncingInfo, feeHistoryOracle, protocolsManager, + forkInfo, secondsPerSlot) { _sequencerRpcClient = sequencerRpcClient; diff --git a/src/Nethermind/Nethermind.Precompiles.Benchmark/Bn254AddBenchmark.cs b/src/Nethermind/Nethermind.Precompiles.Benchmark/BN254AddBenchmark.cs similarity index 72% rename from src/Nethermind/Nethermind.Precompiles.Benchmark/Bn254AddBenchmark.cs rename to src/Nethermind/Nethermind.Precompiles.Benchmark/BN254AddBenchmark.cs index 70fad31a0f4..580095c0a3a 100644 --- a/src/Nethermind/Nethermind.Precompiles.Benchmark/Bn254AddBenchmark.cs +++ b/src/Nethermind/Nethermind.Precompiles.Benchmark/BN254AddBenchmark.cs @@ -3,15 +3,14 @@ using System.Collections.Generic; using Nethermind.Evm.Precompiles; -using Nethermind.Evm.Precompiles.Snarks; namespace Nethermind.Precompiles.Benchmark; -public class Bn254AddBenchmark : PrecompileBenchmarkBase +public class BN254AddBenchmark : PrecompileBenchmarkBase { protected override IEnumerable Precompiles => new[] { - Bn254AddPrecompile.Instance + BN254AddPrecompile.Instance }; protected override string InputsDirectory => "bnadd"; diff --git a/src/Nethermind/Nethermind.Precompiles.Benchmark/Bn254MulBenchmark.cs b/src/Nethermind/Nethermind.Precompiles.Benchmark/BN254MulBenchmark.cs similarity index 72% rename from src/Nethermind/Nethermind.Precompiles.Benchmark/Bn254MulBenchmark.cs rename to src/Nethermind/Nethermind.Precompiles.Benchmark/BN254MulBenchmark.cs index 75e2566f5a8..a9e9b1d9695 100644 --- a/src/Nethermind/Nethermind.Precompiles.Benchmark/Bn254MulBenchmark.cs +++ b/src/Nethermind/Nethermind.Precompiles.Benchmark/BN254MulBenchmark.cs @@ -3,15 +3,14 @@ using System.Collections.Generic; using Nethermind.Evm.Precompiles; -using Nethermind.Evm.Precompiles.Snarks; namespace Nethermind.Precompiles.Benchmark; -public class Bn254MulBenchmark : PrecompileBenchmarkBase +public class BN254MulBenchmark : PrecompileBenchmarkBase { protected override IEnumerable Precompiles => new[] { - Bn254MulPrecompile.Instance + BN254MulPrecompile.Instance }; protected override string InputsDirectory => "bnmul"; diff --git a/src/Nethermind/Nethermind.Precompiles.Benchmark/Bn254PairingBenchmark.cs b/src/Nethermind/Nethermind.Precompiles.Benchmark/BN254PairingBenchmark.cs similarity index 71% rename from src/Nethermind/Nethermind.Precompiles.Benchmark/Bn254PairingBenchmark.cs rename to src/Nethermind/Nethermind.Precompiles.Benchmark/BN254PairingBenchmark.cs index 75afae7838a..93ea0a11a82 100644 --- a/src/Nethermind/Nethermind.Precompiles.Benchmark/Bn254PairingBenchmark.cs +++ b/src/Nethermind/Nethermind.Precompiles.Benchmark/BN254PairingBenchmark.cs @@ -3,15 +3,14 @@ using System.Collections.Generic; using Nethermind.Evm.Precompiles; -using Nethermind.Evm.Precompiles.Snarks; namespace Nethermind.Precompiles.Benchmark; -public class Bn254PairingBenchmark : PrecompileBenchmarkBase +public class BN254PairingBenchmark : PrecompileBenchmarkBase { protected override IEnumerable Precompiles => new[] { - Bn254PairingPrecompile.Instance + BN254PairingPrecompile.Instance }; protected override string InputsDirectory => "bnpair"; diff --git a/src/Nethermind/Nethermind.Precompiles.Benchmark/ModExpBenchmark.cs b/src/Nethermind/Nethermind.Precompiles.Benchmark/ModExpBenchmark.cs index e8d5934b828..1a7f8a3ad00 100644 --- a/src/Nethermind/Nethermind.Precompiles.Benchmark/ModExpBenchmark.cs +++ b/src/Nethermind/Nethermind.Precompiles.Benchmark/ModExpBenchmark.cs @@ -3,22 +3,12 @@ using System; using System.Collections.Generic; -using BenchmarkDotNet.Attributes; using Nethermind.Evm.Precompiles; -namespace Nethermind.Precompiles.Benchmark -{ - public class ModExpBenchmark : PrecompileBenchmarkBase - { - protected override IEnumerable Precompiles => new[] { ModExpPrecompile.Instance }; - protected override string InputsDirectory => "modexp"; +namespace Nethermind.Precompiles.Benchmark; - [Benchmark] - public (ReadOnlyMemory, bool) BigInt() - { -#pragma warning disable CS0618 // Type or member is obsolete - return ModExpPrecompile.OldRun(Input.Bytes); -#pragma warning restore CS0618 // Type or member is obsolete - } - } +public class ModExpBenchmark : PrecompileBenchmarkBase +{ + protected override IEnumerable Precompiles => new[] { ModExpPrecompile.Instance }; + protected override string InputsDirectory => "modexp"; } diff --git a/src/Nethermind/Nethermind.Precompiles.Benchmark/Nethermind.Precompiles.Benchmark.csproj b/src/Nethermind/Nethermind.Precompiles.Benchmark/Nethermind.Precompiles.Benchmark.csproj index 1fa7275f368..679565746ff 100644 --- a/src/Nethermind/Nethermind.Precompiles.Benchmark/Nethermind.Precompiles.Benchmark.csproj +++ b/src/Nethermind/Nethermind.Precompiles.Benchmark/Nethermind.Precompiles.Benchmark.csproj @@ -11,6 +11,8 @@ + + diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index c5109eb2a6c..b8117387ba4 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -111,7 +111,6 @@ public static void MockOutNethermindApi(NethermindApi api) api.TxPool = Substitute.For(); api.Wallet = Substitute.For(); api.BlockTree = Substitute.For(); - api.DbProvider = TestMemDbProvider.Init(); api.ReceiptStorage = Substitute.For(); api.BloomStorage = Substitute.For(); api.BlockProducer = Substitute.For(); diff --git a/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs b/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs index 06d40d24d68..834a4535e15 100644 --- a/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs @@ -209,8 +209,6 @@ public async Task Smoke_CanResolveAllSteps((string file, ConfigProvider configPr api.FileSystem = Substitute.For(); api.BlockTree = Substitute.For(); api.ReceiptStorage = Substitute.For(); - api.DbFactory = new MemDbFactory(); - api.DbProvider = await TestMemDbProvider.InitAsync(); api.BlockProducerRunner = Substitute.For(); if (api is AuRaNethermindApi auRaNethermindApi) diff --git a/src/Nethermind/Nethermind.Runner/configs/base-mainnet.json b/src/Nethermind/Nethermind.Runner/configs/base-mainnet.json index f0d6ffb949c..bce44570880 100644 --- a/src/Nethermind/Nethermind.Runner/configs/base-mainnet.json +++ b/src/Nethermind/Nethermind.Runner/configs/base-mainnet.json @@ -13,8 +13,8 @@ "FastSync": true, "SnapSync": true, "FastSyncCatchUpHeightDelta": "10000000000", - "PivotNumber": 32780000, - "PivotHash": "0x28f0ac563c5dd0098c6ac3c23aa291e5164c77afcbb0ec6f915b5c2ce782cbf6" + "PivotNumber": 33080000, + "PivotHash": "0xf8426b70e8f3da4c5f473fbb4cc76b767781c7ae6e7ff630b2b834c0a60e30a0" }, "Discovery": { "DiscoveryVersion": "V5" diff --git a/src/Nethermind/Nethermind.Runner/configs/base-sepolia.json b/src/Nethermind/Nethermind.Runner/configs/base-sepolia.json index e72ea30695e..396f6d7cf26 100644 --- a/src/Nethermind/Nethermind.Runner/configs/base-sepolia.json +++ b/src/Nethermind/Nethermind.Runner/configs/base-sepolia.json @@ -13,8 +13,8 @@ "FastSync": true, "SnapSync": true, "FastSyncCatchUpHeightDelta": "10000000000", - "PivotNumber": 28290000, - "PivotHash": "0xde9a2994afb2da18d22b4051d2a67a7024c4fa2d6277e4e6022064332570b87d" + "PivotNumber": 28590000, + "PivotHash": "0xc168f8c4b4d80a72758d851549d4f4a7d2bb97f1521589106245befea37f7a88" }, "Discovery": { "DiscoveryVersion": "V5" diff --git a/src/Nethermind/Nethermind.Runner/configs/chiado.json b/src/Nethermind/Nethermind.Runner/configs/chiado.json index ce78beea0b5..f700945802a 100644 --- a/src/Nethermind/Nethermind.Runner/configs/chiado.json +++ b/src/Nethermind/Nethermind.Runner/configs/chiado.json @@ -18,8 +18,8 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 16710000, - "PivotHash": "0xf5e5177ed8b0c340d7d39f31ca73a594b18203095a700868a3e70f673aa0c5b3", + "PivotNumber": 16830000, + "PivotHash": "0x6889240d237418570a6055c05ea3f9dd6d9e0f073467b6d54805ceaae805c32e", "PivotTotalDifficulty": "231708131825107706987652208063906496124457284", "FastSyncCatchUpHeightDelta": 10000000000, "UseGethLimitsInFastBlocks": false diff --git a/src/Nethermind/Nethermind.Runner/configs/energyweb.json b/src/Nethermind/Nethermind.Runner/configs/energyweb.json index 9cb16959521..0d25a77e7fd 100644 --- a/src/Nethermind/Nethermind.Runner/configs/energyweb.json +++ b/src/Nethermind/Nethermind.Runner/configs/energyweb.json @@ -13,9 +13,9 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 36510000, - "PivotHash": "0xafe652ac0d78c419917ccdbbbb1cb8c38d790724ef97005cb3e1f821a84d1586", - "PivotTotalDifficulty": "12423709216283463301047806917333857399871718285", + "PivotNumber": 36610000, + "PivotHash": "0xf619256a2563f55749a80af079ab657eb2b3c5f80679805d2aaa5433bc496eb9", + "PivotTotalDifficulty": "12457737452975557147394144378077034221017104410", "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 }, diff --git a/src/Nethermind/Nethermind.Runner/configs/gnosis.json b/src/Nethermind/Nethermind.Runner/configs/gnosis.json index c0d8eab6642..710ddcfcff7 100644 --- a/src/Nethermind/Nethermind.Runner/configs/gnosis.json +++ b/src/Nethermind/Nethermind.Runner/configs/gnosis.json @@ -14,8 +14,8 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 41040000, - "PivotHash": "0x15849f57931cf7739eed0cdeb0da8df2ea16810b272dcf6d173dcca1af5cd245", + "PivotNumber": 41160000, + "PivotHash": "0x201f9950e670b6010d99186595c6bbc1bc19896701d448e759edb71f90cc18f8", "PivotTotalDifficulty": "8626000110427538733349499292577475819600160930", "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 diff --git a/src/Nethermind/Nethermind.Runner/configs/joc-mainnet.json b/src/Nethermind/Nethermind.Runner/configs/joc-mainnet.json index 21273eea87b..86576eed4f5 100644 --- a/src/Nethermind/Nethermind.Runner/configs/joc-mainnet.json +++ b/src/Nethermind/Nethermind.Runner/configs/joc-mainnet.json @@ -12,9 +12,9 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 18540000, - "PivotHash": "0x3b79719300301258d503a57790407d64cb4d8dca3207643b6979b5659937dc40", - "PivotTotalDifficulty": "34293024" + "PivotNumber": 18660000, + "PivotHash": "0x54fa59d40aa87afcccde55694a9341eb6d4b0f232203b1b65892f40ab5735604", + "PivotTotalDifficulty": "34476648" }, "Metrics": { "NodeName": "JOC-Mainnet" diff --git a/src/Nethermind/Nethermind.Runner/configs/joc-testnet.json b/src/Nethermind/Nethermind.Runner/configs/joc-testnet.json index a18c886578e..e97473e83ed 100644 --- a/src/Nethermind/Nethermind.Runner/configs/joc-testnet.json +++ b/src/Nethermind/Nethermind.Runner/configs/joc-testnet.json @@ -12,9 +12,9 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 12150000, - "PivotHash": "0x593af9bca041f58a9a41a75d56e61a2796b8b63e872427dc855683e767d62d47", - "PivotTotalDifficulty": "20653978" + "PivotNumber": 12270000, + "PivotHash": "0xd715f8b77c3db8c0685ac6b84421a42e17db7196b24a439d3f2932565e6fe4f0", + "PivotTotalDifficulty": "20849186" }, "Metrics": { "NodeName": "JOC-Testnet" diff --git a/src/Nethermind/Nethermind.Runner/configs/linea-mainnet.json b/src/Nethermind/Nethermind.Runner/configs/linea-mainnet.json index b7b48a4f28b..f578ed24fb6 100644 --- a/src/Nethermind/Nethermind.Runner/configs/linea-mainnet.json +++ b/src/Nethermind/Nethermind.Runner/configs/linea-mainnet.json @@ -17,9 +17,9 @@ }, "Sync": { "SnapSync": true, - "PivotNumber": 20800000, - "PivotHash": "0x359161297fb9504f222e5543e2196d7229f3ea869a91a66d10ed6b9f421f038a", - "PivotTotalDifficulty": "41600001", + "PivotNumber": 21040000, + "PivotHash": "0x85b7e32e1db604ce21099ef22d3a9a5e19a37f3aaee60da4f8bea439378cdeb8", + "PivotTotalDifficulty": "42080001", "HeaderStateDistance": 6 }, "JsonRpc": { diff --git a/src/Nethermind/Nethermind.Runner/configs/linea-sepolia.json b/src/Nethermind/Nethermind.Runner/configs/linea-sepolia.json index 1cb54492c84..14b834579e7 100644 --- a/src/Nethermind/Nethermind.Runner/configs/linea-sepolia.json +++ b/src/Nethermind/Nethermind.Runner/configs/linea-sepolia.json @@ -17,9 +17,9 @@ }, "Sync": { "SnapSync": true, - "PivotNumber": 15610000, - "PivotHash": "0x8405842b6afe9749d7c4dae84fbf95ee3febbe11b8291752183c72699f7aba8b", - "PivotTotalDifficulty": "31220001", + "PivotNumber": 15900000, + "PivotHash": "0xee15aaab2eb0ff68763e4155a423fa67e0e5aaa4d40429dbbbd7f7dcce99dab8", + "PivotTotalDifficulty": "31800001", "HeaderStateDistance": 6 }, "JsonRpc": { diff --git a/src/Nethermind/Nethermind.Runner/configs/mainnet.json b/src/Nethermind/Nethermind.Runner/configs/mainnet.json index a4256abf943..2e3593aa864 100644 --- a/src/Nethermind/Nethermind.Runner/configs/mainnet.json +++ b/src/Nethermind/Nethermind.Runner/configs/mainnet.json @@ -10,8 +10,8 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 22905000, - "PivotHash": "0x81116f98d56e3f037149f835477e93a36ebb307ae58853b4f1f695878d77dc8f", + "PivotNumber": 22955000, + "PivotHash": "0x6d6adb1e43494a8d8936eb2a0aec49036db5f18e30c035d6b131da7e41c9fc96", "PivotTotalDifficulty": "58750003716598352816469", "FastSyncCatchUpHeightDelta": "10000000000", "AncientReceiptsBarrier": 15537394, diff --git a/src/Nethermind/Nethermind.Runner/configs/op-mainnet.json b/src/Nethermind/Nethermind.Runner/configs/op-mainnet.json index 2291e055de0..7a9066040aa 100644 --- a/src/Nethermind/Nethermind.Runner/configs/op-mainnet.json +++ b/src/Nethermind/Nethermind.Runner/configs/op-mainnet.json @@ -15,8 +15,8 @@ "FastSyncCatchUpHeightDelta": "10000000000", "AncientBodiesBarrier": 105235063, "AncientReceiptsBarrier": 105235063, - "PivotNumber": 138370000, - "PivotHash": "0x9a4caaacd0359b2b0be23710c96d2af4ca7f403a0d75b312f5833e1b205d36e4" + "PivotNumber": 138670000, + "PivotHash": "0xfcc242fb6a8711365bb1795111845f2b0cd8759d183b2a03d5f103419b64271f" }, "Discovery": { "DiscoveryVersion": "V5" diff --git a/src/Nethermind/Nethermind.Runner/configs/op-sepolia.json b/src/Nethermind/Nethermind.Runner/configs/op-sepolia.json index 9f810e4e1ff..0b3502c78a7 100644 --- a/src/Nethermind/Nethermind.Runner/configs/op-sepolia.json +++ b/src/Nethermind/Nethermind.Runner/configs/op-sepolia.json @@ -13,8 +13,8 @@ "FastSync": true, "SnapSync": true, "FastSyncCatchUpHeightDelta": "10000000000", - "PivotNumber": 30270000, - "PivotHash": "0x2f80ce1ac126baf2ceb86ccd2e157a018530f058edd70532fe92602fee2b00dd" + "PivotNumber": 30570000, + "PivotHash": "0x370ec14de902ce138d46eeeb337761d5c1a714fd12073a8096a73b875d6732da" }, "Discovery": { "DiscoveryVersion": "V5" diff --git a/src/Nethermind/Nethermind.Runner/configs/sepolia.json b/src/Nethermind/Nethermind.Runner/configs/sepolia.json index 4660987c041..daa77ab2184 100644 --- a/src/Nethermind/Nethermind.Runner/configs/sepolia.json +++ b/src/Nethermind/Nethermind.Runner/configs/sepolia.json @@ -18,8 +18,8 @@ "FastSync": true, "SnapSync": true, "UseGethLimitsInFastBlocks": true, - "PivotNumber": 8750000, - "PivotHash": "0x74560d628a79b7b585db1941d697b489eaaea0ad81634a0b7ff131c784ba90e9", + "PivotNumber": 8799000, + "PivotHash": "0xddb69b6cabd779e5c1afb25952e563017079cf31d7b5d2c8622067416abd4a6e", "PivotTotalDifficulty": "17000018015853232", "FastSyncCatchUpHeightDelta": 10000000000, "AncientReceiptsBarrier": 1450409, diff --git a/src/Nethermind/Nethermind.Runner/configs/volta.json b/src/Nethermind/Nethermind.Runner/configs/volta.json index 3cd40bd0647..40ef23e67b0 100644 --- a/src/Nethermind/Nethermind.Runner/configs/volta.json +++ b/src/Nethermind/Nethermind.Runner/configs/volta.json @@ -17,9 +17,9 @@ "Sync": { "FastSync": true, "SnapSync": true, - "PivotNumber": 32680000, - "PivotHash": "0xe8e20981712f6df72b9ff23141ebb068dc2b0ccea48bfe9a99ee46cd5836f90f", - "PivotTotalDifficulty": "11120427750976268985983082170870185149999071660", + "PivotNumber": 32800000, + "PivotHash": "0x11c0fc1fc1d8f0bb77adb515295e73f6b24dc568ca8a99a8ff92998d031cf52e", + "PivotTotalDifficulty": "11161261635006781601598687123761997335373551401", "UseGethLimitsInFastBlocks": false, "FastSyncCatchUpHeightDelta": 10000000000 }, diff --git a/src/Nethermind/Nethermind.Runner/configs/worldchain-mainnet.json b/src/Nethermind/Nethermind.Runner/configs/worldchain-mainnet.json index 99fb11817ed..61a49f2bf72 100644 --- a/src/Nethermind/Nethermind.Runner/configs/worldchain-mainnet.json +++ b/src/Nethermind/Nethermind.Runner/configs/worldchain-mainnet.json @@ -13,8 +13,8 @@ "FastSync": true, "SnapSync": true, "FastSyncCatchUpHeightDelta": "10000000000", - "PivotNumber": 16500000, - "PivotHash": "0x5cdc5965f8ae1e261705fdce4c4379eb0f7c4eb725fd4b79eac9e473305694dc" + "PivotNumber": 16800000, + "PivotHash": "0x844ebc24471652792d1c2ee2808792d1c279b68f36c75d29d8385678e3632485" }, "Discovery": { "DiscoveryVersion": "V5" diff --git a/src/Nethermind/Nethermind.Runner/configs/worldchain-sepolia.json b/src/Nethermind/Nethermind.Runner/configs/worldchain-sepolia.json index d0d0dd22f71..c67399e81bc 100644 --- a/src/Nethermind/Nethermind.Runner/configs/worldchain-sepolia.json +++ b/src/Nethermind/Nethermind.Runner/configs/worldchain-sepolia.json @@ -13,8 +13,8 @@ "FastSync": true, "SnapSync": true, "FastSyncCatchUpHeightDelta": "10000000000", - "PivotNumber": 15900000, - "PivotHash": "0xc52258828e1f01d64dc6e2455cb51baae4c77a91fed1b27e08760f01badc3e3e" + "PivotNumber": 16200000, + "PivotHash": "0xefdd20a0c9c705b3ca34f7259d7efc4a8481af2abfbef6a63f576b637bd3bb23" }, "Discovery": { "DiscoveryVersion": "V5" diff --git a/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs b/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs index 8f021ad4654..56216191d18 100644 --- a/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs @@ -9,6 +9,7 @@ using Nethermind.Core.Specs; using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; +using Nethermind.Core.Test.Db; using Nethermind.Db; using Nethermind.Specs; using Nethermind.Int256; diff --git a/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs b/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs index 764d146d52f..e8242c706fc 100644 --- a/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs +++ b/src/Nethermind/Nethermind.State.Test/WorldStateManagerTests.cs @@ -8,6 +8,7 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Test.Builders; +using Nethermind.Core.Test.Db; using Nethermind.Core.Test.Modules; using Nethermind.Db; using Nethermind.Logging; diff --git a/src/Nethermind/Nethermind.State/OverridableEnv/OverridableCodeInfoRepository.cs b/src/Nethermind/Nethermind.State/OverridableEnv/OverridableCodeInfoRepository.cs index 73109dd67ba..2ed4c2147fb 100644 --- a/src/Nethermind/Nethermind.State/OverridableEnv/OverridableCodeInfoRepository.cs +++ b/src/Nethermind/Nethermind.State/OverridableEnv/OverridableCodeInfoRepository.cs @@ -25,6 +25,11 @@ public ICodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, b : codeInfoRepository.GetCachedCodeInfo(worldState, codeSource, followDelegation, vmSpec, out delegationAddress); } + public bool IsPrecompile(Address address, IReleaseSpec spec) => + _codeOverwrites.TryGetValue(address, out ICodeInfo result) + ? result.IsPrecompile + : codeInfoRepository.IsPrecompile(address, spec); + public void InsertCode(IWorldState state, ReadOnlyMemory code, Address codeOwner, IReleaseSpec spec) => codeInfoRepository.InsertCode(state, code, codeOwner, spec); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/SnapServerTest.cs b/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/SnapServerTest.cs index 2de2c94f8ce..2c17a1316ea 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/SnapServerTest.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SnapSync/SnapServerTest.cs @@ -269,12 +269,11 @@ public void TestGetStorageRange() SnapServer server = new(store.AsReadOnly(), codeDb, CreateConstantStateRootTracker(true), LimboLogs.Instance); - IDbProvider dbProviderClient = new DbProvider(); - dbProviderClient.RegisterDb(DbNames.State, new MemDb()); - dbProviderClient.RegisterDb(DbNames.Code, new MemDb()); + IDb codeDb2 = new MemDb(); + IDb stateDb2 = new MemDb(); - using ProgressTracker progressTracker = new(dbProviderClient.StateDb, new TestSyncConfig(), new StateSyncPivot(null!, new TestSyncConfig(), LimboLogs.Instance), LimboLogs.Instance); - SnapProvider snapProvider = new(progressTracker, dbProviderClient.CodeDb, new NodeStorage(dbProviderClient.StateDb), LimboLogs.Instance); + using ProgressTracker progressTracker = new(stateDb2, new TestSyncConfig(), new StateSyncPivot(null!, new TestSyncConfig(), LimboLogs.Instance), LimboLogs.Instance); + SnapProvider snapProvider = new(progressTracker, codeDb2, new NodeStorage(stateDb2), LimboLogs.Instance); (IOwnedReadOnlyList> storageSlots, IOwnedReadOnlyList? proofs) = server.GetStorageRanges(inputStateTree.RootHash, [TestItem.Tree.AccountsWithPaths[0]], @@ -309,10 +308,6 @@ public void TestGetStorageRange_NoSlotsForAccount() SnapServer server = new(store.AsReadOnly(), codeDb, CreateConstantStateRootTracker(true), LimboLogs.Instance); - IDbProvider dbProviderClient = new DbProvider(); - dbProviderClient.RegisterDb(DbNames.State, new MemDb()); - dbProviderClient.RegisterDb(DbNames.Code, new MemDb()); - ValueHash256 lastStorageHash = TestItem.Tree.SlotsWithPaths[^1].Path; var asInt = lastStorageHash.ToUInt256(); ValueHash256 beyondLast = new ValueHash256((++asInt).ToBigEndian()); @@ -339,12 +334,11 @@ public void TestGetStorageRangeMulti() SnapServer server = new(store.AsReadOnly(), codeDb, CreateConstantStateRootTracker(true), LimboLogs.Instance); - IDbProvider dbProviderClient = new DbProvider(); - dbProviderClient.RegisterDb(DbNames.State, new MemDb()); - dbProviderClient.RegisterDb(DbNames.Code, new MemDb()); + IDb stateDb2 = new MemDb(); + IDb codeDb2 = new MemDb(); - using ProgressTracker progressTracker = new(dbProviderClient.StateDb, new TestSyncConfig(), new StateSyncPivot(null!, new TestSyncConfig(), LimboLogs.Instance), LimboLogs.Instance); - SnapProvider snapProvider = new(progressTracker, dbProviderClient.CodeDb, new NodeStorage(dbProviderClient.StateDb), LimboLogs.Instance); + using ProgressTracker progressTracker = new(stateDb2, new TestSyncConfig(), new StateSyncPivot(null!, new TestSyncConfig(), LimboLogs.Instance), LimboLogs.Instance); + SnapProvider snapProvider = new(progressTracker, codeDb2, new NodeStorage(stateDb2), LimboLogs.Instance); Hash256 startRange = Keccak.Zero; while (true) diff --git a/src/Nethermind/Nethermind.Synchronization.Test/TestSynchronizerModule.cs b/src/Nethermind/Nethermind.Synchronization.Test/TestSynchronizerModule.cs index b35ff56bced..c4f86941504 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/TestSynchronizerModule.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/TestSynchronizerModule.cs @@ -2,11 +2,14 @@ // SPDX-License-Identifier: LGPL-3.0-only using Autofac; +using Nethermind.Api; using Nethermind.Blockchain; +using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Synchronization; using Nethermind.Core; using Nethermind.Core.Timers; using Nethermind.Db; +using Nethermind.Init.Modules; using Nethermind.Logging; using Nethermind.Stats; using Nethermind.Trie; @@ -22,8 +25,8 @@ protected override void Load(ContainerBuilder builder) builder .AddModule(new SynchronizerModule(syncConfig)) - .AddModule(new DbModule()) - .AddSingleton(TestMemDbProvider.Init()) + .AddModule(new DbModule(new InitConfig(), new ReceiptConfig(), syncConfig)) + .AddSingleton((_) => new MemDbFactory()) .Map(dbProvider => new NodeStorage(dbProvider.StateDb)) .AddSingleton(Substitute.For()) .AddSingleton(Substitute.For()) diff --git a/src/Nethermind/Nethermind.Taiko.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Taiko.Test/TransactionProcessorTests.cs index ab13bd88fb3..3b01b805af3 100644 --- a/src/Nethermind/Nethermind.Taiko.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Taiko.Test/TransactionProcessorTests.cs @@ -13,9 +13,9 @@ using Nethermind.Evm.State; using NUnit.Framework; using System.Collections; +using Nethermind.Blockchain; using Nethermind.Core.Test; using Nethermind.Evm; -using Nethermind.Evm.Test; using Nethermind.State; using Nethermind.Taiko.TaikoSpec; @@ -49,7 +49,7 @@ public void Setup() _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(0); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); VirtualMachine virtualMachine = new(new TestBlockhashProvider(_specProvider), _specProvider, LimboLogs.Instance); _transactionProcessor = new TaikoTransactionProcessor(_specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance); } diff --git a/src/Nethermind/Nethermind.Taiko/InitializeBlockchainTaiko.cs b/src/Nethermind/Nethermind.Taiko/InitializeBlockchainTaiko.cs index ba7f68f7eef..b790047a024 100644 --- a/src/Nethermind/Nethermind.Taiko/InitializeBlockchainTaiko.cs +++ b/src/Nethermind/Nethermind.Taiko/InitializeBlockchainTaiko.cs @@ -47,7 +47,6 @@ protected override ITransactionProcessor CreateTransactionProcessor(ICodeInfoRep protected override BlockProcessor CreateBlockProcessor(BlockCachePreWarmer? preWarmer, ITransactionProcessor transactionProcessor, IWorldState worldState) { - if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider)); if (_api.RewardCalculatorSource is null) throw new StepDependencyException(nameof(_api.RewardCalculatorSource)); if (_api.SpecProvider is null) throw new StepDependencyException(nameof(_api.SpecProvider)); if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); diff --git a/src/Nethermind/Nethermind.Taiko/TaikoPlugin.cs b/src/Nethermind/Nethermind.Taiko/TaikoPlugin.cs index be415bcb2b7..771dcbb845f 100644 --- a/src/Nethermind/Nethermind.Taiko/TaikoPlugin.cs +++ b/src/Nethermind/Nethermind.Taiko/TaikoPlugin.cs @@ -29,6 +29,7 @@ using Nethermind.Serialization.Rlp; using Autofac; using Autofac.Core; +using Nethermind.Init.Modules; using Nethermind.JsonRpc.Modules.Eth.GasPrice; using Nethermind.Serialization.Json; using Nethermind.Taiko.BlockTransactionExecutors; @@ -103,8 +104,7 @@ protected override void Load(ContainerBuilder builder) // L1 origin store .AddSingleton, L1OriginDecoder>() - .AddKeyedSingleton(L1OriginStore.L1OriginDbName, ctx => ctx - .Resolve().CreateDb(new DbSettings(L1OriginStore.L1OriginDbName, L1OriginStore.L1OriginDbName.ToLower()))) + .AddDatabase(L1OriginStore.L1OriginDbName, L1OriginStore.L1OriginDbName, L1OriginStore.L1OriginDbName.ToLower()) .AddSingleton() // Sync modification diff --git a/src/Nethermind/Nethermind.Trie.Test/OverlayTrieStoreTests.cs b/src/Nethermind/Nethermind.Trie.Test/OverlayTrieStoreTests.cs index 493ff8e6934..29cf8d7767f 100644 --- a/src/Nethermind/Nethermind.Trie.Test/OverlayTrieStoreTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/OverlayTrieStoreTests.cs @@ -7,6 +7,7 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; +using Nethermind.Core.Test.Db; using Nethermind.Db; using Nethermind.Logging; using Nethermind.Trie.Pruning; diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs index b794d694717..2a72fcf2e84 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs @@ -11,6 +11,7 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; +using Nethermind.Core.Test.Db; using Nethermind.Db; using Nethermind.Int256; using Nethermind.Logging; diff --git a/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs b/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs index 1a8057c4e25..f2114ee1edb 100644 --- a/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/PruningScenariosTests.cs @@ -10,6 +10,7 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; +using Nethermind.Core.Test.Db; using Nethermind.Db; using Nethermind.Int256; using Nethermind.Logging; diff --git a/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs b/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs index e4fd20fc504..9c1e9fea114 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/DelegatedAccountFilterTest.cs @@ -29,7 +29,7 @@ public void Accept_SenderIsNotDelegated_ReturnsAccepted() headInfoProvider.GetCurrentHeadSpec().Returns(Prague.Instance); TxDistinctSortedPool standardPool = new TxDistinctSortedPool(MemoryAllowance.MemPoolSize, Substitute.For>(), NullLogManager.Instance); TxDistinctSortedPool blobPool = new BlobTxDistinctSortedPool(10, Substitute.For>(), NullLogManager.Instance); - DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, Substitute.For(), new CodeInfoRepository(), new DelegationCache()); + DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, Substitute.For(), new EthereumCodeInfoRepository(), new DelegationCache()); Transaction transaction = Build.A.Transaction.SignedAndResolved(new EthereumEcdsa(0), TestItem.PrivateKeyA).TestObject; TxFilteringState state = new(transaction, Substitute.For()); @@ -44,7 +44,7 @@ public void Accept_SenderIsDelegatedWithNoTransactionsInPool_ReturnsAccepted() IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); IWorldState stateProvider = worldStateManager.GlobalWorldState; stateProvider.CreateAccount(TestItem.AddressA, 0); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); byte[] code = [.. Eip7702Constants.DelegationHeader, .. TestItem.PrivateKeyA.Address.Bytes]; codeInfoRepository.InsertCode(stateProvider, code, TestItem.AddressA, Prague.Instance); IChainHeadSpecProvider headInfoProvider = Substitute.For(); @@ -72,7 +72,7 @@ public void Accept_SenderIsDelegatedWithOneTransactionInPoolWithSameNonce_Return IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); IWorldState stateProvider = worldStateManager.GlobalWorldState; stateProvider.CreateAccount(TestItem.AddressA, 0); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); byte[] code = [.. Eip7702Constants.DelegationHeader, .. TestItem.PrivateKeyA.Address.Bytes]; codeInfoRepository.InsertCode(stateProvider, code, TestItem.AddressA, Prague.Instance); DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, stateProvider, codeInfoRepository, new DelegationCache()); @@ -96,7 +96,7 @@ public void Accept_SenderIsDelegatedWithOneTransactionInPoolWithDifferentNonce_R IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); IWorldState stateProvider = worldStateManager.GlobalWorldState; stateProvider.CreateAccount(TestItem.AddressA, 0); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); byte[] code = [.. Eip7702Constants.DelegationHeader, .. TestItem.PrivateKeyA.Address.Bytes]; codeInfoRepository.InsertCode(stateProvider, code, TestItem.AddressA, Prague.Instance); DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, stateProvider, codeInfoRepository, new DelegationCache()); @@ -125,7 +125,7 @@ public void Accept_Eip7702IsNotActivated_ReturnsExpected(bool isActive, AcceptTx IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); IWorldState stateProvider = worldStateManager.GlobalWorldState; stateProvider.CreateAccount(TestItem.AddressA, 0); - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); byte[] code = [.. Eip7702Constants.DelegationHeader, .. TestItem.PrivateKeyA.Address.Bytes]; codeInfoRepository.InsertCode(stateProvider, code, TestItem.AddressA, Prague.Instance); DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, stateProvider, codeInfoRepository, new DelegationCache()); @@ -153,7 +153,7 @@ public void Accept_SenderHasPendingDelegation_OnlyAcceptsIfNonceIsExactMatch(int TxDistinctSortedPool blobPool = new BlobTxDistinctSortedPool(10, Substitute.For>(), NullLogManager.Instance); DelegationCache pendingDelegations = new(); pendingDelegations.IncrementDelegationCount(TestItem.AddressA); - DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, Substitute.For(), new CodeInfoRepository(), pendingDelegations); + DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, Substitute.For(), new EthereumCodeInfoRepository(), pendingDelegations); Transaction transaction = Build.A.Transaction.WithNonce((UInt256)nonce).SignedAndResolved(new EthereumEcdsa(0), TestItem.PrivateKeyA).TestObject; IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); IWorldState stateProvider = worldStateManager.GlobalWorldState; @@ -173,7 +173,7 @@ public void Accept_AuthorityHasPendingTransaction_ReturnsDelegatorHasPendingTx(b headInfoProvider.GetCurrentHeadSpec().Returns(Prague.Instance); TxDistinctSortedPool standardPool = new TxDistinctSortedPool(MemoryAllowance.MemPoolSize, Substitute.For>(), NullLogManager.Instance); TxDistinctSortedPool blobPool = new BlobTxDistinctSortedPool(10, Substitute.For>(), NullLogManager.Instance); - DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, Substitute.For(), new CodeInfoRepository(), new()); + DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, Substitute.For(), new EthereumCodeInfoRepository(), new()); Transaction transaction; if (useBlobPool) { @@ -214,7 +214,7 @@ public void Accept_SetCodeTxHasAuthorityWithPendingTx_ReturnsDelegatorHasPending TxDistinctSortedPool blobPool = new BlobTxDistinctSortedPool(10, Substitute.For>(), NullLogManager.Instance); DelegationCache pendingDelegations = new(); pendingDelegations.IncrementDelegationCount(TestItem.AddressA); - DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, Substitute.For(), new CodeInfoRepository(), pendingDelegations); + DelegatedAccountFilter filter = new(headInfoProvider, standardPool, blobPool, Substitute.For(), new EthereumCodeInfoRepository(), pendingDelegations); Transaction transaction = Build.A.Transaction .WithNonce(1) .SignedAndResolved(new EthereumEcdsa(0), TestItem.PrivateKeyA).TestObject; diff --git a/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs b/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs index ebd1e270117..3402c10146b 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/NonceManagerTests.cs @@ -43,7 +43,7 @@ public void Setup() _blockTree.Head.Returns(block); _blockTree.FindBestSuggestedHeader().Returns(Build.A.BlockHeader.WithNumber(10000000).TestObject); - _headInfo = new ChainHeadInfoProvider(_specProvider, _blockTree, _stateProvider, new CodeInfoRepository()); + _headInfo = new ChainHeadInfoProvider(_specProvider, _blockTree, _stateProvider, new EthereumCodeInfoRepository()); _nonceManager = new NonceManager(_headInfo.ReadOnlyStateProvider); } diff --git a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.Blobs.cs b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.Blobs.cs index 9c92e315abd..16e7597b2dc 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.Blobs.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.Blobs.cs @@ -466,7 +466,7 @@ public void should_allow_to_replace_blob_tx_by_the_one_with_network_wrapper_in_h IChainHeadSpecProvider specProvider = Substitute.For(); specProvider.GetCurrentHeadSpec().Returns(releaseSpec); - ChainHeadInfoProvider chainHeadInfoProvider = new(specProvider, _blockTree, _stateProvider, new CodeInfoRepository()); + ChainHeadInfoProvider chainHeadInfoProvider = new(specProvider, _blockTree, _stateProvider, new EthereumCodeInfoRepository()); _txPool = CreatePool(new TxPoolConfig() { BlobsSupport = BlobsSupportMode.InMemory, Size = 128 }, specProvider: specProvider, chainHeadInfoProvider: chainHeadInfoProvider); diff --git a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs index 279a6fdc54a..dff558165a1 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs @@ -2195,7 +2195,7 @@ private TxPool CreatePool( txStorage ??= new BlobTxStorage(); _headInfo = chainHeadInfoProvider; - _headInfo ??= new ChainHeadInfoProvider(specProvider, _blockTree, _stateProvider, new CodeInfoRepository()); + _headInfo ??= new ChainHeadInfoProvider(specProvider, _blockTree, _stateProvider, new EthereumCodeInfoRepository()); return new TxPool( _ethereumEcdsa, diff --git a/src/Nethermind/Nethermind.slnx b/src/Nethermind/Nethermind.slnx index 68022da596f..f11579ea877 100644 --- a/src/Nethermind/Nethermind.slnx +++ b/src/Nethermind/Nethermind.slnx @@ -95,6 +95,7 @@ + diff --git a/tools/Evm/T8n/T8nExecutor.cs b/tools/Evm/T8n/T8nExecutor.cs index 90b31aa23e3..672a09618e2 100644 --- a/tools/Evm/T8n/T8nExecutor.cs +++ b/tools/Evm/T8n/T8nExecutor.cs @@ -24,6 +24,7 @@ using Nethermind.Logging; using Nethermind.State; using Nethermind.Trie.Pruning; +using Nethermind.Blockchain; namespace Evm.T8n; @@ -39,7 +40,7 @@ public static T8nExecutionResult Execute(T8nCommandArguments arguments) IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); IWorldState stateProvider = worldStateManager.GlobalWorldState; - CodeInfoRepository codeInfoRepository = new(); + EthereumCodeInfoRepository codeInfoRepository = new(); IBlockhashProvider blockhashProvider = ConstructBlockHashProvider(test); IVirtualMachine virtualMachine = new VirtualMachine(