diff --git a/src/Nethermind/Chains/kaustinen.json b/src/Nethermind/Chains/kaustinen.json index 2bc4614f857..1b2bbcb7456 100644 --- a/src/Nethermind/Chains/kaustinen.json +++ b/src/Nethermind/Chains/kaustinen.json @@ -59,7 +59,7 @@ }, "difficulty": "0x01", "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x66190fbc", + "timestamp": "0x6720f8ac", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "", "gasLimit": "0x17D7840" @@ -937,18 +937,11 @@ } }, "nodes": [ - "enode://686762312c36eb5bacd4044f909c39ad360c7bf99966c14bdc72109a06ca656a226aa646e38e21bb8203980490fc82834576062f6b824d3d08f255c814bfae62@49.13.203.116:30303?discport=30303", - "enode://7c51103dd772a164a7c45c2cce2c9171ce1a9e032671a158aac6f8bc7b927dbc0be40a564af1678fd6aec5e2768a41afa3d97d38e3fde6edbeffab31a7a71258@128.140.104.96:30303?discport=30303", - "enode://1ff18a6e90574d3d7276e72516ac396325770b4c7e2db0b6eaa82dc5edb5ec91d0b4ce7c4b22166a64617d2d27b8555f100a804706518e9ecab7131bc1bdd8b1@49.13.196.169:30303?discport=30303", - "enode://3cd52cb1b4839c4defb04662521e0ceb226ff697660e0a88de2abc3f2afa3f15207df9678f2c511b7731f1d4f2077351966cd3c455d4ab5129a5e45424ef9a04@128.140.103.190:30303?discport=30303", - "enode://a74b106aa67636aa7ee28b6928bd7da0115a6fe658630a25f9cb6f7bf02275dcda1b66c5ef98a30d1e462d12c915a4ca248f033f4edbf2c87601aded63990fac@78.47.30.10:30303?discport=30303", - "enode://8a7bc039cdabb77744166b7bb4640b7a1ba3cfc6b9fdb8693663a8615c399e849e0a5cc8f9bde4ff4bf4a14d84611f77b459129251710c499c2b9d96cef1ce6b@116.203.113.205:30303?discport=30303", - "enode://ff62daadb1a1f08cb332ed87893e061252ffd42f32704c512ef4fb1937a19acda00f814e57bd1c8f06d9d8c6d404481bea67b692f412d8e1f8fd628103992465@167.235.68.89:30303?discport=30303", - "enode://0eee8ed3c4d5f06e3d395c2290db054d39989d21a9c4038de9d40009416e3aea5d7269481ec2214d45303aaa0a80d2522bb529673bbdd22a4ec7cb22f5a4f5a4@116.203.223.168:30303?discport=30303", - "enode://627ee97e5c297d3229d08abb53842d61b47d0162618264ef3156654c9f4cd26c994e02c44e0ca1576c932b8d29133a769e24bf5482f6a3412ba4dad5adbb4185@195.201.36.62:30303?discport=30303", - "enode://261ce91ece10fef227bbad6453f3bc5648ea18c42c9750820cf2110b590755630d3d5c32b360cc06787abefafc7ce6dbe92f8c39fb613774c922d8fc340e47a8@128.140.104.94:30303?discport=30303" - - - + "enode://548ff025abb1522c5257f50765abd21754b7ea7159a176a9b96c738ee6456fc378a11c09a62d55d92684634cd32a9cad498f5649256caf693dab77f961a169f6@167.235.68.89:30303?discport=30303", + "enode://7a46b1126d2c602e2d567a75aa3cc2577d93ea2bfcc524d115f985689516159c94a339f3984bbce28eb8b35d49494d1ec7be55f361c7768ae43993bc5b88eb77@128.140.104.94:30303?discport=30303", + "enode://a21d8ecaaea7a199a479672ae11b11afc1b55dce4851d278cae11fd4cf5452866f40890cb7262c3430f9f249d7091ebab39f148740c267f3f3b505c6d27391fe@128.140.104.96:30303?discport=30303", + "enode://145e00c57c837fe19d431bb33cb964b747616cc6be57e350936f13fe51ab4fab5bb167fb38c8399d9b0d687d317466d2c4d0bff2c83068ffa77c4ed16f5f7b28@195.201.139.113:30303?discport=30303", + "enode://9ceb22af386b10ba283cd60f7e83772585e47946e7dddc6029e9acd79730095ea8e5e6ba8619c30149e002084b9bb83ef62e0765cd30c9626667b29ea8f3389e@49.13.196.169:30303?discport=30303", + "enode://e1157ce974bd103852a6df269a772dbcf308f628b185e6fc2774f8eddc127c1309a7f023dfaae922dfe32c5170aa7085245dbe4b88931b21d3ee4bb290b77418@195.201.36.62:30303?discport=30303" ] } diff --git a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs index 98dd868d8ba..008e1a19a95 100644 --- a/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs +++ b/src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs @@ -39,7 +39,7 @@ namespace Ethereum.Test.Base { - public abstract class BlockchainTestBase + public class BlockchainTestBase: IBlockchainTestBase { private static InterfaceLogger _logger = new NUnitLogger(LogLevel.Trace); // private static ILogManager _logManager = new OneLoggerLogManager(_logger); @@ -74,7 +74,7 @@ public UInt256 Calculate(BlockHeader header, BlockHeader parent) } } - protected async Task RunTest(BlockchainTest test, Stopwatch? stopwatch = null, bool failOnInvalidRlp = true) + public async Task RunTest(BlockchainTest test, Stopwatch? stopwatch = null, bool failOnInvalidRlp = true) { TestContext.WriteLine($"Running {test.Name}, Network: [{test.Network.Name}] at {DateTime.UtcNow:HH:mm:ss.ffffff}"); if (test.NetworkAfterTransition is not null) diff --git a/src/Nethermind/Ethereum.Test.Base/IBlockchainTestBase.cs b/src/Nethermind/Ethereum.Test.Base/IBlockchainTestBase.cs new file mode 100644 index 00000000000..70a5239b6b0 --- /dev/null +++ b/src/Nethermind/Ethereum.Test.Base/IBlockchainTestBase.cs @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Diagnostics; +using System.Threading.Tasks; + +namespace Ethereum.Test.Base; + +public interface IBlockchainTestBase +{ + public void Setup(); + + public Task RunTest(BlockchainTest test, Stopwatch? stopwatch = null, bool failOnInvalidRlp = true); +} diff --git a/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs b/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs index 51483884796..9d07aa85275 100644 --- a/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs +++ b/src/Nethermind/Ethereum.Test.Base/JsonToEthereumTest.cs @@ -40,6 +40,7 @@ private static IReleaseSpec ParseSpec(string network) network = network.Replace("Shanghai+6780", "Cancun"); network = network.Replace("GrayGlacier+1153", "Cancun"); network = network.Replace("Merge+1153", "Cancun"); + network = network.Replace("Verkle", "Osaka"); return network switch { "Frontier" => Frontier.Instance, @@ -58,6 +59,7 @@ private static IReleaseSpec ParseSpec(string network) "GrayGlacier" => GrayGlacier.Instance, "Shanghai" => Shanghai.Instance, "Cancun" => Cancun.Instance, + "Osaka" => Osaka.Instance, _ => throw new NotSupportedException() }; } diff --git a/src/Nethermind/Ethereum.Test.Base/LoadBlockchainTestsStrategy.cs b/src/Nethermind/Ethereum.Test.Base/LoadBlockchainTestsStrategy.cs index 7fbc3fa0153..839da79e1a1 100644 --- a/src/Nethermind/Ethereum.Test.Base/LoadBlockchainTestsStrategy.cs +++ b/src/Nethermind/Ethereum.Test.Base/LoadBlockchainTestsStrategy.cs @@ -21,6 +21,7 @@ public IEnumerable Load(string testsDirectoryName, string wildcar } else { + // testDirs = Directory.EnumerateDirectories(testsDirectoryName); testDirs = new[] { testsDirectoryName }; } diff --git a/src/Nethermind/Ethereum.Test.Base/TestBlockJson.cs b/src/Nethermind/Ethereum.Test.Base/TestBlockJson.cs index 2454b75e495..25bb6b26303 100644 --- a/src/Nethermind/Ethereum.Test.Base/TestBlockJson.cs +++ b/src/Nethermind/Ethereum.Test.Base/TestBlockJson.cs @@ -1,8 +1,9 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System.Text.Json; using System.Text.Json.Serialization; +using Nethermind.Core.Verkle; +using Nethermind.Serialization.Json; namespace Ethereum.Test.Base { @@ -12,6 +13,8 @@ public class TestBlockJson public TestBlockHeaderJson[]? UncleHeaders { get; set; } public string? Rlp { get; set; } public LegacyTransactionJson[]? Transactions { get; set; } + [JsonConverter(typeof(ExecutionWitnessConverter))] + public ExecutionWitness? Witness { get; set; } [JsonPropertyName("expectException")] public string? ExpectedException { get; set; } } diff --git a/src/Nethermind/Ethereum.Test.Base/VerkleBlockChainTestBase.cs b/src/Nethermind/Ethereum.Test.Base/VerkleBlockChainTestBase.cs new file mode 100644 index 00000000000..b3ea237d4dc --- /dev/null +++ b/src/Nethermind/Ethereum.Test.Base/VerkleBlockChainTestBase.cs @@ -0,0 +1,465 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Numerics; +using System.Threading; +using System.Threading.Tasks; +using Nethermind.Blockchain; +using Nethermind.Blockchain.Find; +using Nethermind.Blockchain.Receipts; +using Nethermind.Consensus; +using Nethermind.Consensus.Ethash; +using Nethermind.Consensus.Processing; +using Nethermind.Consensus.Rewards; +using Nethermind.Consensus.Validators; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Core.Test; +using Nethermind.Core.Test.Builders; +using Nethermind.Crypto; +using Nethermind.Db; +using Nethermind.Int256; +using Nethermind.Evm; +using Nethermind.Evm.TransactionProcessing; +using Nethermind.Logging; +using Nethermind.Serialization.Rlp; +using Nethermind.Specs.Forks; +using Nethermind.Specs.Test; +using Nethermind.State; +using Nethermind.TxPool; +using Nethermind.Verkle.Tree.TreeStore; +using NUnit.Framework; + +namespace Ethereum.Test.Base +{ + public class VerkleBlockChainTestBase: IBlockchainTestBase + { + private static InterfaceLogger _logger = new NUnitLogger(LogLevel.Trace); + // private static ILogManager _logManager = new OneLoggerLogManager(_logger); + private static ILogManager _logManager = LimboLogs.Instance; + private static ISealValidator Sealer { get; } + private static DifficultyCalculatorWrapper DifficultyCalculator { get; } + + static VerkleBlockChainTestBase() + { + DifficultyCalculator = new DifficultyCalculatorWrapper(); + Sealer = new EthashSealValidator(_logManager, DifficultyCalculator, new CryptoRandom(), new Ethash(_logManager), Timestamper.Default); // temporarily keep reusing the same one as otherwise it would recreate cache for each test + } + + [SetUp] + public void Setup() + { + } + + private class DifficultyCalculatorWrapper : IDifficultyCalculator + { + public IDifficultyCalculator? Wrapped { get; set; } + + public UInt256 Calculate(BlockHeader header, BlockHeader parent) + { + if (Wrapped is null) + { + throw new InvalidOperationException( + $"Cannot calculate difficulty before the {nameof(Wrapped)} calculator is set."); + } + + return Wrapped.Calculate(header, parent); + } + } + + public async Task RunTest(BlockchainTest test, Stopwatch? stopwatch = null, bool failOnInvalidRlp = true) + { + Assert.IsNull(test.LoadFailure, "test data loading failure"); + + IDbProvider dbProvider = TestMemDbProvider.Init(); + IDb codeDb = dbProvider.CodeDb; + + ISpecProvider specProvider = new CustomSpecProvider( + ((ForkActivation)0, Frontier.Instance), + ((ForkActivation)1, test.Network)); + + if (specProvider.GenesisSpec != Frontier.Instance) + { + Assert.Fail("Expected genesis spec to be Frontier for blockchain tests"); + } + + if (test.Network is Cancun) + { + await KzgPolynomialCommitments.InitializeAsync(); + } + + DifficultyCalculator.Wrapped = new EthashDifficultyCalculator(specProvider); + IRewardCalculator rewardCalculator = new RewardCalculator(specProvider); + bool isPostMerge = test.Network != London.Instance && + test.Network != Berlin.Instance && + test.Network != MuirGlacier.Instance && + test.Network != Istanbul.Instance && + test.Network != ConstantinopleFix.Instance && + test.Network != Constantinople.Instance && + test.Network != Byzantium.Instance && + test.Network != SpuriousDragon.Instance && + test.Network != TangerineWhistle.Instance && + test.Network != Dao.Instance && + test.Network != Homestead.Instance && + test.Network != Frontier.Instance && + test.Network != Olympic.Instance; + if (isPostMerge) + { + rewardCalculator = NoBlockRewards.Instance; + specProvider.UpdateMergeTransitionInfo(0, 0); + } + + IEthereumEcdsa ecdsa = new EthereumEcdsa(specProvider.ChainId, _logManager); + + IVerkleTreeStore verkleTreeStore = new VerkleTreeStore(dbProvider, _logManager); + VerkleStateTree verkleStateTree = new VerkleStateTree(verkleTreeStore, _logManager); + + IWorldState stateProvider = new VerkleWorldState(verkleTreeStore, codeDb, _logManager); + IStateReader stateReader = new VerkleStateReader(verkleStateTree, codeDb, _logManager); + + IBlockTree blockTree = Build.A.BlockTree() + .WithSpecProvider(specProvider) + .WithoutSettingHead + .TestObject; + + IReceiptStorage receiptStorage = NullReceiptStorage.Instance; + IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, _logManager); + ITxValidator txValidator = new TxValidator(TestBlockchainIds.ChainId); + IHeaderValidator headerValidator = new HeaderValidator(blockTree, Sealer, specProvider, _logManager); + IUnclesValidator unclesValidator = new UnclesValidator(blockTree, headerValidator, _logManager); + IBlockValidator blockValidator = new BlockValidator(txValidator, headerValidator, unclesValidator, specProvider, _logManager); + IVirtualMachine virtualMachine = new VirtualMachine( + blockhashProvider, + specProvider, + _logManager); + + BlockProcessor blockProcessor = new BlockProcessor( + specProvider, + blockValidator, + rewardCalculator, + new BlockProcessor.BlockValidationTransactionsExecutor( + new TransactionProcessor( + specProvider, + stateProvider, + virtualMachine, + _logManager), + stateProvider), + stateProvider, + receiptStorage, + NullWitnessCollector.Instance, + blockTree, + _logManager); + + // for witness verification + blockProcessor.ShouldVerifyIncomingWitness = true; + blockProcessor.ShouldGenerateWitness = true; + + IBlockchainProcessor blockchainProcessor = new BlockchainProcessor( + blockTree, + blockProcessor, + new RecoverSignatures(ecdsa, NullTxPool.Instance, specProvider, _logManager), + stateReader, + _logManager, + BlockchainProcessor.Options.NoReceipts); + + InitializeTestState(test, stateProvider, specProvider); + + stopwatch?.Start(); + List<(Block Block, string ExpectedException)> correctRlp = DecodeRlps(test, failOnInvalidRlp); + + test.GenesisRlp ??= Rlp.Encode(new Block(JsonToEthereumTest.Convert(test.GenesisBlockHeader))); + + Block genesisBlock = Rlp.Decode(test.GenesisRlp.Bytes); + Assert.That(genesisBlock.Header.Hash, Is.EqualTo(new Hash256(test.GenesisBlockHeader.Hash))); + + ManualResetEvent genesisProcessed = new(false); + + blockTree.NewHeadBlock += (_, args) => + { + if (args.Block.Number == 0) + { + Assert.That(stateProvider.StateRoot, Is.EqualTo(genesisBlock.Header.StateRoot)); + genesisProcessed.Set(); + } + }; + + blockchainProcessor.Start(); + blockTree.SuggestBlock(genesisBlock); + + genesisProcessed.WaitOne(); + for (int i = 0; i < correctRlp.Count; i++) + { + if (correctRlp[i].Block.Hash is null) + { + Assert.Fail($"null hash in {test.Name} block {i}"); + } + + try + { + // TODO: mimic the actual behaviour where block goes through validating sync manager? + correctRlp[i].Block.Header.IsPostMerge = correctRlp[i].Block.Difficulty == 0; + if (!test.SealEngineUsed || blockValidator.ValidateSuggestedBlock(correctRlp[i].Block, out _)) + { + blockTree.SuggestBlock(correctRlp[i].Block); + } + else + { + if (correctRlp[i].ExpectedException is not null) + { + Assert.Fail($"Unexpected invalid block {correctRlp[i].Block.Hash}"); + } + } + } + catch (InvalidBlockException e) + { + if (correctRlp[i].ExpectedException is not null) + { + Assert.Fail($"Unexpected invalid block {correctRlp[i].Block.Hash}: {e}"); + } + } + catch (Exception e) + { + Assert.Fail($"Unexpected exception during processing: {e}"); + } + } + + await blockchainProcessor.StopAsync(true); + stopwatch?.Stop(); + + List differences = RunAssertions(test, blockTree.RetrieveHeadBlock(), stateProvider); + + return new EthereumTestResult + ( + test.Name, + null, + differences.Count == 0 + ); + } + + private List<(Block Block, string ExpectedException)> DecodeRlps(BlockchainTest test, bool failOnInvalidRlp) + { + List<(Block Block, string ExpectedException)> correctRlp = new(); + for (int i = 0; i < test.Blocks.Length; i++) + { + TestBlockJson testBlockJson = test.Blocks[i]; + try + { + var rlpContext = Bytes.FromHexString(testBlockJson.Rlp).AsRlpStream(); + Block suggestedBlock = Rlp.Decode(rlpContext); + suggestedBlock.Header.SealEngineType = + test.SealEngineUsed ? SealEngineType.Ethash : SealEngineType.None; + + if (testBlockJson.BlockHeader is not null) + { + Assert.That(suggestedBlock.Header.Hash, Is.EqualTo(new Hash256(testBlockJson.BlockHeader.Hash))); + + for (int uncleIndex = 0; uncleIndex < suggestedBlock.Uncles.Length; uncleIndex++) + { + Assert.That(suggestedBlock.Uncles[uncleIndex].Hash, Is.EqualTo(new Hash256(testBlockJson.UncleHeaders[uncleIndex].Hash))); + } + + if (testBlockJson.Witness is not null) + { + suggestedBlock.Body.ExecutionWitness = testBlockJson.Witness; + } + + correctRlp.Add((suggestedBlock, testBlockJson.ExpectedException)); + } + } + catch (Exception e) + { + if (testBlockJson.ExpectedException is null) + { + string invalidRlpMessage = $"Invalid RLP ({i}) {e}"; + if (failOnInvalidRlp) + { + Assert.Fail(invalidRlpMessage); + } + else + { + // ForgedTests don't have ExpectedException and at the same time have invalid rlps + // Don't fail here. If test executed incorrectly will fail at last check + _logger.Warn(invalidRlpMessage); + } + } + else + { + _logger.Info($"Expected invalid RLP ({i})"); + } + } + } + + if (correctRlp.Count == 0) + { + Assert.NotNull(test.GenesisBlockHeader); + Assert.That(test.LastBlockHash, Is.EqualTo(new Hash256(test.GenesisBlockHeader.Hash))); + } + + return correctRlp; + } + + private void InitializeTestState(BlockchainTest test, IWorldState stateProvider, ISpecProvider specProvider) + { + foreach (KeyValuePair accountState in + ((IEnumerable>)test.Pre ?? Array.Empty>())) + { + foreach (KeyValuePair storageItem in accountState.Value.Storage) + { + stateProvider.Set(new StorageCell(accountState.Key, storageItem.Key), storageItem.Value); + } + + stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance); + stateProvider.InsertCode(accountState.Key, accountState.Value.Code, specProvider.GenesisSpec); + for (int i = 0; i < accountState.Value.Nonce; i++) + { + stateProvider.IncrementNonce(accountState.Key); + } + } + + stateProvider.Commit(specProvider.GenesisSpec); + + stateProvider.CommitTree(0); + + stateProvider.Reset(); + } + + private List RunAssertions(BlockchainTest test, Block headBlock, IWorldState stateProvider) + { + if (test.PostStateRoot != null) + { + return test.PostStateRoot != stateProvider.StateRoot ? new List { "state root mismatch" } : Enumerable.Empty().ToList(); + } + + TestBlockHeaderJson testHeaderJson = (test.Blocks? + .Where(b => b.BlockHeader != null) + .SingleOrDefault(b => new Hash256(b.BlockHeader.Hash) == headBlock.Hash)?.BlockHeader) ?? test.GenesisBlockHeader; + BlockHeader testHeader = JsonToEthereumTest.Convert(testHeaderJson); + List differences = new(); + + if (test.PostState is not null) + { + IEnumerable> deletedAccounts = test.Pre? + .Where(pre => !(test.PostState?.ContainsKey(pre.Key) ?? false)) ?? Array.Empty>(); + + foreach (KeyValuePair deletedAccount in deletedAccounts) + { + if (stateProvider.AccountExists(deletedAccount.Key)) + { + differences.Add($"Pre state account {deletedAccount.Key} was not deleted as expected."); + } + } + + foreach ((Address acountAddress, AccountState accountState) in test.PostState) + { + int differencesBefore = differences.Count; + + if (differences.Count > 8) + { + Console.WriteLine("More than 8 differences..."); + break; + } + + bool accountExists = stateProvider.AccountExists(acountAddress); + UInt256? balance = accountExists ? stateProvider.GetBalance(acountAddress) : (UInt256?)null; + UInt256? nonce = accountExists ? stateProvider.GetNonce(acountAddress) : (UInt256?)null; + + if (accountState.Balance != balance) + { + differences.Add($"{acountAddress} balance exp: {accountState.Balance}, actual: {balance}, diff: {(balance > accountState.Balance ? balance - accountState.Balance : accountState.Balance - balance)}"); + } + + if (accountState.Nonce != nonce) + { + differences.Add($"{acountAddress} nonce exp: {accountState.Nonce}, actual: {nonce}"); + } + + byte[] code = accountExists ? stateProvider.GetCode(acountAddress) : new byte[0]; + if (!Bytes.AreEqual(accountState.Code, code)) + { + differences.Add($"{acountAddress} code exp: {accountState.Code?.Length}, actual: {code?.Length}"); + } + + if (differences.Count != differencesBefore) + { + _logger.Info($"ACCOUNT STATE ({acountAddress}) HAS DIFFERENCES"); + } + + differencesBefore = differences.Count; + + KeyValuePair[] clearedStorages = new KeyValuePair[0]; + if (test.Pre.ContainsKey(acountAddress)) + { + clearedStorages = test.Pre[acountAddress].Storage.Where(s => !accountState.Storage.ContainsKey(s.Key)).ToArray(); + } + + foreach (KeyValuePair clearedStorage in clearedStorages) + { + ReadOnlySpan value = !stateProvider.AccountExists(acountAddress) ? Bytes.Empty : stateProvider.Get(new StorageCell(acountAddress, clearedStorage.Key)); + if (!value.IsZero()) + { + differences.Add($"{acountAddress} storage[{clearedStorage.Key}] exp: 0x00, actual: {value.ToHexString(true)}"); + } + } + + foreach (KeyValuePair storageItem in accountState.Storage) + { + ReadOnlySpan value = !stateProvider.AccountExists(acountAddress) ? Bytes.Empty : stateProvider.Get(new StorageCell(acountAddress, storageItem.Key)); + if (!Bytes.AreEqual(storageItem.Value, value)) + { + differences.Add($"{acountAddress} storage[{storageItem.Key}] exp: {storageItem.Value.ToHexString(true)}, actual: {value.ToHexString(true)}"); + } + } + + if (differences.Count != differencesBefore) + { + _logger.Info($"ACCOUNT STORAGE ({acountAddress}) HAS DIFFERENCES"); + } + } + } + + BigInteger gasUsed = headBlock.Header.GasUsed; + if ((testHeader?.GasUsed ?? 0) != gasUsed) + { + differences.Add($"GAS USED exp: {testHeader?.GasUsed ?? 0}, actual: {gasUsed}"); + } + + if (headBlock.Transactions.Any() && testHeader.Bloom.ToString() != headBlock.Header.Bloom.ToString()) + { + differences.Add($"BLOOM exp: {testHeader.Bloom}, actual: {headBlock.Header.Bloom}"); + } + + // if (testHeader.StateRoot != stateProvider.StateRoot) + // { + // differences.Add($"STATE ROOT exp: {testHeader.StateRoot}, actual: {stateProvider.StateRoot}"); + // } + + if (testHeader.TxRoot != headBlock.Header.TxRoot) + { + differences.Add($"TRANSACTIONS ROOT exp: {testHeader.TxRoot}, actual: {headBlock.Header.TxRoot}"); + } + + if (testHeader.ReceiptsRoot != headBlock.Header.ReceiptsRoot) + { + differences.Add($"RECEIPT ROOT exp: {testHeader.ReceiptsRoot}, actual: {headBlock.Header.ReceiptsRoot}"); + } + + if (test.LastBlockHash != headBlock.Hash) + { + differences.Add($"LAST BLOCK HASH exp: {test.LastBlockHash}, actual: {headBlock.Hash}"); + } + + foreach (string difference in differences) + { + _logger.Info(difference); + } + + return differences; + } + } +} diff --git a/src/Nethermind/EthereumTests.sln b/src/Nethermind/EthereumTests.sln index 10f3a923f34..0231fdf08e6 100644 --- a/src/Nethermind/EthereumTests.sln +++ b/src/Nethermind/EthereumTests.sln @@ -115,6 +115,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Synchronization" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethermind.Sockets", "Nethermind.Sockets\Nethermind.Sockets.csproj", "{E9D67F92-D848-4DB3-A586-2AC6DE2A3933}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethermind.Verkle.Tree", "Nethermind.Verkle.Tree\Nethermind.Verkle.Tree.csproj", "{A0815CF4-E96D-48F8-A6A9-0AF4D933E963}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethermind.Verkle", "Nethermind.Verkle\Nethermind.Verkle.csproj", "{6C2B695A-A8E1-4D2A-AE68-50EDFC1AAA21}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethermind.Db.Rocks", "Nethermind.Db.Rocks\Nethermind.Db.Rocks.csproj", "{130E2531-A069-4C47-ACC2-4E223A376799}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -341,6 +347,18 @@ Global {E9D67F92-D848-4DB3-A586-2AC6DE2A3933}.Debug|Any CPU.Build.0 = Debug|Any CPU {E9D67F92-D848-4DB3-A586-2AC6DE2A3933}.Release|Any CPU.ActiveCfg = Release|Any CPU {E9D67F92-D848-4DB3-A586-2AC6DE2A3933}.Release|Any CPU.Build.0 = Release|Any CPU + {A0815CF4-E96D-48F8-A6A9-0AF4D933E963}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A0815CF4-E96D-48F8-A6A9-0AF4D933E963}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A0815CF4-E96D-48F8-A6A9-0AF4D933E963}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A0815CF4-E96D-48F8-A6A9-0AF4D933E963}.Release|Any CPU.Build.0 = Release|Any CPU + {6C2B695A-A8E1-4D2A-AE68-50EDFC1AAA21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C2B695A-A8E1-4D2A-AE68-50EDFC1AAA21}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C2B695A-A8E1-4D2A-AE68-50EDFC1AAA21}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C2B695A-A8E1-4D2A-AE68-50EDFC1AAA21}.Release|Any CPU.Build.0 = Release|Any CPU + {130E2531-A069-4C47-ACC2-4E223A376799}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {130E2531-A069-4C47-ACC2-4E223A376799}.Debug|Any CPU.Build.0 = Debug|Any CPU + {130E2531-A069-4C47-ACC2-4E223A376799}.Release|Any CPU.ActiveCfg = Release|Any CPU + {130E2531-A069-4C47-ACC2-4E223A376799}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -380,6 +398,9 @@ Global {EEC15744-BE65-49A9-9224-ABC2BB687F6D} = {199F75FD-E02D-4434-B4F0-0B35B63A1D77} {A3703872-F558-486F-9404-345AA2488D09} = {199F75FD-E02D-4434-B4F0-0B35B63A1D77} {E9D67F92-D848-4DB3-A586-2AC6DE2A3933} = {199F75FD-E02D-4434-B4F0-0B35B63A1D77} + {A0815CF4-E96D-48F8-A6A9-0AF4D933E963} = {199F75FD-E02D-4434-B4F0-0B35B63A1D77} + {6C2B695A-A8E1-4D2A-AE68-50EDFC1AAA21} = {199F75FD-E02D-4434-B4F0-0B35B63A1D77} + {130E2531-A069-4C47-ACC2-4E223A376799} = {199F75FD-E02D-4434-B4F0-0B35B63A1D77} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8C13D618-3E1F-4A60-97AF-A310454B0AD8} diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuraBlockProcessorTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuraBlockProcessorTests.cs index efb076ce2a8..db663e3e931 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/AuraBlockProcessorTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/AuraBlockProcessorTests.cs @@ -159,7 +159,7 @@ void Process(AuRaBlockProcessor auRaBlockProcessor, int blockNumber, Hash256 sta NullReceiptStorage.Instance, LimboLogs.Instance, Substitute.For(), - new WithdrawalProcessor(stateProvider, LimboLogs.Instance), + new WithdrawalProcessor(LimboLogs.Instance), null, txFilter, contractRewriter: contractRewriter); diff --git a/src/Nethermind/Nethermind.Blockchain/BlockHashInState/BlockHashInStateHandler.cs b/src/Nethermind/Nethermind.Blockchain/BlockHashInState/BlockHashInStateHandler.cs index 29fdccb07e4..80088ca8f72 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockHashInState/BlockHashInStateHandler.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockHashInState/BlockHashInStateHandler.cs @@ -34,8 +34,9 @@ public void AddParentBlockHashToState(BlockHeader blockHeader, IReleaseSpec spec var blockIndex = new UInt256((ulong)((blockHeader.Number - 1) % Eip2935Constants.RingBufferSize)); StorageCell blockHashStoreCell = new(eip2935Account, blockIndex); - // TODO: this is just for kaustinen right now - if (!stateProvider.AccountExists(eip2935Account)) stateProvider.CreateAccount(eip2935Account, 0); + // TODO: this check is mostly removed for stateless nodes + // TODO: added for the issue in testnets + if (!stateProvider.AccountExists(eip2935Account)) stateProvider.CreateAccount(eip2935Account, 0, 0); // if (blockHeader.Number == 1) stateProvider.CreateAccount(eip2935Account, 0); stateProvider.Set(blockHashStoreCell, parentBlockHash.Bytes.WithoutLeadingZeros().ToArray()); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Withdrawals/NullWithdrawalProcessor.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Withdrawals/NullWithdrawalProcessor.cs index 5d361d16325..5c28867db78 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Withdrawals/NullWithdrawalProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Withdrawals/NullWithdrawalProcessor.cs @@ -5,12 +5,12 @@ using Nethermind.Core; using Nethermind.Core.Specs; using Nethermind.Evm.Tracing; +using Nethermind.State; namespace Nethermind.Consensus.AuRa.Withdrawals; public class NullWithdrawalProcessor : IWithdrawalProcessor { - public void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSpec spec) { } - public static IWithdrawalProcessor Instance { get; } = new NullWithdrawalProcessor(); + public void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSpec spec, IWorldState worldState) { } } diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs index 851a35c3e14..1aace6971ed 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs @@ -109,7 +109,7 @@ public Task InitBlockProducer(IBlockProductionTrigger? blockProd NullWitnessCollector.Instance, getFromApi.BlockTree, getFromApi.LogManager, - new BlockProductionWithdrawalProcessor(new WithdrawalProcessor(producerEnv.StateProvider, getFromApi.LogManager))); + new BlockProductionWithdrawalProcessor(new WithdrawalProcessor(getFromApi.LogManager))); IBlockchainProcessor producerChainProcessor = new BlockchainProcessor( readOnlyBlockTree, diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index c40ca79367e..bcc1401162b 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -28,6 +28,7 @@ using Nethermind.Evm.Witness; using Nethermind.Int256; using Nethermind.Logging; +using Nethermind.Serialization.Json; using Nethermind.Specs.Forks; using Nethermind.State; using Nethermind.Verkle.Curve; @@ -55,7 +56,7 @@ public partial class BlockProcessor : IBlockProcessor // these two are test flags that can be used to test witness generation and verification public bool ShouldVerifyIncomingWitness { get; set; } = false; - public bool ShouldGenerateWitness { get; set; } = true; + public bool ShouldGenerateWitness { get; set; } = false; /// /// We use a single execution tracer for all blocks. Internally execution tracer forwards most of the calls @@ -82,7 +83,7 @@ public BlockProcessor( _stateProvider = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider)); _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage)); _witnessCollector = witnessCollector ?? throw new ArgumentNullException(nameof(witnessCollector)); - _withdrawalProcessor = withdrawalProcessor ?? new WithdrawalProcessor(stateProvider, logManager); + _withdrawalProcessor = withdrawalProcessor ?? new WithdrawalProcessor(logManager); _rewardCalculator = rewardCalculator ?? throw new ArgumentNullException(nameof(rewardCalculator)); _blockTransactionsExecutor = blockTransactionsExecutor ?? throw new ArgumentNullException(nameof(blockTransactionsExecutor)); _receiptsRootCalculator = receiptsRootCalculator ?? ReceiptsRootCalculator.Instance; @@ -235,6 +236,8 @@ private void ValidateProcessedBlock(Block suggestedBlock, ProcessingOptions opti { if (!options.ContainsFlag(ProcessingOptions.NoValidation) && !_blockValidator.ValidateProcessedBlock(block, receipts, suggestedBlock, out string? error)) { + // var provider = _stateProvider as VerkleWorldState; + // provider.Tree.PrintLeaves(block.Number); if (_logger.IsWarn) _logger.Warn($"Processed block is not valid {suggestedBlock.ToString(Block.Format.FullHashAndNumber)} - {error}"); if (_logger.IsWarn) _logger.Warn($"Suggested block TD: {suggestedBlock.TotalDifficulty}, Suggested block IsPostMerge {suggestedBlock.IsPostMerge}, Block TD: {block.TotalDifficulty}, Block IsPostMerge {block.IsPostMerge}"); throw new InvalidBlockException(suggestedBlock, error); @@ -327,31 +330,45 @@ protected virtual TxReceipt[] ProcessBlock( block.Header.ReceiptsRoot = _receiptsRootCalculator.GetReceiptsRoot(receipts, spec, block.ReceiptsRoot); - if (!block.IsGenesis && block.Transactions.Length != 0 && ExecutionTracer.IsTracingAccessWitness) - { - var gasWitness = new VerkleExecWitness(NullLogManager.Instance, worldState as VerkleWorldState); - gasWitness.AccessForGasBeneficiary(block.Header.GasBeneficiary!); - ExecutionTracer.ReportAccessWitness(gasWitness); - } - - ApplyMinerRewards(block, blockTracer, spec); - _withdrawalProcessor.ProcessWithdrawals(block, ExecutionTracer, spec); + _withdrawalProcessor.ProcessWithdrawals(block, ExecutionTracer, spec, worldState); ExecutionTracer.EndBlockTrace(); // generate and add execution witness to the block - if (!block.IsGenesis && options.ContainsFlag(ProcessingOptions.ProducingBlock) && spec.IsVerkleTreeEipEnabled) + bool isProducingBlocks = options.ContainsFlag(ProcessingOptions.ProducingBlock); + if (!block.IsGenesis && spec.IsVerkleTreeEipEnabled && (isProducingBlocks || ShouldGenerateWitness)) { + // generate the verkle proof before commiting the changes Hash256[] witnessKeys = ExecutionTracer.WitnessKeys.ToArray(); var verkleWorldState = worldState as VerkleWorldState; ExecutionWitness witness = witnessKeys.Length == 0 ? new ExecutionWitness() : verkleWorldState?.GenerateExecutionWitness(witnessKeys, out _); + // commit the new changes worldState.Commit(spec); + // now the state is commited, use the witness with post state values verkleWorldState?.UpdateWithPostStateValues(witness); - block.Body.ExecutionWitness = witness; + + // now there are two reason we generate the witness + // 1. When we are producing the block + // 2. when we want to properly verify the incoming witness (this mode is mostly for hive tests) + + if (isProducingBlocks) + { + block.Body.ExecutionWitness = witness; + } + else if (ShouldVerifyIncomingWitness) + { + // this can be moved to hive tests as well, but we will need to modify the block store + // to store execution witness as well + ExecutionWitness incomingWit = block.Body.ExecutionWitness; + if (!incomingWit!.StateDiff.SequenceEqual(witness!.StateDiff)) + { + throw new Exception($"Different Execution Witness"); + } + } } else { diff --git a/src/Nethermind/Nethermind.Consensus/Processing/StatelessBlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/StatelessBlockProcessor.cs index d73fc4e727c..f1083a64dbb 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/StatelessBlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/StatelessBlockProcessor.cs @@ -2,6 +2,8 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Collections.Frozen; +using System.Collections.Generic; using Nethermind.Blockchain; using Nethermind.Blockchain.Receipts; using Nethermind.Consensus.Rewards; @@ -23,6 +25,7 @@ public class StatelessBlockProcessor : BlockProcessor, IBlockProcessor private readonly ILogger _logger; private readonly ILogManager _logManager; private readonly VerkleWorldState _statelessWorldState; + private readonly FrozenDictionary? _systemAccounts; bool IBlockProcessor.CanProcessStatelessBlock => true; @@ -36,7 +39,8 @@ public StatelessBlockProcessor( IWitnessCollector? witnessCollector, IBlockTree? blockTree, ILogManager? logManager, - IWithdrawalProcessor? withdrawalProcessor = null) + IWithdrawalProcessor? withdrawalProcessor = null, + FrozenDictionary? systemAccounts = null) : base( specProvider, blockValidator, @@ -54,6 +58,7 @@ public StatelessBlockProcessor( NullVerkleTreeStore stateStore = new(); VerkleStateTree? tree = new(stateStore, logManager); _statelessWorldState = new VerkleWorldState(tree, new MemDb(), logManager); + _systemAccounts = systemAccounts; } protected override void InitBranch(Hash256 branchStateRoot, bool incrementReorgMetric = true) diff --git a/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerEnvFactory.cs b/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerEnvFactory.cs index ea2fd4f4ae5..a84ae8a4aab 100644 --- a/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerEnvFactory.cs +++ b/src/Nethermind/Nethermind.Consensus/Producers/BlockProducerEnvFactory.cs @@ -144,7 +144,7 @@ protected virtual BlockProcessor CreateBlockProcessor(ReadOnlyTxProcessingEnv re NullWitnessCollector.Instance, _blockTree, logManager, - new BlockProductionWithdrawalProcessor(new WithdrawalProcessor(readOnlyTxProcessingEnv.StateProvider, logManager))); + new BlockProductionWithdrawalProcessor(new WithdrawalProcessor(logManager))); } } diff --git a/src/Nethermind/Nethermind.Consensus/Withdrawals/BlockProductionWithdrawalProcessor.cs b/src/Nethermind/Nethermind.Consensus/Withdrawals/BlockProductionWithdrawalProcessor.cs index 1c29d77c9c9..fc7ae968127 100644 --- a/src/Nethermind/Nethermind.Consensus/Withdrawals/BlockProductionWithdrawalProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Withdrawals/BlockProductionWithdrawalProcessor.cs @@ -6,6 +6,7 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Evm.Tracing; +using Nethermind.State; using Nethermind.State.Proofs; namespace Nethermind.Consensus.Withdrawals; @@ -17,9 +18,9 @@ public class BlockProductionWithdrawalProcessor : IWithdrawalProcessor public BlockProductionWithdrawalProcessor(IWithdrawalProcessor processor) => _processor = processor ?? throw new ArgumentNullException(nameof(processor)); - public void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSpec spec) + public void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSpec spec, IWorldState worldState) { - _processor.ProcessWithdrawals(block, blockTracer, spec); + _processor.ProcessWithdrawals(block, blockTracer, spec, worldState); if (spec.WithdrawalsEnabled) { diff --git a/src/Nethermind/Nethermind.Consensus/Withdrawals/IWithdrawalProcessor.cs b/src/Nethermind/Nethermind.Consensus/Withdrawals/IWithdrawalProcessor.cs index 16dbf557238..fe20b8b69c5 100644 --- a/src/Nethermind/Nethermind.Consensus/Withdrawals/IWithdrawalProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Withdrawals/IWithdrawalProcessor.cs @@ -4,10 +4,11 @@ using Nethermind.Core; using Nethermind.Core.Specs; using Nethermind.Evm.Tracing; +using Nethermind.State; namespace Nethermind.Consensus.Withdrawals; public interface IWithdrawalProcessor { - void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSpec spec); + void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSpec spec, IWorldState worldState); } diff --git a/src/Nethermind/Nethermind.Consensus/Withdrawals/WithdrawalProcessor.cs b/src/Nethermind/Nethermind.Consensus/Withdrawals/WithdrawalProcessor.cs index 3eeb1fbcdb7..9ee7bb70869 100644 --- a/src/Nethermind/Nethermind.Consensus/Withdrawals/WithdrawalProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Withdrawals/WithdrawalProcessor.cs @@ -15,17 +15,15 @@ namespace Nethermind.Consensus.Withdrawals; public class WithdrawalProcessor : IWithdrawalProcessor { private readonly ILogger _logger; - private readonly IWorldState _stateProvider; - public WithdrawalProcessor(IWorldState stateProvider, ILogManager logManager) + public WithdrawalProcessor(ILogManager logManager) { ArgumentNullException.ThrowIfNull(logManager); _logger = logManager.GetClassLogger(); - _stateProvider = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider)); } - public void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSpec spec) + public void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSpec spec, IWorldState worldState) { if (!spec.WithdrawalsEnabled) return; @@ -33,7 +31,7 @@ public void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSp if (_logger.IsTrace) _logger.Trace($"Applying withdrawals for block {block}"); IExecutionWitness witness = blockTracer.IsTracingAccessWitness - ? new VerkleExecWitness(NullLogManager.Instance, _stateProvider as VerkleWorldState) + ? new VerkleExecWitness(NullLogManager.Instance, worldState as VerkleWorldState) : new NoExecWitness(); if (block.Withdrawals is not null) @@ -45,13 +43,13 @@ public void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSp witness.AccessAccountForWithdrawal(withdrawal.Address); // Consensus clients are using Gwei for withdrawals amount. We need to convert it to Wei before applying state changes https://github.com/ethereum/execution-apis/pull/354 - if (_stateProvider.AccountExists(withdrawal.Address)) + if (worldState.AccountExists(withdrawal.Address)) { - _stateProvider.AddToBalance(withdrawal.Address, withdrawal.AmountInWei, spec); + worldState.AddToBalance(withdrawal.Address, withdrawal.AmountInWei, spec); } else { - _stateProvider.CreateAccount(withdrawal.Address, withdrawal.AmountInWei); + worldState.CreateAccount(withdrawal.Address, withdrawal.AmountInWei); } } } diff --git a/src/Nethermind/Nethermind.Core.Test/Json/ExecutionWitnessConvertorTests.cs b/src/Nethermind/Nethermind.Core.Test/Json/ExecutionWitnessConvertorTests.cs index 03e3f45dedd..1fc014de78a 100644 --- a/src/Nethermind/Nethermind.Core.Test/Json/ExecutionWitnessConvertorTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Json/ExecutionWitnessConvertorTests.cs @@ -3,6 +3,7 @@ using System; using System.Text.Json; +using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Verkle; using Nethermind.Serialization.Json; @@ -77,7 +78,7 @@ public void TestRoundTripNew() Banderwagon.FromBytes( Bytes.FromHexString("0x248acc46e79ce410ecd151b7c685d3b3156ca37e89015653b55cfcc133852a1f"))!.Value, item - )); + ), Keccak.EmptyTreeHash); var options = new JsonSerializerOptions { Converters = diff --git a/src/Nethermind/Nethermind.Core/Eip2935Constants.cs b/src/Nethermind/Nethermind.Core/Eip2935Constants.cs index 75d04c51e48..768146f080a 100644 --- a/src/Nethermind/Nethermind.Core/Eip2935Constants.cs +++ b/src/Nethermind/Nethermind.Core/Eip2935Constants.cs @@ -18,6 +18,10 @@ public static class Eip2935Constants /// /// Gets the RING_BUFFER_SIZE parameter. /// - public static readonly long RingBufferSize = 8192; + public const long RingBufferSize = 8192; + /// + /// Gets the RING_BUFFER_SIZE parameter. + /// + public const long OpCodeServeWindow = 256; } diff --git a/src/Nethermind/Nethermind.Core/Verkle/AccountHeader.cs b/src/Nethermind/Nethermind.Core/Verkle/AccountHeader.cs index cf7bded886f..2899c8f621c 100644 --- a/src/Nethermind/Nethermind.Core/Verkle/AccountHeader.cs +++ b/src/Nethermind/Nethermind.Core/Verkle/AccountHeader.cs @@ -58,7 +58,7 @@ public static Account BasicDataToAccount(in ReadOnlySpan basicData, Hash25 byte version = basicData[0]; var nonce = new UInt256(basicData.Slice(NonceOffset, NonceBytesLength), true); var codeSize = new UInt256(basicData.Slice(CodeSizeOffset, CodeSizeBytesLength), true); - var balance = new UInt256( basicData.Slice(BalanceOffset, BalanceBytesLength), true); + var balance = new UInt256(basicData.Slice(BalanceOffset, BalanceBytesLength), true); return new Account(nonce, balance, codeSize, version, Keccak.EmptyTreeHash, codeHash); } diff --git a/src/Nethermind/Nethermind.Core/Verkle/ExecutionWitness.cs b/src/Nethermind/Nethermind.Core/Verkle/ExecutionWitness.cs index 027b8fdf227..4353c6ceb4e 100644 --- a/src/Nethermind/Nethermind.Core/Verkle/ExecutionWitness.cs +++ b/src/Nethermind/Nethermind.Core/Verkle/ExecutionWitness.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text.Json.Serialization; using FastEnumUtility; +using Nethermind.Core.Crypto; using Nethermind.Verkle.Curve; using Nethermind.Verkle.Proofs; @@ -17,16 +18,20 @@ public class ExecutionWitness public StemStateDiff[] StateDiff { get; } public WitnessVerkleProof? VerkleProof { get; } + public Hash256 ParentStateRoot { get; } + public ExecutionWitness() { - StateDiff = Array.Empty(); + StateDiff = []; VerkleProof = null; + ParentStateRoot = Keccak.EmptyTreeHash; } - public ExecutionWitness(StemStateDiff[] stateDiff, WitnessVerkleProof proof) + public ExecutionWitness(StemStateDiff[] stateDiff, WitnessVerkleProof proof, Hash256 parentStateRoot) { StateDiff = stateDiff; VerkleProof = proof; + ParentStateRoot = parentStateRoot; } } @@ -79,13 +84,28 @@ public struct StateDiff public List SuffixDiffs { get; set; } } -public struct StemStateDiff +public struct StemStateDiff : IEquatable { public Stem Stem { get; set; } public List SuffixDiffs { get; set; } + + public bool Equals(StemStateDiff other) + { + return Stem.Equals(other.Stem) && SuffixDiffs.SequenceEqual(other.SuffixDiffs); + } + + public override bool Equals(object? obj) + { + return obj is StemStateDiff other && Equals(other); + } + + public override int GetHashCode() + { + return HashCode.Combine(Stem, SuffixDiffs); + } } -public struct SuffixStateDiff +public struct SuffixStateDiff : IEquatable { public byte Suffix { get; set; } // add null if the values are not there - part of the spec @@ -93,4 +113,26 @@ public struct SuffixStateDiff public byte[]? CurrentValue { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public byte[]? NewValue { get; set; } + + public bool Equals(SuffixStateDiff other) + { + if (Suffix != other.Suffix) + return false; + + if (CurrentValue is null) + return other.CurrentValue is null; + + return other.CurrentValue is not null && + Extensions.Bytes.AreEqual(CurrentValue, other.CurrentValue); + } + + public override bool Equals(object? obj) + { + return obj is SuffixStateDiff other && Equals(other); + } + + public override int GetHashCode() + { + return HashCode.Combine(Suffix, CurrentValue); + } } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 869a493054f..6232934c21b 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -13,6 +13,7 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Crypto; +using Nethermind.Db; using Nethermind.Evm.CodeAnalysis; using Nethermind.Evm.Tracing; using Nethermind.Evm.Witness; @@ -21,6 +22,7 @@ using Nethermind.Specs; using Nethermind.State; using Nethermind.State.Tracing; +using Nethermind.Verkle.Tree.TreeStore; using static Nethermind.Core.Extensions.MemoryExtensions; using static Nethermind.Evm.VirtualMachine; @@ -144,7 +146,7 @@ protected virtual TransactionResult Execute(Transaction tx, in BlockExecutionCon long gasAvailable = tx.GasLimit - intrinsicGas; ExecuteEvmCall(tx, header, spec, tracer, opts, gasAvailable, env, out TransactionSubstate? substate, out long spentGas, out byte statusCode); - PayFees(tx, header, spec, tracer, substate, spentGas, premiumPerGas, statusCode); + PayFees(tx, header, spec, tracer, executionWitness, substate, spentGas, premiumPerGas, statusCode); // Finalize if (restore) @@ -472,13 +474,18 @@ protected void ExecuteEvmCall( { if (tx.IsContractCreation) { - if (!env.Witness.AccessForContractCreationInit(env.ExecutingAccount, ref unspentGas)) + if (!env.Witness.AccessForContractCreationCheck(env.ExecutingAccount, ref unspentGas)) { ThrowOutOfGasException(); } // if transaction is a contract creation then recipient address is the contract deployment address PrepareAccountForContractDeployment(env.ExecutingAccount, spec); + + if (!env.Witness.AccessForContractCreationInit(env.ExecutingAccount, ref unspentGas)) + { + ThrowOutOfGasException(); + } } ExecutionType executionType = tx.IsContractCreation ? ExecutionType.CREATE : ExecutionType.TRANSACTION; @@ -586,7 +593,7 @@ protected void ExecuteEvmCall( header.GasUsed += spentGas; } - protected virtual void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, in TransactionSubstate substate, in long spentGas, in UInt256 premiumPerGas, in byte statusCode) + protected virtual void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, IExecutionWitness executionWitness, in TransactionSubstate substate, in long spentGas, in UInt256 premiumPerGas, in byte statusCode) { if (!tx.IsSystem()) { @@ -596,7 +603,9 @@ protected virtual void PayFees(Transaction tx, BlockHeader header, IReleaseSpec UInt256 fees = (UInt256)spentGas * premiumPerGas; UInt256 burntFees = !tx.IsFree() ? (UInt256)spentGas * header.BaseFeePerGas : 0; - WorldState.AddToBalanceAndCreateIfNotExists(header.GasBeneficiary, fees, spec); + if (!fees.IsZero) executionWitness.AccessForGasBeneficiary(header.GasBeneficiary!); + + WorldState.AddToBalanceAndCreateIfNotExists(header.GasBeneficiary!, fees, spec); if (spec.IsEip1559Enabled && spec.Eip1559FeeCollector is not null && !burntFees.IsZero) WorldState.AddToBalanceAndCreateIfNotExists(spec.Eip1559FeeCollector, burntFees, spec); diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 29258e90996..689dec18807 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -75,7 +75,8 @@ public class VirtualMachine : IVirtualMachine public VirtualMachine( IBlockhashProvider? blockhashProvider, ISpecProvider? specProvider, - ILogManager? logManager) + ILogManager? logManager, + bool isStateless = false) { ILogger logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); if (!logger.IsTrace) @@ -86,6 +87,7 @@ public VirtualMachine( { _evm = new VirtualMachine(blockhashProvider, specProvider, logger); } + if (isStateless) CodeCache.Clear(); } public CodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, IReleaseSpec spec) @@ -634,7 +636,7 @@ private bool ChargeAccountAccessGas(ref long gasAvailable, EvmState vmState, Add case Instruction.DELEGATECALL: case Instruction.STATICCALL: { - if (!isAddressPreCompile) + if (!isAddressPreCompile && !isSystemContract) { var gasBefore = gasAvailable; result = vmState.Env.Witness.AccessAccountData(address, ref gasAvailable); @@ -817,8 +819,19 @@ private CallResult ExecuteCall(EvmState vmState, ReadOnlyM { if (!_state.AccountExists(env.ExecutingAccount)) { - // charge gas and add witness for proof of absence - if (!env.Witness.AccessForAbsentAccount(env.ExecutingAccount, ref gasAvailable)) goto OutOfGas; + // here we end up in two cases + // 1. trying to see if the tx.To is a contract and execute the contract + // 2. executing the *CALL opCode + // when we get here the first way, we already have a proof of absence as we access the entire account + // as proof of absence so nothing is do there technically in th first case + // when we get here in the second case, we just have to make a write touch to the codeHash if there is + // a value transfer because we end up creating the account. + if (!env.TransferValue.IsZero + && vmState.ExecutionType != ExecutionType.TRANSACTION + && !env.Witness.AccessCodeHash(env.ExecutingAccount, ref gasAvailable, isWrite: true)) + { + goto OutOfGas; + } _state.CreateAccount(env.ExecutingAccount, env.TransferValue); } else @@ -924,6 +937,7 @@ private CallResult ExecuteCode externalCode = GetCachedCodeInfo(_worldState, address, spec).MachineCode; int codeSizeToUse = (int)result; slice = externalCode.SliceWithZeroPadding(b, codeSizeToUse); @@ -1628,20 +1641,24 @@ private CallResult ExecuteCode= currentBlockNumber || - blockNumber + Eip2935Constants.RingBufferSize < currentBlockNumber) + blockNumber + Eip2935Constants.OpCodeServeWindow < currentBlockNumber) { return null; } var blockIndex = new UInt256((ulong)(blockNumber % Eip2935Constants.RingBufferSize)); Address? eip2935Account = spec.Eip2935ContractAddress ?? Eip2935Constants.BlockHashHistoryAddress; StorageCell blockHashStoreCell = new(eip2935Account, blockIndex); - vmState.Env.Witness.AccessForBlockHashOpCode(blockHashStoreCell.Address, - blockHashStoreCell.Index, - ref gasAvailable); + if (!vmState.Env.Witness.AccessForBlockHashOpCode(blockHashStoreCell.Address, + blockHashStoreCell.Index, + ref gasAvailable)) + { + outOfGas = true; + } ReadOnlySpan data = _worldState.Get(blockHashStoreCell); return data.SequenceEqual(emptyBytes) ? null : new Hash256(data); } @@ -1651,10 +1668,13 @@ private CallResult ExecuteCode long.MaxValue ? long.MaxValue : (long)a; + bool outForGas = false; Hash256 blockHash = spec.IsEip2935Enabled - ? GetBlockHashFromState(number, blkCtx.Header.Number) + ? GetBlockHashFromState(number, blkCtx.Header.Number, out outForGas) : _blockhashProvider.GetBlockhash(blkCtx.Header, number); + if (outForGas) goto OutOfGas; + stack.PushBytes(blockHash is not null ? blockHash.Bytes : BytesZero32); if (typeof(TLogger) == typeof(IsTracing)) @@ -1836,8 +1856,13 @@ private CallResult ExecuteCode jumpDest) + { + if (env.Witness.AccessForCodeProgramCounter(vmState.To, jumpDest, ref gasAvailable)) + goto OutOfGas; + } + goto InvalidJumpDestination; } break; @@ -1852,8 +1877,13 @@ private CallResult ExecuteCode jumpDest) + { + if (env.Witness.AccessForCodeProgramCounter(vmState.To, (int)result, ref gasAvailable)) + goto OutOfGas; + + } goto InvalidJumpDestination; } } @@ -2298,8 +2328,12 @@ private CallResult ExecuteCode jumpDestInt) + { + if (env.Witness.AccessForCodeProgramCounter(vmState.To, (int)jumpDest, ref gasAvailable)) + goto OutOfGas; + } goto InvalidJumpDestination; } programCounter++; @@ -2439,13 +2473,21 @@ private EvmExceptionType InstructionCall( // transfer is technically a noOp in case of callCode as the caller = target if (!transferValue.IsZero && instruction == Instruction.CALL) { + var gasBefore = gasAvailable; if (!vmState.Env.Witness.AccessForValueTransfer(caller, target, ref gasAvailable)) return EvmExceptionType.OutOfGas; + if (gasBefore == gasAvailable) + { + if (!UpdateGas(GasCostOf.WarmStateRead, ref gasAvailable)) return EvmExceptionType.OutOfGas; + } vmState.WarmUp(caller); vmState.WarmUp(target); } - if (!ChargeAccountAccessGas(ref gasAvailable, vmState, codeSource, spec, opCode: instruction)) return EvmExceptionType.OutOfGas; + if (transferValue.IsZero || instruction != Instruction.CALL) + { + if (!ChargeAccountAccessGas(ref gasAvailable, vmState, codeSource, spec, opCode: instruction)) return EvmExceptionType.OutOfGas; + } if (typeof(TLogger) == typeof(IsTracing)) { @@ -2613,7 +2655,9 @@ private EvmExceptionType InstructionSelfDestruct(EvmState vmState, ref // get the verkle witness cost and charge the account access gas if the verkle cost is zero var gasBefore = gasAvailable; if (!vmState.Env.Witness.AccessForSelfDestruct(executingAccount, inheritor, contractBalance.IsZero, - inheritorAccountExists, ref gasAvailable)) + inheritorAccountExists, + inheritor.IsPrecompile(spec) || inheritor.IsSystemContract(spec), + ref gasAvailable)) { return EvmExceptionType.OutOfGas; } @@ -2737,10 +2781,12 @@ private EvmExceptionType InstructionSelfDestruct(EvmState vmState, ref long callGas = spec.Use63Over64Rule ? gasAvailable - gasAvailable / 64L : gasAvailable; if (!UpdateGas(callGas, ref gasAvailable)) return (EvmExceptionType.OutOfGas, null); + _state.IncrementNonce(env.ExecutingAccount); + // for the collision check, we need on check the existence of the account and no need to write to it if (!env.Witness.AccessForContractCreationCheck(contractAddress, ref callGas)) { - return (EvmExceptionType.OutOfGas, null); + return (EvmExceptionType.None, null); } if (spec.UseHotAndColdStorage) @@ -2749,8 +2795,6 @@ private EvmExceptionType InstructionSelfDestruct(EvmState vmState, ref vmState.WarmUp(contractAddress); } - _state.IncrementNonce(env.ExecutingAccount); - Snapshot snapshot = _worldState.TakeSnapshot(); bool accountExists = _state.AccountExists(contractAddress); @@ -2764,18 +2808,21 @@ private EvmExceptionType InstructionSelfDestruct(EvmState vmState, ref return (EvmExceptionType.None, null); } - if (accountExists) - { - if (!spec.IsVerkleTreeEipEnabled) _state.UpdateStorageRoot(contractAddress, Keccak.EmptyTreeHash); - } - else if (_state.IsDeadAccount(contractAddress)) + if (!spec.IsVerkleTreeEipEnabled) { - if (!spec.IsVerkleTreeEipEnabled) _state.ClearStorage(contractAddress); + if (accountExists) + { + _state.UpdateStorageRoot(contractAddress, Keccak.EmptyTreeHash); + } + else if (_state.IsDeadAccount(contractAddress)) + { + _state.ClearStorage(contractAddress); + } } if (!env.Witness.AccessForContractCreationInit(contractAddress, ref callGas)) { - return (EvmExceptionType.OutOfGas, null); + return (EvmExceptionType.None, null); } _state.SubtractFromBalance(env.ExecutingAccount, value, spec); diff --git a/src/Nethermind/Nethermind.Evm/Witness/IExecutionWitness.cs b/src/Nethermind/Nethermind.Evm/Witness/IExecutionWitness.cs index 0b0910a6959..9e9a8e98e9d 100644 --- a/src/Nethermind/Nethermind.Evm/Witness/IExecutionWitness.cs +++ b/src/Nethermind/Nethermind.Evm/Witness/IExecutionWitness.cs @@ -32,7 +32,7 @@ public interface IExecutionWitness bool AccessAccountData(Address caller, ref long gasAvailable); bool AccessForBalanceOpCode(Address address, ref long gasAvailable); - bool AccessCodeHash(Address address, ref long gasAvailable); + bool AccessCodeHash(Address address, ref long gasAvailable, bool isWrite = false); /// /// When SLOAD and SSTORE opcodes are called with a given address @@ -64,7 +64,8 @@ public interface IExecutionWitness bool AccessAccountForWithdrawal(Address address); bool AccessForBlockhashInsertionWitness(Address address, UInt256 key); - bool AccessForSelfDestruct(Address contract, Address inheritor, bool balanceIsZero, bool inheritorExist, ref long gasAvailable); + bool AccessForSelfDestruct(Address contract, Address inheritor, bool balanceIsZero, bool inheritorExist, + bool isPrecompileOrSystemContract, ref long gasAvailable); Hash256[] GetAccessedKeys(); bool AccessForValueTransfer(Address from, Address to, ref long gasAvailable); diff --git a/src/Nethermind/Nethermind.Evm/Witness/NoExecWitness.cs b/src/Nethermind/Nethermind.Evm/Witness/NoExecWitness.cs index 994dc7d3538..2cb5c858eb4 100644 --- a/src/Nethermind/Nethermind.Evm/Witness/NoExecWitness.cs +++ b/src/Nethermind/Nethermind.Evm/Witness/NoExecWitness.cs @@ -24,7 +24,7 @@ public bool AccessForTransaction(Address originAddress, Address? destinationAddr public bool AccessForBalanceOpCode(Address address, ref long gasAvailable) => true; - public bool AccessCodeHash(Address address, ref long gasAvailable) => true; + public bool AccessCodeHash(Address address, ref long gasAvailable, bool isWrite = false) => true; public bool AccessForStorage(Address address, UInt256 key, bool isWrite, ref long gasAvailable) => true; public bool AccessForBlockHashOpCode(Address address, UInt256 key, ref long gasAvailable) => true; @@ -41,7 +41,7 @@ public bool AccessForCodeProgramCounter(Address address, int programCounter, ref public bool AccessAccountForWithdrawal(Address address) => true; public bool AccessForBlockhashInsertionWitness(Address address, UInt256 key) => true; public bool AccessForSelfDestruct(Address contract, Address inheritor, bool balanceIsZero, - bool inheritorExist, ref long gasAvailable) => true; + bool inheritorExist, bool isPrecompileOrSystemContract, ref long gasAvailable) => true; public Hash256[] GetAccessedKeys() => []; public bool AccessForValueTransfer(Address from, Address to, ref long gasAvailable) => true; public bool AccessForContractCreationCheck(Address contractAddress, ref long gasAvailable) => true; diff --git a/src/Nethermind/Nethermind.Evm/Witness/VerkleExecWitness.cs b/src/Nethermind/Nethermind.Evm/Witness/VerkleExecWitness.cs index 8ff62f755f6..48530aa23c3 100644 --- a/src/Nethermind/Nethermind.Evm/Witness/VerkleExecWitness.cs +++ b/src/Nethermind/Nethermind.Evm/Witness/VerkleExecWitness.cs @@ -52,10 +52,11 @@ public bool AccessAccountData(Address caller, ref long gasAvailable) /// /// /// + /// /// - public bool AccessCodeHash(Address address, ref long gasAvailable) + public bool AccessCodeHash(Address address, ref long gasAvailable, bool isWrite = false) { - return AccessCodeHash(address, ref gasAvailable); + return AccessCodeHash(address, ref gasAvailable, isWrite); } @@ -147,7 +148,7 @@ public bool AccessCodeChunk(Address address, UInt256 chunkId, bool isWrite, ref /// public bool AccessForAbsentAccount(Address address, ref long gasAvailable) { - return AccessCompleteAccount(address, ref gasAvailable); + return AccessCompleteAccount(address, ref gasAvailable, true); } /// @@ -156,9 +157,11 @@ public bool AccessForAbsentAccount(Address address, ref long gasAvailable) /// /// /// + /// /// /// public bool AccessForSelfDestruct(Address contract, Address inheritor, bool balanceIsZero, bool inheritorExist, + bool isPrecompileOrSystemContract, ref long gasAvailable) { // access the basic data for the contract calling the selfdestruct @@ -166,7 +169,7 @@ public bool AccessForSelfDestruct(Address contract, Address inheritor, bool bala // TODO: move precompile check to outside // if the inheritor is a pre-compile and there is no balance transfer, there is nothing else to do - if (inheritor.IsPrecompile(Osaka.Instance) && balanceIsZero) return true; + if (isPrecompileOrSystemContract && balanceIsZero) return true; // now if the contract and inheritor is not the same, then access the inheritor basic data // here this is charged because we need gas to check if the inheritor exists or not @@ -255,7 +258,6 @@ public bool AccessAccountForWithdrawal(Address address) public bool AccessForBlockhashInsertionWitness(Address address, UInt256 key) { long fakeGas = 1_000_000; - AccessCompleteAccount(address, ref fakeGas); AccessKey(AccountHeader.GetTreeKeyForStorageSlot(address.Bytes, key), ref fakeGas, true); return true; } @@ -275,7 +277,7 @@ public bool AccessForTransaction(Address originAddress, Address? destinationAddr if (destinationAddress is null) return true; return AccessBasicData(destinationAddress, ref fakeGas, isValueTransfer) && - AccessCodeHash(destinationAddress, ref fakeGas); + AccessCodeHash(destinationAddress, ref fakeGas, isValueTransfer); } /// @@ -363,19 +365,23 @@ private bool AccessKey(Hash256 key, ref long gasAvailable, bool isWr } if (requiredGas > gasAvailable) return false; - gasAvailable -= requiredGas; } - _accessedLeaves.Add(key); - _accessedSubtrees.Add(subTreeStem); - - if (!isWrite) return true; + if (!isWrite) + { + if (TGasCharge.ChargeGas) + { + gasAvailable -= requiredGas; + } + _accessedLeaves.Add(key); + _accessedSubtrees.Add(subTreeStem); + return true; + } // write check if (TGasCharge.ChargeGas) { - requiredGas = 0; // if `wasPreviouslyNotAccessed = true`, this implies that _modifiedLeaves.Contains(key) = false if (wasPreviouslyNotAccessed || !_modifiedLeaves.Contains(key)) { @@ -392,6 +398,8 @@ private bool AccessKey(Hash256 key, ref long gasAvailable, bool isWr gasAvailable -= requiredGas; } + _accessedLeaves.Add(key); + _accessedSubtrees.Add(subTreeStem); _modifiedLeaves.Add(key); _modifiedSubtrees.Add(subTreeStem); diff --git a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuraWithdrawalProcessorTests.cs b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuraWithdrawalProcessorTests.cs index d372fbe7c00..d932d537828 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuraWithdrawalProcessorTests.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuraWithdrawalProcessorTests.cs @@ -12,6 +12,7 @@ using Nethermind.Logging; using Nethermind.Merge.AuRa.Contracts; using Nethermind.Merge.AuRa.Withdrawals; +using Nethermind.State; using NSubstitute; using NUnit.Framework; @@ -51,7 +52,7 @@ public void Should_invoke_contract_as_expected() Arg.Do>(a => values = a.ToArray()), Arg.Do>(a => addresses = a.ToArray())); - withdrawalProcessor.ProcessWithdrawals(block, NullBlockTracer.Instance, spec); + withdrawalProcessor.ProcessWithdrawals(block, NullBlockTracer.Instance, spec, Substitute.For()); contract .Received(1) @@ -73,7 +74,7 @@ public void Should_not_invoke_contract_before_Shanghai() spec.WithdrawalsEnabled.Returns(false); - withdrawalProcessor.ProcessWithdrawals(block, NullBlockTracer.Instance, spec); + withdrawalProcessor.ProcessWithdrawals(block, NullBlockTracer.Instance, spec, Substitute.For()); contract .Received(0) diff --git a/src/Nethermind/Nethermind.Merge.AuRa/Withdrawals/AuraWithdrawalProcessor.cs b/src/Nethermind/Nethermind.Merge.AuRa/Withdrawals/AuraWithdrawalProcessor.cs index 4930de5ba19..bc854de2e12 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/Withdrawals/AuraWithdrawalProcessor.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/Withdrawals/AuraWithdrawalProcessor.cs @@ -13,6 +13,7 @@ using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Merge.AuRa.Contracts; +using Nethermind.State; namespace Nethermind.Merge.AuRa.Withdrawals; @@ -30,7 +31,7 @@ public AuraWithdrawalProcessor(IWithdrawalContract contract, ILogManager logMana _logger = logManager.GetClassLogger(); } - public void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSpec spec) + public void ProcessWithdrawals(Block block, IBlockTracer blockTracer, IReleaseSpec spec, IWorldState worldState) { if (!spec.WithdrawalsEnabled || block.Withdrawals is null) // The second check seems redundant return; diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.HelperFunctions.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.HelperFunctions.cs index 42b905dedc4..dbd5c21f3a1 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.HelperFunctions.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.HelperFunctions.cs @@ -96,7 +96,7 @@ private static ExecutionPayload CreateBlockRequest(MergeTestBlockchain chain, Ex blockRequest.TryGetBlock(out Block? block); Snapshot before = chain.State.TakeSnapshot(); - chain.WithdrawalProcessor?.ProcessWithdrawals(block!, new BlockReceiptsTracer(), chain.SpecProvider.GenesisSpec); + chain.WithdrawalProcessor?.ProcessWithdrawals(block!, new BlockReceiptsTracer(), chain.SpecProvider.GenesisSpec, chain.State); chain.State.Commit(chain.SpecProvider.GenesisSpec); chain.State.RecalculateStateRoot(); @@ -116,7 +116,7 @@ private static ExecutionPayloadV3 CreateBlockRequestV3(MergeTestBlockchain chain Snapshot before = chain.State.TakeSnapshot(); _beaconBlockRootHandler.ApplyContractStateChanges(block!, chain.SpecProvider.GenesisSpec, chain.State); - chain.WithdrawalProcessor?.ProcessWithdrawals(block!, new BlockReceiptsTracer(), chain.SpecProvider.GenesisSpec); + chain.WithdrawalProcessor?.ProcessWithdrawals(block!, new BlockReceiptsTracer(), chain.SpecProvider.GenesisSpec, chain.State); chain.State.Commit(chain.SpecProvider.GenesisSpec); chain.State.RecalculateStateRoot(); diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs index 422b8d38111..3539d442d0b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs @@ -242,7 +242,7 @@ protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolT protected override IBlockProcessor CreateBlockProcessor() { BlockValidator = CreateBlockValidator(); - WithdrawalProcessor = new WithdrawalProcessor(State, LogManager); + WithdrawalProcessor = new WithdrawalProcessor(LogManager); IBlockProcessor processor = new BlockProcessor( SpecProvider, BlockValidator, @@ -295,7 +295,7 @@ public class MergeTestStatelessBlockchain( protected override IBlockProcessor CreateBlockProcessor() { BlockValidator = CreateBlockValidator(); - WithdrawalProcessor = new WithdrawalProcessor(State, LogManager); + WithdrawalProcessor = new WithdrawalProcessor(LogManager); IBlockProcessor processor = new StatelessBlockProcessor( SpecProvider, BlockValidator, diff --git a/src/Nethermind/Nethermind.Network/P2P/P2PMessageKey.cs b/src/Nethermind/Nethermind.Network/P2P/P2PMessageKey.cs index 8f4e62c8c57..17bcacfb843 100644 --- a/src/Nethermind/Nethermind.Network/P2P/P2PMessageKey.cs +++ b/src/Nethermind/Nethermind.Network/P2P/P2PMessageKey.cs @@ -59,7 +59,7 @@ private string GetMessageType() if (!MessageNames.TryGetValue((Protocol.Protocol, PacketType), out string messageName)) { #if DEBUG - throw new NotImplementedException($"Message name for protocol {Protocol.Protocol} message id {PacketType} not set."); + throw new NotImplementedException($"Message name for protocol {Protocol.Protocol} message id {PacketType} not set."); #else return PacketType.ToString(); // Just use the integer directly then #endif diff --git a/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs b/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs index cbccf1f919b..47c353efe33 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismBlockProducerEnvFactory.cs @@ -92,6 +92,6 @@ protected override BlockProcessor CreateBlockProcessor( logManager, _specHelper, new Create2DeployerContractRewriter(_specHelper, _specProvider, _blockTree), - new BlockProductionWithdrawalProcessor(new WithdrawalProcessor(readOnlyTxProcessingEnv.StateProvider, logManager))); + new BlockProductionWithdrawalProcessor(new WithdrawalProcessor(logManager))); } } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs index 4322fa58f32..f10f76de87e 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs @@ -7,6 +7,7 @@ using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; +using Nethermind.Evm.Witness; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.State; @@ -150,13 +151,13 @@ protected override TransactionResult IncrementNonce(Transaction tx, BlockHeader protected override TransactionResult ValidateSender(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts) => tx.IsDeposit() ? TransactionResult.Ok : base.ValidateSender(tx, header, spec, tracer, opts); - protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, + protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, IExecutionWitness execWitness, in TransactionSubstate substate, in long spentGas, in UInt256 premiumPerGas, in byte statusCode) { if (!tx.IsDeposit()) { // Skip coinbase payments for deposit tx in Regolith - base.PayFees(tx, header, spec, tracer, substate, spentGas, premiumPerGas, statusCode); + base.PayFees(tx, header, spec, tracer, execWitness, substate, spentGas, premiumPerGas, statusCode); if (_opConfigHelper.IsBedrock(header)) { diff --git a/src/Nethermind/Nethermind.Serialization.Json/ExecutionWitnessConverter.cs b/src/Nethermind/Nethermind.Serialization.Json/ExecutionWitnessConverter.cs index 775077d661c..15ef6b8bc19 100644 --- a/src/Nethermind/Nethermind.Serialization.Json/ExecutionWitnessConverter.cs +++ b/src/Nethermind/Nethermind.Serialization.Json/ExecutionWitnessConverter.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using System.Text.Json; +using Nethermind.Core.Crypto; using Nethermind.Core.Verkle; namespace Nethermind.Serialization.Json; @@ -19,7 +20,10 @@ public override ExecutionWitness Read(ref Utf8JsonReader reader, Type typeToConv reader.Read(); WitnessVerkleProof proof = JsonSerializer.Deserialize(ref reader, options); reader.Read(); - return new ExecutionWitness(stateDiff, proof); + reader.Read(); + Hash256 parentStateRoot = JsonSerializer.Deserialize(ref reader, options); + reader.Read(); + return new ExecutionWitness(stateDiff, proof, parentStateRoot); } public override void Write(Utf8JsonWriter writer, ExecutionWitness value, JsonSerializerOptions options) diff --git a/src/Nethermind/Nethermind.State.Test/VerkleTreeTests.cs b/src/Nethermind/Nethermind.State.Test/VerkleTreeTests.cs index f4220b58105..606d4c22213 100644 --- a/src/Nethermind/Nethermind.State.Test/VerkleTreeTests.cs +++ b/src/Nethermind/Nethermind.State.Test/VerkleTreeTests.cs @@ -148,7 +148,7 @@ public void TestHiveState() Console.WriteLine(worldState.StateRoot); VerkleStateTree tree = new VerkleStateTree(store, LimboLogs.Instance); - tree.Set(address1, new Account(1,0,Keccak.EmptyTreeHash, new Hash256("0xdf61faef43babbb1ebde8fd82ab9cb4cb74c240d0025138521477e073f72080a"))); + tree.Set(address1, new Account(1, 0, Keccak.EmptyTreeHash, new Hash256("0xdf61faef43babbb1ebde8fd82ab9cb4cb74c240d0025138521477e073f72080a"))); tree.Commit(); Console.WriteLine(tree.StateRoot); } diff --git a/src/Nethermind/Nethermind.State.Test/VerkleWitnessAccessCostTest.cs b/src/Nethermind/Nethermind.State.Test/VerkleWitnessAccessCostTest.cs index 5adae864e70..19f4f5d0ea4 100644 --- a/src/Nethermind/Nethermind.State.Test/VerkleWitnessAccessCostTest.cs +++ b/src/Nethermind/Nethermind.State.Test/VerkleWitnessAccessCostTest.cs @@ -335,7 +335,7 @@ public void TestAccessForSelfDestruct() + GasCostOf.WitnessBranchWrite * 2 + GasCostOf.WitnessChunkFill * 2; - bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressB, false, false, ref expectedGas); + bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressB, false, false, false, ref expectedGas); Assert.True(result); Assert.That(expectedGas, Is.EqualTo(0)); @@ -349,7 +349,7 @@ public void TestAccessForSelfDestructWithBalanceZero() long expectedGas = GasCostOf.WitnessChunkRead + GasCostOf.WitnessBranchRead; - bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressB, true, false, ref expectedGas); + bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressB, true, false, false, ref expectedGas); Assert.True(result); Assert.That(expectedGas, Is.EqualTo(0)); @@ -366,7 +366,7 @@ public void TestAccessForSelfDestructWithInheritorExist() + GasCostOf.WitnessBranchWrite * 2 + GasCostOf.WitnessChunkFill * 2; - bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressB, false, true, ref expectedGas); + bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressB, false, true, false, ref expectedGas); Assert.True(result); Assert.That(expectedGas, Is.EqualTo(0)); @@ -380,7 +380,7 @@ public void TestAccessForSelfDestructWithBalanceZeroAndInheritorExist() long expectedGas = GasCostOf.WitnessChunkRead + GasCostOf.WitnessBranchRead; - bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressB, true, true, ref expectedGas); + bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressB, true, true, false, ref expectedGas); Assert.True(result); Assert.That(expectedGas, Is.EqualTo(0)); @@ -397,7 +397,7 @@ public void TestAccessForSelfDestructWithEqualAddresses() + GasCostOf.WitnessBranchWrite * 1 + GasCostOf.WitnessChunkFill * 1; - bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressA, false, false, ref expectedGas); + bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressA, false, false, false, ref expectedGas); Assert.True(result); Assert.That(expectedGas, Is.EqualTo(0)); @@ -411,7 +411,7 @@ public void TestAccessForSelfDestructWithEqualAddressesAndBalanceZero() long expectedGas = GasCostOf.WitnessChunkRead * 1 + GasCostOf.WitnessBranchRead * 1; - bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressA, true, false, ref expectedGas); + bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressA, true, false, false, ref expectedGas); Assert.True(result); Assert.That(expectedGas, Is.EqualTo(0)); @@ -428,7 +428,7 @@ public void TestAccessForSelfDestructWithEqualAddressesAndInheritorExist() + GasCostOf.WitnessBranchWrite * 1 + GasCostOf.WitnessChunkFill * 1; - bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressA, false, true, ref expectedGas); + bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressA, false, true, false, ref expectedGas); Assert.True(result); Assert.That(expectedGas, Is.EqualTo(0)); @@ -442,7 +442,7 @@ public void TestAccessForSelfDestructWithEqualAddressesAndBalanceZeroAndInherito long expectedGas = GasCostOf.WitnessChunkRead * 1 + GasCostOf.WitnessBranchRead * 1; - bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressA, true, true, ref expectedGas); + bool result = witness.AccessForSelfDestruct(TestItem.AddressA, TestItem.AddressA, true, true, false, ref expectedGas); Assert.True(result); Assert.That(expectedGas, Is.EqualTo(0)); diff --git a/src/Nethermind/Nethermind.State/StatelessVerkleWorldState.cs b/src/Nethermind/Nethermind.State/StatelessVerkleWorldState.cs new file mode 100644 index 00000000000..c67bf4a3c70 --- /dev/null +++ b/src/Nethermind/Nethermind.State/StatelessVerkleWorldState.cs @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Collections.Frozen; +using System.Collections.Generic; +using Nethermind.Core; +using Nethermind.Core.Verkle; +using Nethermind.Db; +using Nethermind.Logging; +using Nethermind.Verkle.Curve; +using Nethermind.Verkle.Tree.TreeStore; + +namespace Nethermind.State; + +public class StatelessVerkleWorldState( + FrozenDictionary? systemAccounts, + IKeyValueStore? codeDb, + ILogManager logManager) + : VerkleWorldState(new VerkleStateTree(new NullVerkleTreeStore(), logManager), codeDb, logManager) +{ + protected override Account? GetAndAddToCache(Address address) + { + if (systemAccounts is null || !systemAccounts.TryGetValue(address, out Account? account)) + { + account = base.GetAndAddToCache(address); + } + + return account; + } +} diff --git a/src/Nethermind/Nethermind.State/VerklePersistentStorageProvider.cs b/src/Nethermind/Nethermind.State/VerklePersistentStorageProvider.cs index 49d717fa97d..caa6c5425bb 100644 --- a/src/Nethermind/Nethermind.State/VerklePersistentStorageProvider.cs +++ b/src/Nethermind/Nethermind.State/VerklePersistentStorageProvider.cs @@ -156,7 +156,14 @@ protected override void CommitCore(IStorageTracer tracer) } Db.Metrics.StorageTreeWrites++; - if (!_selfDestructAddress.Contains(change.StorageCell.Address)) toSet[change.StorageCell] = change.Value; + if (!_selfDestructAddress.Contains(change.StorageCell.Address)) + { + if (change.Value.IsZero() && _originalValues[change.StorageCell].IsZero()) + { + return; + } + toSet[change.StorageCell] = change.Value; + } if (isTracing) { diff --git a/src/Nethermind/Nethermind.State/VerkleStateTree.cs b/src/Nethermind/Nethermind.State/VerkleStateTree.cs index 730cd0b7674..ae953fe7e3a 100644 --- a/src/Nethermind/Nethermind.State/VerkleStateTree.cs +++ b/src/Nethermind/Nethermind.State/VerkleStateTree.cs @@ -30,13 +30,14 @@ public class VerkleStateTree(IVerkleTreeStore stateStore, ILogManager logManager byte[] headerTreeKey = AccountHeader.GetTreeKeyPrefix(address.Bytes, 0); headerTreeKey[31] = AccountHeader.BasicDataLeafKey; byte[]? basicDataLeafVal = Get(headerTreeKey); - if (basicDataLeafVal is null) return null; + // if (basicDataLeafVal is null) return null; headerTreeKey[31] = AccountHeader.CodeHash; - var codeHashBytes = Get(headerTreeKey); + byte[]? codeHashBytes = Get(headerTreeKey); Hash256 codeHash = codeHashBytes is null ? Keccak.EmptyTreeHash : new Hash256(codeHashBytes); + if (basicDataLeafVal is null && codeHashBytes is null) return null; - return AccountHeader.BasicDataToAccount(basicDataLeafVal, codeHash); + return AccountHeader.BasicDataToAccount(basicDataLeafVal ?? new byte[32], codeHash); } public bool TryGetStruct(Address address, out AccountStruct account, Hash256? rootHash = null) @@ -119,7 +120,7 @@ public void SetStorage(StorageCell cell, byte[] value) public void BulkSet(IDictionary values) { // Put the sets into a list to be sorted - using ArrayPoolList> theList = new ArrayPoolList>(values.Count, values); + using var theList = new ArrayPoolList>(values.Count, values); // Sort by address and index. theList.AsSpan().Sort((kv1, kv2) => @@ -128,7 +129,7 @@ public void BulkSet(IDictionary values) return addressCompare != 0 ? addressCompare : kv1.Key.Index.CompareTo(kv2.Key.Index); }); - ActionBlock<(Hash256, Dictionary)> insertStem = + var insertStem = new ActionBlock<(Hash256, Dictionary)>((item) => { InsertStemBatch(item.Item1.Bytes[..31], item.Item2.Select(kv => (kv.Key, kv.Value))); @@ -139,7 +140,7 @@ public void BulkSet(IDictionary values) }); Hash256 currentStem = Hash256.Zero; - Dictionary stemValues = new Dictionary(); + var stemValues = new Dictionary(); foreach (KeyValuePair kv in theList) { // Because of the way the mapping works diff --git a/src/Nethermind/Nethermind.State/VerkleWorldState.cs b/src/Nethermind/Nethermind.State/VerkleWorldState.cs index 5fa9b195119..17dee2007b3 100644 --- a/src/Nethermind/Nethermind.State/VerkleWorldState.cs +++ b/src/Nethermind/Nethermind.State/VerkleWorldState.cs @@ -33,18 +33,18 @@ public class VerkleWorldState : IWorldState public StateType StateType => StateType.Verkle; private const int StartCapacity = Resettable.StartCapacity; - protected readonly ResettableDictionary> _intraBlockCache = new ResettableDictionary>(); - private readonly ResettableHashSet
_committedThisRound = new ResettableHashSet
(); + protected readonly ResettableDictionary> IntraBlockCache = new(); + private readonly ResettableHashSet
_committedThisRound = []; - private readonly List _keptInCache = new List(); + private readonly List _keptInCache = []; private readonly ILogger _logger; - protected readonly IKeyValueStore _codeDb; + protected readonly IKeyValueStore CodeDb; private int _capacity = StartCapacity; - protected Change?[] _changes = new Change?[StartCapacity]; + protected Change?[] Changes = new Change?[StartCapacity]; private int _currentPosition = Resettable.EmptyPosition; - protected readonly VerkleStateTree _tree; + public readonly VerkleStateTree Tree; private readonly VerkleStorageProvider _storageProvider; // Only guarding against hot duplicates so filter doesn't need to be too big @@ -56,15 +56,15 @@ public class VerkleWorldState : IWorldState public VerkleWorldState(VerkleStateTree verkleTree, IKeyValueStore? codeDb, ILogManager? logManager) { _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - _codeDb = codeDb ?? throw new ArgumentNullException(nameof(codeDb)); - _tree = verkleTree; + CodeDb = codeDb ?? throw new ArgumentNullException(nameof(codeDb)); + Tree = verkleTree; _storageProvider = new VerkleStorageProvider(verkleTree, logManager); } public void InsertExecutionWitness(ExecutionWitness? executionWitness, Banderwagon root) { - _tree.Reset(); - if (!_tree.InsertIntoStatelessTree(executionWitness, root)) + Tree.Reset(); + if (!Tree.InsertIntoStatelessTree(executionWitness, root)) { throw new InvalidDataException("stateless tree cannot be created: invalid proof"); } @@ -73,31 +73,31 @@ public void InsertExecutionWitness(ExecutionWitness? executionWitness, Banderwag internal VerkleWorldState(VerklePersistentStorageProvider storageProvider, VerkleStateTree verkleTree, IKeyValueStore? codeDb, ILogManager? logManager) { _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - _codeDb = codeDb ?? throw new ArgumentNullException(nameof(codeDb)); - _tree = verkleTree; + CodeDb = codeDb ?? throw new ArgumentNullException(nameof(codeDb)); + Tree = verkleTree; _storageProvider = new VerkleStorageProvider(storageProvider, new VerkleTransientStorageProvider(logManager)); } public VerkleWorldState(IVerkleTreeStore verkleStateStore, IKeyValueStore? codeDb, ILogManager? logManager) { _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - _codeDb = codeDb ?? throw new ArgumentNullException(nameof(codeDb)); - _tree = new VerkleStateTree(verkleStateStore, logManager); - _storageProvider = new VerkleStorageProvider(_tree, logManager); + CodeDb = codeDb ?? throw new ArgumentNullException(nameof(codeDb)); + Tree = new VerkleStateTree(verkleStateStore, logManager); + _storageProvider = new VerkleStorageProvider(Tree, logManager); } // create a state provider using execution witness public VerkleWorldState(ExecutionWitness? executionWitness, Banderwagon root, ILogManager? logManager) { _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); - _tree = VerkleStateTree.CreateStatelessTreeFromExecutionWitness(executionWitness, root, logManager); - _codeDb = new MemDb(); - _storageProvider = new VerkleStorageProvider(_tree, logManager); + Tree = VerkleStateTree.CreateStatelessTreeFromExecutionWitness(executionWitness, root, logManager); + CodeDb = new MemDb(); + _storageProvider = new VerkleStorageProvider(Tree, logManager); } public bool ValuePresentInTree(Hash256 key) { - return _tree.HasLeaf(key); + return Tree.HasLeaf(key); } public bool IsContract(Address address) @@ -116,7 +116,7 @@ public void Accept(ITreeVisitor? visitor, Hash256? stateRoot, VisitingOptions? v ArgumentNullException.ThrowIfNull(visitor); ArgumentNullException.ThrowIfNull(stateRoot); - _tree.Accept(visitor, stateRoot, visitingOptions); + Tree.Accept(visitor, stateRoot, visitingOptions); } public void RecalculateStateRoot() @@ -127,25 +127,25 @@ public void RecalculateStateRoot() public Hash256 StateRoot { - get => _tree.StateRoot; - set => _tree.StateRoot = value; + get => Tree.StateRoot; + set => Tree.StateRoot = value; } public ExecutionWitness GenerateExecutionWitness(Hash256[] keys, out Banderwagon rootPoint) { - return _tree.GenerateExecutionWitnessFromStore(keys, out rootPoint); + return Tree.GenerateExecutionWitnessFromStore(keys, out rootPoint); } public void UpdateWithPostStateValues(ExecutionWitness executionWitness) { - _tree.UpdateWithPostStateValues(executionWitness); + Tree.UpdateWithPostStateValues(executionWitness); } public bool AccountExists(Address address) { - if (_intraBlockCache.TryGetValue(address, out Stack? value)) + if (IntraBlockCache.TryGetValue(address, out Stack? value)) { - return _changes[value.Peek()]!.ChangeType != ChangeType.Delete; + return Changes[value.Peek()]!.ChangeType != ChangeType.Delete; } return GetAndAddToCache(address) is not null; @@ -162,7 +162,7 @@ public bool IsEmptyAccount(Address address) return account.IsEmpty; } - public bool HasStateForRoot(Hash256 stateRoot) => _tree.HasStateForStateRoot(stateRoot); + public bool HasStateForRoot(Hash256 stateRoot) => Tree.HasStateForStateRoot(stateRoot); public Account GetAccount(Address address) { @@ -211,19 +211,19 @@ public void InsertCode(Address address, Hash256 codeHash, ReadOnlyMemory c // or people copy and pasting popular contracts if (!_codeInsertFilter.Get(codeHash)) { - if (!_codeDb.PreferWriteByArray) + if (!CodeDb.PreferWriteByArray) { - _codeDb.PutSpan(codeHash.Bytes, code.Span); + CodeDb.PutSpan(codeHash.Bytes, code.Span); } else if (MemoryMarshal.TryGetArray(code, out ArraySegment codeArray) && codeArray.Offset == 0 && codeArray.Count == code.Length) { - _codeDb[codeHash.Bytes] = codeArray.Array; + CodeDb[codeHash.Bytes] = codeArray.Array; } else { - _codeDb[codeHash.Bytes] = code.ToArray(); + CodeDb[codeHash.Bytes] = code.ToArray(); } _codeInsertFilter.Set(codeHash); @@ -238,7 +238,7 @@ public void InsertCode(Address address, Hash256 codeHash, ReadOnlyMemory c if (account.CodeHash != codeHash) { if (_logger.IsDebug) _logger.Debug($" Update {address} C {account.CodeHash} -> {codeHash}"); - Account changedAccount = account.WithChangedCodeHash(codeHash, _codeDb[codeHash.Bytes]); + Account changedAccount = account.WithChangedCodeHash(codeHash, CodeDb[codeHash.Bytes]); PushUpdate(address, changedAccount); } else if (releaseSpec.IsEip158Enabled && !isGenesis) @@ -345,7 +345,7 @@ public void DecrementNonce(Address address) public void TouchCode(in ValueHash256 codeHash) { - if (_codeDb is WitnessingStore witnessingStore) + if (CodeDb is WitnessingStore witnessingStore) { witnessingStore.Touch(codeHash.Bytes); } @@ -359,7 +359,7 @@ public ValueHash256 GetCodeHash(Address address) public byte[] GetCode(Hash256 codeHash) { - byte[]? code = codeHash == Keccak.OfAnEmptyString ? Array.Empty() : _codeDb[codeHash.Bytes]; + byte[]? code = codeHash == Keccak.OfAnEmptyString ? Array.Empty() : CodeDb[codeHash.Bytes]; if (code is null) { throw new InvalidOperationException($"Code {codeHash} is missing from the database."); @@ -368,17 +368,11 @@ public byte[] GetCode(Hash256 codeHash) return code; } - public byte[] GetCode(ValueHash256 codeHash) + public byte[]? GetCode(ValueHash256 codeHash) { - byte[]? code = codeHash == Keccak.OfAnEmptyString ? Array.Empty() : _codeDb[codeHash.Bytes]; - if (code is null) - { - if (codeHash == Keccak.Zero) code = Array.Empty(); - else - throw new InvalidOperationException($"Code {codeHash} is missing from the database."); - } - - return code; + byte[]? code = codeHash == Keccak.OfAnEmptyString ? Array.Empty() : CodeDb[codeHash.Bytes]; + if (code is not null) return code; + return codeHash == Keccak.Zero ? Array.Empty() : null; } public virtual byte[] GetCodeChunk(Address codeOwner, UInt256 codeChunk) @@ -386,7 +380,7 @@ public virtual byte[] GetCodeChunk(Address codeOwner, UInt256 codeChunk) // TODO: add functionality to add and get from cache instead - because there can be case // where the code was updated while executing Hash256? treeKey = AccountHeader.GetTreeKeyForCodeChunk(codeOwner.Bytes, codeChunk); - byte[]? chunk = _tree.Get(treeKey); + byte[]? chunk = Tree.Get(treeKey); if (chunk is null) { throw new InvalidOperationException($"Code Chunk {chunk} is missing from the database."); @@ -411,12 +405,12 @@ public ReadOnlyMemory GetCodeFromCodeChunksForStatelessProcessing(Address for (int i = 0; i < endChunkId; i++) { Hash256? treeKey = AccountHeader.GetTreeKeyForCodeChunk(owner.Bytes, (UInt256)i); - byte[]? chunk = _tree.Get(treeKey); + byte[]? chunk = Tree.Get(treeKey); chunk?[1..].CopyTo(codeSliceSpan); codeSliceSpan = codeSliceSpan[31..]; } Hash256? treeKeyEndChunk = AccountHeader.GetTreeKeyForCodeChunk(owner.Bytes, (UInt256)endChunkId); - byte[]? endChunk = _tree.Get(treeKeyEndChunk); + byte[]? endChunk = Tree.Get(treeKeyEndChunk); endChunk?[1..(endChunkLoc + 1)].CopyTo(codeSliceSpan); return codeSlice; } @@ -513,12 +507,12 @@ private void ReportChanges(IStateTracer stateTracer, Dictionary() - : _codeDb[beforeCodeHash.Bytes]; + : CodeDb[beforeCodeHash.Bytes]; byte[]? afterCode = afterCodeHash is null ? null : afterCodeHash == Keccak.OfAnEmptyString ? Array.Empty() - : _codeDb[afterCodeHash.Bytes]; + : CodeDb[afterCodeHash.Bytes]; if (!((beforeCode?.Length ?? 0) == 0 && (afterCode?.Length ?? 0) == 0)) { @@ -550,34 +544,34 @@ private void ReportChanges(IStateTracer stateTracer, Dictionary accountChange) + protected void BulkSet(Dictionary accountChange) { - void SetStateKV(KeyValuePair keyValuePair) + void SetStateKeyValue(KeyValuePair keyValuePair) { - SetState(keyValuePair.Key, keyValuePair.Value); + SetState(keyValuePair.Key, keyValuePair.Value.Item1, keyValuePair.Value.Item2); } if (accountChange.Count == 1) { - foreach (KeyValuePair keyValuePair in accountChange) + foreach (KeyValuePair keyValuePair in accountChange) { - SetStateKV(keyValuePair); + SetStateKeyValue(keyValuePair); } return; } - ActionBlock> setStateAction = new ActionBlock>( - SetStateKV, + var setStateAction = new ActionBlock>( + SetStateKeyValue, new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }); - foreach (KeyValuePair keyValuePair in accountChange) + foreach (KeyValuePair keyValuePair in accountChange) { setStateAction.Post(keyValuePair); } @@ -586,16 +580,25 @@ void SetStateKV(KeyValuePair keyValuePair) setStateAction.Completion.Wait(); } - protected void SetState(Address address, Account? account) + protected void SetState(Address address, Account account, bool isNew) { Db.Metrics.StateTreeWrites++; byte[] headerTreeKey = AccountHeader.GetTreeKeyPrefix(address.Bytes, 0); // TODO: is there a case where account is even null - anyways deleting a account is not supported in verkle trees - if (account != null) _tree.InsertStemBatch(headerTreeKey.AsSpan()[..31], account.ToVerkleDict()); - else throw new StateException.StateDeleteNotSupported(); - if (account!.Code is not null) _tree.SetCode(address, account.Code); + + LeafInSubTree[]? data = account.ToVerkleDict(); + if (isNew) + { + Tree.InsertStemBatch(headerTreeKey.AsSpan()[..31], data); + if (account!.Code is not null) Tree.SetCode(address, account.Code); + } + else + { + if (account.CodeHash == Keccak.EmptyTreeHash) data = [data[0]]; + Tree.InsertStemBatch(headerTreeKey.AsSpan()[..31], data); + } } protected readonly HashSet
_nullAccountReads = []; @@ -620,9 +623,9 @@ protected void SetState(Address address, Account? account) private Account? GetThroughCache(Address address) { - if (_intraBlockCache.TryGetValue(address, out Stack? value)) + if (IntraBlockCache.TryGetValue(address, out Stack? value)) { - return _changes[value!.Peek()]!.Account; + return Changes[value!.Peek()]!.Account; } Account account = GetAndAddToCache(address); @@ -654,14 +657,14 @@ private void Push(ChangeType changeType, Address address, Account? touchedAccoun { Stack stack = SetupCache(address); if (changeType == ChangeType.Touch - && _changes[stack.Peek()]!.ChangeType == ChangeType.Touch) + && Changes[stack.Peek()]!.ChangeType == ChangeType.Touch) { return; } if (changeType == ChangeType.Delete) { - if (!(stack.Count > 0 && _changes[stack.Peek()]?.ChangeType == ChangeType.New)) + if (!(stack.Count > 0 && Changes[stack.Peek()]?.ChangeType == ChangeType.New)) { throw new StateException.StateDeleteNotSupported( "Account can only be deleted when it was created in the same transaction"); @@ -672,7 +675,7 @@ private void Push(ChangeType changeType, Address address, Account? touchedAccoun { // this is to make sure that ChangeType for new account stays ChangeType.New so that we can handle Eip158 properly // for new account - we dont save Empty accounts, but for old accounts we can save empty accounts - if (stack.Count > 0 && _changes[stack.Peek()]?.ChangeType == ChangeType.New) + if (stack.Count > 0 && Changes[stack.Peek()]?.ChangeType == ChangeType.New) { changeType = ChangeType.New; } @@ -680,7 +683,7 @@ private void Push(ChangeType changeType, Address address, Account? touchedAccoun IncrementChangePosition(); stack.Push(_currentPosition); - _changes[_currentPosition] = new Change(changeType, address, touchedAccount); + Changes[_currentPosition] = new Change(changeType, address, touchedAccount); } private void PushNew(Address address, Account account) @@ -688,17 +691,17 @@ private void PushNew(Address address, Account account) Stack stack = SetupCache(address); IncrementChangePosition(); stack.Push(_currentPosition); - _changes[_currentPosition] = new Change(ChangeType.New, address, account); + Changes[_currentPosition] = new Change(ChangeType.New, address, account); } private void IncrementChangePosition() { - Resettable.IncrementPosition(ref _changes, ref _capacity, ref _currentPosition); + Resettable.IncrementPosition(ref Changes, ref _capacity, ref _currentPosition); } private Stack SetupCache(Address address) { - ref Stack? value = ref _intraBlockCache.GetValueRefOrAddDefault(address, out bool exists); + ref Stack? value = ref IntraBlockCache.GetValueRefOrAddDefault(address, out bool exists); if (!exists) { value = new Stack(); @@ -730,19 +733,19 @@ public void SetTransientState(in StorageCell storageCell, byte[] newValue) public void Reset() { if (_logger.IsTrace) _logger.Trace("Clearing state provider caches"); - _tree.Reset(); - _intraBlockCache.Reset(); + Tree.Reset(); + IntraBlockCache.Reset(); _committedThisRound.Reset(); _nullAccountReads.Clear(); _currentPosition = Resettable.EmptyPosition; - Array.Clear(_changes, 0, _changes.Length); + Array.Clear(Changes, 0, Changes.Length); _storageProvider.Reset(); } public void CommitTree(long blockNumber) { - _tree.CommitTree(blockNumber); + Tree.CommitTree(blockNumber); } @@ -808,12 +811,12 @@ public void Commit(IReleaseSpec releaseSpec, IStateTracer stateTracer, bool isGe } if (_logger.IsTrace) _logger.Trace($"Committing state changes (at {_currentPosition})"); - if (_changes[_currentPosition] is null) + if (Changes[_currentPosition] is null) { throw new InvalidOperationException($"Change at current position {_currentPosition} was null when commiting {nameof(WorldState)}"); } - if (_changes[_currentPosition + 1] is not null) + if (Changes[_currentPosition + 1] is not null) { throw new InvalidOperationException($"Change after current position ({_currentPosition} + 1) was not null when commiting {nameof(WorldState)}"); } @@ -825,10 +828,10 @@ public void Commit(IReleaseSpec releaseSpec, IStateTracer stateTracer, bool isGe trace = new Dictionary(); } - Dictionary accountChange = new Dictionary(); + var accountChange = new Dictionary(); for (int i = 0; i <= _currentPosition; i++) { - Change change = _changes[_currentPosition - i]; + Change change = Changes[_currentPosition - i]; if (!isTracing && change!.ChangeType == ChangeType.JustCache) { continue; @@ -850,7 +853,7 @@ public void Commit(IReleaseSpec releaseSpec, IStateTracer stateTracer, bool isGe _nullAccountReads.Add(change.Address); continue; } - Stack stack = _intraBlockCache[change.Address]; + Stack stack = IntraBlockCache[change.Address]; int forAssertion = stack.Pop(); if (forAssertion != _currentPosition - i) { @@ -873,7 +876,7 @@ public void Commit(IReleaseSpec releaseSpec, IStateTracer stateTracer, bool isGe if (_logger.IsTrace) if (change.Account != null) _logger.Trace($" Commit update {change.Address} B = {change.Account.Balance} N = {change.Account.Nonce} C = {change.Account.CodeHash}"); - accountChange[change.Address] = change.Account; + accountChange[change.Address] = (change.Account, false); if (isTracing) { trace[change.Address] = new ChangeTrace(change.Account); @@ -884,10 +887,10 @@ public void Commit(IReleaseSpec releaseSpec, IStateTracer stateTracer, bool isGe case ChangeType.New: { // For new accounts we do not need to save empty accounts when Eip158 enabled with Verkle - if (change.Account != null && (!releaseSpec.IsEip158Enabled || !change.Account.IsEmpty || isGenesis || change.Address == new Address("0xfffffffffffffffffffffffffffffffffffffffe"))) + if (change.Account != null && (!releaseSpec.IsEip158Enabled || !change.Account.IsEmpty || isGenesis)) { if (_logger.IsTrace) _logger.Trace($" Commit create {change.Address} B = {change.Account.Balance} N = {change.Account.Nonce}"); - accountChange[change.Address] = change.Account; + accountChange[change.Address] = (change.Account, true); if (isTracing) { trace[change.Address] = new ChangeTrace(change.Account); @@ -903,7 +906,7 @@ public void Commit(IReleaseSpec releaseSpec, IStateTracer stateTracer, bool isGe while (stack.Count > 0) { int previousOne = stack.Pop(); - wasItCreatedNow |= _changes[previousOne]!.ChangeType == ChangeType.New; + wasItCreatedNow |= Changes[previousOne]!.ChangeType == ChangeType.New; if (wasItCreatedNow) { break; @@ -912,11 +915,7 @@ public void Commit(IReleaseSpec releaseSpec, IStateTracer stateTracer, bool isGe if (!wasItCreatedNow) { - accountChange[change.Address] = null; - if (isTracing) - { - trace[change.Address] = new ChangeTrace(null); - } + throw new StateException.StateDeleteNotSupported(); } break; @@ -936,11 +935,11 @@ public void Commit(IReleaseSpec releaseSpec, IStateTracer stateTracer, bool isGe } BulkSet(accountChange); - _tree.Commit(); - Resettable.Reset(ref _changes, ref _capacity, ref _currentPosition); + Tree.Commit(); + Resettable.Reset(ref Changes, ref _capacity, ref _currentPosition); _committedThisRound.Reset(); _nullAccountReads.Clear(); - _intraBlockCache.Reset(); + IntraBlockCache.Reset(); if (isTracing) { @@ -969,8 +968,8 @@ public void Restore(int snapshot) for (int i = 0; i < _currentPosition - snapshot; i++) { - Change change = _changes[_currentPosition - i]; - Stack stack = _intraBlockCache[change!.Address]; + Change change = Changes[_currentPosition - i]; + Stack stack = IntraBlockCache[change!.Address]; if (stack.Count == 1) { if (change.ChangeType == ChangeType.JustCache) @@ -982,12 +981,12 @@ public void Restore(int snapshot) } _keptInCache.Add(change); - _changes[actualPosition] = null; + Changes[actualPosition] = null; continue; } } - _changes[_currentPosition - i] = null; // TODO: temp, ??? + Changes[_currentPosition - i] = null; // TODO: temp, ??? int forChecking = stack.Pop(); if (forChecking != _currentPosition - i) { @@ -996,7 +995,7 @@ public void Restore(int snapshot) if (stack.Count == 0) { - _intraBlockCache.Remove(change.Address); + IntraBlockCache.Remove(change.Address); } } @@ -1004,8 +1003,8 @@ public void Restore(int snapshot) foreach (Change kept in _keptInCache) { _currentPosition++; - _changes[_currentPosition] = kept; - _intraBlockCache[kept.Address].Push(_currentPosition); + Changes[_currentPosition] = kept; + IntraBlockCache[kept.Address].Push(_currentPosition); } _keptInCache.Clear(); diff --git a/src/Nethermind/Nethermind.Test.Runner/BlockchainTestsRunner.cs b/src/Nethermind/Nethermind.Test.Runner/BlockchainTestsRunner.cs index ee23932b43e..073c069a411 100644 --- a/src/Nethermind/Nethermind.Test.Runner/BlockchainTestsRunner.cs +++ b/src/Nethermind/Nethermind.Test.Runner/BlockchainTestsRunner.cs @@ -11,17 +11,19 @@ namespace Nethermind.Test.Runner; -public class BlockchainTestsRunner : BlockchainTestBase, IBlockchainTestRunner +public class BlockchainTestsRunner : IBlockchainTestRunner { private readonly ConsoleColor _defaultColour; private readonly ITestSourceLoader _testsSource; private readonly string? _filter; + private readonly IBlockchainTestBase _blockchainTestBase; - public BlockchainTestsRunner(ITestSourceLoader testsSource, string? filter) + public BlockchainTestsRunner(ITestSourceLoader testsSource, string? filter, IBlockchainTestBase blockchainTestBase) { _testsSource = testsSource ?? throw new ArgumentNullException(nameof(testsSource)); _defaultColour = Console.ForegroundColor; _filter = filter; + _blockchainTestBase = blockchainTestBase; } public async Task> RunTestsAsync() @@ -32,7 +34,7 @@ public async Task> RunTestsAsync() { if (_filter is not null && !Regex.Match(test.Name, $"^({_filter})").Success) continue; - Setup(); + _blockchainTestBase.Setup(); Console.Write($"{test,-120} "); if (test.LoadFailure != null) @@ -42,7 +44,7 @@ public async Task> RunTestsAsync() } else { - EthereumTestResult result = await RunTest(test); + EthereumTestResult result = await _blockchainTestBase.RunTest(test); testResults.Add(result); if (result.Pass) WriteGreen("PASS"); diff --git a/src/Nethermind/Nethermind.Test.Runner/Nethermind.Test.Runner.csproj b/src/Nethermind/Nethermind.Test.Runner/Nethermind.Test.Runner.csproj index fd96da1e534..ab958d164e1 100644 --- a/src/Nethermind/Nethermind.Test.Runner/Nethermind.Test.Runner.csproj +++ b/src/Nethermind/Nethermind.Test.Runner/Nethermind.Test.Runner.csproj @@ -23,12 +23,16 @@ + PreserveNewest Always + + Always + PreserveNewest diff --git a/src/Nethermind/Nethermind.Test.Runner/Program.cs b/src/Nethermind/Nethermind.Test.Runner/Program.cs index ccb60229cb5..8815b700156 100644 --- a/src/Nethermind/Nethermind.Test.Runner/Program.cs +++ b/src/Nethermind/Nethermind.Test.Runner/Program.cs @@ -40,6 +40,9 @@ public class Options [Option('x', "stdin", Required = false, HelpText = "If stdin is used, the state runner will read inputs (filenames) from stdin, and continue executing until empty line is read.")] public bool Stdin { get; set; } + + [Option('v', "VerkleTest", Required = false, HelpText = "")] + public bool VerkleTest { get; set; } } public static async Task Main(params string[] args) @@ -64,8 +67,10 @@ private static async Task Run(Options options) while (!string.IsNullOrWhiteSpace(input)) { - if (options.BlockTest) - await RunBlockTest(input, source => new BlockchainTestsRunner(source, options.Filter)); + if (options.VerkleTest) + await RunBlockTest(input, source => new BlockchainTestsRunner(source, options.Filter, new VerkleBlockChainTestBase())); + else if (options.BlockTest) + await RunBlockTest(input, source => new BlockchainTestsRunner(source, options.Filter, new BlockchainTestBase())); else RunStateTest(input, source => new StateTestsRunner(source, whenTrace, !options.ExcludeMemory, !options.ExcludeStack, options.Filter)); if (!options.Stdin) diff --git a/src/Nethermind/Nethermind.Test.Runner/Properties/launchSettings.json b/src/Nethermind/Nethermind.Test.Runner/Properties/launchSettings.json index c2bffc4ce24..e984e24e717 100644 --- a/src/Nethermind/Nethermind.Test.Runner/Properties/launchSettings.json +++ b/src/Nethermind/Nethermind.Test.Runner/Properties/launchSettings.json @@ -8,6 +8,10 @@ "commandName": "Project", "commandLineArgs": "-b -i blockchainTest1.json" }, + "Verkle Test": { + "commandName": "Project", + "commandLineArgs": "-v -i /home/eurus/review/blockchain_tests/verkle/eip4762_verkle_gas_witness" + }, "Regex State Test": { "commandName": "Project", "commandLineArgs": "-i statetest1.json -f \"randomStatetestmartin-Wed_10_02_29-14338-([0-9]+)\"" diff --git a/src/Nethermind/Nethermind.Test.Runner/StateTestTxTracer.cs b/src/Nethermind/Nethermind.Test.Runner/StateTestTxTracer.cs index 31707568258..c9578a69c2f 100644 --- a/src/Nethermind/Nethermind.Test.Runner/StateTestTxTracer.cs +++ b/src/Nethermind/Nethermind.Test.Runner/StateTestTxTracer.cs @@ -32,6 +32,7 @@ public class StateTestTxTracer : ITxTracer, IDisposable public bool IsTracingBlockHash { get; } = false; public bool IsTracingAccess { get; } = false; public bool IsTracingFees => false; + public bool IsTracingAccessWitness => false; public bool IsTracing => IsTracingReceipt || IsTracingActions || IsTracingOpLevelStorage || IsTracingMemory || IsTracingInstructions || IsTracingRefunds || IsTracingCode || IsTracingStack || IsTracingBlockHash || IsTracingAccess || IsTracingFees; @@ -252,6 +253,10 @@ public void ReportStackPush(in ReadOnlySpan stackItem) { } + public void ReportAccessWitness(IReadOnlyList verkleWitnessKeys) + { + throw new NotImplementedException(); + } public StateTestTxTrace BuildResult() { return _trace; diff --git a/src/Nethermind/Nethermind.Test.Runner/verkle.json b/src/Nethermind/Nethermind.Test.Runner/verkle.json new file mode 100644 index 00000000000..0d18cc97358 --- /dev/null +++ b/src/Nethermind/Nethermind.Test.Runner/verkle.json @@ -0,0 +1,1348 @@ +{ + "tests/verkle/eip4762_verkle_gas_witness/test_balance.py::test_balance[fork_Verkle-blockchain_test-warm_True-target_0xd94f5374fce5edbc8e2a8697c15331677e6ebf0c]": { + "network": "Verkle", + "genesisBlockHeader": { + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x3206378ced310ea498e05fa80aa1f7056571fd1e7aa10a78600c4d772786e561", + "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x00", + "gasLimit": "0x02540be400", + "gasUsed": "0x00", + "timestamp": "0x00", + "extraData": "0x00", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0x54bf3ea55c1418219b2f2fd3ccf3e5ec451d8773da6086d3c02878b4d79c4c4c" + }, + "pre": { + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x60203611603157600143035f35116029575f356120000143116029576120005f3506545f5260205ff35b5f5f5260205ff35b5f5ffd00", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x00", + "balance": "0x3635c9adc5dea00000", + "code": "0x", + "storage": {} + }, + "0x8a0a19589531694250d570040a0c4b74576919b8": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x73d94f5374fce5edbc8e2a8697c15331677e6ebf0c3173d94f5374fce5edbc8e2a8697c15331677e6ebf0c315f55", + "storage": {} + }, + "0x0000000000000000000000000000000000000004": { + "nonce": "0x00", + "balance": "0xf0", + "code": "0x", + "storage": {} + }, + "0xd94f5374fce5edbc8e2a8697c15331677e6ebf0c": { + "nonce": "0x00", + "balance": "0xf2", + "code": "0x", + "storage": {} + } + }, + "lastblockhash": "0xc8d086959b2ae9f0115820122e63ef793cf6490d0f94d1d290a653b219673e0c", + "genesisRLP": "0xf9021af90214a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a03206378ced310ea498e05fa80aa1f7056571fd1e7aa10a78600c4d772786e561a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808502540be400808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421c0c0c0", + "blocks": [ + { + "blockHeader": { + "parentHash": "0x54bf3ea55c1418219b2f2fd3ccf3e5ec451d8773da6086d3c02878b4d79c4c4c", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "stateRoot": "0x2d1ce811ef3d1d318b0b9c3ca0fb565e7c14e64b81400ab8e707ad1e0e29ea43", + "transactionsTrie": "0x3689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1", + "receiptTrie": "0xd6936e27d4dfb5a8246189dfaea4daaf851caab7a0d6df7355e072664bdae78a", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x01", + "gasLimit": "0x02540be400", + "gasUsed": "0x6aac", + "timestamp": "0x0c", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0xc8d086959b2ae9f0115820122e63ef793cf6490d0f94d1d290a653b219673e0c" + }, + "transactions": [ + { + "type": "0x00", + "chainId": "0x01", + "nonce": "0x00", + "gasPrice": "0x0a", + "gasLimit": "0x0f4240", + "to": "0x8a0a19589531694250d570040a0c4b74576919b8", + "value": "0x00", + "data": "0x", + "v": "0x26", + "r": "0xf072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572", + "s": "0x68aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615", + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" + } + ], + "uncleHeaders": [], + "withdrawals": [], + "witness": { + "stateDiff": [ + { + "stem": "0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000", + "newValue": "0x00000000000000000000000000000001000000000000003635c9adc5de9bd548" + }, + { + "suffix": 1, + "currentValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "newValue": null + } + ] + }, + { + "stem": "0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad7", + "suffixDiffs": [ + { + "suffix": 64, + "newValue": "0x54bf3ea55c1418219b2f2fd3ccf3e5ec451d8773da6086d3c02878b4d79c4c4c", + "currentValue": null + } + ] + }, + { + "stem": "0x914ec5f0e0c27fe094862fbd89a6abe684939af6940434d8bf218cedb2d624", + "suffixDiffs": [ + { + "suffix": 0, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000014004", + "currentValue": null + }, + { + "suffix": 1, + "newValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "currentValue": null + } + ] + }, + { + "stem": "0x9bcc6e55c098e22bfe2feee3cefcd2abab05249f3fd93a77cb65eeee3e0398", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x00000000000000000000000000000000000000000000000000000000000000f2", + "newValue": null + } + ] + }, + { + "stem": "0xecb505156708480caf702cd85124f67f3ed78ae4bc890a6dcb62574ba9a90c", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x000000000000002e000000000000000000000000000000000000000000000000", + "newValue": null + }, + { + "suffix": 1, + "currentValue": "0x0546cc153cff9682e7cf3cda3237c5923d81960775c2e5b4e09b4bb1ce897062", + "newValue": null + }, + { + "suffix": 64, + "newValue": "0x00000000000000000000000000000000000000000000000000000000000000f2", + "currentValue": null + }, + { + "suffix": 128, + "currentValue": "0x0073d94f5374fce5edbc8e2a8697c15331677e6ebf0c3173d94f5374fce5edbc", + "newValue": null + }, + { + "suffix": 129, + "currentValue": "0x0c8e2a8697c15331677e6ebf0c315f5500000000000000000000000000000000", + "newValue": null + } + ] + } + ], + "verkleProof": { + "otherStems": [], + "depthExtensionPresent": "0xa0a080a0a", + "commitmentsByPath": [ + "0x360bcc4c15a10f6f058d1d07e13e9a271da3da0cd69026d5a9ab25e1c0a5d697", + "0x324e7b7405bbfae46866bad5c94ac2983093b86f85035fe5984ec40a1b5e5ce3", + "0x61506c1cc4f27c9231a546a4b0d249d5f3ba4ba9e63c5ebb84087665eb396e95", + "0x4909fc1889e10819cda41706a26373145c4e4575d68b96569af12db69040b6e1", + "0x24ef52dcec1f1337acccfcd7f4971281e7103fd2c3bc2290953c6108c625e62d", + "0x14727a2ae64efbc4eac9e7fdf4523648c56dc2c965d71a8ee4e1e851a96b39ab", + "0x724a6725e28bbaad77b0b9a9ca1fc32028dc1fac049a57241c5abaec2b14e0df", + "0x3fea8026efb24696cf44034bb4d596526768c695d7ad46aab8c599b7c78416b6", + "0x24bb6cbeee95f2b1b52cbef3e2acbc5291c6c7cfa2bf56a1de70486c6f0a53e6" + ], + "d": "0x5d008fe514c478f93b436da25faeb559d83af290dc16add8db9d6d3de0f055b2", + "ipaProof": { + "cl": [ + "0x4f2899d6266397fedf63231ef5c010fe1d7bca5ca574ba0d2b8f4ee16109387f", + "0x259f6f79856cec14a8e65979a4d2e07a0b81249b0e549d003d1fd96bc5ab6c56", + "0x54bd5c499bca67c95793e8e72c8e7427b643d01a1624e0a028f99d076fb29182", + "0x2939b05a9bf1aeb04715700c7a893abaf02397b4a65c9bb7a76b803e198947d6", + "0x61b18c8dff1086695cefdb92d285f859f9b73db614632fdbf54b73c43fe4d0e1", + "0x2335563e43c60da9963e629d53213942bb5bb2e69a4229e3a7397ff9f870cd12", + "0x539e6680fb9d63470da8e28cb7ee98dc71ea363cc77b3bfdd6eb03b376b8004d", + "0x4a9065a3f4d498d7ce79284e9116f4aeb1d678c61e87ba4856af8a6498c4af32" + ], + "cr": [ + "0x168d22909450da9193e684886ef68b457e3fadbf55c496f8dd3643450d801d4f", + "0x7212a208cc19764a29d87ff9f992c31605d44de773a0ad61d38a055b8966caaa", + "0x5eacea5cc3702f3b859315f9e27d9a76cb39487d6bd7ebe984cf506f43343c58", + "0x7266e11c83a503ea5c201cac6c2327c531328b5644259ecd125e82a3dddbd07c", + "0x54ec3233dd3188015ed57ea5a7d93af4b0f51c7086c5a44de303e8bbf523efe1", + "0x23013e490f06334d9ed308d739d4f662a4c67f0b2b6d19d62d7904fe400cb3a4", + "0x42013704123021c839c0aed5d9f1e741f22c535850b9b46c703e24056190bc30", + "0x1e17ab7998147931cb36a4f380d0f3121a38776170ab83f8e0dbbab1b13abfeb" + ], + "finalEvaluation": "0x0578ed365ee4c896039f16cca3eaa2108d3db654831189b9cef20b6997ab36a9" + } + } + }, + "rlp": "0xf9027ff90216a054bf3ea55c1418219b2f2fd3ccf3e5ec451d8773da6086d3c02878b4d79c4c4ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa02d1ce811ef3d1d318b0b9c3ca0fb565e7c14e64b81400ab8e707ad1e0e29ea43a03689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1a0d6936e27d4dfb5a8246189dfaea4daaf851caab7a0d6df7355e072664bdae78ab901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080018502540be400826aac0c80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f862f860800a830f4240948a0a19589531694250d570040a0c4b74576919b8808026a0f072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572a068aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615c0c0", + "blocknumber": "1" + } + ], + "sealEngine": "NoProof", + "_info": { + "hash": "0x384e396cfcb317e9a48e0b3aff4bdebf15b4d98d9a49766fdfc01b2102e27469", + "comment": "`execution-spec-tests` generated test", + "filling-transition-tool": "evm version 1.12.1-unstable-ffc1f2de-20240927", + "description": "Test function documentation:\n\n Test BALANCE witness with/without WARM access.", + "url": "https://github.com/ethereum/execution-spec-tests/blob/12010a55ade19ee93352740cffbd5f39c1c981c4/tests/verkle/eip4762_verkle_gas_witness/test_balance.py#L34", + "reference-spec": "https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4762.md", + "reference-spec-version": "2f8299df31bb8173618901a03a8366a3183479b0" + } + }, + "tests/verkle/eip4762_verkle_gas_witness/test_balance.py::test_balance[fork_Verkle-blockchain_test-warm_True-target_0x0000000000000000000000000000000000000004]": { + "network": "Verkle", + "genesisBlockHeader": { + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x32348ce318ebf66a95101bb624fd1ec155523b2d8e3a8e53fcc9764ecdb5b8e2", + "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x00", + "gasLimit": "0x02540be400", + "gasUsed": "0x00", + "timestamp": "0x00", + "extraData": "0x00", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0x76f3348e712d2ffe1060d5ae4515cd50ee59d2c114045b5919e4ae0b58ac2dfa" + }, + "pre": { + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x60203611603157600143035f35116029575f356120000143116029576120005f3506545f5260205ff35b5f5f5260205ff35b5f5ffd00", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x00", + "balance": "0x3635c9adc5dea00000", + "code": "0x", + "storage": {} + }, + "0x8a0a19589531694250d570040a0c4b74576919b8": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x6004316004315f55", + "storage": {} + }, + "0x0000000000000000000000000000000000000004": { + "nonce": "0x00", + "balance": "0xf0", + "code": "0x", + "storage": {} + } + }, + "lastblockhash": "0xd06731e7be5bd862ed579eefb76001de9539eb4a7cf52f6ebbe50cbc53082289", + "genesisRLP": "0xf9021af90214a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a032348ce318ebf66a95101bb624fd1ec155523b2d8e3a8e53fcc9764ecdb5b8e2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808502540be400808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421c0c0c0", + "blocks": [ + { + "blockHeader": { + "parentHash": "0x76f3348e712d2ffe1060d5ae4515cd50ee59d2c114045b5919e4ae0b58ac2dfa", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "stateRoot": "0x00805f6f3e4852168a14681a6529f13ff7fb289c6c4f3ae0d801eca4b5cff63e", + "transactionsTrie": "0x3689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1", + "receiptTrie": "0x811b1657c116c65ab08d2dca5e6d0e990a5e43544bb1e432b80039dd686db1cc", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x01", + "gasLimit": "0x02540be400", + "gasUsed": "0x69e4", + "timestamp": "0x0c", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0xd06731e7be5bd862ed579eefb76001de9539eb4a7cf52f6ebbe50cbc53082289" + }, + "transactions": [ + { + "type": "0x00", + "chainId": "0x01", + "nonce": "0x00", + "gasPrice": "0x0a", + "gasLimit": "0x0f4240", + "to": "0x8a0a19589531694250d570040a0c4b74576919b8", + "value": "0x00", + "data": "0x", + "v": "0x26", + "r": "0xf072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572", + "s": "0x68aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615", + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" + } + ], + "uncleHeaders": [], + "withdrawals": [], + "witness": { + "stateDiff": [ + { + "stem": "0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000", + "newValue": "0x00000000000000000000000000000001000000000000003635c9adc5de9bdd18" + }, + { + "suffix": 1, + "currentValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "newValue": null + } + ] + }, + { + "stem": "0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad7", + "suffixDiffs": [ + { + "suffix": 64, + "newValue": "0x76f3348e712d2ffe1060d5ae4515cd50ee59d2c114045b5919e4ae0b58ac2dfa", + "currentValue": null + } + ] + }, + { + "stem": "0x914ec5f0e0c27fe094862fbd89a6abe684939af6940434d8bf218cedb2d624", + "suffixDiffs": [ + { + "suffix": 0, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000013dac", + "currentValue": null + }, + { + "suffix": 1, + "newValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "currentValue": null + } + ] + }, + { + "stem": "0x96ebb44953d7b9e535617760759dfbe7dcf03cc5933454b5abed216a3cf278", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x00000000000000000000000000000000000000000000000000000000000000f0", + "newValue": null + } + ] + }, + { + "stem": "0xecb505156708480caf702cd85124f67f3ed78ae4bc890a6dcb62574ba9a90c", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x0000000000000008000000000000000000000000000000000000000000000000", + "newValue": null + }, + { + "suffix": 1, + "currentValue": "0xcbb5d73981a82fc059e8361e3685f5b27310c30dcbee58f03d8646d716acc87d", + "newValue": null + }, + { + "suffix": 64, + "newValue": "0x00000000000000000000000000000000000000000000000000000000000000f0", + "currentValue": null + }, + { + "suffix": 128, + "currentValue": "0x006004316004315f550000000000000000000000000000000000000000000000", + "newValue": null + } + ] + } + ], + "verkleProof": { + "otherStems": [], + "depthExtensionPresent": "0xa0a080a0a", + "commitmentsByPath": [ + "0x360bcc4c15a10f6f058d1d07e13e9a271da3da0cd69026d5a9ab25e1c0a5d697", + "0x324e7b7405bbfae46866bad5c94ac2983093b86f85035fe5984ec40a1b5e5ce3", + "0x61506c1cc4f27c9231a546a4b0d249d5f3ba4ba9e63c5ebb84087665eb396e95", + "0x4909fc1889e10819cda41706a26373145c4e4575d68b96569af12db69040b6e1", + "0x09ecbfb650c2c9edfa6008277eb582c2a8f3877f5eb7b751fedf62f3be52a0f1", + "0x141a0b8d04ccd9d1712b7e031f145f0b3ce56dbe3ca21c95f9359325fcdf802c", + "0x330d3140a5f6042669a42dfb3cc93888c1012b31e672bc0375350a92d880286a", + "0x396c7b100b2d3f55db7dd6f4c7f938ec02dd2a4b0473af71fb9fdfd1971c2efa", + "0x594e44a1b0ada80aee9f740de84ab113cf359cb7394055af613cc2dfc11f8d51" + ], + "d": "0x71cab2e8d892272e6d9d49fbb00c8ecd1cf92817a25deb1803b3ddb01e7e077c", + "ipaProof": { + "cl": [ + "0x5dfa931726c1ae6fc63e09f34d2fb403272c522e372e5bcc661a4783f05836ee", + "0x52773b72e1521bd4e7c068dc5739d5cc33aa65b23f109df25a7efa65c257daf6", + "0x6da27f7c5b41d61128c6384f41814699703a86531851ba9f1eae7dcfdcc94694", + "0x390342ecc9ff2fb432b26d3b72926ef1fe00ae8c64c53cc4ec60590e36126aad", + "0x1c852775ef1eb21a8fcf3244b630e85d02ff28d0c2e904baf52a3ecde727dccf", + "0x13c5ad7f88f432ea75a2e98425f12b59aa74b64a25d5b1856184fce5cf7951fb", + "0x1345cb01498cab1ce8cbb91f79623e5791204b0b8c72a68d4d3d23e8d604041e", + "0x1862bc4cee026ce0f2508eaf9f02b098d762e4e6508d69bc0a401d6f48c11d5d" + ], + "cr": [ + "0x3faf4337243c7d06883440ed052f9a9fb4982a8b504e78347c41250c1b21e8eb", + "0x2742904cabc3e7f3222f8babc3d29dd71ea5f24cc2ab977b8b0e5b80bf068303", + "0x046abce21a6a6a93a4ffbf048d8c5c2e2d95dc839fd2bb1d920ae37da5075431", + "0x5c60a105bd508a57652f80c3b9a21508b451d0734c1c52fcfc8fece01ee9a98f", + "0x22a7eab31b556dcef337944971ec532bd075ba8d1d34782f60f9c23dd7f4b7dc", + "0x015772c57fc3bec9815f808117f4ac61188c3860405ee8ad55034fff6786d949", + "0x381c2e25824fc1b2636c2df7e7204a97c8c8906d6b8b0c7056353a0871a79b37", + "0x0bdb5235545f7838497dc0f5b06e5066cb82e0aade2cd974c368b65928428be1" + ], + "finalEvaluation": "0x0063ec7a8c6aa5b71d960d8f3a3c1f9b809246a408123db28e346a47f1439fe6" + } + } + }, + "rlp": "0xf9027ff90216a076f3348e712d2ffe1060d5ae4515cd50ee59d2c114045b5919e4ae0b58ac2dfaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa000805f6f3e4852168a14681a6529f13ff7fb289c6c4f3ae0d801eca4b5cff63ea03689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1a0811b1657c116c65ab08d2dca5e6d0e990a5e43544bb1e432b80039dd686db1ccb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080018502540be4008269e40c80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f862f860800a830f4240948a0a19589531694250d570040a0c4b74576919b8808026a0f072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572a068aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615c0c0", + "blocknumber": "1" + } + ], + "sealEngine": "NoProof", + "_info": { + "hash": "0x810026f8e853c4eee19e9b28fe8adc2e63f8d4c01928bd832ce1c1d468a5ca5f", + "comment": "`execution-spec-tests` generated test", + "filling-transition-tool": "evm version 1.12.1-unstable-ffc1f2de-20240927", + "description": "Test function documentation:\n\n Test BALANCE witness with/without WARM access.", + "url": "https://github.com/ethereum/execution-spec-tests/blob/12010a55ade19ee93352740cffbd5f39c1c981c4/tests/verkle/eip4762_verkle_gas_witness/test_balance.py#L34", + "reference-spec": "https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4762.md", + "reference-spec-version": "2f8299df31bb8173618901a03a8366a3183479b0" + } + }, + "tests/verkle/eip4762_verkle_gas_witness/test_balance.py::test_balance[fork_Verkle-blockchain_test-warm_True-target_0xfffffffffffffffffffffffffffffffffffffffe]": { + "network": "Verkle", + "genesisBlockHeader": { + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x6632aa148d2e5e48ac166208112b1c097d2338e2f5ec94618716f45cd2caa70f", + "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x00", + "gasLimit": "0x02540be400", + "gasUsed": "0x00", + "timestamp": "0x00", + "extraData": "0x00", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0x951aeeef5f64d7eeab1f945fd66d641b0b53dfe84e7b8941606f50c1b40b07bc" + }, + "pre": { + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x60203611603157600143035f35116029575f356120000143116029576120005f3506545f5260205ff35b5f5f5260205ff35b5f5ffd00", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x00", + "balance": "0x3635c9adc5dea00000", + "code": "0x", + "storage": {} + }, + "0x8a0a19589531694250d570040a0c4b74576919b8": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x73fffffffffffffffffffffffffffffffffffffffe3173fffffffffffffffffffffffffffffffffffffffe315f55", + "storage": {} + }, + "0x0000000000000000000000000000000000000004": { + "nonce": "0x00", + "balance": "0xf0", + "code": "0x", + "storage": {} + } + }, + "lastblockhash": "0x975db7188e846dd0e478f01da58b1cb2829b7cbef5fa17ab1931107d4bad2e6c", + "genesisRLP": "0xf9021af90214a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a06632aa148d2e5e48ac166208112b1c097d2338e2f5ec94618716f45cd2caa70fa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808502540be400808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421c0c0c0", + "blocks": [ + { + "blockHeader": { + "parentHash": "0x951aeeef5f64d7eeab1f945fd66d641b0b53dfe84e7b8941606f50c1b40b07bc", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "stateRoot": "0x3f5248ae90e865525132c05fb21d4a841c2f4fed673498a2b7d245f636893fac", + "transactionsTrie": "0x3689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1", + "receiptTrie": "0xd6936e27d4dfb5a8246189dfaea4daaf851caab7a0d6df7355e072664bdae78a", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x01", + "gasLimit": "0x02540be400", + "gasUsed": "0x6aac", + "timestamp": "0x0c", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0x975db7188e846dd0e478f01da58b1cb2829b7cbef5fa17ab1931107d4bad2e6c" + }, + "transactions": [ + { + "type": "0x00", + "chainId": "0x01", + "nonce": "0x00", + "gasPrice": "0x0a", + "gasLimit": "0x0f4240", + "to": "0x8a0a19589531694250d570040a0c4b74576919b8", + "value": "0x00", + "data": "0x", + "v": "0x26", + "r": "0xf072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572", + "s": "0x68aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615", + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" + } + ], + "uncleHeaders": [], + "withdrawals": [], + "witness": { + "stateDiff": [ + { + "stem": "0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000", + "newValue": "0x00000000000000000000000000000001000000000000003635c9adc5de9bd548" + }, + { + "suffix": 1, + "currentValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "newValue": null + } + ] + }, + { + "stem": "0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad7", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x0000000000000036000000000000000100000000000000000000000000000000", + "newValue": null + }, + { + "suffix": 64, + "newValue": "0x951aeeef5f64d7eeab1f945fd66d641b0b53dfe84e7b8941606f50c1b40b07bc", + "currentValue": null + } + ] + }, + { + "stem": "0x914ec5f0e0c27fe094862fbd89a6abe684939af6940434d8bf218cedb2d624", + "suffixDiffs": [ + { + "suffix": 0, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000014004", + "currentValue": null + }, + { + "suffix": 1, + "newValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "currentValue": null + } + ] + }, + { + "stem": "0xecb505156708480caf702cd85124f67f3ed78ae4bc890a6dcb62574ba9a90c", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x000000000000002e000000000000000000000000000000000000000000000000", + "newValue": null + }, + { + "suffix": 1, + "currentValue": "0xb9470add0386f7d0a32032ad85c3812d6a4b21ee2136a19157a4c664417b7272", + "newValue": null + }, + { + "suffix": 64, + "currentValue": null, + "newValue": null + }, + { + "suffix": 128, + "currentValue": "0x0073fffffffffffffffffffffffffffffffffffffffe3173ffffffffffffffff", + "newValue": null + }, + { + "suffix": 129, + "currentValue": "0x0cfffffffffffffffffffffffe315f5500000000000000000000000000000000", + "newValue": null + } + ] + } + ], + "verkleProof": { + "otherStems": [], + "depthExtensionPresent": "0xa0a080a", + "commitmentsByPath": [ + "0x360bcc4c15a10f6f058d1d07e13e9a271da3da0cd69026d5a9ab25e1c0a5d697", + "0x324e7b7405bbfae46866bad5c94ac2983093b86f85035fe5984ec40a1b5e5ce3", + "0x61506c1cc4f27c9231a546a4b0d249d5f3ba4ba9e63c5ebb84087665eb396e95", + "0x4909fc1889e10819cda41706a26373145c4e4575d68b96569af12db69040b6e1", + "0x416fca69b9d9af7ea114a793f9b8df7d97bb1123c4d4f2e9e9ff090e73d1feee", + "0x63bddf4626533d5d7f344d3a651c0664249f149b60b5ab698e19f302d675e3db", + "0x4272013119aeffdf3b1f1d06b701c641b7da5cb96ee7802c0d52a373605f5880" + ], + "d": "0x6df91bd75091345da2ec2a1d0b2e032797991206183343284936ffd997a4437f", + "ipaProof": { + "cl": [ + "0x02c90de13d4a11bb2cf06178aebcd878a107bf85998d71274f6ef7eca1e24890", + "0x066d9de8e077b227d71867e16ac08b61869501b89bb13922902f4fec208e4df6", + "0x706c92ec32f67231835475fdaf897c892a2d257eb5a78e52b1451db960feeced", + "0x6c4d3ec863f7d44396d68d651ae7c9e93b5ed3150f4f4a09047bc36ae4433c2c", + "0x4b9f46ec9f013e8b28e3ef697e3ca9c54dd36429213134788c212da62364eb35", + "0x14c051cb99e1981e9f2665ad389e891f1c6deb14180b902511d3c5b5361cf859", + "0x1755c5060abede14228e71932709067005413789ee91dc4cced1dabcf58d63e2", + "0x2c94f56b5a58192e182cf604540b81b50b75656b3122cde0f4bd1c20ddc1977f" + ], + "cr": [ + "0x710368db5bcd2445bf6190f99a5490d618d1784b1521f98a60d9419c0750cb32", + "0x4dcb233940c32d20d6e63e3d59bf00692630813969bc7dc58db37eb1c526d4d7", + "0x3000ccfb930cbfa8791af77288de1ccd8190ef4c00f99fbdea937362bef28f5d", + "0x6849490862a999fba9395f3cc63ba71b002c9f19e96a411f8fbb503b3c3874e1", + "0x44fd2e1c7d9769adc5f984e41657b8c90859a9e19640ab53d7e428db2c383f80", + "0x312c086a8bbad15756c51d94fbaa912f78da62efd605b468961d1cedf14117be", + "0x5e674da6d641b25cbfbdc62b2793f6b1cb73687de4cfa96c5f95a4accb9dc6c4", + "0x0d735317e8fad5c3888ec6a68a2c26143416bc800b116ae572d264dd6aa2012c" + ], + "finalEvaluation": "0x077c8b26ce21235265772149e477b653761a285d5c41f159ec3751d282f66e4a" + } + } + }, + "rlp": "0xf9027ff90216a0951aeeef5f64d7eeab1f945fd66d641b0b53dfe84e7b8941606f50c1b40b07bca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa03f5248ae90e865525132c05fb21d4a841c2f4fed673498a2b7d245f636893faca03689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1a0d6936e27d4dfb5a8246189dfaea4daaf851caab7a0d6df7355e072664bdae78ab901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080018502540be400826aac0c80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f862f860800a830f4240948a0a19589531694250d570040a0c4b74576919b8808026a0f072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572a068aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615c0c0", + "blocknumber": "1" + } + ], + "sealEngine": "NoProof", + "_info": { + "hash": "0x6dc745b51efbb95c30d70a4f7464ba1d3484bff9d5d3f20a02ab7f7b21c3ca41", + "comment": "`execution-spec-tests` generated test", + "filling-transition-tool": "evm version 1.12.1-unstable-ffc1f2de-20240927", + "description": "Test function documentation:\n\n Test BALANCE witness with/without WARM access.", + "url": "https://github.com/ethereum/execution-spec-tests/blob/12010a55ade19ee93352740cffbd5f39c1c981c4/tests/verkle/eip4762_verkle_gas_witness/test_balance.py#L34", + "reference-spec": "https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4762.md", + "reference-spec-version": "2f8299df31bb8173618901a03a8366a3183479b0" + } + }, + "tests/verkle/eip4762_verkle_gas_witness/test_balance.py::test_balance[fork_Verkle-blockchain_test-warm_False-target_0xd94f5374fce5edbc8e2a8697c15331677e6ebf0c]": { + "network": "Verkle", + "genesisBlockHeader": { + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x43f42844321e615a750468be1925f1f470bac332a9593273a45d5b9b38fb394a", + "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x00", + "gasLimit": "0x02540be400", + "gasUsed": "0x00", + "timestamp": "0x00", + "extraData": "0x00", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0x892b44e01fa0b7b9c9c8a359730008de8560443044046a67d331d2eeb7d41b6c" + }, + "pre": { + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x60203611603157600143035f35116029575f356120000143116029576120005f3506545f5260205ff35b5f5f5260205ff35b5f5ffd00", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x00", + "balance": "0x3635c9adc5dea00000", + "code": "0x", + "storage": {} + }, + "0x8a0a19589531694250d570040a0c4b74576919b8": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x73d94f5374fce5edbc8e2a8697c15331677e6ebf0c315f55", + "storage": {} + }, + "0x0000000000000000000000000000000000000004": { + "nonce": "0x00", + "balance": "0xf0", + "code": "0x", + "storage": {} + }, + "0xd94f5374fce5edbc8e2a8697c15331677e6ebf0c": { + "nonce": "0x00", + "balance": "0xf2", + "code": "0x", + "storage": {} + } + }, + "lastblockhash": "0xb5ad60d496c9ce007d90daf8c8a1fbdbf4e98fb7b0d89c3073da617ea8a18504", + "genesisRLP": "0xf9021af90214a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a043f42844321e615a750468be1925f1f470bac332a9593273a45d5b9b38fb394aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808502540be400808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421c0c0c0", + "blocks": [ + { + "blockHeader": { + "parentHash": "0x892b44e01fa0b7b9c9c8a359730008de8560443044046a67d331d2eeb7d41b6c", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "stateRoot": "0x42a8e67dc42253ba01bbac869dfcb61b81fa5e75728bbafb7937b3be88b575be", + "transactionsTrie": "0x3689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1", + "receiptTrie": "0xd6e45eb365ae2c934788bbfa773a7c2801621f553b9999509dc935fa7c1ef45a", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x01", + "gasLimit": "0x02540be400", + "gasUsed": "0x697d", + "timestamp": "0x0c", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0xb5ad60d496c9ce007d90daf8c8a1fbdbf4e98fb7b0d89c3073da617ea8a18504" + }, + "transactions": [ + { + "type": "0x00", + "chainId": "0x01", + "nonce": "0x00", + "gasPrice": "0x0a", + "gasLimit": "0x0f4240", + "to": "0x8a0a19589531694250d570040a0c4b74576919b8", + "value": "0x00", + "data": "0x", + "v": "0x26", + "r": "0xf072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572", + "s": "0x68aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615", + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" + } + ], + "uncleHeaders": [], + "withdrawals": [], + "witness": { + "stateDiff": [ + { + "stem": "0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000", + "newValue": "0x00000000000000000000000000000001000000000000003635c9adc5de9be11e" + }, + { + "suffix": 1, + "currentValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "newValue": null + } + ] + }, + { + "stem": "0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad7", + "suffixDiffs": [ + { + "suffix": 64, + "newValue": "0x892b44e01fa0b7b9c9c8a359730008de8560443044046a67d331d2eeb7d41b6c", + "currentValue": null + } + ] + }, + { + "stem": "0x914ec5f0e0c27fe094862fbd89a6abe684939af6940434d8bf218cedb2d624", + "suffixDiffs": [ + { + "suffix": 0, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000013c77", + "currentValue": null + }, + { + "suffix": 1, + "newValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "currentValue": null + } + ] + }, + { + "stem": "0x9bcc6e55c098e22bfe2feee3cefcd2abab05249f3fd93a77cb65eeee3e0398", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x00000000000000000000000000000000000000000000000000000000000000f2", + "newValue": null + } + ] + }, + { + "stem": "0xecb505156708480caf702cd85124f67f3ed78ae4bc890a6dcb62574ba9a90c", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x0000000000000018000000000000000000000000000000000000000000000000", + "newValue": null + }, + { + "suffix": 1, + "currentValue": "0xf57da5fd839f9b72c3eb938958ef432c5edf6fb9bfab01538c8d80684abaa911", + "newValue": null + }, + { + "suffix": 64, + "newValue": "0x00000000000000000000000000000000000000000000000000000000000000f2", + "currentValue": null + }, + { + "suffix": 128, + "currentValue": "0x0073d94f5374fce5edbc8e2a8697c15331677e6ebf0c315f5500000000000000", + "newValue": null + } + ] + } + ], + "verkleProof": { + "otherStems": [], + "depthExtensionPresent": "0xa0a080a0a", + "commitmentsByPath": [ + "0x360bcc4c15a10f6f058d1d07e13e9a271da3da0cd69026d5a9ab25e1c0a5d697", + "0x324e7b7405bbfae46866bad5c94ac2983093b86f85035fe5984ec40a1b5e5ce3", + "0x61506c1cc4f27c9231a546a4b0d249d5f3ba4ba9e63c5ebb84087665eb396e95", + "0x4909fc1889e10819cda41706a26373145c4e4575d68b96569af12db69040b6e1", + "0x24ef52dcec1f1337acccfcd7f4971281e7103fd2c3bc2290953c6108c625e62d", + "0x14727a2ae64efbc4eac9e7fdf4523648c56dc2c965d71a8ee4e1e851a96b39ab", + "0x0098c8c4150df18b8fd89a3e7f00b9acf0b4cd57ec150822b59fb892f117c978", + "0x4a73708b3fc437457f291df1c60e3f666809981e33bcce5c5c0e1477410310e6", + "0x4c4d16009e8244534c7e9787689c1e5bd689b66cc94b5432bb710d454d7f669a" + ], + "d": "0x67470dc63d2c7cc9cd9e592edd56d00821b6594c34e0bacf86b1c5c9a9718082", + "ipaProof": { + "cl": [ + "0x7112c1af1235966871a6502db6a39d61ed1de9a264bb7f9f940ea503e39ccd94", + "0x32bc4bdb63baadd736c7a8d29ab727b85f8ac387c333729880eac7dc733c7dca", + "0x50bf88ec84560dac51f03f7b5465a6657271f5bb469bcd995b36e3b10fa4195d", + "0x65a65ff55de65b4f47ba2d471a7e93aa9758e42774092d09695cc0228a5ef06d", + "0x703d1459c98e0b82bb50e13e04d495b32d06a3dc37f8a674891c3787756f7f93", + "0x473a2ba27f5abaab9deec701a0f0e8496a09e377c66707a580a5e92e2876e863", + "0x6fd3e965ccb597f2ba5d6ce1dba40d5e30f323c90d7d2c40c446c0a9a6e9e429", + "0x4b80256157896233467a3c034e614b891e16f42983eaa1b6c3a4bede7892a485" + ], + "cr": [ + "0x49915432075a35f9ebb1d6cf4eb0b17a4c3f0d10b64090a5816a7d0f2d5647f2", + "0x405875e0ae5a8696f36d4d8a039304d11354389c4cb9b17ba74dd90268699b3e", + "0x1403ed6283ab9438081c3a931bf3e4274d25f02457632dbf1f74c0067acae2b8", + "0x294116383e4ea8814af33169de08c15253085f48e453086a39dc2f0ceca28605", + "0x4c32ab8ccbabb55165fa4345bef2ee66feba0cb75bc7a90c82d1fd4213852d01", + "0x4385c056b930c76515808cd5ec5a48647bd9a950aad2ce27045c557a49cb14db", + "0x1425890c216ef762c14fc2214008c76b7240be5f84470c929b30a04195683846", + "0x37b3dae65bd6b9ff8849236ae82e56cc32d46fe41f29ffdd9e42620a70c6aae7" + ], + "finalEvaluation": "0x10dbaf004f5f3265b8b00ecfbd798ed74e978a87b2c60f26ebc9ec62a7bb2f33" + } + } + }, + "rlp": "0xf9027ff90216a0892b44e01fa0b7b9c9c8a359730008de8560443044046a67d331d2eeb7d41b6ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa042a8e67dc42253ba01bbac869dfcb61b81fa5e75728bbafb7937b3be88b575bea03689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1a0d6e45eb365ae2c934788bbfa773a7c2801621f553b9999509dc935fa7c1ef45ab901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080018502540be40082697d0c80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f862f860800a830f4240948a0a19589531694250d570040a0c4b74576919b8808026a0f072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572a068aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615c0c0", + "blocknumber": "1" + } + ], + "sealEngine": "NoProof", + "_info": { + "hash": "0x038aad9fce5eb794861e615c24a9fb4bb7eb297210a973fc8fc068c7771b36c8", + "comment": "`execution-spec-tests` generated test", + "filling-transition-tool": "evm version 1.12.1-unstable-ffc1f2de-20240927", + "description": "Test function documentation:\n\n Test BALANCE witness with/without WARM access.", + "url": "https://github.com/ethereum/execution-spec-tests/blob/12010a55ade19ee93352740cffbd5f39c1c981c4/tests/verkle/eip4762_verkle_gas_witness/test_balance.py#L34", + "reference-spec": "https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4762.md", + "reference-spec-version": "2f8299df31bb8173618901a03a8366a3183479b0" + } + }, + "tests/verkle/eip4762_verkle_gas_witness/test_balance.py::test_balance[fork_Verkle-blockchain_test-warm_False-target_0x0000000000000000000000000000000000000004]": { + "network": "Verkle", + "genesisBlockHeader": { + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x1e9b1209d0b6e9ec0041c8937642045cd2fb02b3b4c4d6de1ed9e187f4c809b8", + "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x00", + "gasLimit": "0x02540be400", + "gasUsed": "0x00", + "timestamp": "0x00", + "extraData": "0x00", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0x366f70e065194e8db41e7fa1553ad09e029780fac8adeeb5e794c078f723dfd1" + }, + "pre": { + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x60203611603157600143035f35116029575f356120000143116029576120005f3506545f5260205ff35b5f5f5260205ff35b5f5ffd00", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x00", + "balance": "0x3635c9adc5dea00000", + "code": "0x", + "storage": {} + }, + "0x8a0a19589531694250d570040a0c4b74576919b8": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x6004315f55", + "storage": {} + }, + "0x0000000000000000000000000000000000000004": { + "nonce": "0x00", + "balance": "0xf0", + "code": "0x", + "storage": {} + } + }, + "lastblockhash": "0x6b6f61c249cb88f9f1025113efdaa27f34ad13acde2530f3d6937385288c9d12", + "genesisRLP": "0xf9021af90214a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a01e9b1209d0b6e9ec0041c8937642045cd2fb02b3b4c4d6de1ed9e187f4c809b8a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808502540be400808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421c0c0c0", + "blocks": [ + { + "blockHeader": { + "parentHash": "0x366f70e065194e8db41e7fa1553ad09e029780fac8adeeb5e794c078f723dfd1", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "stateRoot": "0x6e98028caf3e0bf0087cc3ab798b16baa14837bbe379bd20b8dbfb5f32523946", + "transactionsTrie": "0x3689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1", + "receiptTrie": "0xd6e45eb365ae2c934788bbfa773a7c2801621f553b9999509dc935fa7c1ef45a", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x01", + "gasLimit": "0x02540be400", + "gasUsed": "0x697d", + "timestamp": "0x0c", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0x6b6f61c249cb88f9f1025113efdaa27f34ad13acde2530f3d6937385288c9d12" + }, + "transactions": [ + { + "type": "0x00", + "chainId": "0x01", + "nonce": "0x00", + "gasPrice": "0x0a", + "gasLimit": "0x0f4240", + "to": "0x8a0a19589531694250d570040a0c4b74576919b8", + "value": "0x00", + "data": "0x", + "v": "0x26", + "r": "0xf072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572", + "s": "0x68aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615", + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" + } + ], + "uncleHeaders": [], + "withdrawals": [], + "witness": { + "stateDiff": [ + { + "stem": "0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000", + "newValue": "0x00000000000000000000000000000001000000000000003635c9adc5de9be11e" + }, + { + "suffix": 1, + "currentValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "newValue": null + } + ] + }, + { + "stem": "0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad7", + "suffixDiffs": [ + { + "suffix": 64, + "newValue": "0x366f70e065194e8db41e7fa1553ad09e029780fac8adeeb5e794c078f723dfd1", + "currentValue": null + } + ] + }, + { + "stem": "0x914ec5f0e0c27fe094862fbd89a6abe684939af6940434d8bf218cedb2d624", + "suffixDiffs": [ + { + "suffix": 0, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000013c77", + "currentValue": null + }, + { + "suffix": 1, + "newValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "currentValue": null + } + ] + }, + { + "stem": "0x96ebb44953d7b9e535617760759dfbe7dcf03cc5933454b5abed216a3cf278", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x00000000000000000000000000000000000000000000000000000000000000f0", + "newValue": null + } + ] + }, + { + "stem": "0xecb505156708480caf702cd85124f67f3ed78ae4bc890a6dcb62574ba9a90c", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x0000000000000005000000000000000000000000000000000000000000000000", + "newValue": null + }, + { + "suffix": 1, + "currentValue": "0x6742266a17dbbd7bdeac71bd810c854a9cc4e8465728312798fb6bd16bef5b02", + "newValue": null + }, + { + "suffix": 64, + "newValue": "0x00000000000000000000000000000000000000000000000000000000000000f0", + "currentValue": null + }, + { + "suffix": 128, + "currentValue": "0x006004315f550000000000000000000000000000000000000000000000000000", + "newValue": null + } + ] + } + ], + "verkleProof": { + "otherStems": [], + "depthExtensionPresent": "0xa0a080a0a", + "commitmentsByPath": [ + "0x360bcc4c15a10f6f058d1d07e13e9a271da3da0cd69026d5a9ab25e1c0a5d697", + "0x324e7b7405bbfae46866bad5c94ac2983093b86f85035fe5984ec40a1b5e5ce3", + "0x61506c1cc4f27c9231a546a4b0d249d5f3ba4ba9e63c5ebb84087665eb396e95", + "0x4909fc1889e10819cda41706a26373145c4e4575d68b96569af12db69040b6e1", + "0x09ecbfb650c2c9edfa6008277eb582c2a8f3877f5eb7b751fedf62f3be52a0f1", + "0x141a0b8d04ccd9d1712b7e031f145f0b3ce56dbe3ca21c95f9359325fcdf802c", + "0x35f8d98250123f1ef0c38e55229407bf9355d233437b7419879cf4353eb93ad0", + "0x708d490392a696f9e22324f5dfcdb1f5217277c4572e65bc880b5f1fafe3d9e8", + "0x1ee8240ab28fae122e786e8bcb32fe6d6eb09ccd1d3f091e77b4da7eef4e4420" + ], + "d": "0x180c89c359d1360e1d530be4dff96f835d943f2213e31c4afd9cee2ccd380afb", + "ipaProof": { + "cl": [ + "0x1cbcb3c212c870df12f46084c2a1a86b5fda770c92123486878ef6ff0720835d", + "0x5635e106ce2783c62181942eb2323dca065e77da19a64eed6fa441fa9963e5ce", + "0x68adb575cdfab8d33df2506304a2d9d249cd21fece7f68a56e6512ef087cece7", + "0x2b412a3996f14d0ec274c2f05bb1345d3867207f954363bfa62fa9b65c051707", + "0x44d93e0c52502534a4fe15b80069ecb09b9c54f892087c8519b3977a43aae83b", + "0x64b2919a534d411fe12d77da9d55b4a76b5ebb4090364c72ac8e7b414b71a0fd", + "0x40aee071d2b1736ac76debe4b86f06db664c3ca9508033fab3c54af23f636c67", + "0x50b628e571d6316415d45f7aeb887eb6450856e0f878993137d2cabfaa023e59" + ], + "cr": [ + "0x4dc945410ec7ddfc03756390d2420d305bffa72e75b94f97f2c9af7acf644b35", + "0x0525f86a1b32e918fcecff5fe84d44047971290cb74e7cd5283761ca304705fd", + "0x4bf481da8dd06e063356c9eed7501ed3fda6c2f8bb2857d0f125da519e743573", + "0x508c98201dee2ddd4921cd46c68f7c4b74ab42e5a04ec42cd79219f9990dc209", + "0x5e2f88af22bbc144ea69507c9aae4ad0c6353d26554526960ce4898c5d8d403a", + "0x22af27d44a541e2f28fd60015e2489ed73f3e2f7a4784b325e46ec4f38d1b9c0", + "0x5a2bddc58a38c84cef5e9ccb759f956333efa761d7d81c69e78d5b2fd85d34e8", + "0x136fe6268aec905627d988bed15d29f02456b16dfc5289f39002d37cdc3e2331" + ], + "finalEvaluation": "0x072f248bd76b3344ef24637d99da0d4300bb961258dbf9d9cf6aafd1f5ef22c2" + } + } + }, + "rlp": "0xf9027ff90216a0366f70e065194e8db41e7fa1553ad09e029780fac8adeeb5e794c078f723dfd1a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa06e98028caf3e0bf0087cc3ab798b16baa14837bbe379bd20b8dbfb5f32523946a03689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1a0d6e45eb365ae2c934788bbfa773a7c2801621f553b9999509dc935fa7c1ef45ab901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080018502540be40082697d0c80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f862f860800a830f4240948a0a19589531694250d570040a0c4b74576919b8808026a0f072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572a068aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615c0c0", + "blocknumber": "1" + } + ], + "sealEngine": "NoProof", + "_info": { + "hash": "0x726f45b58d27273262c0e633c094283db0c4d9d42e199717dae3b6c8c7507e96", + "comment": "`execution-spec-tests` generated test", + "filling-transition-tool": "evm version 1.12.1-unstable-ffc1f2de-20240927", + "description": "Test function documentation:\n\n Test BALANCE witness with/without WARM access.", + "url": "https://github.com/ethereum/execution-spec-tests/blob/12010a55ade19ee93352740cffbd5f39c1c981c4/tests/verkle/eip4762_verkle_gas_witness/test_balance.py#L34", + "reference-spec": "https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4762.md", + "reference-spec-version": "2f8299df31bb8173618901a03a8366a3183479b0" + } + }, + "tests/verkle/eip4762_verkle_gas_witness/test_balance.py::test_balance[fork_Verkle-blockchain_test-warm_False-target_0xfffffffffffffffffffffffffffffffffffffffe]": { + "network": "Verkle", + "genesisBlockHeader": { + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x305495567c67d89f7d1921a3577c3a382114276067a1af7fe57c8c810f163c67", + "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x00", + "gasLimit": "0x02540be400", + "gasUsed": "0x00", + "timestamp": "0x00", + "extraData": "0x00", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0x0c32f89c323bcf264b0969870944fc21af268c212ef57403b3be571e19d152a5" + }, + "pre": { + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x60203611603157600143035f35116029575f356120000143116029576120005f3506545f5260205ff35b5f5f5260205ff35b5f5ffd00", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x00", + "balance": "0x3635c9adc5dea00000", + "code": "0x", + "storage": {} + }, + "0x8a0a19589531694250d570040a0c4b74576919b8": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x73fffffffffffffffffffffffffffffffffffffffe315f55", + "storage": {} + }, + "0x0000000000000000000000000000000000000004": { + "nonce": "0x00", + "balance": "0xf0", + "code": "0x", + "storage": {} + } + }, + "lastblockhash": "0xee346dd880723b59e27b998e40dc2a370cb34a1b3ba247c276179eaf68d445be", + "genesisRLP": "0xf9021af90214a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0305495567c67d89f7d1921a3577c3a382114276067a1af7fe57c8c810f163c67a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808502540be400808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421c0c0c0", + "blocks": [ + { + "blockHeader": { + "parentHash": "0x0c32f89c323bcf264b0969870944fc21af268c212ef57403b3be571e19d152a5", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "stateRoot": "0x3f5148211e7dd55875d632da63beec74f0b105775bd7014564ee90e43a07c655", + "transactionsTrie": "0x3689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1", + "receiptTrie": "0xd6e45eb365ae2c934788bbfa773a7c2801621f553b9999509dc935fa7c1ef45a", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x01", + "gasLimit": "0x02540be400", + "gasUsed": "0x697d", + "timestamp": "0x0c", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0xee346dd880723b59e27b998e40dc2a370cb34a1b3ba247c276179eaf68d445be" + }, + "transactions": [ + { + "type": "0x00", + "chainId": "0x01", + "nonce": "0x00", + "gasPrice": "0x0a", + "gasLimit": "0x0f4240", + "to": "0x8a0a19589531694250d570040a0c4b74576919b8", + "value": "0x00", + "data": "0x", + "v": "0x26", + "r": "0xf072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572", + "s": "0x68aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615", + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" + } + ], + "uncleHeaders": [], + "withdrawals": [], + "witness": { + "stateDiff": [ + { + "stem": "0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000", + "newValue": "0x00000000000000000000000000000001000000000000003635c9adc5de9be11e" + }, + { + "suffix": 1, + "currentValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "newValue": null + } + ] + }, + { + "stem": "0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad7", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x0000000000000036000000000000000100000000000000000000000000000000", + "newValue": null + }, + { + "suffix": 64, + "newValue": "0x0c32f89c323bcf264b0969870944fc21af268c212ef57403b3be571e19d152a5", + "currentValue": null + } + ] + }, + { + "stem": "0x914ec5f0e0c27fe094862fbd89a6abe684939af6940434d8bf218cedb2d624", + "suffixDiffs": [ + { + "suffix": 0, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000013c77", + "currentValue": null + }, + { + "suffix": 1, + "newValue": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "currentValue": null + } + ] + }, + { + "stem": "0xecb505156708480caf702cd85124f67f3ed78ae4bc890a6dcb62574ba9a90c", + "suffixDiffs": [ + { + "suffix": 0, + "currentValue": "0x0000000000000018000000000000000000000000000000000000000000000000", + "newValue": null + }, + { + "suffix": 1, + "currentValue": "0xb8f4249828c617bb67c300eb19fcd5552d2bf6aaf529e8fab0ad0d6a6ceb1eef", + "newValue": null + }, + { + "suffix": 64, + "currentValue": null, + "newValue": null + }, + { + "suffix": 128, + "currentValue": "0x0073fffffffffffffffffffffffffffffffffffffffe315f5500000000000000", + "newValue": null + } + ] + } + ], + "verkleProof": { + "otherStems": [], + "depthExtensionPresent": "0xa0a080a", + "commitmentsByPath": [ + "0x360bcc4c15a10f6f058d1d07e13e9a271da3da0cd69026d5a9ab25e1c0a5d697", + "0x324e7b7405bbfae46866bad5c94ac2983093b86f85035fe5984ec40a1b5e5ce3", + "0x61506c1cc4f27c9231a546a4b0d249d5f3ba4ba9e63c5ebb84087665eb396e95", + "0x4909fc1889e10819cda41706a26373145c4e4575d68b96569af12db69040b6e1", + "0x3b19dd06da550a236381d2a07f2e19fcf49db0651c2b2dc2d44843e3caec1e94", + "0x293f6e1aad91ca2d8b12247d59f36ca20ca7ed3689e2c070a36a08f2eba303f0", + "0x129e0196d70daac4e116f74edc7d927880b6d22b76d04fc6e430a706fd7f2872" + ], + "d": "0x1ac7754a728120a46ce4c00806109671ab028f7dec6138f3cdb0cd2be0f800d1", + "ipaProof": { + "cl": [ + "0x196bf5965f10b26a92720ef7fbbc98b53185230c37556ab07e42e43ff15d8e7c", + "0x6b27fef4a2e07c4d56994995cf78d32c140c416b669672ba17799cd772dafd8a", + "0x3335a2a4a3f40190cb723c5400e275619073d9b49166d51cbdc80a6012fed517", + "0x18a27eca6391d0c5c51237dece4791146a8ef799bb83304e4244c2696027c0bc", + "0x14cf391129fec384acbc39b37237355f47eeb33f63fb3e87deeba625179f9115", + "0x17c014d7b9350567750217191a16dad79b6a6354a4387281760c5809fd9a13a1", + "0x11256a82d9cf46d3e68743b1b9784901c6cf244dfc05490a7227f5870e17f784", + "0x26fb1be88d9e0a9a084ed1fdb5958843184b532034ab68b03162af36208a4b80" + ], + "cr": [ + "0x3b4d592b6da9e3b306fff0228d30727bdd4240cf778f36c036cbb15b0cdb4d41", + "0x37a6b17b73c1fbed1cd0720e35ed5f12908c7fd506f9da19d8c65cfa661b9ec8", + "0x37d2c0eba9aa9af976639f2fda18c525e6d18629452cc77b6935b9c5cd8c130a", + "0x592d1f283e654070433c0970154e6f1ec6e5f7d1862a16c02704a53925aa0125", + "0x3bc7bed56a1e127d410b27500e4d8a66f07d019f552326cd0a1341109c7d5671", + "0x4979f0cd50150c3183d633ae051df41038f00682931620cc2aa8b866b64e3d67", + "0x53fdd3dfcaa56571eb8417fbbba8d40fbebb6963ef14bb8b3fe92db2157b48c6", + "0x17ff21cb3fbeeff4e3d384df978b2f38653dc01db47e042d0a0a0a063c3514a2" + ], + "finalEvaluation": "0x084c9b913f0a3d3121c6165dcd84f33fbe704a410b8cfec685a302e28dcbf030" + } + } + }, + "rlp": "0xf9027ff90216a00c32f89c323bcf264b0969870944fc21af268c212ef57403b3be571e19d152a5a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa03f5148211e7dd55875d632da63beec74f0b105775bd7014564ee90e43a07c655a03689aafcc5e72f08b809aa44a48978afe322c74ba051c10d3b175e1b5e8892b1a0d6e45eb365ae2c934788bbfa773a7c2801621f553b9999509dc935fa7c1ef45ab901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080018502540be40082697d0c80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f862f860800a830f4240948a0a19589531694250d570040a0c4b74576919b8808026a0f072481d98bbf72e5b77c44ae076dd6b2f0db9073936b73556ba2aae4b22f572a068aab80c9019049f258dc900bac0b30846e7384a64a521938ee0e2b1969f5615c0c0", + "blocknumber": "1" + } + ], + "sealEngine": "NoProof", + "_info": { + "hash": "0x3ce34788467bedb85c6cadd88fa5e0f0ee47e489325749d2f6f9d9f669cbb073", + "comment": "`execution-spec-tests` generated test", + "filling-transition-tool": "evm version 1.12.1-unstable-ffc1f2de-20240927", + "description": "Test function documentation:\n\n Test BALANCE witness with/without WARM access.", + "url": "https://github.com/ethereum/execution-spec-tests/blob/12010a55ade19ee93352740cffbd5f39c1c981c4/tests/verkle/eip4762_verkle_gas_witness/test_balance.py#L34", + "reference-spec": "https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4762.md", + "reference-spec-version": "2f8299df31bb8173618901a03a8366a3183479b0" + } + } +} diff --git a/src/Nethermind/Nethermind.Verkle.Tests/Nethermind.Verkle.Tests.csproj b/src/Nethermind/Nethermind.Verkle.Tests/Nethermind.Verkle.Tests.csproj index 2e97ad8e827..5c79e7426c3 100644 --- a/src/Nethermind/Nethermind.Verkle.Tests/Nethermind.Verkle.Tests.csproj +++ b/src/Nethermind/Nethermind.Verkle.Tests/Nethermind.Verkle.Tests.csproj @@ -9,15 +9,15 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Nethermind/Nethermind.Verkle.Tests/Polynomial/LagrangeBasisTests.cs b/src/Nethermind/Nethermind.Verkle.Tests/Polynomial/LagrangeBasisTests.cs index 02c9690458b..f2ec5504521 100644 --- a/src/Nethermind/Nethermind.Verkle.Tests/Polynomial/LagrangeBasisTests.cs +++ b/src/Nethermind/Nethermind.Verkle.Tests/Polynomial/LagrangeBasisTests.cs @@ -10,13 +10,21 @@ public void TestAddSub() { FrE[] domainSq = [ - FrE.SetElement(), FrE.SetElement(1), FrE.SetElement(4), FrE.SetElement(9), FrE.SetElement(16), + FrE.SetElement(), + FrE.SetElement(1), + FrE.SetElement(4), + FrE.SetElement(9), + FrE.SetElement(16), FrE.SetElement(25) ]; FrE[] domain2 = [ - FrE.SetElement(2), FrE.SetElement(3), FrE.SetElement(4), FrE.SetElement(5), FrE.SetElement(6), + FrE.SetElement(2), + FrE.SetElement(3), + FrE.SetElement(4), + FrE.SetElement(5), + FrE.SetElement(6), FrE.SetElement(7) ]; @@ -25,7 +33,11 @@ public void TestAddSub() FrE[] expected = [ - FrE.SetElement(2), FrE.SetElement(4), FrE.SetElement(8), FrE.SetElement(14), FrE.SetElement(22), + FrE.SetElement(2), + FrE.SetElement(4), + FrE.SetElement(8), + FrE.SetElement(14), + FrE.SetElement(22), FrE.SetElement(32) ]; LagrangeBasis ex = new(expected); @@ -43,12 +55,20 @@ public void TestMul() { FrE[] domainSq = [ - FrE.SetElement(), FrE.SetElement(1), FrE.SetElement(4), FrE.SetElement(9), FrE.SetElement(16), + FrE.SetElement(), + FrE.SetElement(1), + FrE.SetElement(4), + FrE.SetElement(9), + FrE.SetElement(16), FrE.SetElement(25) ]; FrE[] domainPow4 = [ - FrE.SetElement(), FrE.SetElement(1), FrE.SetElement(16), FrE.SetElement(81), FrE.SetElement(256), + FrE.SetElement(), + FrE.SetElement(1), + FrE.SetElement(16), + FrE.SetElement(81), + FrE.SetElement(256), FrE.SetElement(625) ]; @@ -67,7 +87,11 @@ public void TestScale() { FrE[] domainSq = [ - FrE.SetElement(), FrE.SetElement(1), FrE.SetElement(4), FrE.SetElement(9), FrE.SetElement(16), + FrE.SetElement(), + FrE.SetElement(1), + FrE.SetElement(4), + FrE.SetElement(9), + FrE.SetElement(16), FrE.SetElement(25) ]; @@ -78,7 +102,11 @@ public void TestScale() FrE[] expected = [ - FrE.SetElement(), FrE.SetElement(10), FrE.SetElement(40), FrE.SetElement(90), FrE.SetElement(160), + FrE.SetElement(), + FrE.SetElement(10), + FrE.SetElement(40), + FrE.SetElement(90), + FrE.SetElement(160), FrE.SetElement(250) ]; LagrangeBasis ex = new(expected); diff --git a/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/IVerkleTreeStore.cs b/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/IVerkleTreeStore.cs index a37dc099fc8..b2e0b1a6220 100644 --- a/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/IVerkleTreeStore.cs +++ b/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/IVerkleTreeStore.cs @@ -12,6 +12,7 @@ namespace Nethermind.Verkle.Tree.TreeStore; public interface IVerkleTreeStore : IStoreWithReorgBoundary, IVerkleSyncTreeStore { + public void DumpTree(long block, VerkleMemoryDb cache); Hash256 StateRoot { get; } bool HasStateForBlock(Hash256 stateRoot); diff --git a/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/NullVerkleTreeStore.cs b/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/NullVerkleTreeStore.cs index 17687c219fd..defcde610f9 100644 --- a/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/NullVerkleTreeStore.cs +++ b/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/NullVerkleTreeStore.cs @@ -39,6 +39,8 @@ public void InsertSyncBatch(long blockNumber, VerkleMemoryDb batch) { } + public void DumpTree(long block, VerkleMemoryDb cache) { Console.WriteLine($"Empty Tree"); } + public Hash256 StateRoot => Hash256.Zero; public bool HasStateForBlock(Hash256 stateRoot) { diff --git a/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/ReadOnlyVerkleStateStore.cs b/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/ReadOnlyVerkleStateStore.cs index 44f4d01498b..9625adbd407 100644 --- a/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/ReadOnlyVerkleStateStore.cs +++ b/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/ReadOnlyVerkleStateStore.cs @@ -18,6 +18,8 @@ public class ReadOnlyVerkleStateStore(IVerkleTreeStore verkleStateStore, VerkleM { private static Span RootNodeKey => Array.Empty(); + public void DumpTree(long block, VerkleMemoryDb cache) => verkleStateStore.DumpTree(block, cache); + public Hash256 StateRoot { get diff --git a/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/VerkleTreeStore.Sync.cs b/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/VerkleTreeStore.Sync.cs index 95290a3efe6..fa57305b692 100644 --- a/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/VerkleTreeStore.Sync.cs +++ b/src/Nethermind/Nethermind.Verkle.Tree/TreeStore/VerkleTreeStore.Sync.cs @@ -3,11 +3,13 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using Nethermind.Core.Collections; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Verkle; +using Nethermind.Db; using Nethermind.Verkle.Curve; using Nethermind.Verkle.Tree.Cache; using Nethermind.Verkle.Tree.Sync; @@ -19,6 +21,40 @@ namespace Nethermind.Verkle.Tree.TreeStore; public partial class VerkleTreeStore { + // TODO: this works, but why is the range dump not working? + public void DumpTree(long block, VerkleMemoryDb cache) + { + var db = new MemDb(sorted: true); + + foreach (KeyValuePair d in cache.LeafTable) + { + db[d.Key] = d.Value; + } + + IEnumerable? data = BlockCache.GetEnumerable(StateRoot); + + foreach (BlockBranchNode? node in data) + { + foreach (var d in node.Data.StateDiff.LeafTable) + { + db[d.Key] = d.Value; + } + } + + foreach (KeyValuePair dx in Storage.LeafDb.GetAll()) + { + db[dx.Key] = dx.Value; + } + string docPath = "/home/eurus/"; + using var outputFile = new StreamWriter(Path.Combine(docPath, $"{block}.txt")); + + foreach (KeyValuePair n in db.GetAll(true)) + { + outputFile.WriteLine($"{n.Key.ToHexString()}: {n.Value.ToHexString()}"); + } + + } + public void InsertRootNodeAfterSyncCompletion(byte[] rootHash, long blockNumber) { Banderwagon rootPoint = Banderwagon.FromBytes(rootHash, subgroupCheck: false)!.Value; diff --git a/src/Nethermind/Nethermind.Verkle.Tree/VerkleTree.Prover.cs b/src/Nethermind/Nethermind.Verkle.Tree/VerkleTree.Prover.cs index e11ea156ce8..9f071859861 100644 --- a/src/Nethermind/Nethermind.Verkle.Tree/VerkleTree.Prover.cs +++ b/src/Nethermind/Nethermind.Verkle.Tree/VerkleTree.Prover.cs @@ -61,7 +61,7 @@ public ExecutionWitness GenerateExecutionWitness(Hash256[] keys, out Banderwagon { Stem = stemStateDiffData.Key, SuffixDiffs = stemStateDiffData.Value }; } - return new ExecutionWitness(stemStateDiffList, proof); + return new ExecutionWitness(stemStateDiffList, proof, StateRoot); } public void UpdateWithPostStateValues(ExecutionWitness executionWitness) diff --git a/src/Nethermind/Nethermind.Verkle.Tree/VerkleTree.Visitor.cs b/src/Nethermind/Nethermind.Verkle.Tree/VerkleTree.Visitor.cs index 566d7d19097..b5b9227e44b 100644 --- a/src/Nethermind/Nethermind.Verkle.Tree/VerkleTree.Visitor.cs +++ b/src/Nethermind/Nethermind.Verkle.Tree/VerkleTree.Visitor.cs @@ -2,15 +2,38 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.IO; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Core.Verkle; using Nethermind.Trie; +using Nethermind.Verkle.Tree.Sync; using Nethermind.Verkle.Tree.TreeNodes; namespace Nethermind.Verkle.Tree; public partial class VerkleTree { + public void PrintLeaves(long block) + { + // string docPath = "/home/eurus/"; + // using var outputFile = new StreamWriter(Path.Combine(docPath, "WriteLines.txt"), true); + // + // foreach (PathWithSubTree data in VerkleStateStore.GetLeafRangeIterator(Stem.Zero, Stem.MaxValue, root, long.MaxValue)) + // { + // byte[] stem = new byte[32]; + // data.Path.BytesAsSpan.CopyTo(stem); + // + // foreach (var inner in data.SubTree) + // { + // stem[31] = inner.SuffixByte; + // outputFile.WriteLine($"{stem.ToHexString()}: {inner.Leaf.ToHexString()}"); + // } + // } + + VerkleStateStore.DumpTree(block, TreeCache); + + } public void Accept(ITreeVisitor visitor, Hash256 rootHash, VisitingOptions? visitingOptions = null) { if (visitor is null) throw new ArgumentNullException(nameof(visitor)); diff --git a/src/Nethermind/Nethermind.Verkle/Curve/CurveParams.cs b/src/Nethermind/Nethermind.Verkle/Curve/CurveParams.cs index a6c9656a11e..cf07f7aa10d 100644 --- a/src/Nethermind/Nethermind.Verkle/Curve/CurveParams.cs +++ b/src/Nethermind/Nethermind.Verkle/Curve/CurveParams.cs @@ -10,14 +10,74 @@ public readonly struct CurveParams { private static readonly byte[] _numY = [ - 102, 65, 151, 204, 182, 103, 49, 94, 96, 100, 228, 238, 129, 173, 140, 53, 134, 213, 220, 186, 80, 139, 125, - 21, 15, 62, 18, 218, 158, 102, 108, 42 + 102, + 65, + 151, + 204, + 182, + 103, + 49, + 94, + 96, + 100, + 228, + 238, + 129, + 173, + 140, + 53, + 134, + 213, + 220, + 186, + 80, + 139, + 125, + 21, + 15, + 62, + 18, + 218, + 158, + 102, + 108, + 42 ]; private static readonly byte[] _numX = [ - 24, 174, 82, 162, 102, 24, 231, 225, 101, 132, 153, 173, 34, 192, 121, 43, 243, 66, 190, 123, 119, 17, 55, - 116, 197, 52, 11, 44, 204, 50, 193, 41 + 24, + 174, + 82, + 162, + 102, + 24, + 231, + 225, + 101, + 132, + 153, + 173, + 34, + 192, + 121, + 43, + 243, + 66, + 190, + 123, + 119, + 17, + 55, + 116, + 197, + 52, + 11, + 44, + 204, + 50, + 193, + 41 ]; public static readonly FpE A = FpE.SetElement(5).Negative(); diff --git a/src/Nethermind/Nethermind.Verkle/Fields/FpEElement/Element.Arithmatic.cs b/src/Nethermind/Nethermind.Verkle/Fields/FpEElement/Element.Arithmatic.cs index b5dedc15e57..d42b38295bf 100644 --- a/src/Nethermind/Nethermind.Verkle/Fields/FpEElement/Element.Arithmatic.cs +++ b/src/Nethermind/Nethermind.Verkle/Fields/FpEElement/Element.Arithmatic.cs @@ -136,15 +136,15 @@ public static void Lsh(in FE x, int n, out FE res) a = Rsh(res.u0, 64 - n); z0 = Lsh(res.u0, n); - sh64: + sh64: b = Rsh(res.u1, 64 - n); z1 = Lsh(res.u1, n) | a; - sh128: + sh128: a = Rsh(res.u2, 64 - n); z2 = Lsh(res.u2, n) | b; - sh192: + sh192: z3 = Lsh(res.u3, n) | a; res = new FE(z0, z1, z2, z3); @@ -229,15 +229,15 @@ public static void Rsh(in FE x, int n, out FE res) a = Lsh(res.u3, 64 - n); z3 = Rsh(res.u3, n); - sh64: + sh64: b = Lsh(res.u2, 64 - n); z2 = Rsh(res.u2, n) | a; - sh128: + sh128: a = Lsh(res.u1, 64 - n); z1 = Rsh(res.u1, n) | b; - sh192: + sh192: z0 = Rsh(res.u0, n) | a; res = new FE(z0, z1, z2, z3); diff --git a/src/Nethermind/Nethermind.Verkle/Fields/FpEElement/Element.Operators.cs b/src/Nethermind/Nethermind.Verkle/Fields/FpEElement/Element.Operators.cs index cb8a309ec1d..b7ae2349908 100644 --- a/src/Nethermind/Nethermind.Verkle/Fields/FpEElement/Element.Operators.cs +++ b/src/Nethermind/Nethermind.Verkle/Fields/FpEElement/Element.Operators.cs @@ -31,7 +31,7 @@ public readonly partial struct FpE return c; } - public static FE operator >> (in FE a, int n) + public static FE operator >>(in FE a, int n) { a.RightShift(n, out FE res); return res; diff --git a/src/Nethermind/Nethermind.Verkle/Fields/FrEElement/Element.Arithmatic.cs b/src/Nethermind/Nethermind.Verkle/Fields/FrEElement/Element.Arithmatic.cs index f1029d8babe..53ddd22e133 100644 --- a/src/Nethermind/Nethermind.Verkle/Fields/FrEElement/Element.Arithmatic.cs +++ b/src/Nethermind/Nethermind.Verkle/Fields/FrEElement/Element.Arithmatic.cs @@ -145,15 +145,15 @@ public static void Lsh(in FE x, int n, out FE res) a = Rsh(res.u0, 64 - n); z0 = Lsh(res.u0, n); - sh64: + sh64: b = Rsh(res.u1, 64 - n); z1 = Lsh(res.u1, n) | a; - sh128: + sh128: a = Rsh(res.u2, 64 - n); z2 = Lsh(res.u2, n) | b; - sh192: + sh192: z3 = Lsh(res.u3, n) | a; res = new FE(z0, z1, z2, z3); @@ -238,15 +238,15 @@ public static void Rsh(in FE x, int n, out FE res) a = Lsh(res.u3, 64 - n); z3 = Rsh(res.u3, n); - sh64: + sh64: b = Lsh(res.u2, 64 - n); z2 = Rsh(res.u2, n) | a; - sh128: + sh128: a = Lsh(res.u1, 64 - n); z1 = Rsh(res.u1, n) | b; - sh192: + sh192: z0 = Rsh(res.u0, n) | a; res = new FE(z0, z1, z2, z3); diff --git a/src/Nethermind/Nethermind.Verkle/Fields/FrEElement/Element.Operators.cs b/src/Nethermind/Nethermind.Verkle/Fields/FrEElement/Element.Operators.cs index 2a742369ce3..8ebf30d078a 100644 --- a/src/Nethermind/Nethermind.Verkle/Fields/FrEElement/Element.Operators.cs +++ b/src/Nethermind/Nethermind.Verkle/Fields/FrEElement/Element.Operators.cs @@ -31,7 +31,7 @@ public readonly partial struct FrE return c; } - public static FE operator >> (in FE a, int n) + public static FE operator >>(in FE a, int n) { a.RightShift(n, out FE res); return res; diff --git a/src/Nethermind/Nethermind.Verkle/Nethermind.Verkle.csproj b/src/Nethermind/Nethermind.Verkle/Nethermind.Verkle.csproj index c52b9488e9a..d686d20b593 100644 --- a/src/Nethermind/Nethermind.Verkle/Nethermind.Verkle.csproj +++ b/src/Nethermind/Nethermind.Verkle/Nethermind.Verkle.csproj @@ -9,9 +9,7 @@ - - - + diff --git a/src/Nethermind/Nethermind.Verkle/Polynomial/MonomialBasis.cs b/src/Nethermind/Nethermind.Verkle/Polynomial/MonomialBasis.cs index 0e0f2459609..d3792b4fff5 100644 --- a/src/Nethermind/Nethermind.Verkle/Polynomial/MonomialBasis.cs +++ b/src/Nethermind/Nethermind.Verkle/Polynomial/MonomialBasis.cs @@ -23,8 +23,8 @@ private static MonomialBasis Mul(MonomialBasis a, MonomialBasis b) { FrE[] output = new FrE[a.Length() + b.Length() - 1]; for (int i = 0; i < a.Length(); i++) - for (int j = 0; j < b.Length(); j++) - output[i + j] += a.Coeffs[i]! * b.Coeffs[j]!; + for (int j = 0; j < b.Length(); j++) + output[i + j] += a.Coeffs[i]! * b.Coeffs[j]!; return new MonomialBasis(output); } diff --git a/src/Nethermind/Nethermind.Verkle/Proofs/ProofStructs.cs b/src/Nethermind/Nethermind.Verkle/Proofs/ProofStructs.cs index 5e0d95b082d..776adcefa2d 100644 --- a/src/Nethermind/Nethermind.Verkle/Proofs/ProofStructs.cs +++ b/src/Nethermind/Nethermind.Verkle/Proofs/ProofStructs.cs @@ -156,4 +156,4 @@ public override string ToString() stringBuilder.Append(IpaProofSerialized.ToString()); return stringBuilder.ToString(); } -} \ No newline at end of file +} diff --git a/src/Nethermind/Nethermind.Verkle/Proofs/Queries.cs b/src/Nethermind/Nethermind.Verkle/Proofs/Queries.cs index 49ccd35c459..b1abd02acff 100644 --- a/src/Nethermind/Nethermind.Verkle/Proofs/Queries.cs +++ b/src/Nethermind/Nethermind.Verkle/Proofs/Queries.cs @@ -156,4 +156,4 @@ public override string ToString() stringBuilder.AppendJoin(", ", ChildHash); return stringBuilder.ToString(); } -} \ No newline at end of file +} diff --git a/src/Nethermind/Nethermind.VerkleMigration.Cli/Program.cs b/src/Nethermind/Nethermind.VerkleMigration.Cli/Program.cs index e8dc49fd7fa..27c993f1465 100644 --- a/src/Nethermind/Nethermind.VerkleMigration.Cli/Program.cs +++ b/src/Nethermind/Nethermind.VerkleMigration.Cli/Program.cs @@ -1,4 +1,4 @@ -using Nethermind.Api; +using Nethermind.Api; using Nethermind.Config; using Nethermind.Crypto; using Nethermind.Db;