From ec2a030c88a4b086b8c6a3074a7fd74b71185aaf Mon Sep 17 00:00:00 2001 From: Tanishq Jasoria Date: Wed, 11 Jan 2023 20:56:53 +0530 Subject: [PATCH 1/4] replace init interfaces --- .../Nethermind.Abi.Contracts/Contract.cs | 8 ++++---- .../AccountAbstractionPeerManagerTests.cs | 2 +- .../UserOperationPoolTests.cs | 2 +- .../Nethermind.Api/IApiWithBlockchain.cs | 2 -- src/Nethermind/Nethermind.Api/NethermindApi.cs | 2 -- .../AuRaBlockProducerTests.cs | 4 ++-- .../Contract/ValidatorContractTests.cs | 4 ++-- .../Validators/ContractBasedValidatorTests.cs | 10 +++++----- .../ReportingContractBasedValidatorTests.cs | 4 ++-- .../BlockProcessorTests.cs | 10 +++------- ...BlockProducerBaseTests.IsProducingBlocks.cs | 2 +- .../Producers/BlockProducerBaseTests.cs | 6 +++--- .../Producers/DevBlockproducerTests.cs | 7 +------ .../Contracts/CallableContract.cs | 2 +- .../CliqueBlockProducerTests.cs | 5 +---- .../CliqueRpcModuleTests.cs | 2 +- .../AuRaBlockProducer.cs | 2 +- .../Contracts/ValidatorContract.cs | 4 ++-- .../InitializeBlockchainAuRa.cs | 2 +- .../LoadGenesisBlockAuRa.cs | 2 +- .../CliqueBlockProducer.cs | 4 ++-- .../MinedBlockProducer.cs | 2 +- .../Producers/BlockProducerBase.cs | 4 ++-- .../Producers/DevBlockProducer.cs | 2 +- .../Nethermind.Consensus/Tracing/Tracer.cs | 4 ++-- .../Blockchain/TestBlockProducer.cs | 2 +- .../Steps/InitializeBlockchain.cs | 18 ++++-------------- .../Nethermind.Init/Steps/LoadGenesisBlock.cs | 7 +++---- .../Modules/Trace/ParityStyleTracerTests.cs | 4 +--- .../AuRaPostMergeBlockProducer.cs | 2 +- .../BlockProduction/PostMergeBlockProducer.cs | 2 +- .../Nethermind.Merge.Plugin/MergePlugin.cs | 2 +- .../Ethereum/ContextWithMocks.cs | 3 +-- .../StorageProviderTests.cs | 4 ++-- .../SyncThreadTests.cs | 2 +- .../Nethermind.TxPool.Test/TxPoolTests.cs | 4 ++-- 36 files changed, 59 insertions(+), 89 deletions(-) diff --git a/src/Nethermind/Nethermind.Abi.Contracts/Contract.cs b/src/Nethermind/Nethermind.Abi.Contracts/Contract.cs index e31e2382d45..ef4002e5e12 100644 --- a/src/Nethermind/Nethermind.Abi.Contracts/Contract.cs +++ b/src/Nethermind/Nethermind.Abi.Contracts/Contract.cs @@ -17,8 +17,8 @@ namespace Nethermind.Consensus.AuRa.Contracts /// Base class for contracts that will be interacted by the node engine. /// /// - /// This class is intended to be inherited and concrete contract class should provide contract specific methods to be able for the node to use the contract. - /// + /// This class is intended to be inherited and concrete contract class should provide contract specific methods to be able for the node to use the contract. + /// /// There are 3 main ways a node can interact with contract: /// 1. It can that will be added to a block. /// 2. It can contract and modify current state of execution. @@ -27,7 +27,7 @@ namespace Nethermind.Consensus.AuRa.Contracts public abstract partial class Contract { /// - /// Default gas limit of transactions generated from contract. + /// Default gas limit of transactions generated from contract. /// public const long DefaultContractGasLimit = 1_600_000L; @@ -182,7 +182,7 @@ protected bool TryCall(BlockHeader header, AbiFunctionDescription function, Addr /// Creates account if its not in current state. /// /// State provider. - protected void EnsureSystemAccount(IStateProvider stateProvider) + protected void EnsureSystemAccount(IWorldState stateProvider) { if (!stateProvider.AccountExists(Address.SystemUser)) { diff --git a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionPeerManagerTests.cs b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionPeerManagerTests.cs index 6c4b8adef3a..669ed08377d 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionPeerManagerTests.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction.Test/AccountAbstractionPeerManagerTests.cs @@ -41,7 +41,7 @@ public class AccountAbstractionPeerManagerTests private IBlockTree _blockTree = Substitute.For(); private ILogger _logger = Substitute.For(); private ILogFinder _logFinder = Substitute.For(); - private IStateProvider _stateProvider = Substitute.For(); + private IWorldState _stateProvider = Substitute.For(); private ISpecProvider _specProvider = Substitute.For(); private readonly ISigner _signer = Substitute.For(); private readonly string[] _entryPointContractAddress = { "0x8595dd9e0438640b5e1254f9df579ac12a86865f", "0x96cc609c8f5458fb8a7da4d94b678e38ebf3d04e" }; diff --git a/src/Nethermind/Nethermind.AccountAbstraction.Test/UserOperationPoolTests.cs b/src/Nethermind/Nethermind.AccountAbstraction.Test/UserOperationPoolTests.cs index 834a3cf9574..12a232ef3fa 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction.Test/UserOperationPoolTests.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction.Test/UserOperationPoolTests.cs @@ -44,7 +44,7 @@ public class UserOperationPoolTests private IBlockTree _blockTree = Substitute.For(); private IReceiptFinder _receiptFinder = Substitute.For(); private ILogFinder _logFinder = Substitute.For(); - private IStateProvider _stateProvider = Substitute.For(); + private IWorldState _stateProvider = Substitute.For(); private ISpecProvider _specProvider = Substitute.For(); private readonly ISigner _signer = Substitute.For(); private readonly Keccak _userOperationEventTopic = new("0x33fd4d1f25a5461bea901784a6571de6debc16cd0831932c22c6969cd73ba994"); diff --git a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs index 0ee57dfb5c9..3f846b5634a 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs @@ -53,11 +53,9 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory /// /// DO NOT USE OUTSIDE OF PROCESSING BLOCK CONTEXT! /// - IStateProvider? StateProvider { get; set; } IKeyValueStoreWithBatching? MainStateDbWithCache { get; set; } IReadOnlyStateProvider? ChainHeadStateProvider { get; set; } IStateReader? StateReader { get; set; } - IStorageProvider? StorageProvider { get; set; } IWorldState? WorldState { get; set; } ITransactionProcessor? TransactionProcessor { get; set; } ITrieStore? TrieStore { get; set; } diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 1d6fec6a0d1..01d004c26c4 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -181,11 +181,9 @@ public ISealEngine SealEngine public IPeerDifficultyRefreshPool? PeerDifficultyRefreshPool { get; set; } public ISynchronizer? Synchronizer { get; set; } public ISyncServer? SyncServer { get; set; } - public IStateProvider? StateProvider { get; set; } public IWorldState? WorldState { get; set; } public IReadOnlyStateProvider? ChainHeadStateProvider { get; set; } public IStateReader? StateReader { get; set; } - public IStorageProvider? StorageProvider { get; set; } public IStaticNodesManager? StaticNodesManager { get; set; } public ITimestamper Timestamper { get; } = Core.Timestamper.Default; public ITimerFactory TimerFactory { get; } = Core.Timers.TimerFactory.Default; diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs index 25b1a25bb31..874605e7faf 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaBlockProducerTests.cs @@ -43,7 +43,7 @@ private class Context public ISealer Sealer { get; } public IBlockTree BlockTree { get; } public IBlockProcessingQueue BlockProcessingQueue { get; } - public IStateProvider StateProvider { get; } + public IWorldState StateProvider { get; } public ITimestamper Timestamper { get; } public IAuRaStepCalculator AuRaStepCalculator { get; } public Address NodeAddress { get; } @@ -58,7 +58,7 @@ public Context() Sealer = Substitute.For(); BlockTree = Substitute.For(); BlockProcessingQueue = Substitute.For(); - StateProvider = Substitute.For(); + StateProvider = Substitute.For(); Timestamper = Substitute.For(); AuRaStepCalculator = Substitute.For(); NodeAddress = TestItem.AddressA; diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/ValidatorContractTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/ValidatorContractTests.cs index 1e6898597ea..9b287c3735f 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/ValidatorContractTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/ValidatorContractTests.cs @@ -27,7 +27,7 @@ public class ValidatorContractTests private readonly Address _contractAddress = Address.FromNumber(long.MaxValue); private IReadOnlyTransactionProcessor _transactionProcessor; private IReadOnlyTxProcessorSource _readOnlyTxProcessorSource; - private IStateProvider _stateProvider; + private IWorldState _stateProvider; [SetUp] public void SetUp() @@ -36,7 +36,7 @@ public void SetUp() _transactionProcessor = Substitute.For(); _readOnlyTxProcessorSource = Substitute.For(); _readOnlyTxProcessorSource.Build(TestItem.KeccakA).Returns(_transactionProcessor); - _stateProvider = Substitute.For(); + _stateProvider = Substitute.For(); _stateProvider.StateRoot.Returns(TestItem.KeccakA); } diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs index 9a1d41724b6..d35dedb6e70 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ContractBasedValidatorTests.cs @@ -36,7 +36,7 @@ namespace Nethermind.AuRa.Test.Validators { public class ContractBasedValidatorTests { - private IStateProvider _stateProvider; + private IWorldState _stateProvider; private IAbiEncoder _abiEncoder; private ILogManager _logManager; private AuRaParameters.Validator _validator; @@ -60,7 +60,7 @@ public void SetUp() { _validatorStore = new ValidatorStore(new MemDb()); _validSealerStrategy = new ValidSealerStrategy(); - _stateProvider = Substitute.For(); + _stateProvider = Substitute.For(); _abiEncoder = Substitute.For(); _logManager = LimboLogs.Instance; _blockTree = Substitute.For(); @@ -333,7 +333,7 @@ public static IEnumerable ConsecutiveInitiateChangeData InitializeBlock = 3, FinalizeBlock = 3 }, - new() + new() // this will not get finalized because of reorganisation { Addresses = GenerateValidators(2), @@ -346,7 +346,7 @@ public static IEnumerable ConsecutiveInitiateChangeData { 7, new ConsecutiveInitiateChangeTestParameters.ChainInfo() { - BlockNumber = 5, //reorganisation to block 5 in order to invalidate last initiate change + BlockNumber = 5, //reorganisation to block 5 in order to invalidate last initiate change ExpectedFinalizationCount = 0, NumberOfSteps = 10, } @@ -447,7 +447,7 @@ public static IEnumerable ConsecutiveInitiateChangeData { 7, new ConsecutiveInitiateChangeTestParameters.ChainInfo() { - BlockNumber = 6, //reorganisation to block 6 in order to keep last initiate change + BlockNumber = 6, //reorganisation to block 6 in order to keep last initiate change ExpectedFinalizationCount = 2, NumberOfSteps = 10, Validators = new List() diff --git a/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs index 03419992874..af37c7a7bbe 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Validators/ReportingContractBasedValidatorTests.cs @@ -159,7 +159,7 @@ public void Report_ignores_duplicates_in_same_block() context.Validator.ReportMalicious(MaliciousMinerAddress, 100, Bytes.Empty, IReportingValidator.MaliciousCause.DuplicateStep); // ignored context.Validator.ReportMalicious(MaliciousMinerAddress, 100, Bytes.Empty, IReportingValidator.MaliciousCause.SiblingBlocksInSameStep); // ignored context.Validator.ReportMalicious(MaliciousMinerAddress, 100, Bytes.Empty, IReportingValidator.MaliciousCause.SiblingBlocksInSameStep); // ignored - context.Validator.ReportBenign(TestItem.AddressC, 100, IReportingValidator.BenignCause.FutureBlock); // sent + context.Validator.ReportBenign(TestItem.AddressC, 100, IReportingValidator.BenignCause.FutureBlock); // sent context.Validator.ReportBenign(TestItem.AddressC, 100, IReportingValidator.BenignCause.FutureBlock); // ignored context.Validator.ReportBenign(MaliciousMinerAddress, 101, IReportingValidator.BenignCause.FutureBlock); //sent context.Validator.ReportBenign(MaliciousMinerAddress, 101, IReportingValidator.BenignCause.IncorrectProposer); //ignored @@ -204,7 +204,7 @@ public TestContext(bool forSealing, ReportingContractBasedValidator.Cache cache TxSender = Substitute.For(); ITxPool txPool = Substitute.For(); - IStateProvider stateProvider = Substitute.For(); + IWorldState stateProvider = Substitute.For(); ISpecProvider specProvider = Substitute.For(); stateProvider.GetNonce(ReportingValidatorContract.NodeAddress).Returns(UInt256.One); diff --git a/src/Nethermind/Nethermind.Blockchain.Test/BlockProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/BlockProcessorTests.cs index 7698e71aadf..82aaac65308 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/BlockProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/BlockProcessorTests.cs @@ -40,16 +40,14 @@ public void Prepared_block_contains_author_field() IDb stateDb = new MemDb(); IDb codeDb = new MemDb(); TrieStore trieStore = new(stateDb, LimboLogs.Instance); - IStateProvider stateProvider = new StateProvider(trieStore, codeDb, LimboLogs.Instance); - IStorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, LimboLogs.Instance); - IWorldState worldState = new WorldState(trieStore, codeDb, LimboLogs.Instance); + IWorldState stateProvider = new WorldState(trieStore, codeDb, LimboLogs.Instance); ITransactionProcessor transactionProcessor = Substitute.For(); BlockProcessor processor = new( RinkebySpecProvider.Instance, TestBlockValidator.AlwaysValid, NoBlockRewards.Instance, new BlockProcessor.BlockValidationTransactionsExecutor(transactionProcessor, new WorldState(trieStore, codeDb, LimboLogs.Instance)), - worldState, + stateProvider, NullReceiptStorage.Instance, NullWitnessCollector.Instance, LimboLogs.Instance); @@ -72,7 +70,7 @@ public void Can_store_a_witness() IDb codeDb = new MemDb(); var trieStore = new TrieStore(stateDb, LimboLogs.Instance); - IStateProvider stateProvider = new StateProvider(trieStore, codeDb, LimboLogs.Instance); + IWorldState stateProvider = new WorldState(trieStore, codeDb, LimboLogs.Instance); IStorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, LimboLogs.Instance); ITransactionProcessor transactionProcessor = Substitute.For(); IWitnessCollector witnessCollector = Substitute.For(); @@ -103,8 +101,6 @@ public void Recovers_state_on_cancel() IDb stateDb = new MemDb(); IDb codeDb = new MemDb(); TrieStore trieStore = new(stateDb, LimboLogs.Instance); - IStateProvider stateProvider = new StateProvider(trieStore, codeDb, LimboLogs.Instance); - IStorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, LimboLogs.Instance); IWorldState worldState = new WorldState(trieStore, codeDb, LimboLogs.Instance); ITransactionProcessor transactionProcessor = Substitute.For(); BlockProcessor processor = new( diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.IsProducingBlocks.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.IsProducingBlocks.cs index 0eed5969071..bd24f22d5ff 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.IsProducingBlocks.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.IsProducingBlocks.cs @@ -99,7 +99,7 @@ public async Task AuraTestBlockProducer_IsProducingBlocks_returns_expected_resul Substitute.For(), Substitute.For(), Substitute.For(), - Substitute.For(), + Substitute.For(), Substitute.For(), Substitute.For(), Substitute.For(), diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.cs index 0185af1ddf5..a5c91bea105 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/BlockProducerBaseTests.cs @@ -32,7 +32,7 @@ public ProducerUnderTest( ISealer sealer, IBlockTree blockTree, IBlockProductionTrigger blockProductionTrigger, - IStateProvider stateProvider, + IWorldState stateProvider, IGasLimitCalculator gasLimitCalculator, ITimestamper timestamper, ILogManager logManager, @@ -80,7 +80,7 @@ public void Time_passing_does_not_break_the_block() NullSealEngine.Instance, Build.A.BlockTree().TestObject, Substitute.For(), - Substitute.For(), + Substitute.For(), Substitute.For(), timestamper, LimboLogs.Instance, @@ -103,7 +103,7 @@ public void Parent_timestamp_is_used_consistently() NullSealEngine.Instance, Build.A.BlockTree().TestObject, Substitute.For(), - Substitute.For(), + Substitute.For(), Substitute.For(), timestamper, LimboLogs.Instance, diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs index fe27d2b5ef2..ad651f16a92 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Producers/DevBlockproducerTests.cs @@ -52,12 +52,7 @@ public void Test() NoPruning.Instance, Archive.Instance, LimboLogs.Instance); - StateProvider stateProvider = new( - trieStore, - dbProvider.RegisteredDbs[DbNames.Code], - LimboLogs.Instance); StateReader stateReader = new(trieStore, dbProvider.GetDb(DbNames.State), LimboLogs.Instance); - StorageProvider storageProvider = new(trieStore, stateProvider, LimboLogs.Instance); WorldState worldState = new WorldState(trieStore, dbProvider.RegisteredDbs[DbNames.Code], LimboLogs.Instance); BlockhashProvider blockhashProvider = new(blockTree, LimboLogs.Instance); VirtualMachine virtualMachine = new( @@ -90,7 +85,7 @@ public void Test() DevBlockProducer devBlockProducer = new( EmptyTxSource.Instance, blockchainProcessor, - stateProvider, + worldState, blockTree, trigger, timestamper, diff --git a/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs b/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs index e04906115a7..41dff35a7c9 100644 --- a/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs +++ b/src/Nethermind/Nethermind.Blockchain/Contracts/CallableContract.cs @@ -117,7 +117,7 @@ protected bool TryCall(BlockHeader header, string functionName, Address sender, /// Creates account if its not in current state. /// /// State provider. - protected void EnsureSystemAccount(IStateProvider stateProvider) + protected void EnsureSystemAccount(IWorldState stateProvider) { if (!stateProvider.AccountExists(Address.SystemUser)) { diff --git a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs index 95047cfa52d..5bb5382d18e 100644 --- a/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/CliqueBlockProducerTests.cs @@ -139,9 +139,6 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f processor.Start(); IReadOnlyTrieStore minerTrieStore = trieStore.AsReadOnly(); - - StateProvider minerStateProvider = new(minerTrieStore, codeDb, nodeLogManager); - StorageProvider minerStorageProvider = new(minerTrieStore, minerStateProvider, nodeLogManager); WorldState minerWorldState = new WorldState(minerTrieStore, codeDb, nodeLogManager); VirtualMachine minerVirtualMachine = new(blockhashProvider, specProvider, nodeLogManager); TransactionProcessor minerTransactionProcessor = new TransactionProcessor(goerliSpecProvider, minerWorldState, minerVirtualMachine, nodeLogManager); @@ -171,7 +168,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f CliqueBlockProducer blockProducer = new( txPoolTxSource, minerProcessor, - minerStateProvider, + minerWorldState, blockTree, _timestamper, new CryptoRandom(), diff --git a/src/Nethermind/Nethermind.Clique.Test/CliqueRpcModuleTests.cs b/src/Nethermind/Nethermind.Clique.Test/CliqueRpcModuleTests.cs index 78497639a30..92a313f2dd8 100644 --- a/src/Nethermind/Nethermind.Clique.Test/CliqueRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.Clique.Test/CliqueRpcModuleTests.cs @@ -35,7 +35,7 @@ public void Sets_clique_block_producer_properly() CliqueBlockProducer producer = new( Substitute.For(), Substitute.For(), - Substitute.For(), + Substitute.For(), blockTree, Substitute.For(), Substitute.For(), diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockProducer.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockProducer.cs index f6644e8d2f2..6a9b4207fe8 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockProducer.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaBlockProducer.cs @@ -30,7 +30,7 @@ public class AuRaBlockProducer : BlockProducerBase public AuRaBlockProducer(ITxSource txSource, IBlockchainProcessor processor, IBlockProductionTrigger blockProductionTrigger, - IStateProvider stateProvider, + IWorldState stateProvider, ISealer sealer, IBlockTree blockTree, ITimestamper timestamper, diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ValidatorContract.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ValidatorContract.cs index 3f4c32a89b2..4f909a8442a 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ValidatorContract.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Contracts/ValidatorContract.cs @@ -54,7 +54,7 @@ public partial interface IValidatorContract public sealed partial class ValidatorContract : CallableContract, IValidatorContract { - private readonly IStateProvider _stateProvider; + private readonly IWorldState _stateProvider; private readonly ISigner _signer; private IConstantContract Constant { get; } @@ -63,7 +63,7 @@ public ValidatorContract( ITransactionProcessor transactionProcessor, IAbiEncoder abiEncoder, Address contractAddress, - IStateProvider stateProvider, + IWorldState stateProvider, IReadOnlyTxProcessorSource readOnlyTxProcessorSource, ISigner signer) : base(transactionProcessor, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress))) diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs index 15ed931f4ae..ea42254326b 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/InitializeBlockchainAuRa.cs @@ -53,7 +53,7 @@ protected override BlockProcessor CreateBlockProcessor() if (_api.RewardCalculatorSource is null) throw new StepDependencyException(nameof(_api.RewardCalculatorSource)); if (_api.TransactionProcessor is null) throw new StepDependencyException(nameof(_api.TransactionProcessor)); if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider)); - if (_api.WorldState is null) throw new StepDependencyException(nameof(_api.StateProvider)); + if (_api.WorldState is null) throw new StepDependencyException(nameof(_api.WorldState)); if (_api.TxPool is null) throw new StepDependencyException(nameof(_api.TxPool)); if (_api.ReceiptStorage is null) throw new StepDependencyException(nameof(_api.ReceiptStorage)); if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/LoadGenesisBlockAuRa.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/LoadGenesisBlockAuRa.cs index 87290856327..06890d4fefc 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/LoadGenesisBlockAuRa.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/LoadGenesisBlockAuRa.cs @@ -31,7 +31,7 @@ private void CreateSystemAccounts() bool hasConstructorAllocation = _api.ChainSpec.Allocations.Values.Any(a => a.Constructor is not null); if (hasConstructorAllocation) { - if (_api.WorldState is null) throw new StepDependencyException(nameof(_api.StateProvider)); + if (_api.WorldState is null) throw new StepDependencyException(nameof(_api.WorldState)); _api.WorldState.CreateAccount(Address.Zero, UInt256.Zero); _api.WorldState.Commit(Homestead.Instance); diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliqueBlockProducer.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliqueBlockProducer.cs index e1b43054e30..dec089eeab0 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliqueBlockProducer.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliqueBlockProducer.cs @@ -29,7 +29,7 @@ namespace Nethermind.Consensus.Clique; public class CliqueBlockProducer : ICliqueBlockProducer, IDisposable { private readonly IBlockTree _blockTree; - private readonly IStateProvider _stateProvider; + private readonly IWorldState _stateProvider; private readonly ITimestamper _timestamper; private readonly ILogger _logger; private readonly ICryptoRandom _cryptoRandom; @@ -52,7 +52,7 @@ public class CliqueBlockProducer : ICliqueBlockProducer, IDisposable public CliqueBlockProducer( ITxSource txSource, IBlockchainProcessor blockchainProcessor, - IStateProvider stateProvider, + IWorldState stateProvider, IBlockTree blockTree, ITimestamper timestamper, ICryptoRandom cryptoRandom, diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/MinedBlockProducer.cs b/src/Nethermind/Nethermind.Consensus.Ethash/MinedBlockProducer.cs index b9316a09cc3..b927e2b85c8 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/MinedBlockProducer.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/MinedBlockProducer.cs @@ -26,7 +26,7 @@ public MinedBlockProducer(ITxSource txSource, ISealer sealer, IBlockTree blockTree, IBlockProductionTrigger blockProductionTrigger, - IStateProvider stateProvider, + IWorldState stateProvider, IGasLimitCalculator gasLimitCalculator, ITimestamper timestamper, ISpecProvider specProvider, diff --git a/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerBase.cs b/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerBase.cs index 64b12fba0fa..332c0eed1db 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerBase.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerBase.cs @@ -41,7 +41,7 @@ public abstract class BlockProducerBase : IBlockProducer public event EventHandler? BlockProduced; private ISealer Sealer { get; } - private IStateProvider StateProvider { get; } + private IWorldState StateProvider { get; } private readonly IGasLimitCalculator _gasLimitCalculator; private readonly IDifficultyCalculator _difficultyCalculator; private readonly ISpecProvider _specProvider; @@ -62,7 +62,7 @@ protected BlockProducerBase( ISealer? sealer, IBlockTree? blockTree, IBlockProductionTrigger? trigger, - IStateProvider? stateProvider, + IWorldState? stateProvider, IGasLimitCalculator? gasLimitCalculator, ITimestamper? timestamper, ISpecProvider? specProvider, diff --git a/src/Nethermind/Nethermind.Consensus/Producers/DevBlockProducer.cs b/src/Nethermind/Nethermind.Consensus/Producers/DevBlockProducer.cs index 57a9c38d7b9..162a9e2dfcb 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/DevBlockProducer.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/DevBlockProducer.cs @@ -21,7 +21,7 @@ public class DevBlockProducer : BlockProducerBase, IDisposable public DevBlockProducer( ITxSource? txSource, IBlockchainProcessor? processor, - IStateProvider? stateProvider, + IWorldState? stateProvider, IBlockTree? blockTree, IBlockProductionTrigger? trigger, ITimestamper? timestamper, diff --git a/src/Nethermind/Nethermind.Consensus/Tracing/Tracer.cs b/src/Nethermind/Nethermind.Consensus/Tracing/Tracer.cs index 89232edff0f..731f6b4f1a6 100644 --- a/src/Nethermind/Nethermind.Consensus/Tracing/Tracer.cs +++ b/src/Nethermind/Nethermind.Consensus/Tracing/Tracer.cs @@ -13,11 +13,11 @@ namespace Nethermind.Consensus.Tracing { public class Tracer : ITracer { - private readonly IStateProvider _stateProvider; + private readonly IWorldState _stateProvider; private readonly IBlockchainProcessor _blockProcessor; private readonly ProcessingOptions _processingOptions; - public Tracer(IStateProvider stateProvider, IBlockchainProcessor blockProcessor, ProcessingOptions processingOptions = ProcessingOptions.Trace) + public Tracer(IWorldState stateProvider, IBlockchainProcessor blockProcessor, ProcessingOptions processingOptions = ProcessingOptions.Trace) { _stateProvider = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider)); _blockProcessor = blockProcessor ?? throw new ArgumentNullException(nameof(blockProcessor)); diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockProducer.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockProducer.cs index ec3100b070d..78e03de4f2e 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockProducer.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockProducer.cs @@ -25,7 +25,7 @@ public class TestBlockProducer : BlockProducerBase public TestBlockProducer( ITxSource txSource, IBlockchainProcessor processor, - IStateProvider stateProvider, + IWorldState stateProvider, ISealer sealer, IBlockTree blockTree, IBlockProductionTrigger blockProductionTrigger, diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs index 3c74fa864bf..d649d8f8eca 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeBlockchain.cs @@ -148,11 +148,7 @@ private Task InitBlockchain() getApi.DisposeStack.Push(trieStore); ITrieStore readOnlyTrieStore = setApi.ReadOnlyTrieStore = trieStore.AsReadOnly(cachedStateDb); - - IStateProvider stateProvider = setApi.StateProvider = new StateProvider( - trieStore, - codeDb, - getApi.LogManager); + IWorldState worldState = setApi.WorldState = new WorldState(trieStore, codeDb, getApi.LogManager); ReadOnlyDbProvider readOnly = new(getApi.DbProvider, false); @@ -162,7 +158,7 @@ private Task InitBlockchain() setApi.ChainHeadStateProvider = new ChainHeadReadOnlyStateProvider(getApi.BlockTree, stateReader); Account.AccountStartNonce = getApi.ChainSpec.Parameters.AccountStartNonce; - stateProvider.StateRoot = getApi.BlockTree!.Head?.StateRoot ?? Keccak.EmptyTreeHash; + worldState.StateRoot = getApi.BlockTree!.Head?.StateRoot ?? Keccak.EmptyTreeHash; if (_api.Config().DiagnosticMode == DiagnosticMode.VerifyTrie) { @@ -171,7 +167,7 @@ private Task InitBlockchain() try { _logger!.Info("Collecting trie stats and verifying that no nodes are missing..."); - TrieStats stats = stateProvider.CollectStats(getApi.DbProvider.CodeDb, _api.LogManager); + TrieStats stats = worldState.CollectStats(getApi.DbProvider.CodeDb, _api.LogManager); _logger.Info($"Starting from {getApi.BlockTree.Head?.Number} {getApi.BlockTree.Head?.StateRoot}{Environment.NewLine}" + stats); } catch (Exception ex) @@ -184,7 +180,7 @@ private Task InitBlockchain() // Init state if we need system calls before actual processing starts if (getApi.BlockTree!.Head?.StateRoot is not null) { - stateProvider.StateRoot = getApi.BlockTree.Head.StateRoot; + worldState.StateRoot = getApi.BlockTree.Head.StateRoot; } TxValidator txValidator = setApi.TxValidator = new TxValidator(getApi.SpecProvider.ChainId); @@ -198,12 +194,6 @@ private Task InitBlockchain() _api.BlockPreprocessor.AddFirst( new RecoverSignatures(getApi.EthereumEcdsa, txPool, getApi.SpecProvider, getApi.LogManager)); - IStorageProvider storageProvider = setApi.StorageProvider = new StorageProvider( - trieStore, - stateProvider, - getApi.LogManager); - - IWorldState worldState = setApi.WorldState = new WorldState(trieStore, codeDb, getApi.LogManager); // blockchain processing BlockhashProvider blockhashProvider = new( diff --git a/src/Nethermind/Nethermind.Init/Steps/LoadGenesisBlock.cs b/src/Nethermind/Nethermind.Init/Steps/LoadGenesisBlock.cs index e1425946e44..ea64368dabd 100644 --- a/src/Nethermind/Nethermind.Init/Steps/LoadGenesisBlock.cs +++ b/src/Nethermind/Nethermind.Init/Steps/LoadGenesisBlock.cs @@ -55,8 +55,7 @@ protected virtual void Load() { if (_api.ChainSpec is null) throw new StepDependencyException(nameof(_api.ChainSpec)); if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); - if (_api.StateProvider is null) throw new StepDependencyException(nameof(_api.StateProvider)); - if (_api.StorageProvider is null) throw new StepDependencyException(nameof(_api.StorageProvider)); + if (_api.WorldState is null) throw new StepDependencyException(nameof(_api.WorldState)); if (_api.SpecProvider is null) throw new StepDependencyException(nameof(_api.SpecProvider)); if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider)); if (_api.TransactionProcessor is null) throw new StepDependencyException(nameof(_api.TransactionProcessor)); @@ -95,13 +94,13 @@ void GenesisProcessed(object? sender, BlockEventArgs args) /// private void ValidateGenesisHash(Keccak? expectedGenesisHash) { - if (_api.StateProvider is null) throw new StepDependencyException(nameof(_api.StateProvider)); + if (_api.WorldState is null) throw new StepDependencyException(nameof(_api.WorldState)); if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); BlockHeader genesis = _api.BlockTree.Genesis!; if (expectedGenesisHash is not null && genesis.Hash != expectedGenesisHash) { - if (_logger.IsWarn) _logger.Warn(_api.StateProvider.DumpState()); + if (_logger.IsWarn) _logger.Warn(_api.WorldState.DumpState()); if (_logger.IsWarn) _logger.Warn(genesis.ToString(BlockHeader.Format.Full)); if (_logger.IsError) _logger.Error($"Unexpected genesis hash, expected {expectedGenesisHash}, but was {genesis.Hash}"); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs index ff79d02008e..d784258eae6 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Trace/ParityStyleTracerTests.cs @@ -52,8 +52,6 @@ public void Setup() MemDb stateDb = new(); MemDb codeDb = new(); ITrieStore trieStore = new TrieStore(stateDb, LimboLogs.Instance).AsReadOnly(); - StateProvider stateProvider = new StateProvider(trieStore, codeDb, LimboLogs.Instance); - StorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, LimboLogs.Instance); WorldState worldState = new WorldState(trieStore, codeDb, LimboLogs.Instance); StateReader stateReader = new StateReader(trieStore, codeDb, LimboLogs.Instance); @@ -78,7 +76,7 @@ public void Setup() _blockTree.SuggestBlock(genesis); _processor.Process(genesis, ProcessingOptions.None, NullBlockTracer.Instance); - _tracer = new Tracer(stateProvider, _processor); + _tracer = new Tracer(worldState, _processor); } [Test] diff --git a/src/Nethermind/Nethermind.Merge.AuRa/AuRaPostMergeBlockProducer.cs b/src/Nethermind/Nethermind.Merge.AuRa/AuRaPostMergeBlockProducer.cs index 88f907b0864..ef571255c8d 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/AuRaPostMergeBlockProducer.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/AuRaPostMergeBlockProducer.cs @@ -19,7 +19,7 @@ public AuRaPostMergeBlockProducer( IBlockchainProcessor processor, IBlockTree blockTree, IBlockProductionTrigger blockProductionTrigger, - IStateProvider stateProvider, + IWorldState stateProvider, IGasLimitCalculator gasLimitCalculator, ISealEngine sealEngine, ITimestamper timestamper, diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PostMergeBlockProducer.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PostMergeBlockProducer.cs index 1838f708795..29b0e88c41f 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PostMergeBlockProducer.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PostMergeBlockProducer.cs @@ -24,7 +24,7 @@ public PostMergeBlockProducer( IBlockchainProcessor processor, IBlockTree blockTree, IBlockProductionTrigger blockProductionTrigger, - IStateProvider stateProvider, + IWorldState stateProvider, IGasLimitCalculator gasLimitCalculator, ISealEngine sealEngine, ITimestamper timestamper, diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index 43d08720132..42a9aba43ae 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -259,7 +259,7 @@ public Task InitRpcModules() if (_api.RpcModuleProvider is null) throw new ArgumentNullException(nameof(_api.RpcModuleProvider)); if (_api.BlockTree is null) throw new ArgumentNullException(nameof(_api.BlockTree)); if (_api.BlockchainProcessor is null) throw new ArgumentNullException(nameof(_api.BlockchainProcessor)); - if (_api.StateProvider is null) throw new ArgumentNullException(nameof(_api.StateProvider)); + if (_api.WorldState is null) throw new ArgumentNullException(nameof(_api.WorldState)); if (_api.HeaderValidator is null) throw new ArgumentNullException(nameof(_api.HeaderValidator)); if (_api.EthSyncingInfo is null) throw new ArgumentNullException(nameof(_api.EthSyncingInfo)); if (_api.Sealer is null) throw new ArgumentNullException(nameof(_api.Sealer)); diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index 56d4206e3e0..3484d5816f2 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -95,9 +95,8 @@ public static NethermindApi ContextWithMocks() => SealValidator = Substitute.For(), SessionMonitor = Substitute.For(), SnapProvider = Substitute.For(), - StateProvider = Substitute.For(), + WorldState = Substitute.For(), StateReader = Substitute.For(), - StorageProvider = Substitute.For(), TransactionProcessor = Substitute.For(), TxSender = Substitute.For(), BlockProcessingQueue = Substitute.For(), diff --git a/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs b/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs index 80174a9812e..a3a5d84912c 100644 --- a/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs @@ -413,14 +413,14 @@ public void Persistent_state_restores_independent_of_transient_state(int snapsho private class Context { - public IStateProvider StateProvider { get; } + public IWorldState StateProvider { get; } public readonly Address Address1 = new(Keccak.Compute("1")); public readonly Address Address2 = new(Keccak.Compute("2")); public Context() { - StateProvider = new StateProvider(new TrieStore(new MemDb(), LimboLogs.Instance), Substitute.For(), LogManager); + StateProvider = new WorldState(new TrieStore(new MemDb(), LimboLogs.Instance), Substitute.For(), LogManager); StateProvider.CreateAccount(Address1, 0); StateProvider.CreateAccount(Address2, 0); StateProvider.Commit(Frontier.Instance); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs index c8edcaaa79b..b662b34c0a3 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs @@ -228,7 +228,7 @@ private class SyncTestContext public IBlockchainProcessor? BlockchainProcessor { get; set; } public ISynchronizer? Synchronizer { get; set; } public IBlockTree Tree { get; set; } = null!; - public IStateProvider StateProvider { get; set; } = null!; + public IWorldState StateProvider { get; set; } = null!; public DevBlockProducer? BlockProducer { get; set; } public ConsoleAsyncLogger? Logger { get; set; } diff --git a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs index 1283125eea1..fe59bdc0605 100644 --- a/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs +++ b/src/Nethermind/Nethermind.TxPool.Test/TxPoolTests.cs @@ -42,7 +42,7 @@ public class TxPoolTests private IEthereumEcdsa _ethereumEcdsa; private ISpecProvider _specProvider; private TxPool _txPool; - private IStateProvider _stateProvider; + private IWorldState _stateProvider; private IBlockTree _blockTree; private int _txGasLimit = 1_000_000; @@ -55,7 +55,7 @@ public void Setup() _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, _logManager); var trieStore = new TrieStore(new MemDb(), _logManager); var codeDb = new MemDb(); - _stateProvider = new StateProvider(trieStore, codeDb, _logManager); + _stateProvider = new WorldState(trieStore, codeDb, _logManager); _blockTree = Substitute.For(); Block block = Build.A.Block.WithNumber(0).TestObject; _blockTree.Head.Returns(block); From ad167e0dfac217d13265f3e08dec8f4d76c1c984 Mon Sep 17 00:00:00 2001 From: Tanishq Jasoria Date: Thu, 8 Dec 2022 02:45:05 +0530 Subject: [PATCH 2/4] add verkle tree eip in cancun hardfork (#4975) --- src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs | 11 +++++++++-- .../Nethermind.Serialization.Rlp/HeaderDecoder.cs | 1 + .../Nethermind.Specs.Test/OverridableReleaseSpec.cs | 1 + .../ChainSpecStyle/ChainParameters.cs | 5 +++++ .../Nethermind.Specs/ChainSpecStyle/ChainSpec.cs | 3 ++- .../ChainSpecStyle/ChainSpecBasedSpecProvider.cs | 2 ++ .../ChainSpecStyle/ChainSpecLoader.cs | 4 +++- .../ChainSpecStyle/Json/ChainSpecParamsJson.cs | 3 ++- src/Nethermind/Nethermind.Specs/Forks/00_Olympic.cs | 1 + src/Nethermind/Nethermind.Specs/Forks/16_Cancun.cs | 1 + src/Nethermind/Nethermind.Specs/ReleaseSpec.cs | 2 ++ .../Nethermind.Specs/SystemTransactionReleaseSpec.cs | 1 + 12 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs index 07982931547..288e92d01b9 100644 --- a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs @@ -220,7 +220,7 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec bool IsEip3529Enabled { get; } /// - /// Reject new contracts starting with the 0xEF byte + /// Reject new contracts starting with the 0xEF byte /// bool IsEip3541Enabled { get; } @@ -250,13 +250,18 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec /// bool IsEip3860Enabled { get; } + /// + /// State - Verkle Trees + /// + bool IsVerkleTreeEipEnabled { get; } + /// /// Should transactions be validated against chainId. /// /// Backward compatibility for early Kovan blocks. bool ValidateChainId => true; - // STATE related + // STATE related public bool ClearEmptyAccountWhenTouched => IsEip158Enabled; // VM @@ -322,5 +327,7 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec public bool IncludePush0Instruction => IsEip3855Enabled; public bool TransientStorageEnabled => IsEip1153Enabled; + + public bool VerkleTreeEnabled => IsVerkleTreeEipEnabled; } } diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs index ab7fcb70312..24e208236ae 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs @@ -14,6 +14,7 @@ public class HeaderDecoder : IRlpValueDecoder, IRlpStreamDecoder _spec.IsEip3651Enabled; public bool IsEip3855Enabled => _spec.IsEip3855Enabled; public bool IsEip3860Enabled => _spec.IsEip3860Enabled; + public bool IsVerkleTreeEipEnabled => _spec.IsVerkleTreeEipEnabled; } } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs index 31e3faab5fb..dcfe0874977 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs @@ -118,5 +118,10 @@ public class ChainParameters public ulong? Eip3651TransitionTimestamp { get; set; } public ulong? Eip3855TransitionTimestamp { get; set; } public ulong? Eip3860TransitionTimestamp { get; set; } + + /// + /// this feild will indicate the timestamp at which this Verkle Trees will be enabled. + /// + public ulong? VerkleTreeTransitionTimestamp { get; set; } } } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs index e6c4cca3632..ff3aa1f375c 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpec.cs @@ -11,7 +11,7 @@ namespace Nethermind.Specs.ChainSpecStyle { /// /// https://github.com/ethereum/wiki/wiki/Ethereum-Chain-Spec-Format - /// https://wiki.parity.io/Chain-specification + /// https://wiki.parity.io/Chain-specification /// [DebuggerDisplay("{Name}, ChainId = {ChainId}")] public class ChainSpec @@ -76,5 +76,6 @@ public class ChainSpec public UInt256? TerminalTotalDifficulty { get; set; } public ulong? ShanghaiTimestamp { get; set; } + public ulong? CancunTimestamp { get; set; } } } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs index 193d2f277c3..d24624758f6 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs @@ -228,6 +228,8 @@ private static ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releaseSt releaseSpec.IsEip3651Enabled = (chainSpec.Parameters.Eip3651TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsEip3855Enabled = (chainSpec.Parameters.Eip3855TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; releaseSpec.IsEip3860Enabled = (chainSpec.Parameters.Eip3860TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; + releaseSpec.IsVerkleTreeEipEnabled = (chainSpec.Parameters.VerkleTreeTransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp; + releaseSpec.VerkleTreeTransitionTimeStamp = chainSpec.Parameters.VerkleTreeTransitionTimestamp ?? ulong.MaxValue; return releaseSpec; } diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs index cba5ca82c31..841ddafee62 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs @@ -19,7 +19,7 @@ namespace Nethermind.Specs.ChainSpecStyle { /// - /// This class can load a Parity-style chain spec file and build a out of it. + /// This class can load a Parity-style chain spec file and build a out of it. /// public class ChainSpecLoader : IChainSpecLoader { @@ -137,6 +137,7 @@ private void LoadParameters(ChainSpecJson chainSpecJson, ChainSpec chainSpec) Eip3651TransitionTimestamp = chainSpecJson.Params.Eip3651TransitionTimestamp, Eip3855TransitionTimestamp = chainSpecJson.Params.Eip3855TransitionTimestamp, Eip3860TransitionTimestamp = chainSpecJson.Params.Eip3860TransitionTimestamp, + VerkleTreeTransitionTimestamp = chainSpecJson.Params.VerkleTreeTransitionTimestamp, TransactionPermissionContract = chainSpecJson.Params.TransactionPermissionContract, TransactionPermissionContractTransition = chainSpecJson.Params.TransactionPermissionContractTransition, ValidateChainIdTransition = chainSpecJson.Params.ValidateChainIdTransition, @@ -214,6 +215,7 @@ chainSpec.Parameters.Eip1283DisableTransition is null chainSpec.Ethash?.DifficultyBombDelays.Keys.ToArray()[5] : null; chainSpec.ShanghaiTimestamp = chainSpec.Parameters.Eip3651TransitionTimestamp ?? (long.MaxValue - 1); + chainSpec.CancunTimestamp = chainSpec.Parameters.VerkleTreeTransitionTimestamp ?? (long.MaxValue - 1); // TheMerge parameters chainSpec.MergeForkIdBlockNumber = chainSpec.Parameters.MergeForkIdTransition; diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs index a550fda673b..990f3d8f256 100644 --- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs +++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs @@ -100,7 +100,7 @@ internal class ChainSpecParamsJson public long? Eip3541Transition { get; set; } - // We explicitly want this to be enabled by default on all the networks + // We explicitly want this to be enabled by default on all the networks // we can disable it if needed, but its expected not to cause issues public long? Eip3607Transition { get; set; } = 0; @@ -137,5 +137,6 @@ internal class ChainSpecParamsJson public ulong? Eip3651TransitionTimestamp { get; set; } public ulong? Eip3855TransitionTimestamp { get; set; } public ulong? Eip3860TransitionTimestamp { get; set; } + public ulong? VerkleTreeTransitionTimestamp { get; set; } } } diff --git a/src/Nethermind/Nethermind.Specs/Forks/00_Olympic.cs b/src/Nethermind/Nethermind.Specs/Forks/00_Olympic.cs index 4180bb4cd52..ed13b3c7329 100644 --- a/src/Nethermind/Nethermind.Specs/Forks/00_Olympic.cs +++ b/src/Nethermind/Nethermind.Specs/Forks/00_Olympic.cs @@ -24,6 +24,7 @@ protected Olympic() IsEip3607Enabled = true; MaximumUncleCount = 2; Eip1559TransitionBlock = long.MaxValue; + VerkleTreeTransitionTimeStamp = ulong.MaxValue; ValidateChainId = true; ValidateReceipts = true; } diff --git a/src/Nethermind/Nethermind.Specs/Forks/16_Cancun.cs b/src/Nethermind/Nethermind.Specs/Forks/16_Cancun.cs index c4d08d5dc5d..edc10c3be9d 100644 --- a/src/Nethermind/Nethermind.Specs/Forks/16_Cancun.cs +++ b/src/Nethermind/Nethermind.Specs/Forks/16_Cancun.cs @@ -14,6 +14,7 @@ protected Cancun() { Name = "Cancun"; IsEip1153Enabled = true; + IsVerkleTreeEipEnabled = true; } public new static IReleaseSpec Instance => LazyInitializer.EnsureInitialized(ref _instance, () => new Cancun()); diff --git a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs index 08b2a4587ff..16abc3a2913 100644 --- a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs @@ -75,5 +75,7 @@ public ReleaseSpec Clone() public bool IsEip3651Enabled { get; set; } public bool IsEip3855Enabled { get; set; } public bool IsEip3860Enabled { get; set; } + public bool IsVerkleTreeEipEnabled { get; set; } + public ulong VerkleTreeTransitionTimeStamp { get; set; } } } diff --git a/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs b/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs index 38e4c405473..5fe2c03c45f 100644 --- a/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs @@ -121,5 +121,6 @@ public bool IsEip158IgnoredAccount(Address address) public bool IsEip3651Enabled => _spec.IsEip3651Enabled; public bool IsEip3855Enabled => _spec.IsEip3855Enabled; public bool IsEip3860Enabled => _spec.IsEip3860Enabled; + public bool IsVerkleTreeEipEnabled => _spec.IsVerkleTreeEipEnabled; } } From 86ad3c001d3b77d769c342fc5f5c88d1823e2145 Mon Sep 17 00:00:00 2001 From: Tanishq Jasoria Date: Thu, 8 Dec 2022 02:45:44 +0530 Subject: [PATCH 3/4] add new gas costs (#4976) --- src/Nethermind/Nethermind.Evm/GasCostOf.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Nethermind/Nethermind.Evm/GasCostOf.cs b/src/Nethermind/Nethermind.Evm/GasCostOf.cs index 59d33449635..cd5eb0ba814 100644 --- a/src/Nethermind/Nethermind.Evm/GasCostOf.cs +++ b/src/Nethermind/Nethermind.Evm/GasCostOf.cs @@ -60,5 +60,11 @@ public static class GasCostOf public const long AccessStorageListEntry = 1900; // eip-2930 public const long TLoad = WarmStateRead; // eip-1153 public const long TStore = WarmStateRead; // eip-1153 + + public const long WitnessChunkRead = 200; // verkle-trees + public const long WitnessChunkWrite = 500; // verkle-trees + public const long WitnessChunkFill = 6200; // verkle-trees + public const long WitnessBranchRead = 1900; // verkle-trees + public const long WitnessBranchWrite = 3000; // verkle-trees } } From c9b226921cdd0f045c6a4c8e4a4e8f5d4a4e63c7 Mon Sep 17 00:00:00 2001 From: Tanishq Jasoria Date: Thu, 8 Dec 2022 03:17:12 +0530 Subject: [PATCH 4/4] modify blockHeader and account (#4977) * update account * update block header * add verkle witness interface * modify header decoder --- src/Nethermind/Nethermind.Core/Account.cs | 36 +++ src/Nethermind/Nethermind.Core/BlockHeader.cs | 5 + .../Nethermind.Core/IVerkleWitness.cs | 33 ++ .../Nethermind.Core/Specs/IReleaseSpec.cs | 2 + src/Nethermind/Nethermind.Evm/EvmState.cs | 90 +++++- .../Nethermind.Init/Steps/InitRlp.cs | 1 + .../HeaderDecoder.cs | 99 +++++- .../OverridableReleaseSpec.cs | 7 + .../SystemTransactionReleaseSpec.cs | 1 + .../Nethermind.State/VerkleWitness.cs | 294 ++++++++++++++++++ .../Nethermind.Trie/Nethermind.Trie.csproj | 1 + src/Nethermind/Nethermind.Trie/VerkleUtils.cs | 222 +++++++++++++ 12 files changed, 785 insertions(+), 6 deletions(-) create mode 100644 src/Nethermind/Nethermind.Core/IVerkleWitness.cs create mode 100644 src/Nethermind/Nethermind.State/VerkleWitness.cs create mode 100644 src/Nethermind/Nethermind.Trie/VerkleUtils.cs diff --git a/src/Nethermind/Nethermind.Core/Account.cs b/src/Nethermind/Nethermind.Core/Account.cs index 8ed5f59f536..f473f680df9 100644 --- a/src/Nethermind/Nethermind.Core/Account.cs +++ b/src/Nethermind/Nethermind.Core/Account.cs @@ -12,6 +12,9 @@ public class Account private static UInt256 _accountStartNonce = UInt256.Zero; + // todo: change codeHash when this set + public byte[]? Code; + /// /// This is a special field that was used by some of the testnets (namely - Morden and Mordor). /// It makes all the account nonces start from a different number then zero, @@ -35,6 +38,30 @@ public Account(UInt256 balance) CodeHash = Keccak.OfAnEmptyString; StorageRoot = Keccak.EmptyTreeHash; IsTotallyEmpty = Balance.IsZero; + CodeSize = 0; + Version = UInt256.Zero; + } + + public Account(UInt256 balance, UInt256 nonce, Keccak codeHash, UInt256 codeSize, UInt256 version) + { + Balance = balance; + Nonce = nonce; + CodeHash = codeHash; + StorageRoot = Keccak.EmptyTreeHash; + IsTotallyEmpty = Balance.IsZero && Nonce == _accountStartNonce && CodeHash == Keccak.OfAnEmptyString && StorageRoot == Keccak.EmptyTreeHash; + CodeSize = codeSize; + Version = version; + } + + public Account(UInt256 balance, UInt256 nonce, Keccak codeHash) + { + Balance = balance; + Nonce = nonce; + CodeHash = codeHash; + StorageRoot = Keccak.EmptyTreeHash; + IsTotallyEmpty = Balance.IsZero && Nonce == _accountStartNonce && CodeHash == Keccak.OfAnEmptyString && StorageRoot == Keccak.EmptyTreeHash; + CodeSize = 0; + Version = UInt256.Zero; } private Account() @@ -44,6 +71,8 @@ private Account() CodeHash = Keccak.OfAnEmptyString; StorageRoot = Keccak.EmptyTreeHash; IsTotallyEmpty = true; + CodeSize = 0; + Version = UInt256.Zero; } public Account(in UInt256 nonce, in UInt256 balance, Keccak storageRoot, Keccak codeHash) @@ -53,6 +82,8 @@ public Account(in UInt256 nonce, in UInt256 balance, Keccak storageRoot, Keccak StorageRoot = storageRoot; CodeHash = codeHash; IsTotallyEmpty = Balance.IsZero && Nonce == _accountStartNonce && CodeHash == Keccak.OfAnEmptyString && StorageRoot == Keccak.EmptyTreeHash; + CodeSize = 0; + Version = UInt256.Zero; } private Account(in UInt256 nonce, in UInt256 balance, Keccak storageRoot, Keccak codeHash, bool isTotallyEmpty) @@ -62,6 +93,8 @@ private Account(in UInt256 nonce, in UInt256 balance, Keccak storageRoot, Keccak StorageRoot = storageRoot; CodeHash = codeHash; IsTotallyEmpty = isTotallyEmpty; + CodeSize = 0; + Version = UInt256.Zero; } public bool HasCode => !CodeHash.Equals(Keccak.OfAnEmptyString); @@ -70,6 +103,8 @@ private Account(in UInt256 nonce, in UInt256 balance, Keccak storageRoot, Keccak public UInt256 Nonce { get; } public UInt256 Balance { get; } + public UInt256 CodeSize { get; } + public UInt256 Version { get; } public Keccak StorageRoot { get; } public Keccak CodeHash { get; } public bool IsTotallyEmpty { get; } @@ -93,6 +128,7 @@ public Account WithChangedStorageRoot(Keccak newStorageRoot) public Account WithChangedCodeHash(Keccak newCodeHash) { + // TODO: does the code and codeHash match? return new(Nonce, Balance, StorageRoot, newCodeHash, IsTotallyEmpty && newCodeHash == Keccak.OfAnEmptyString); } } diff --git a/src/Nethermind/Nethermind.Core/BlockHeader.cs b/src/Nethermind/Nethermind.Core/BlockHeader.cs index 0239c0aea96..19403fa662f 100644 --- a/src/Nethermind/Nethermind.Core/BlockHeader.cs +++ b/src/Nethermind/Nethermind.Core/BlockHeader.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Generic; using System.Diagnostics; using System.Text; using Nethermind.Core.Attributes; @@ -63,6 +64,8 @@ public BlockHeader( public byte[]? AuRaSignature { get; set; } public long? AuRaStep { get; set; } public UInt256 BaseFeePerGas { get; set; } + public byte[]? VerkleProof { get; set; } + public List? VerkleWitnesses { get; set; } public bool HasBody => UnclesHash != Keccak.OfAnEmptySequenceRlp || TxRoot != Keccak.EmptyTreeHash; public string SealEngineType { get; set; } = Nethermind.Core.SealEngineType.Ethash; @@ -91,6 +94,8 @@ public string ToString(string indent) builder.AppendLine($"{indent}BaseFeePerGas: {BaseFeePerGas}"); builder.AppendLine($"{indent}IsPostMerge: {IsPostMerge}"); builder.AppendLine($"{indent}TotalDifficulty: {TotalDifficulty}"); + builder.AppendLine($"{indent}Verkle Proof: {VerkleProof?.ToHexString()}"); + builder.AppendLine($"{indent}Verkle Witness Count- {VerkleWitnesses?.Count}"); return builder.ToString(); } diff --git a/src/Nethermind/Nethermind.Core/IVerkleWitness.cs b/src/Nethermind/Nethermind.Core/IVerkleWitness.cs new file mode 100644 index 00000000000..c235d5a5612 --- /dev/null +++ b/src/Nethermind/Nethermind.Core/IVerkleWitness.cs @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + + +using Nethermind.Int256; + +namespace Nethermind.Core; + +public interface IVerkleWitness : IJournal +{ + public byte[][] GetAccessedKeys(); + public long AccessForCodeOpCodes(Address caller); + public long AccessValueTransfer(Address caller, Address callee); + + public long AccessForContractCreationInit(Address contractAddress, bool isValueTransfer); + + public long AccessContractCreated(Address contractAddress); + + public long AccessBalance(Address address); + + public long AccessCodeHash(Address address); + + public long AccessStorage(Address address, UInt256 key, bool isWrite); + + public long AccessCodeChunk(Address address, byte chunkId, bool isWrite); + + public long AccessCompleteAccount(Address address, bool isWrite = false); + + public long AccessAccount(Address address, bool[] bitVector, bool isWrite = false); + public long AccessKey(byte[] key, bool isWrite = false); + + public long AccessForTransaction(Address originAddress, Address destinationAddress, bool isValueTransfer); +} diff --git a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs index 288e92d01b9..2ca7c2992c9 100644 --- a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs @@ -329,5 +329,7 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec public bool TransientStorageEnabled => IsEip1153Enabled; public bool VerkleTreeEnabled => IsVerkleTreeEipEnabled; + + public ulong VerkleTreeTransitionTimeStamp { get; } } } diff --git a/src/Nethermind/Nethermind.Evm/EvmState.cs b/src/Nethermind/Nethermind.Evm/EvmState.cs index 6d74423c6c1..ee3f2b67269 100644 --- a/src/Nethermind/Nethermind.Evm/EvmState.cs +++ b/src/Nethermind/Nethermind.Evm/EvmState.cs @@ -1,5 +1,18 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only +// Copyright (c) 2021 Demerzel Solutions Limited +// This file is part of the Nethermind library. +// +// The Nethermind library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The Nethermind library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the Nethermind. If not, see . using System; using System.Collections.Concurrent; @@ -38,7 +51,7 @@ public StackPool(int maxCallStackDepth = VirtualMachine.MaxCallDepth * 2) /// /// The word 'return' acts here once as a verb 'to return stack to the pool' and once as a part of the - /// compound noun 'return stack' which is a stack of subroutine return values. + /// compound noun 'return stack' which is a stack of subroutine return values. /// /// /// @@ -106,14 +119,21 @@ private int[] RentReturnStack() // As we can add here from VM, we need it as ICollection public ICollection Logs => _logs; + /// + /// Verkle Tree: to maintain a list of all accessed subtrees and leaves + /// + public IVerkleWitness VerkleTreeWitness => _verkleWitness; + private readonly JournalSet
_accessedAddresses; private readonly JournalSet _accessedStorageCells; private readonly JournalCollection _logs; private readonly JournalSet
_destroyList; + private readonly IVerkleWitness _verkleWitness; private readonly int _accessedAddressesSnapshot; private readonly int _accessedStorageKeysSnapshot; private readonly int _destroyListSnapshot; private readonly int _logsSnapshot; + private readonly int _verkleWitnessSnapshot; public int DataStackHead = 0; @@ -137,12 +157,65 @@ public EvmState( false, null, isContinuation, - false) + false, + new VerkleWitness()) { GasAvailable = gasAvailable; Env = env; } + public EvmState( + long gasAvailable, + ExecutionEnvironment env, + ExecutionType executionType, + bool isTopLevel, + Snapshot snapshot, + bool isContinuation, + IVerkleWitness verkleWitness) + : this(gasAvailable, + env, + executionType, + isTopLevel, + snapshot, + 0L, + 0L, + false, + null, + isContinuation, + false, + verkleWitness) + { + GasAvailable = gasAvailable; + Env = env; + } + + internal EvmState( + long gasAvailable, + ExecutionEnvironment env, + ExecutionType executionType, + bool isTopLevel, + Snapshot snapshot, + long outputDestination, + long outputLength, + bool isStatic, + EvmState? stateForAccessLists, + bool isContinuation, + bool isCreateOnPreExistingAccount) : + this(gasAvailable, + env, + executionType, + isTopLevel, + snapshot, + outputDestination, + outputLength, + isStatic, + stateForAccessLists, + isContinuation, + isCreateOnPreExistingAccount, + new VerkleWitness() + ) + { } + internal EvmState( long gasAvailable, ExecutionEnvironment env, @@ -154,7 +227,8 @@ internal EvmState( bool isStatic, EvmState? stateForAccessLists, bool isContinuation, - bool isCreateOnPreExistingAccount) + bool isCreateOnPreExistingAccount, + IVerkleWitness verkleWitness) { if (isTopLevel && isContinuation) { @@ -172,6 +246,7 @@ internal EvmState( IsStatic = isStatic; IsContinuation = isContinuation; IsCreateOnPreExistingAccount = isCreateOnPreExistingAccount; + _verkleWitness = verkleWitness; if (stateForAccessLists is not null) { // if we are sub-call, then we use the main collection for this transaction @@ -179,6 +254,7 @@ internal EvmState( _accessedStorageCells = stateForAccessLists._accessedStorageCells; _destroyList = stateForAccessLists._destroyList; _logs = stateForAccessLists._logs; + _verkleWitness = stateForAccessLists._verkleWitness; } else { @@ -187,6 +263,7 @@ internal EvmState( _accessedStorageCells = new JournalSet(); _destroyList = new JournalSet
(); _logs = new JournalCollection(); + _verkleWitness = new VerkleWitness(); } _accessedAddressesSnapshot = _accessedAddresses.TakeSnapshot(); @@ -194,6 +271,8 @@ internal EvmState( _destroyListSnapshot = _destroyList.TakeSnapshot(); _logsSnapshot = _logs.TakeSnapshot(); + _verkleWitnessSnapshot = _verkleWitness.TakeSnapshot(); + } public Address From @@ -288,6 +367,7 @@ private void Restore() _destroyList.Restore(_destroyListSnapshot); _accessedAddresses.Restore(_accessedAddressesSnapshot); _accessedStorageCells.Restore(_accessedStorageKeysSnapshot); + _verkleWitness.Restore(_verkleWitnessSnapshot); } } } diff --git a/src/Nethermind/Nethermind.Init/Steps/InitRlp.cs b/src/Nethermind/Nethermind.Init/Steps/InitRlp.cs index cb69a2d533e..03f0f66139c 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitRlp.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitRlp.cs @@ -34,6 +34,7 @@ public virtual Task Execute(CancellationToken _) } HeaderDecoder.Eip1559TransitionBlock = _api.SpecProvider.GenesisSpec.Eip1559TransitionBlock; + HeaderDecoder.VerkleTreeTransitionTimestamp = _api.SpecProvider.GenesisSpec.VerkleTreeTransitionTimeStamp; return Task.CompletedTask; } diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs index 24e208236ae..c1a101995b1 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/HeaderDecoder.cs @@ -4,6 +4,7 @@ using System; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Int256; namespace Nethermind.Serialization.Rlp @@ -76,6 +77,31 @@ public class HeaderDecoder : IRlpValueDecoder, IRlpStreamDecoder= VerkleTreeTransitionTimestamp) + { + blockHeader.VerkleProof = decoderContext.DecodeByteArray(); + if (blockHeader.VerkleProof.IsZero()) + { + blockHeader.VerkleProof = null; + } + + int verkleWitnessSequenceLength = decoderContext.ReadSequenceLength(); + int verkleWitnessCheck = decoderContext.Position + verkleWitnessSequenceLength; + blockHeader.VerkleWitnesses = new(); + while (decoderContext.Position < verkleWitnessCheck) + { + int witnessSequenceLength = decoderContext.ReadSequenceLength(); + int witnessCheck = decoderContext.Position + witnessSequenceLength; + blockHeader.VerkleWitnesses.Add(new[] { decoderContext.DecodeByteArray(), decoderContext.DecodeByteArray() }); + decoderContext.Check(witnessCheck); + } + decoderContext.Check(verkleWitnessCheck); + if (blockHeader.VerkleWitnesses.Capacity == 0) + { + blockHeader.VerkleWitnesses = null; + } + } + if ((rlpBehaviors & RlpBehaviors.AllowExtraData) != RlpBehaviors.AllowExtraData) { decoderContext.Check(headerCheck); @@ -144,6 +170,31 @@ public class HeaderDecoder : IRlpValueDecoder, IRlpStreamDecoder= VerkleTreeTransitionTimestamp) + { + blockHeader.VerkleProof = rlpStream.DecodeByteArray(); + if (blockHeader.VerkleProof.IsZero()) + { + blockHeader.VerkleProof = null; + } + + int verkleWitnessSequenceLength = rlpStream.ReadSequenceLength(); + int verkleWitnessCheck = rlpStream.Position + verkleWitnessSequenceLength; + blockHeader.VerkleWitnesses = new(); + while (rlpStream.Position < verkleWitnessCheck) + { + int witnessSequenceLength = rlpStream.ReadSequenceLength(); + int witnessCheck = rlpStream.Position + witnessSequenceLength; + blockHeader.VerkleWitnesses.Add(new[] { rlpStream.DecodeByteArray(), rlpStream.DecodeByteArray() }); + rlpStream.Check(witnessCheck); + } + rlpStream.Check(verkleWitnessCheck); + if (blockHeader.VerkleWitnesses.Capacity == 0) + { + blockHeader.VerkleWitnesses = null; + } + } + if ((rlpBehaviors & RlpBehaviors.AllowExtraData) != RlpBehaviors.AllowExtraData) { rlpStream.Check(headerCheck); @@ -195,6 +246,29 @@ public void Encode(RlpStream rlpStream, BlockHeader? header, RlpBehaviors rlpBeh { rlpStream.Encode(header.BaseFeePerGas); } + + if (header.Timestamp >= VerkleTreeTransitionTimestamp) + { + // do i need to check here if the verkle witness exists? and if no witness, then does the proof exist? + // ANS: yes, add a null proof maybe? + if (header.VerkleProof == null) + { + rlpStream.EncodeEmptyByteArray(); + rlpStream.EncodeNullObject(); + } + else + { + rlpStream.Encode(header.VerkleProof); + // assumption here that if proof is not null then the witness is not null + rlpStream.StartSequence(GetWitnessLength(header, rlpBehaviors)); + foreach (var witness in header.VerkleWitnesses) + { + rlpStream.StartSequence(Rlp.LengthOf(witness[0]) + Rlp.LengthOf(witness[1])); + rlpStream.Encode(witness[0]); + rlpStream.Encode(witness[1]); + } + } + } } public Rlp Encode(BlockHeader? item, RlpBehaviors rlpBehaviors = RlpBehaviors.None) @@ -232,7 +306,9 @@ private static int GetContentLength(BlockHeader? item, RlpBehaviors rlpBehaviors + Rlp.LengthOf(item.GasUsed) + Rlp.LengthOf(item.Timestamp) + Rlp.LengthOf(item.ExtraData) - + (item.Number < Eip1559TransitionBlock ? 0 : Rlp.LengthOf(item.BaseFeePerGas)); + + (item.Number < Eip1559TransitionBlock ? 0 : Rlp.LengthOf(item.BaseFeePerGas)) + + (item.Timestamp < VerkleTreeTransitionTimestamp ? 0 : Rlp.LengthOf(item.VerkleProof)) + + (item.Timestamp < VerkleTreeTransitionTimestamp ? 0 : Rlp.LengthOfSequence(GetWitnessLength(item, rlpBehaviors))); if (notForSealing) { @@ -252,6 +328,27 @@ private static int GetContentLength(BlockHeader? item, RlpBehaviors rlpBehaviors return contentLength; } + private static int GetWitnessLength(BlockHeader item, RlpBehaviors rlpBehaviors) + { + int witnessCount = item.VerkleWitnesses?.Count ?? 0; + if (witnessCount == 0) + { + return 0; + } + + int wintessLength = 0; + + foreach (var witness in item.VerkleWitnesses) + { + int thisWitnessLength = 0; + thisWitnessLength += Rlp.LengthOf(witness[0]); + thisWitnessLength += Rlp.LengthOf(witness[1]); + wintessLength += Rlp.LengthOfSequence(thisWitnessLength); + } + + return wintessLength; + } + public int GetLength(BlockHeader? item, RlpBehaviors rlpBehaviors) { return Rlp.LengthOfSequence(GetContentLength(item, rlpBehaviors)); diff --git a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs index 7c9df7182d4..3acdd58c2bd 100644 --- a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs @@ -133,6 +133,13 @@ public Address? Eip1559FeeCollector set => _overridenEip1559FeeCollector = value; } + private ulong? _overridenVerkleTreeTransitionTimeStamp; + public ulong VerkleTreeTransitionTimeStamp + { + get => _overridenVerkleTreeTransitionTimeStamp ?? _spec.VerkleTreeTransitionTimeStamp; + set => _overridenVerkleTreeTransitionTimeStamp = value; + } + public bool IsEip1153Enabled => _spec.IsEip1153Enabled; public bool IsEip3651Enabled => _spec.IsEip3651Enabled; public bool IsEip3855Enabled => _spec.IsEip3855Enabled; diff --git a/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs b/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs index 5fe2c03c45f..21abbf7cb3c 100644 --- a/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs @@ -117,6 +117,7 @@ public bool IsEip158IgnoredAccount(Address address) public long Eip1559TransitionBlock => _spec.Eip1559TransitionBlock; public Address Eip1559FeeCollector => _spec.Eip1559FeeCollector; + public ulong VerkleTreeTransitionTimeStamp => _spec.VerkleTreeTransitionTimeStamp; public bool IsEip1153Enabled => _spec.IsEip1153Enabled; public bool IsEip3651Enabled => _spec.IsEip3651Enabled; public bool IsEip3855Enabled => _spec.IsEip3855Enabled; diff --git a/src/Nethermind/Nethermind.State/VerkleWitness.cs b/src/Nethermind/Nethermind.State/VerkleWitness.cs new file mode 100644 index 00000000000..16bef3bd8be --- /dev/null +++ b/src/Nethermind/Nethermind.State/VerkleWitness.cs @@ -0,0 +1,294 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Generic; +using System.Linq; +using Nethermind.Core; +using Nethermind.Core.Collections; +using Nethermind.Int256; +using Nethermind.Trie; + +namespace Nethermind.State; + +// TODO: this can be definitely optimized by caching the keys from StateProvider - because for every access we +// already calculate keys in StateProvider - or we maintain pre images? +public class VerkleWitness : IVerkleWitness +{ + // const int VersionLeafKey = 0; + // const int BalanceLeafKey = 1; + // const int NonceLeafKey = 2; + // const int CodeKeccakLeafKey = 3; + // const int CodeSizeLeafKey = 4; + private readonly JournalSet _accessedSubtrees; + private readonly JournalSet _accessedLeaves; + private readonly JournalSet _modifiedSubtrees; + private readonly JournalSet _modifiedLeaves; + + // TODO: add these in GasPrices List + public const long WitnessChunkRead = 200; // verkle-trie + public const long WitnessChunkWrite = 500; // verkle-trie + public const long WitnessChunkFill = 6200; // verkle-trie + public const long WitnessBranchRead = 1900; // verkle-trie + public const long WitnessBranchWrite = 3000; // verkle-trie + + private readonly Dictionary _snapshots = new(); + private int NextSnapshot = 0; + + public VerkleWitness() + { + _accessedSubtrees = new JournalSet(); + _accessedLeaves = new JournalSet(); + _modifiedLeaves = new JournalSet(); + _modifiedSubtrees = new JournalSet(); + } + /// + /// When a non-precompile address is the target of a CALL, CALLCODE, + /// DELEGATECALL, SELFDESTRUCT, EXTCODESIZE, or EXTCODECOPY opcode, + /// or is the target address of a contract creation whose initcode + /// starts execution. + /// + /// + /// + public long AccessForCodeOpCodes(Address caller) + { + // (address, 0, VERSION_LEAF_KEY) + // (address, 0, CODE_SIZE_LEAF_KEY) + bool[] accountAccess = { true, false, false, false, true }; + return AccessAccount(caller, accountAccess); + } + + /// + /// Use this in two scenarios: + /// 1. If a call is value-bearing (ie. it transfers nonzero wei), whether + /// or not the callee is a precompile + /// 2. If the SELFDESTRUCT/SENDALL opcode is called by some caller_address + /// targeting some target_address (regardless of whether it’s value-bearing + /// or not) + /// + /// + /// + /// + /// + public long AccessValueTransfer(Address caller, Address callee) + { + // (caller_address, 0, BALANCE_LEAF_KEY) + // (callee_address, 0, BALANCE_LEAF_KEY) + bool[] accountAccess = { false, true, false, false, false }; + return AccessAccount(caller, accountAccess, true) + AccessAccount(callee, accountAccess, true); + } + + /// + /// When a contract creation is initialized. + /// + /// + /// + /// + public long AccessForContractCreationInit(Address contractAddress, bool isValueTransfer) + { + // (contract_address, 0, VERSION_LEAF_KEY) + // (contract_address, 0, NONCE_LEAF_KEY) + bool[] accountAccess = { true, false, true, false, false }; + if (isValueTransfer) + { + // (contract_address, 0, BALANCE_LEAF_KEY) + accountAccess[1] = true; + } + return AccessAccount(contractAddress, accountAccess, true); + } + + /// + /// When a contract is created. + /// + /// + /// + public long AccessContractCreated(Address contractAddress) + { + // (contract_address, 0, VERSION_LEAF_KEY) + // (contract_address, 0, NONCE_LEAF_KEY) + // (contract_address, 0, BALANCE_LEAF_KEY) + // (contract_address, 0, CODE_KECCAK_LEAF_KEY) + // (contract_address, 0, CODE_SIZE_LEAF_KEY) + return AccessCompleteAccount(contractAddress, true); + } + + /// + /// If the BALANCE opcode is called targeting some address. + /// + /// + /// + public long AccessBalance(Address address) + { + // (address, 0, BALANCE_LEAF_KEY) + bool[] accountAccess = { false, true, false, false, false }; + return AccessAccount(address, accountAccess); + } + + /// + /// If the EXTCODEHASH opcode is called targeting some address. + /// + /// + /// + public long AccessCodeHash(Address address) + { + + bool[] accountAccess = { false, false, false, true, false }; + return AccessAccount(address, accountAccess); + } + + /// + /// When SLOAD and SSTORE opcodes are called with a given address + /// and key. + /// + /// + /// + /// + /// + public long AccessStorage(Address address, UInt256 key, bool isWrite) + { + return AccessKey(VerkleUtils.GetTreeKeyForStorageSlot(address, key), isWrite); + } + + /// + /// When the code chunk chunk_id is accessed is accessed + /// + /// + /// + /// + /// + public long AccessCodeChunk(Address address, byte chunkId, bool isWrite) + { + return AccessKey(VerkleUtils.GetTreeKeyForCodeChunk(address, chunkId), isWrite); + } + + /// + /// When you are starting to execute a transaction. + /// + /// + /// + /// + /// + /// + public long AccessForTransaction(Address originAddress, Address destinationAddress, bool isValueTransfer) + { + + long gasCost = AccessCompleteAccount(originAddress) + AccessCompleteAccount(destinationAddress); + + // when you are executing a transaction, you are writing to the nonce of the origin address + bool[] accountAccess = { false, false, true, false, false }; + gasCost += AccessAccount(originAddress, accountAccess, true); + if (isValueTransfer) + { + // when you are executing a transaction with value transfer, + // you are writing to the balance of the origin and destination address + gasCost += AccessValueTransfer(originAddress, destinationAddress); + } + + return gasCost; + } + + /// + /// When you have to access the complete account + /// + /// + /// + /// + public long AccessCompleteAccount(Address address, bool isWrite = false) + { + bool[] accountAccess = { true, true, true, true, true }; + return AccessAccount(address, accountAccess, isWrite); + } + + /// + /// When you have to access the certain keys for the account + /// you can specify the keys you want to access using the bitVector. + /// set the bits to true if you want to access the key. + /// bitVector[0] for VersionLeafKey + /// bitVector[1] for BalanceLeafKey + /// bitVector[2] for NonceLeafKey + /// bitVector[3] for CodeKeccakLeafKey + /// bitVector[4] for CodeSizeLeafKey + /// + /// + /// + /// + /// + public long AccessAccount(Address address, bool[] bitVector, bool isWrite = false) + { + + long gasUsed = 0; + for (int i = 0; i < bitVector.Length; i++) + { + if (bitVector[i]) + { + gasUsed += AccessKey(VerkleUtils.GetTreeKey(address, UInt256.Zero, (byte)i), isWrite); + } + } + + return gasUsed; + } + + public long AccessKey(byte[] key, bool isWrite = false) + { + bool newSubTreeAccess = false; + bool newSubTreeWrite = false; + bool newLeafAccess = false; + bool newLeafWrite = false; + bool newLeafFill = false; + + if (!_accessedLeaves.Contains((key))) + { + newLeafAccess = true; + _accessedLeaves.Add((key)); + } + + if (!_accessedSubtrees.Add(key[..31])) + { + newSubTreeAccess = true; + _accessedSubtrees.Add(key[..31]); + } + + if (isWrite) + { + if (!_modifiedLeaves.Contains((key))) + { + newLeafWrite = true; + _modifiedLeaves.Add((key)); + // are we just writing or filling the chunk? - implement the difference + } + + if (!_modifiedSubtrees.Add(key[..31])) + { + newSubTreeWrite = true; + _modifiedSubtrees.Add(key[..31]); + } + } + + return (newLeafAccess ? WitnessChunkRead : 0) + + (newLeafWrite ? WitnessChunkWrite : 0) + + (newLeafFill ? WitnessChunkFill : 0) + + (newSubTreeAccess ? WitnessBranchRead : 0) + + (newSubTreeWrite ? WitnessBranchWrite : 0); + } + + public byte[][] GetAccessedKeys() + { + return _accessedLeaves.ToArray(); + } + + public int TakeSnapshot() + { + int[] snapshot = new int[2]; + snapshot[0] = _accessedSubtrees.TakeSnapshot(); + snapshot[1] = _accessedLeaves.TakeSnapshot(); + _snapshots.Add(NextSnapshot, snapshot); + return NextSnapshot++; + } + + public void Restore(int snapshot) + { + int[] Snapshot = _snapshots[snapshot]; + _accessedSubtrees.Restore(Snapshot[0]); + _accessedLeaves.Restore(Snapshot[1]); + } + +} diff --git a/src/Nethermind/Nethermind.Trie/Nethermind.Trie.csproj b/src/Nethermind/Nethermind.Trie/Nethermind.Trie.csproj index 87a2575af0d..ceedaab4a8c 100644 --- a/src/Nethermind/Nethermind.Trie/Nethermind.Trie.csproj +++ b/src/Nethermind/Nethermind.Trie/Nethermind.Trie.csproj @@ -6,6 +6,7 @@ true true true + true diff --git a/src/Nethermind/Nethermind.Trie/VerkleUtils.cs b/src/Nethermind/Nethermind.Trie/VerkleUtils.cs new file mode 100644 index 00000000000..925afa2677e --- /dev/null +++ b/src/Nethermind/Nethermind.Trie/VerkleUtils.cs @@ -0,0 +1,222 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Core; +using Nethermind.Int256; + +namespace Nethermind.Trie; + +public static class PedersenHash +{ + public static byte[] CalculatePedersenHash(Span keyPrefix) + { + throw new ArgumentException(); + } +} + +public static unsafe class VerkleUtils +{ + public const int VersionLeafKey = 0; + public const int BalanceLeafKey = 1; + public const int NonceLeafKey = 2; + public const int CodeKeccakLeafKey = 3; + public const int CodeSizeLeafKey = 4; + + const int MainStorageOffsetExponent = 31; + + static readonly UInt256 HeaderStorageOffset = 64; + static readonly UInt256 CodeOffset = 128; + static readonly UInt256 VerkleNodeWidth = 256; + + static readonly UInt256 MainStorageOffsetBase = 256; + static readonly UInt256 MainStorageOffset = MainStorageOffsetBase << MainStorageOffsetExponent; + + public static byte[] GetTreeKeyPrefix(Address address, UInt256 treeIndex) + { + // allocate the array on stack + Span keyPrefix = stackalloc byte[64]; + // first 12 bytes are '0' padding to convert 12 byte address -> 32 bytes + // Span cursor = keyPrefix.Slice(12); + Span cursor = keyPrefix.Slice(0); + address.Bytes.CopyTo(cursor); + // copy the address to the remaining 20 bytes - + //TODO: correct this when geth corrects it, it should be left padded and not right + // cursor = cursor.Slice(20); + cursor = cursor.Slice(32); + // copy the tree index to the remaining 32 bytes + treeIndex.ToBigEndian(cursor); + byte[] prefix = PedersenHash.CalculatePedersenHash(keyPrefix); + prefix[31] = 0; + return prefix; + } + + public static byte[] GetTreeKeyPrefixAccount(Address address) => GetTreeKeyPrefix(address, 0); + + public static byte[] GetTreeKey(Address address, UInt256 treeIndex, byte subIndexBytes) + { + byte[] treeKeyPrefix = GetTreeKeyPrefix(address, treeIndex); + treeKeyPrefix[31] = subIndexBytes; + return treeKeyPrefix; + } + + public static byte[] GetTreeKeyForVersion(Address address) => GetTreeKey(address, UInt256.Zero, VersionLeafKey); + public static byte[] GetTreeKeyForBalance(Address address) => GetTreeKey(address, UInt256.Zero, BalanceLeafKey); + public static byte[] GetTreeKeyForNonce(Address address) => GetTreeKey(address, UInt256.Zero, NonceLeafKey); + public static byte[] GetTreeKeyForCodeKeccak(Address address) => GetTreeKey(address, UInt256.Zero, CodeKeccakLeafKey); + public static byte[] GetTreeKeyForCodeSize(Address address) => GetTreeKey(address, UInt256.Zero, CodeSizeLeafKey); + + public static byte[] GetTreeKeyForCodeChunk(Address address, UInt256 chunk) + { + UInt256 chunkOffset = CodeOffset + chunk; + + UInt256 treeIndex = chunkOffset / VerkleNodeWidth; + + UInt256.Mod(chunkOffset, VerkleNodeWidth, out UInt256 subIndex); + return GetTreeKey(address, treeIndex, subIndex.ToBigEndian()[31]); + } + + public static byte[] GetTreeKeyForStorageSlot(Address address, UInt256 storageKey) + { + UInt256 pos; + + if (storageKey < CodeOffset - HeaderStorageOffset) + { + pos = HeaderStorageOffset + storageKey; + } + else + { + pos = MainStorageOffset + storageKey; + } + + UInt256 treeIndex = pos / VerkleNodeWidth; + + UInt256.Mod(pos, VerkleNodeWidth, out UInt256 subIndex); + return GetTreeKey(address, treeIndex, subIndex.ToBigEndian()[31]); + } + + + public static void FillTreeAndSubIndexForChunk(UInt256 chunkId, ref Span subIndexBytes, out UInt256 treeIndex) + { + UInt256 chunkOffset = CodeOffset + chunkId; + treeIndex = chunkOffset / VerkleNodeWidth; + UInt256.Mod(chunkOffset, VerkleNodeWidth, out UInt256 subIndex); + subIndex.ToBigEndian(subIndexBytes); + } + + public ref struct CodeChunkEnumerator + { + const byte PushOffset = 95; + const byte Push1 = PushOffset + 1; + const byte Push32 = PushOffset + 32; + + private Span _code; + private byte _rollingOverPushLength = 0; + private readonly byte[] _bufferChunk = new byte[32]; + private readonly Span _bufferChunkCodePart; + + public CodeChunkEnumerator(Span code) + { + _code = code; + _bufferChunkCodePart = _bufferChunk.AsSpan().Slice(1); + } + + // Try get next chunk + public bool TryGetNextChunk(out byte[] chunk) + { + chunk = _bufferChunk; + + // we don't have chunks left + if (_code.IsEmpty) + { + return false; + } + + // we don't have full chunk + if (_code.Length < 31) + { + // need to have trailing zeroes + _bufferChunkCodePart.Fill(0); + + // set number of push bytes + _bufferChunk[0] = _rollingOverPushLength; + + // copy main bytes + _code.CopyTo(_bufferChunkCodePart); + + // we are done + _code = Span.Empty; + } + else + { + // fill up chunk to store + + // get current chunk of code + Span currentChunk = _code.Slice(0, 31); + + // copy main bytes + currentChunk.CopyTo(_bufferChunkCodePart); + + switch (_rollingOverPushLength) + { + case 32 or 31: // all bytes are roll over + + // set number of push bytes + _bufferChunk[0] = 31; + + // if 32, then we will roll over with 1 to even next chunk + _rollingOverPushLength -= 31; + break; + default: + // set number of push bytes + _bufferChunk[0] = _rollingOverPushLength; + _rollingOverPushLength = 0; + + // check if we have a push instruction in remaining code + // ignore the bytes we rolled over, they are not instructions + for (int i = _bufferChunk[0]; i < 31;) + { + byte instruction = currentChunk[i]; + i++; + if (instruction is >= Push1 and <= Push32) + { + // we calculate data to ignore in code + i += instruction - PushOffset; + + // check if we rolled over the chunk + _rollingOverPushLength = (byte)Math.Max(i - 31, 0); + } + } + + break; + } + + // move to next chunk + _code = _code.Slice(31); + } + + return true; + } + } + + public static byte[,] To2D(byte[][] jagged) + { + byte[,] keys = new byte[jagged.Length, 32]; + unsafe + { + for (int i = 0; i < jagged.Length; i++) + { + fixed (byte* pInKey = jagged[i]) + { + fixed (byte* pOutKey = &keys[i, 0]) + { + Buffer.MemoryCopy(pInKey, pOutKey, 32, 32); + } + } + } + } + + return keys; + } + +}