diff --git a/.gitmodules b/.gitmodules index ab7a384e..a4f4ce54 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "src/Nethermind"] path = src/Nethermind url = https://github.com/NethermindEth/nethermind.git - branch = feature/arbitrum-setup + branch = master diff --git a/src/Nethermind b/src/Nethermind index 7d8dc587..eee5ac23 160000 --- a/src/Nethermind +++ b/src/Nethermind @@ -1 +1 @@ -Subproject commit 7d8dc5879012259c8ef7db0c4e566af1803f4c72 +Subproject commit eee5ac232a5cdb8f517aa0803db9e23a8e3a2e68 diff --git a/src/Nethermind.Arbitrum.Test/Arbos/ArbosGenesisLoaderTests.cs b/src/Nethermind.Arbitrum.Test/Arbos/ArbosGenesisLoaderTests.cs index a687b31b..47b0340f 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/ArbosGenesisLoaderTests.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/ArbosGenesisLoaderTests.cs @@ -1,15 +1,10 @@ using FluentAssertions; -using Nethermind.Arbitrum.Config; -using Nethermind.Arbitrum.Data; -using Nethermind.Arbitrum.Genesis; using Nethermind.Arbitrum.Test.Infrastructure; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Test; -using Nethermind.Logging; -using Nethermind.Specs.ChainSpecStyle; +using Nethermind.Evm.State; using Nethermind.State; -using NUnit.Framework; namespace Nethermind.Arbitrum.Test.Arbos; @@ -18,7 +13,11 @@ public class ArbosGenesisLoaderTests [Test] public void Load_FullChainSimulationAtV32_ProducesCorrectHash() { - (_, Block genesisBlock) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesisBlock = ArbOSInitialization.Create(worldState); genesisBlock.Hash.Should().Be(new Hash256("0xbd9f2163899efb7c39f945c9a7744b2c3ff12cfa00fe573dcb480a436c0803a8")); } diff --git a/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.BackedByBigInteger.cs b/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.BackedByBigInteger.cs index 62196008..5dedf812 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.BackedByBigInteger.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.BackedByBigInteger.cs @@ -1,8 +1,10 @@ -using System.Numerics; using FluentAssertions; using Nethermind.Arbitrum.Arbos.Storage; using Nethermind.Arbitrum.Test.Infrastructure; using Nethermind.Core.Crypto; +using Nethermind.Core.Test; +using System.Numerics; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Test.Arbos; @@ -25,7 +27,7 @@ public partial class ArbosStorageTests public void SetCheckedStorageBackedByBigInteger_Always_SetsAndGetsTheSameValue(string strValue, string expectedHash) { const ulong offset = 0ul; - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedBigInteger backedStorage = new(storage, offset); BigInteger value = BigInteger.Parse(strValue); @@ -47,7 +49,7 @@ public void SetCheckedStorageBackedByBigInteger_Always_SetsAndGetsTheSameValue(s public void SetCheckedStorageBackedByBigInteger_Overflow_Throws(string strValue) { const ulong offset = 0ul; - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedBigInteger backedStorage = new(storage, offset); BigInteger value = strValue switch @@ -77,7 +79,7 @@ public void SetCheckedStorageBackedByBigInteger_Overflow_Throws(string strValue) public void SetSaturatingStorageBackedByBigInteger_Always_SetsAndGetsTheSameValue(string strValue, string expectedHash) { const ulong offset = 0ul; - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedBigInteger backedStorage = new(storage, offset); BigInteger value = BigInteger.Parse(strValue); @@ -100,7 +102,7 @@ public void SetSaturatingStorageBackedByBigInteger_Underflow_UsesMaxUInt256Value BigInteger expectedValue = ArbosStorageBackedBigInteger.TwoToThe255 * -1; const ulong offset = 0ul; - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedBigInteger backedStorage = new(storage, offset); BigInteger value = strValue == "min" @@ -126,7 +128,7 @@ public void SetSaturatingStorageBackedByBigInteger_Overflow_UsesMaxUInt256MinusO BigInteger expectedValue = ArbosStorageBackedBigInteger.TwoToThe255MinusOne; const ulong offset = 0ul; - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedBigInteger backedStorage = new(storage, offset); BigInteger value = strValue == "max" @@ -160,7 +162,7 @@ public void SetSaturatingStorageBackedByBigInteger_Overflow_UsesMaxUInt256MinusO public void SetPreVersion7StorageBackedByBigInteger_Always_HandlesNegativeValuesIncorrectly(string strValue, string expectedHash) { const ulong offset = 0ul; - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedBigInteger backedStorage = new(storage, offset); BigInteger value = BigInteger.Parse(strValue); @@ -179,7 +181,7 @@ public void SetPreVersion7StorageBackedByBigInteger_Always_HandlesNegativeValues public void SetStorageBackedByBigInteger_Always_SetsAndGetsTheSameValue(ulong value) { const ulong offset = 0ul; - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedBigInteger backedStorage = new(storage, offset); backedStorage.Set(value); diff --git a/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.BackedByType.cs b/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.BackedByType.cs index fa820526..c1619897 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.BackedByType.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.BackedByType.cs @@ -17,7 +17,7 @@ public partial class ArbosStorageTests [TestCase(ulong.MaxValue, uint.MaxValue)] public void GetSetStorageBackedByUInt_Always_SetsAndGetsTheSameValue(ulong offset, uint value) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedUInt backedStorage = new(storage, offset); backedStorage.Set(value); @@ -34,7 +34,7 @@ public void GetSetStorageBackedByUInt_Always_SetsAndGetsTheSameValue(ulong offse [TestCase(ulong.MaxValue, ulong.MaxValue)] public void GetSetStorageBackedByULong_Always_SetsAndGetsTheSameValue(ulong offset, ulong value) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedULong backedStorage = new(storage, offset); backedStorage.Set(value); @@ -46,7 +46,7 @@ public void GetSetStorageBackedByULong_Always_SetsAndGetsTheSameValue(ulong offs [Test] public void IncrementStorageBackedByULong_IncrementULongMax_Throws() { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedULong backedStorage = new(storage, 10); backedStorage.Set(ulong.MaxValue); @@ -58,7 +58,7 @@ public void IncrementStorageBackedByULong_IncrementULongMax_Throws() [Test] public void IncrementStorageBackedByULong_Always_IncrementsCorrectly() { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedULong backedStorage = new(storage, 10); backedStorage.Get().Should().Be(0); @@ -71,7 +71,7 @@ public void IncrementStorageBackedByULong_Always_IncrementsCorrectly() [Test] public void DecrementStorageBackedByULong_DecrementZero_Throws() { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedULong backedStorage = new(storage, 10); var underflow = () => backedStorage.Decrement(); @@ -81,7 +81,7 @@ public void DecrementStorageBackedByULong_DecrementZero_Throws() [Test] public void DecrementStorageBackedByULong_Always_DecrementsCorrectly() { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedULong backedStorage = new(storage, 10); backedStorage.Set(3); @@ -101,7 +101,7 @@ public void DecrementStorageBackedByULong_Always_DecrementsCorrectly() [TestCase(ulong.MaxValue, "18446744073709551615999999999999")] // much larger than ulong.MaxValue public void GetSetStorageBackedByUInt256_Always_SetsAndGetsTheSameValue(ulong offset, string rawValue) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedUInt256 backedStorage = new(storage, offset); UInt256 value = UInt256.Parse(rawValue); @@ -116,7 +116,7 @@ public void GetSetStorageBackedByUInt256_Always_SetsAndGetsTheSameValue(ulong of [TestCase(100ul, "0x123456ffffffffffffffffffffffffffffffffff")] public void GetSetStorageBackedByAddress_Always_SetsAndGetsTheSameValue(ulong offset, string rawAddress) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedAddress backedStorage = new(storage, offset); Address value = new(rawAddress); @@ -133,7 +133,7 @@ public void GetSetStorageBackedByAddress_Always_SetsAndGetsTheSameValue(ulong of [TestCase(5, 200)] public void GetSetStorageBackedByBytes_Always_SetsAndGetsTheSameValue(byte offset, int length) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ArbosStorageBackedBytes backedStorage = new(storage.OpenSubStorage([offset])); byte[] value = RandomNumberGenerator.GetBytes(length); diff --git a/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.cs b/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.cs index ef6c2013..66265189 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.cs @@ -4,12 +4,13 @@ using Nethermind.Arbitrum.Arbos.Storage; using Nethermind.Arbitrum.Test.Infrastructure; using Nethermind.Arbitrum.Tracing; +using Nethermind.Blockchain.Tracing.GethStyle; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Evm; using Nethermind.Evm.CodeAnalysis; -using Nethermind.Evm.Tracing.GethStyle; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Test.Arbos; @@ -27,7 +28,7 @@ public partial class ArbosStorageTests [TestCase(1, 255, "0xdbdac6271f6e6f0b61b2d13ce15962a39f49ff9593aa09e53e4a9ce085ccd03b")] public void Set_Always_MapsAddressTheSameWayAsNitro(byte byte1, byte byte2, string cellHash) { - (ArbosStorage storage, TrackingWorldState worldState) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out TrackingWorldState worldState, out ArbosStorage storage, TestAccount); storage.Set(Hash256.FromBytesWithPadding([byte1, byte2]), Hash256.Zero); @@ -42,7 +43,7 @@ public void Set_Always_TrimsLeadingZeroes(byte byte1, byte byte2, byte byte3) { byte[] expectedValue = new[] { byte1, byte2, byte3 }.WithoutLeadingZeros().ToArray(); - (ArbosStorage storage, TrackingWorldState worldState) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out TrackingWorldState worldState, out ArbosStorage storage, TestAccount); storage.Set(Hash256.FromBytesWithPadding([1]), new ValueHash256(Bytes32(byte1, byte2, byte3))); @@ -55,7 +56,7 @@ public void Set_Always_TrimsLeadingZeroes(byte byte1, byte byte2, byte byte3) [TestCase(255, 255, 255)] public void SetGet_Always_GetReturnsWhatsSet(byte byte1, byte byte2, byte byte3) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ValueHash256 key = Hash256.FromBytesWithPadding([1]); ValueHash256 value = new Hash256(Bytes32(byte1, byte2, byte3)); @@ -70,7 +71,7 @@ public void SetGet_Always_GetReturnsWhatsSet(byte byte1, byte byte2, byte byte3) public void Get_Always_BurnsStorageReadCost() { SystemBurner systemBurner = new SystemBurner(); - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount, systemBurner); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount, systemBurner); storage.Get(Hash256.FromBytesWithPadding([1])); @@ -81,7 +82,7 @@ public void Get_Always_BurnsStorageReadCost() public void GetFree_Always_BurnsNothing() { SystemBurner systemBurner = new SystemBurner(); - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount, systemBurner); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount, systemBurner); storage.GetFree(Hash256.FromBytesWithPadding([1])); @@ -92,7 +93,7 @@ public void GetFree_Always_BurnsNothing() public void Set_ValueIsEmpty_BurnsStorageWriteZeroCost() { SystemBurner systemBurner = new SystemBurner(); - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount, systemBurner); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount, systemBurner); storage.Set(Hash256.FromBytesWithPadding([1]), Hash256.Zero); @@ -103,7 +104,7 @@ public void Set_ValueIsEmpty_BurnsStorageWriteZeroCost() public void Set_ValueIsNonEmpty_BurnsStorageWriteCost() { SystemBurner systemBurner = new SystemBurner(); - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount, systemBurner); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount, systemBurner); storage.Set(Hash256.FromBytesWithPadding([1]), new ValueHash256(Bytes32(1, 2, 3))); @@ -116,7 +117,7 @@ public void Set_ValueIsNonEmpty_BurnsStorageWriteCost() [TestCase(ulong.MaxValue)] public void GetSetULong_Always_SetsAndGetsProperValue(ulong value) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); storage.Set(Hash256.FromBytesWithPadding([1]), value); @@ -130,7 +131,7 @@ public void GetSetULong_Always_SetsAndGetsProperValue(ulong value) [TestCase(ulong.MaxValue)] public void GetSetByULong_Always_SetsAndGetsTheSameValue(ulong key) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ValueHash256 value = new ValueHash256(RandomNumberGenerator.GetBytes(Hash256.Size)); storage.Set(key, value); @@ -145,7 +146,7 @@ public void GetSetByULong_Always_SetsAndGetsTheSameValue(ulong key) [TestCase(ulong.MaxValue, ulong.MaxValue)] public void GetSetULongByULong_Always_SetsAndGetsTheSameValue(ulong key, ulong value) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); storage.Set(key, value); @@ -156,7 +157,7 @@ public void GetSetULongByULong_Always_SetsAndGetsTheSameValue(ulong key, ulong v [Test] public void Clear_Always_ClearsStorage() { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ValueHash256 key = Hash256.FromBytesWithPadding([1]); storage.Set(key, new ValueHash256(Bytes32(1, 2, 3))); @@ -169,7 +170,7 @@ public void Clear_Always_ClearsStorage() [Test] public void ClearByULong_Always_ClearsStorage() { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); ulong key = 999; storage.Set(key, new ValueHash256(Bytes32(1, 2, 3))); @@ -185,7 +186,7 @@ public void ClearByULong_Always_ClearsStorage() [TestCase(100)] public void GetBytesLength_Always_ReturnsCorrectLength(int length) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); byte[] value = RandomNumberGenerator.GetBytes(length); @@ -203,7 +204,7 @@ public void GetBytesLength_Always_ReturnsCorrectLength(int length) [TestCase(400)] public void SetBytesGetBytes_Always_SetsAndGetsTheSameValue(int length) { - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount); byte[] value = RandomNumberGenerator.GetBytes(length); @@ -217,7 +218,7 @@ public void SetBytesGetBytes_Always_SetsAndGetsTheSameValue(int length) [TestCase(100)] public void ClearBytes_Always_ClearsStorage(int length) { - (ArbosStorage storage, TrackingWorldState worldState) = TestArbosStorage.Create(TestAccount); + using var disposable = TestArbosStorage.Create(out TrackingWorldState worldState, out ArbosStorage storage, TestAccount); worldState.Commit(FullChainSimulationReleaseSpec.Instance); worldState.CommitTree(0); @@ -241,7 +242,7 @@ public void ClearBytes_Always_ClearsStorage(int length) public void GetCodeHash_Always_BurnsStorageReadCostAndGetsHash() { SystemBurner systemBurner = new SystemBurner(); - (ArbosStorage storage, TrackingWorldState worldState) = TestArbosStorage.Create(TestAccount, systemBurner); + using var disposable = TestArbosStorage.Create(out TrackingWorldState worldState, out ArbosStorage storage, TestAccount, systemBurner); // Insert random code to ensure the code hash is set. byte[] code = RandomNumberGenerator.GetBytes(Hash256.Size); @@ -263,7 +264,7 @@ public void GetCodeHash_Always_BurnsStorageReadCostAndGetsHash() public void CalculateHash_Always_BurnsProperCostAndReturnsHash(int bytesLength, ulong burnedCost) { SystemBurner systemBurner = new SystemBurner(); - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount, systemBurner); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount, systemBurner); ReadOnlySpan data = RandomNumberGenerator.GetBytes(bytesLength); ValueHash256 expected = Keccak.Compute(data); @@ -285,7 +286,7 @@ public void Trace_OnlyDuringEvm_RecordStorageGet(TracingScenario scenario) var tracingInfo = new TracingInfo(tracer, scenario, executionEnv); SystemBurner systemBurner = new SystemBurner(tracingInfo); - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount, systemBurner); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount, systemBurner); storage.Get(Hash256.FromBytesWithPadding([1])); @@ -314,7 +315,7 @@ public void Trace_OnlyDuringEvm_RecordStorageSet(TracingScenario scenario) var tracingInfo = new TracingInfo(tracer, scenario, executionEnv); SystemBurner systemBurner = new SystemBurner(tracingInfo); - (ArbosStorage storage, _) = TestArbosStorage.Create(TestAccount, systemBurner); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage, TestAccount, systemBurner); storage.Set(Hash256.FromBytesWithPadding([1]), Hash256.FromBytesWithPadding([2])); diff --git a/src/Nethermind.Arbitrum.Test/Arbos/Programs/StylusProgramsTests.cs b/src/Nethermind.Arbitrum.Test/Arbos/Programs/StylusProgramsTests.cs index b9656b80..b4588125 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/Programs/StylusProgramsTests.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/Programs/StylusProgramsTests.cs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System.Security.Cryptography; using FluentAssertions; using Nethermind.Arbitrum.Arbos; using Nethermind.Arbitrum.Arbos.Compression; @@ -11,6 +10,7 @@ using Nethermind.Arbitrum.Precompiles; using Nethermind.Arbitrum.Test.Arbos.Stylus.Infrastructure; using Nethermind.Arbitrum.Test.Infrastructure; +using Nethermind.Blockchain; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; @@ -18,8 +18,9 @@ using Nethermind.Core.Test.Builders; using Nethermind.Evm; using Nethermind.Evm.CodeAnalysis; +using Nethermind.Evm.State; using Nethermind.Int256; -using Nethermind.State; +using System.Security.Cryptography; namespace Nethermind.Arbitrum.Test.Arbos.Programs; @@ -41,7 +42,7 @@ public class StylusProgramsTests [Test] public void Initialize_EmptyState_InitializesState() { - (ArbosStorage storage, TrackingWorldState state) = TestArbosStorage.Create(); + using IDisposable disposable = TestArbosStorage.Create(out TrackingWorldState state, out ArbosStorage storage); StylusPrograms.Initialize(DefaultArbosVersion, storage); StylusPrograms programs = new(storage, DefaultArbosVersion); @@ -84,7 +85,9 @@ public void Initialize_EmptyState_InitializesState() [Test] public void ActivateProgram_NoProgram_Fails() { - (StylusPrograms programs, TrackingWorldState state, _) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, _) = CreateTestPrograms(state); Address randomAddress = new(RandomNumberGenerator.GetBytes(Address.Size)); ProgramActivationResult result = programs.ActivateProgram(randomAddress, state, 0, MessageRunMode.MessageCommitMode, true); @@ -96,7 +99,9 @@ public void ActivateProgram_NoProgram_Fails() [Test] public void ActivateProgram_AddressHasNoCode_Fails() { - (StylusPrograms programs, TrackingWorldState state, _) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, _) = CreateTestPrograms(state); Address contract = new(RandomNumberGenerator.GetBytes(Address.Size)); state.CreateAccountIfNotExists(contract, balance: 1, nonce: 0); @@ -112,7 +117,9 @@ public void ActivateProgram_AddressHasNoCode_Fails() [Test] public void ActivateProgram_ContractIsNotWasm_Fails() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state); (_, Address contract, BlockHeader header) = DeployCounterContract(state, repository, prependStylusPrefix: false); ProgramActivationResult result = programs.ActivateProgram(contract, state, header.Timestamp, MessageRunMode.MessageCommitMode, true); @@ -124,7 +131,9 @@ public void ActivateProgram_ContractIsNotWasm_Fails() [Test] public void ActivateProgram_ContractIsNotCompressed_Fails() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state); (_, Address contract, BlockHeader header) = DeployCounterContract(state, repository, compress: false); ProgramActivationResult result = programs.ActivateProgram(contract, state, header.Timestamp, MessageRunMode.MessageCommitMode, true); @@ -136,7 +145,9 @@ public void ActivateProgram_ContractIsNotCompressed_Fails() [Test] public void ActivateProgram_NotEnoughGasForActivation_FailsAndConsumesAllGas() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state); (_, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ProgramActivationResult result = programs.ActivateProgram(contract, state, header.Timestamp, MessageRunMode.MessageCommitMode, true); @@ -148,7 +159,9 @@ public void ActivateProgram_NotEnoughGasForActivation_FailsAndConsumesAllGas() [Test] public void ActivateProgram_ValidContractAndEnoughGas_Succeeds() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + ActivationBudget); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, InitBudget + ActivationBudget); (_, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ProgramActivationResult result = programs.ActivateProgram(contract, state, header.Timestamp, MessageRunMode.MessageCommitMode, true); @@ -161,7 +174,9 @@ public void ActivateProgram_ValidContractAndEnoughGas_Succeeds() [Test] public void CallProgram_ProgramIsNotActivated_Fails() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + CallBudget); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, InitBudget + CallBudget); (Address caller, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ICodeInfo codeInfo = repository.GetCachedCodeInfo(state, contract, ReleaseSpec, out _); @@ -179,7 +194,9 @@ public void CallProgram_ProgramIsNotActivated_Fails() [Test] public void CallProgram_StylusVersionIsHigherThanPrograms_Fails() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + ActivationBudget + CallBudget); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, InitBudget + ActivationBudget + CallBudget); (Address caller, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ICodeInfo codeInfo = repository.GetCachedCodeInfo(state, contract, ReleaseSpec, out _); @@ -204,7 +221,9 @@ public void CallProgram_StylusVersionIsHigherThanPrograms_Fails() [Test] public void CallProgram_ProgramExpired_Fails() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + ActivationBudget + CallBudget); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, InitBudget + ActivationBudget + CallBudget); (Address caller, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ICodeInfo codeInfo = repository.GetCachedCodeInfo(state, contract, ReleaseSpec, out _); @@ -229,7 +248,9 @@ public void CallProgram_ProgramExpired_Fails() [Test] public void CallProgram_CorruptedCallData_Fails() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + ActivationBudget + CallBudget); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, InitBudget + ActivationBudget + CallBudget); (Address caller, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ICodeInfo codeInfo = repository.GetCachedCodeInfo(state, contract, ReleaseSpec, out _); @@ -250,7 +271,9 @@ public void CallProgram_CorruptedCallData_Fails() [Test] public void CallProgram_SetGetNumber_SuccessfullySetsAndGets() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: (InitBudget + ActivationBudget + CallBudget) * 10); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, (InitBudget + ActivationBudget + CallBudget) * 10); (Address caller, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ICodeInfo codeInfo = repository.GetCachedCodeInfo(state, contract, ReleaseSpec, out _); @@ -281,7 +304,9 @@ public void CallProgram_SetGetNumber_SuccessfullySetsAndGets() [Test] public void CallProgram_IncrementNumber_SuccessfullyIncrements() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: (InitBudget + ActivationBudget + CallBudget) * 10); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, (InitBudget + ActivationBudget + CallBudget) * 10); (Address caller, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ICodeInfo codeInfo = repository.GetCachedCodeInfo(state, contract, ReleaseSpec, out _); @@ -360,7 +385,9 @@ private EvmState CreateEvmState(IWorldState state, Address caller, Address contr [Test] public void ProgramKeepalive_WithNonActivatedProgram_ThrowsInvalidOperation() { - (StylusPrograms programs, TrackingWorldState _, _) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, _) = CreateTestPrograms(state); Hash256 nonActivatedCodeHash = Hash256.Zero; ulong timestamp = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); StylusParams stylusParams = programs.GetParams(); @@ -374,7 +401,9 @@ public void ProgramKeepalive_WithNonActivatedProgram_ThrowsInvalidOperation() [Test] public void ProgramKeepalive_WithTooEarlyKeepalive_ThrowsInvalidOperation() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + ActivationBudget * 10); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, availableGas: InitBudget + ActivationBudget * 10); (_, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ValueHash256 codeHash = state.GetCodeHash(contract); @@ -394,7 +423,9 @@ public void ProgramKeepalive_WithTooEarlyKeepalive_ThrowsInvalidOperation() [Test] public void CodeHashVersion_WithNonActivatedProgram_ReturnsZero() { - (StylusPrograms programs, TrackingWorldState _, _) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, _) = CreateTestPrograms(state); Hash256 nonActivatedCodeHash = Hash256.Zero; ulong timestamp = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); StylusParams stylusParams = programs.GetParams(); @@ -407,7 +438,9 @@ public void CodeHashVersion_WithNonActivatedProgram_ReturnsZero() [Test] public void CodeHashVersion_WithActivatedProgram_ReturnsVersion() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + ActivationBudget * 10); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, availableGas: InitBudget + ActivationBudget * 10); (_, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ValueHash256 codeHash = state.GetCodeHash(contract); @@ -426,7 +459,9 @@ public void CodeHashVersion_WithActivatedProgram_ReturnsVersion() [Test] public void ProgramAsmSize_WithNonActivatedProgram_ThrowsInvalidOperation() { - (StylusPrograms programs, TrackingWorldState _, _) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository _) = CreateTestPrograms(state); Hash256 nonActivatedCodeHash = Hash256.Zero; ulong timestamp = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); StylusParams stylusParams = programs.GetParams(); @@ -440,7 +475,9 @@ public void ProgramAsmSize_WithNonActivatedProgram_ThrowsInvalidOperation() [Test] public void ProgramAsmSize_WithActivatedProgram_ReturnsSize() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + ActivationBudget * 10); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, availableGas: InitBudget + ActivationBudget * 10); (_, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ValueHash256 codeHash = state.GetCodeHash(contract); @@ -459,7 +496,9 @@ public void ProgramAsmSize_WithActivatedProgram_ReturnsSize() [Test] public void ProgramInitGas_WithNonActivatedProgram_ThrowsInvalidOperation() { - (StylusPrograms programs, TrackingWorldState _, _) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, _) = CreateTestPrograms(state); ValueHash256 nonActivatedCodeHash = Hash256.Zero; ulong timestamp = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); StylusParams stylusParams = programs.GetParams(); @@ -473,7 +512,9 @@ public void ProgramInitGas_WithNonActivatedProgram_ThrowsInvalidOperation() [Test] public void ProgramInitGas_WithActivatedProgram_ReturnsGasValues() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + ActivationBudget * 10); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, availableGas: InitBudget + ActivationBudget * 10); (_, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ValueHash256 codeHash = state.GetCodeHash(contract); @@ -493,7 +534,9 @@ public void ProgramInitGas_WithActivatedProgram_ReturnsGasValues() [Test] public void ProgramMemoryFootprint_WithNonActivatedProgram_ThrowsInvalidOperation() { - (StylusPrograms programs, TrackingWorldState _, _) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, _) = CreateTestPrograms(state); ValueHash256 nonActivatedCodeHash = Hash256.Zero; ulong timestamp = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); StylusParams stylusParams = programs.GetParams(); @@ -507,7 +550,9 @@ public void ProgramMemoryFootprint_WithNonActivatedProgram_ThrowsInvalidOperatio [Test] public void ProgramMemoryFootprint_WithActivatedProgram_ReturnsFootprint() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + ActivationBudget * 10); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, availableGas: InitBudget + ActivationBudget * 10); (_, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ValueHash256 codeHash = state.GetCodeHash(contract); @@ -525,7 +570,9 @@ public void ProgramMemoryFootprint_WithActivatedProgram_ReturnsFootprint() [Test] public void ProgramTimeLeft_WithNonActivatedProgram_ThrowsInvalidOperation() { - (StylusPrograms programs, TrackingWorldState _, _) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, _) = CreateTestPrograms(state); ValueHash256 nonActivatedCodeHash = Hash256.Zero; ulong timestamp = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); StylusParams stylusParams = programs.GetParams(); @@ -539,7 +586,9 @@ public void ProgramTimeLeft_WithNonActivatedProgram_ThrowsInvalidOperation() [Test] public void ProgramTimeLeft_WithActivatedProgram_ReturnsTimeLeft() { - (StylusPrograms programs, TrackingWorldState state, ICodeInfoRepository repository) = CreateTestPrograms(availableGas: InitBudget + ActivationBudget * 10); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, ICodeInfoRepository repository) = CreateTestPrograms(state, availableGas: InitBudget + ActivationBudget * 10); (_, Address contract, BlockHeader header) = DeployCounterContract(state, repository); ValueHash256 codeHash = state.GetCodeHash(contract); @@ -557,7 +606,9 @@ public void ProgramTimeLeft_WithActivatedProgram_ReturnsTimeLeft() [Test] public void GetParams_Always_ReturnsValidParams() { - (StylusPrograms programs, _, _) = CreateTestPrograms(); + TrackingWorldState state = TrackingWorldState.CreateNewInMemory(); + state.BeginScope(IWorldState.PreGenesis); + (StylusPrograms programs, _) = CreateTestPrograms(state); StylusParams stylusParams = programs.GetParams(); @@ -567,17 +618,17 @@ public void GetParams_Always_ReturnsValidParams() stylusParams.MaxStackDepth.Should().Be(262144u); // InitialStackDepth } - private static (StylusPrograms programs, TrackingWorldState state, ArbitrumCodeInfoRepository repository) CreateTestPrograms(ulong availableGas = InitBudget) + private static (StylusPrograms programs, ArbitrumCodeInfoRepository repository) CreateTestPrograms(TrackingWorldState state, ulong availableGas = InitBudget) { StylusTargets.PopulateStylusTargetCache(new StylusTargetConfig()); - ArbitrumCodeInfoRepository repository = new(new CodeInfoRepository()); + ArbitrumCodeInfoRepository repository = new(new EthereumCodeInfoRepository()); TestArbosStorage.TestBurner burner = new(availableGas, null); - (ArbosStorage storage, TrackingWorldState state) = TestArbosStorage.Create(burner: burner); + var storage = TestArbosStorage.Create(state, burner: burner); StylusPrograms.Initialize(DefaultArbosVersion, storage); StylusPrograms programs = new(storage, DefaultArbosVersion); - return (programs, state, repository); + return (programs, repository); } } diff --git a/src/Nethermind.Arbitrum.Test/Arbos/Storage/AddressSetTests.cs b/src/Nethermind.Arbitrum.Test/Arbos/Storage/AddressSetTests.cs index 8b490c68..f2264422 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/Storage/AddressSetTests.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/Storage/AddressSetTests.cs @@ -11,7 +11,7 @@ public class AddressSetTests [Test] public void Initialize_NewSet_SetsSizeToZero() { - (ArbosStorage storage, TrackingWorldState state) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out TrackingWorldState state, out ArbosStorage storage); AddressSet.Initialize(storage); storage.GetULong(0).Should().Be(0); @@ -21,7 +21,7 @@ public void Initialize_NewSet_SetsSizeToZero() [Test] public void Size_EmptySet_ReturnsZero() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -33,7 +33,7 @@ public void Size_EmptySet_ReturnsZero() [TestCase(3u)] public void Size_HasMember_ReturnsCorrectSize(ulong size) { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -48,7 +48,7 @@ public void Size_HasMember_ReturnsCorrectSize(ulong size) [Test] public void IsMember_EmptySet_ReturnsFalse() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -60,7 +60,7 @@ public void IsMember_EmptySet_ReturnsFalse() [Test] public void IsMember_HasMember_ReturnsTrue() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -73,7 +73,7 @@ public void IsMember_HasMember_ReturnsTrue() [Test] public void AllMembers_EmptySet_ReturnsEmptyCollection() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -84,7 +84,7 @@ public void AllMembers_EmptySet_ReturnsEmptyCollection() [TestCase(5, 6)] public void AllMembers_QueryWithConstraint_ReturnsCorrectNumber(byte totalMembers, byte queryCount) { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -102,7 +102,7 @@ public void AllMembers_QueryWithConstraint_ReturnsCorrectNumber(byte totalMember [Test] public void ClearList_HasMembers_ClearsAllMembers() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -118,7 +118,7 @@ public void ClearList_HasMembers_ClearsAllMembers() [Test] public void Remove_NoSuchMember_DoesNothing() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -132,7 +132,7 @@ public void Remove_NoSuchMember_DoesNothing() [Test] public void Remove_HasMember_RemovesMember() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -147,7 +147,7 @@ public void Remove_HasMember_RemovesMember() [Test] public void Remove_HasMultipleMembers_ReordersAfterRemoval() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -166,7 +166,7 @@ public void Remove_HasMultipleMembers_ReordersAfterRemoval() [Test] public void Remove_RemoveAllMembers_ClearsAllMembers() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -188,7 +188,7 @@ public void Remove_RemoveAllMembers_ClearsAllMembers() [Test] public void RectifyMapping_AddressIsNotMember_Throws() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -201,7 +201,7 @@ public void RectifyMapping_AddressIsNotMember_Throws() [Test] public void RectifyMapping_MappingIsCorrect_Throws() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); @@ -215,7 +215,7 @@ public void RectifyMapping_MappingIsCorrect_Throws() [Test] public void RectifyMapping_MappingIsIncorrect_CorrectsMapping() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); AddressSet.Initialize(storage); AddressSet addressSet = new(storage); diff --git a/src/Nethermind.Arbitrum.Test/Arbos/Storage/AddressTableTests.cs b/src/Nethermind.Arbitrum.Test/Arbos/Storage/AddressTableTests.cs index 01bf2285..a06dea34 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/Storage/AddressTableTests.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/Storage/AddressTableTests.cs @@ -18,7 +18,7 @@ public sealed class AddressTableTests [Test] public void Initialize_OnNewStorage_CreatesEmptyTable() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); AddressTable.Initialize(storage); var addressTable = new AddressTable(storage); @@ -35,7 +35,7 @@ public void Initialize_OnNewStorage_CreatesEmptyTable() [Test] public void Register_WithNewAddress_ReturnsZeroIndex() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); @@ -48,7 +48,7 @@ public void Register_WithNewAddress_ReturnsZeroIndex() [Test] public void Register_WithExistingAddress_ReturnsSameIndex() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); @@ -62,7 +62,7 @@ public void Register_WithExistingAddress_ReturnsSameIndex() [Test] public void Register_WithMultipleAddresses_AssignsSequentialIndices() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var address1 = new Address("0x1111111111111111111111111111111111111111"); var address2 = new Address("0x2222222222222222222222222222222222222222"); @@ -81,7 +81,7 @@ public void Register_WithMultipleAddresses_AssignsSequentialIndices() [Test] public void Lookup_WithExistingAddress_ReturnsCorrectIndex() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); var expectedIndex = addressTable.Register(testAddress); @@ -95,7 +95,7 @@ public void Lookup_WithExistingAddress_ReturnsCorrectIndex() [Test] public void Lookup_WithNonExistentAddress_ReturnsNotFound() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); @@ -107,7 +107,7 @@ public void Lookup_WithNonExistentAddress_ReturnsNotFound() [Test] public void AddressExists_WithRegisteredAddress_ReturnsTrue() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); addressTable.Register(testAddress); @@ -120,7 +120,7 @@ public void AddressExists_WithRegisteredAddress_ReturnsTrue() [Test] public void AddressExists_WithUnregisteredAddress_ReturnsFalse() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); @@ -132,7 +132,7 @@ public void AddressExists_WithUnregisteredAddress_ReturnsFalse() [Test] public void LookupIndex_WithValidIndex_ReturnsCorrectAddress() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); var index = addressTable.Register(testAddress); @@ -146,7 +146,7 @@ public void LookupIndex_WithValidIndex_ReturnsCorrectAddress() [Test] public void LookupIndex_OnEmptyTable_ReturnsNotFound() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var (_, found) = addressTable.LookupIndex(0); @@ -157,7 +157,7 @@ public void LookupIndex_OnEmptyTable_ReturnsNotFound() [Test] public void LookupIndex_WithOutOfRangeIndex_ReturnsNotFound() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); addressTable.Register(testAddress); @@ -170,7 +170,7 @@ public void LookupIndex_WithOutOfRangeIndex_ReturnsNotFound() [Test] public void Compress_WithUnregisteredAddress_ReturnsFullAddress() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); @@ -187,7 +187,7 @@ public void Compress_WithUnregisteredAddress_ReturnsFullAddress() [Test] public void Compress_WithRegisteredAddress_ReturnsCompressedIndex() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); addressTable.Register(testAddress); @@ -201,7 +201,7 @@ public void Compress_WithRegisteredAddress_ReturnsCompressedIndex() [Test] public void Decompress_WithFullAddressData_ReturnsOriginalAddress() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); var compressed = addressTable.Compress(testAddress); @@ -215,7 +215,7 @@ public void Decompress_WithFullAddressData_ReturnsOriginalAddress() [Test] public void Decompress_WithCompressedIndexData_ReturnsOriginalAddress() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); addressTable.Register(testAddress); @@ -230,7 +230,7 @@ public void Decompress_WithCompressedIndexData_ReturnsOriginalAddress() [Test] public void Decompress_WithInvalidIndex_ThrowsInvalidOperationException() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); // Create compressed data with invalid index (999) @@ -244,7 +244,7 @@ public void Decompress_WithInvalidIndex_ThrowsInvalidOperationException() [Test] public void CompressAndDecompress_InSequence_PreservesOriginalAddress() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var addressTable = new AddressTable(storage); ReadOnlySpan
testAddresses = [ @@ -269,7 +269,7 @@ public void CompressAndDecompress_InSequence_PreservesOriginalAddress() [Test] public void AddressTable_WithSameStorage_PreservesStateAcrossInstances() { - var storage = CreateStorage(); + TestArbosStorage.Create(out _, out ArbosStorage storage); var testAddress = new Address("0x1234567890123456789012345678901234567890"); // First instance - register address @@ -289,12 +289,4 @@ public void AddressTable_WithSameStorage_PreservesStateAcrossInstances() indexFound.Should().BeTrue(); lookupAddress.Should().Be(testAddress); } - - private static ArbosStorage CreateStorage() - { - var worldState = TrackingWorldState.CreateNewInMemory(); - worldState.CreateAccountIfNotExists(TestAccount, UInt256.Zero, UInt256.One); - var burner = new SystemBurner(); - return new ArbosStorage(worldState, burner, TestAccount); - } } diff --git a/src/Nethermind.Arbitrum.Test/Arbos/Storage/BatchPostersTableTests.cs b/src/Nethermind.Arbitrum.Test/Arbos/Storage/BatchPostersTableTests.cs index ecdf8dfd..89b4c7db 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/Storage/BatchPostersTableTests.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/Storage/BatchPostersTableTests.cs @@ -12,7 +12,7 @@ public class BatchPostersTableTests [Test] public void Initialize_NewTable_InitializesTotalFundsDueAndAddressSet() { - (ArbosStorage storage, TrackingWorldState state) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out TrackingWorldState state, out ArbosStorage storage); BatchPostersTable.Initialize(storage); @@ -24,7 +24,7 @@ public void Initialize_NewTable_InitializesTotalFundsDueAndAddressSet() [Test] public void AddPoster_NewPoster_AddsPosterAndInitializesStorage() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -40,7 +40,7 @@ public void AddPoster_NewPoster_AddsPosterAndInitializesStorage() [Test] public void AddPoster_ExistingPoster_Throws() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -56,7 +56,7 @@ public void AddPoster_ExistingPoster_Throws() [Test] public void ContainsPoster_NoPoster_ReturnsFalse() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -66,7 +66,7 @@ public void ContainsPoster_NoPoster_ReturnsFalse() [Test] public void ContainsPoster_HasPoster_ReturnsTrue() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -80,7 +80,7 @@ public void ContainsPoster_HasPoster_ReturnsTrue() [Test] public void GetAllPosters_EmptyTable_ReturnsEmptyCollection() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -91,7 +91,7 @@ public void GetAllPosters_EmptyTable_ReturnsEmptyCollection() [TestCase(3u, 5u)] public void GetAllPosters_HasPosters_ReturnsCorrectCount(ulong numPosters, ulong maxNumToReturn) { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -109,7 +109,7 @@ public void GetAllPosters_HasPosters_ReturnsCorrectCount(ulong numPosters, ulong [Test] public void OpenPoster_HasPoster_ReturnsPoster() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -126,7 +126,7 @@ public void OpenPoster_HasPoster_ReturnsPoster() [Test] public void OpenPoster_NoPosterAndAutocreate_CreatesPoster() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -140,7 +140,7 @@ public void OpenPoster_NoPosterAndAutocreate_CreatesPoster() [Test] public void OpenPoster_NoPosterDontAutocreate_Throws() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -153,7 +153,7 @@ public void OpenPoster_NoPosterDontAutocreate_Throws() [Test] public void SetFundsDueSaturating_Always_SetsPostersFundsDueAndUpdatesTotal() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -170,7 +170,7 @@ public void SetFundsDueSaturating_Always_SetsPostersFundsDueAndUpdatesTotal() [Test] public void SetFundsDueSaturating_ChangePostersFundsDue_AppliesChangeCorrectly() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -187,7 +187,7 @@ public void SetFundsDueSaturating_ChangePostersFundsDue_AppliesChangeCorrectly() [Test] public void SetFundsDueSaturating_MultiplePostersFundsDue_CalculatesTotalCorrectly() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); @@ -203,7 +203,7 @@ public void SetFundsDueSaturating_MultiplePostersFundsDue_CalculatesTotalCorrect [Test] public void SetFundsDueSaturating_SaturatedFundsDue_SetsSaturatedValue() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); BatchPostersTable.Initialize(storage); BatchPostersTable postersTable = new(storage); diff --git a/src/Nethermind.Arbitrum.Test/Arbos/Storage/L1PricingTests.cs b/src/Nethermind.Arbitrum.Test/Arbos/Storage/L1PricingTests.cs index 5fb030fb..91632b7b 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/Storage/L1PricingTests.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/Storage/L1PricingTests.cs @@ -7,7 +7,6 @@ using Nethermind.Core.Test.Builders; using Nethermind.Int256; using Nethermind.Logging; -using Nethermind.State; using FluentAssertions; using Nethermind.Arbitrum.Execution; @@ -19,7 +18,7 @@ internal class L1PricingTests [TestCaseSource(nameof(GetL1PricingTests))] public void UpdateForBatchPosterSpending_CorrectlyCalculates_FundsDue(L1PricingTestData testItem) { - (ArbosStorage storage, IWorldState worldState) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out TrackingWorldState worldState, out ArbosStorage storage); worldState.CreateAccountIfNotExists(TestArbosStorage.DefaultTestAccount, UInt256.Zero, UInt256.One); storage.Set(ArbosStateOffsets.VersionOffset, 32); @@ -71,7 +70,7 @@ public void UpdateForBatchPosterSpending_CorrectlyCalculates_FundsDue(L1PricingT [TestCase(2_000_000_000UL, 2_000_000_000UL)] public void UpdateForBatchPosterSpending_CorrectlyCalculates_PriceChange(ulong initialL1BasefeeEstimate, ulong equilibriumL1BasefeeEstimate) { - (ArbosStorage storage, IWorldState worldState) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out TrackingWorldState worldState, out ArbosStorage storage); worldState.CreateAccountIfNotExists(TestArbosStorage.DefaultTestAccount, UInt256.Zero, UInt256.One); storage.Set(ArbosStateOffsets.VersionOffset, 3); @@ -118,7 +117,7 @@ public void UpdateForBatchPosterSpending_CorrectlyCalculates_PriceChange(ulong i [TestCase(32UL, false, "insufficient sender balance")] public void UpdateForBatchPosterSpending_NotEnoughBalanceForL1Fees_ReturnsCorrectResult(ulong version, bool success, string? error) { - (ArbosStorage storage, IWorldState worldState) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out TrackingWorldState worldState, out ArbosStorage storage); worldState.CreateAccountIfNotExists(TestArbosStorage.DefaultTestAccount, UInt256.Zero, UInt256.One); storage.Set(ArbosStateOffsets.VersionOffset, version); diff --git a/src/Nethermind.Arbitrum.Test/Arbos/Storage/MerkleAccumulatorTests.cs b/src/Nethermind.Arbitrum.Test/Arbos/Storage/MerkleAccumulatorTests.cs index cf34cc5f..113aefd9 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/Storage/MerkleAccumulatorTests.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/Storage/MerkleAccumulatorTests.cs @@ -12,7 +12,7 @@ public class MerkleAccumulatorTests [Test] public void CalculateRoot_EmptyAccumulator_ReturnsZeroHash() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); MerkleAccumulator accumulator = new(storage); accumulator.CalculateRoot().Should().Be(default); @@ -21,7 +21,7 @@ public void CalculateRoot_EmptyAccumulator_ReturnsZeroHash() [Test] public void CalculateRoot_SingleNode_ReturnsCorrectRootAndSize() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); MerkleAccumulator accumulator = new(storage); ValueHash256 node = new(RandomNumberGenerator.GetBytes(Hash256.Size)); @@ -36,7 +36,7 @@ public void CalculateRoot_SingleNode_ReturnsCorrectRootAndSize() [Test] public void CalculateRoot_3Nodes_ReturnsCorrectRootAndSize() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); MerkleAccumulator accumulator = new(storage); ValueHash256 node1 = new(RandomNumberGenerator.GetBytes(Hash256.Size)); @@ -65,7 +65,7 @@ public void CalculateRoot_3Nodes_ReturnsCorrectRootAndSize() [Test] public void CalculateRoot_4Nodes_ReturnsCorrectRootAndSize() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); MerkleAccumulator accumulator = new(storage); ValueHash256 node1 = new(RandomNumberGenerator.GetBytes(Hash256.Size)); @@ -101,7 +101,7 @@ public void CalculateRoot_4Nodes_ReturnsCorrectRootAndSize() [Test] public void GetExportState_3Nodes_ReturnsCorrectState() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); MerkleAccumulator accumulator = new(storage); accumulator.Append(new("0x0000000000000000000000000000000000000000000000000000000000000001")); @@ -122,7 +122,7 @@ public void GetExportState_3Nodes_ReturnsCorrectState() [Test] public void GetExportState_4Nodes_ReturnsCorrectState() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); MerkleAccumulator accumulator = new(storage); accumulator.Append(new("0x0000000000000000000000000000000000000000000000000000000000000001")); diff --git a/src/Nethermind.Arbitrum.Test/Arbos/Storage/StorageQueueTests.cs b/src/Nethermind.Arbitrum.Test/Arbos/Storage/StorageQueueTests.cs index 3d53b24d..677c5f90 100644 --- a/src/Nethermind.Arbitrum.Test/Arbos/Storage/StorageQueueTests.cs +++ b/src/Nethermind.Arbitrum.Test/Arbos/Storage/StorageQueueTests.cs @@ -12,7 +12,7 @@ public class StorageQueueTests [Test] public void Initialize_NewQueue_CreatesNextPushAndNextPopOffsets() { - (ArbosStorage storage, TrackingWorldState state) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out TrackingWorldState state, out ArbosStorage storage); StorageQueue.Initialize(storage); @@ -24,7 +24,7 @@ public void Initialize_NewQueue_CreatesNextPushAndNextPopOffsets() [Test] public void IsEmpty_EmptyQueue_ReturnsTrue() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); StorageQueue.Initialize(storage); StorageQueue queue = new(storage); @@ -36,7 +36,7 @@ public void IsEmpty_EmptyQueue_ReturnsTrue() [Test] public void Peek_EmptyQueue_ReturnsDefault() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); StorageQueue.Initialize(storage); StorageQueue queue = new(storage); @@ -46,7 +46,7 @@ public void Peek_EmptyQueue_ReturnsDefault() [Test] public void Peek_HasValueInQueue_ReturnsValue() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); StorageQueue.Initialize(storage); StorageQueue queue = new(storage); @@ -62,7 +62,7 @@ public void Peek_HasValueInQueue_ReturnsValue() [Test] public void Pop_EmptyQueue_ReturnsDefault() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); StorageQueue.Initialize(storage); StorageQueue queue = new(storage); @@ -72,7 +72,7 @@ public void Pop_EmptyQueue_ReturnsDefault() [Test] public void Pop_HasValueInQueue_ReturnsValueAndRemovesIt() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); StorageQueue.Initialize(storage); StorageQueue queue = new(storage); @@ -88,7 +88,7 @@ public void Pop_HasValueInQueue_ReturnsValueAndRemovesIt() [Test] public void Size_EmptyQueue_ReturnsZero() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); StorageQueue.Initialize(storage); StorageQueue queue = new(storage); @@ -100,7 +100,7 @@ public void Size_EmptyQueue_ReturnsZero() [TestCase(3u)] public void Size_HasValuesInQueue_ReturnsCorrectSize(ulong count) { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); StorageQueue.Initialize(storage); StorageQueue queue = new(storage); @@ -115,7 +115,7 @@ public void Size_HasValuesInQueue_ReturnsCorrectSize(ulong count) [Test] public void ForEach_EmptyQueue_DoesNotInvokeHandler() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); StorageQueue.Initialize(storage); StorageQueue queue = new(storage); @@ -128,7 +128,7 @@ public void ForEach_EmptyQueue_DoesNotInvokeHandler() [Test] public void ForEach_HasValuesInQueue_InvokesHandlerForEachValue() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); StorageQueue.Initialize(storage); StorageQueue queue = new(storage); @@ -150,7 +150,7 @@ public void ForEach_HasValuesInQueue_InvokesHandlerForEachValue() [Test] public void ForEach_HandlerReturnsTrue_StopsProcessing() { - (ArbosStorage storage, _) = TestArbosStorage.Create(); + using var disposable = TestArbosStorage.Create(out _, out ArbosStorage storage); StorageQueue.Initialize(storage); StorageQueue queue = new(storage); diff --git a/src/Nethermind.Arbitrum.Test/BlockProcessing/ArbitrumTxReceiptsTests.cs b/src/Nethermind.Arbitrum.Test/BlockProcessing/ArbitrumTxReceiptsTests.cs index 5204e3b2..5b8ff5e1 100644 --- a/src/Nethermind.Arbitrum.Test/BlockProcessing/ArbitrumTxReceiptsTests.cs +++ b/src/Nethermind.Arbitrum.Test/BlockProcessing/ArbitrumTxReceiptsTests.cs @@ -6,9 +6,9 @@ using Nethermind.Consensus.Producers; using Nethermind.Core; using Nethermind.Core.Test.Builders; +using Nethermind.Evm.State; using Nethermind.Int256; using Nethermind.Logging; -using Nethermind.State; namespace Nethermind.Arbitrum.Test.BlockProcessing; @@ -31,12 +31,12 @@ public void BlockProcessing_TransactionProcessed_ReceiptHasProperGasUsedForL1() .SignedAndResolved(TestItem.PrivateKeyA) .TestObject; + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); BlockToProduce block = BlockProcessingUtilities.CreateBlockFromTx(chain, transferTx, _baseFeePerGas); ArbitrumTxReceipt receipt = (ArbitrumTxReceipt)BlockProcessingUtilities.ProcessBlockWithInternalTx(chain, block)[1]; ulong callDataUnits = BlockProcessingUtilities.GetCallDataUnits(chain.WorldStateManager.GlobalWorldState, transferTx); ulong posterGas = GetPosterGas(chain.WorldStateManager.GlobalWorldState, _baseFeePerGas, callDataUnits); - receipt.GasUsedForL1.Should().Be(posterGas); } diff --git a/src/Nethermind.Arbitrum.Test/BlockProcessing/BlockProcessorTests.cs b/src/Nethermind.Arbitrum.Test/BlockProcessing/BlockProcessorTests.cs index e88ca0ef..1097c570 100644 --- a/src/Nethermind.Arbitrum.Test/BlockProcessing/BlockProcessorTests.cs +++ b/src/Nethermind.Arbitrum.Test/BlockProcessing/BlockProcessorTests.cs @@ -4,16 +4,16 @@ using Nethermind.Arbitrum.Execution.Transactions; using Nethermind.Arbitrum.Test.Infrastructure; using Nethermind.Arbitrum.Test.Precompiles; +using Nethermind.Blockchain.Tracing; using Nethermind.Consensus.Processing; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; using Nethermind.Evm; -using Nethermind.Evm.Tracing; +using Nethermind.Evm.State; using Nethermind.Int256; using Nethermind.Logging; -using Nethermind.State; namespace Nethermind.Arbitrum.Test.BlockProcessing { @@ -83,6 +83,8 @@ public void ProcessTransactions_SubmitRetryable_CreatesRetryTx() []), body); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var dispose = worldState.BeginScope(chain.BlockTree.Head!.Header); + var arbosState = ArbosState.OpenArbosState(worldState, new SystemBurner(), LimboLogs.Instance.GetLogger("arbosState")); newBlock.Header.BaseFeePerGas = arbosState.L2PricingState.BaseFeeWeiStorage.Get(); @@ -97,8 +99,7 @@ public void ProcessTransactions_SubmitRetryable_CreatesRetryTx() var blockTracer = new BlockReceiptsTracer(); blockTracer.StartNewBlockTrace(newBlock); - chain.BlockProcessor.Process(chain.BlockTree.Head?.StateRoot ?? Keccak.EmptyTreeHash, - [newBlock], ProcessingOptions.ProducingBlock, blockTracer); + chain.BlockProcessor.ProcessOne(newBlock, ProcessingOptions.ProducingBlock, blockTracer, chain.SpecProvider.GenesisSpec); blockTracer.EndBlockTrace(); diff --git a/src/Nethermind.Arbitrum.Test/BlockProcessing/BlockProducerTests.cs b/src/Nethermind.Arbitrum.Test/BlockProcessing/BlockProducerTests.cs index c3d632e3..514a98ac 100644 --- a/src/Nethermind.Arbitrum.Test/BlockProcessing/BlockProducerTests.cs +++ b/src/Nethermind.Arbitrum.Test/BlockProcessing/BlockProducerTests.cs @@ -6,15 +6,16 @@ using Nethermind.Arbitrum.Execution.Transactions; using Nethermind.Arbitrum.Precompiles; using Nethermind.Arbitrum.Test.Infrastructure; +using Nethermind.Blockchain.Tracing; using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; using Nethermind.Evm; -using Nethermind.Evm.Tracing; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Serialization.Rlp; +using Nethermind.State; namespace Nethermind.Arbitrum.Test.BlockProcessing { @@ -85,7 +86,7 @@ public void BuildBlock_SignedTransaction_RecoversSenderAddressFromSignature() }; ArbitrumRpcTestBlockchain chain = ArbitrumRpcTestBlockchain.CreateDefault(preConfigurer); - + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); ArbosState arbosState = ArbosState.OpenArbosState(chain.WorldStateManager.GlobalWorldState, new SystemBurner(), LimboNoErrorLogger.Instance); @@ -165,7 +166,7 @@ public void BuildBlock_WhenTimestampSmallerThanParents_SetsAsParents() chain.BlockTree.SuggestBlock(block1!); ManualResetEventSlim blockProcessedEvent = new(false); - chain.BlockProcessor.BlockProcessed += (_, _) => + chain.BranchProcessor.BlockProcessed += (_, _) => { chain.BlockTree.UpdateMainChain([block1!], true); blockProcessedEvent.Set(); diff --git a/src/Nethermind.Arbitrum.Test/BlockProcessing/CachedL1PriceDataTests.cs b/src/Nethermind.Arbitrum.Test/BlockProcessing/CachedL1PriceDataTests.cs index 3fc89637..6990efc8 100644 --- a/src/Nethermind.Arbitrum.Test/BlockProcessing/CachedL1PriceDataTests.cs +++ b/src/Nethermind.Arbitrum.Test/BlockProcessing/CachedL1PriceDataTests.cs @@ -29,6 +29,7 @@ public void CacheL1PriceDataOfMsg_CacheStartingBlockIs0And1BlockGetsProcessed_Ov .SignedAndResolved(TestItem.PrivateKeyA) .TestObject; + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); BlockToProduce block = BlockProcessingUtilities.CreateBlockFromTx(chain, transferTx, _baseFeePerGas); ArbitrumTxReceipt receipt = (ArbitrumTxReceipt)BlockProcessingUtilities.ProcessBlockWithInternalTx(chain, block)[1]; @@ -58,6 +59,7 @@ public void CacheL1PriceDataOfMsg_2BlocksGetProcessed_AddsToCache() .SignedAndResolved(TestItem.PrivateKeyA) .TestObject; + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); BlockToProduce block1 = BlockProcessingUtilities.CreateBlockFromTx(chain, transferTx1, _baseFeePerGas); ArbitrumTxReceipt receipt1 = (ArbitrumTxReceipt)BlockProcessingUtilities.ProcessBlockWithInternalTx(chain, block1)[1]; @@ -70,7 +72,7 @@ public void CacheL1PriceDataOfMsg_2BlocksGetProcessed_AddsToCache() .WithValue(1_000_000) .WithGasLimit(22_000) .WithGasPrice(1_000) - .WithNonce(0) + .WithNonce(1) .WithSenderAddress(TestItem.AddressA) .SignedAndResolved(TestItem.PrivateKeyA) .TestObject; @@ -111,6 +113,7 @@ public void MarkFeedStart_FeedStartEqualToEndOfCache_ResetCache() .TestObject; UInt256 baseFeePerGas = 1_000; + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); BlockToProduce block = BlockProcessingUtilities.CreateBlockFromTx(chain, transferTx, baseFeePerGas); BlockProcessingUtilities.ProcessBlockWithInternalTx(chain, block); @@ -148,6 +151,7 @@ public void MarkFeedStart_FeedStartIsWithinCacheWindow_CacheTrimmed() .TestObject; UInt256 baseFeePerGas = 1_000; + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); BlockToProduce block1 = BlockProcessingUtilities.CreateBlockFromTx(chain, transferTx1, baseFeePerGas); BlockProcessingUtilities.ProcessBlockWithInternalTx(chain, block1); diff --git a/src/Nethermind.Arbitrum.Test/Config/ArbitrumChainSpecProviderTests.cs b/src/Nethermind.Arbitrum.Test/Config/ArbitrumChainSpecProviderTests.cs index be38a70c..ca0a2a2f 100644 --- a/src/Nethermind.Arbitrum.Test/Config/ArbitrumChainSpecProviderTests.cs +++ b/src/Nethermind.Arbitrum.Test/Config/ArbitrumChainSpecProviderTests.cs @@ -5,7 +5,9 @@ using Nethermind.Arbitrum.Test.Infrastructure; using Nethermind.Core; using Nethermind.Core.Specs; +using Nethermind.Core.Test; using Nethermind.Core.Test.Modules; +using Nethermind.Evm.State; using Nethermind.Logging; using Nethermind.Specs.ChainSpecStyle; using Nethermind.State; @@ -27,6 +29,9 @@ public void ChainSpecProvider_SeveralLifetimeScopes_OneSpecProviderPerScope() ContainerBuilder containerBuilder = new(); containerBuilder.AddModule(new TestNethermindModule()); + //ArbitrumChainSpecBasedSpecProvider is now dependent on base spec provider instead directly deriving from ChainSpecBasedSpecProvider + //therefore need to specifically register ChainSpecBasedSpecProvider to be used instead of TestSpecProvider used in TestNethermindModule + containerBuilder.AddSingleton(_ => new ChainSpecBasedSpecProvider(chainSpec)); containerBuilder.AddModule(module); IContainer rootContainer = containerBuilder.Build(); @@ -55,8 +60,12 @@ public void ChainSpecProvider_SeveralLifetimeScopes_OneSpecProviderPerScope() spec1.IsEip7002Enabled.Should().BeFalse(); spec1.IsEip6110Enabled.Should().BeFalse(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + // In the scope spec provider, the spec uses arbos version 32 (from arbos state) - (IWorldState worldState, _) = ArbOSInitialization.Create(); + _ = ArbOSInitialization.Create(worldState); ArbosState state = ArbosState.OpenArbosState(worldState, new SystemBurner(), NullLogger.Instance); ILifetimeScope scope = rootContainer.BeginLifetimeScope(builder => { diff --git a/src/Nethermind.Arbitrum.Test/Execution/ArbitrumTransactionProcessorTests.cs b/src/Nethermind.Arbitrum.Test/Execution/ArbitrumTransactionProcessorTests.cs index 5755a68d..41f163dd 100644 --- a/src/Nethermind.Arbitrum.Test/Execution/ArbitrumTransactionProcessorTests.cs +++ b/src/Nethermind.Arbitrum.Test/Execution/ArbitrumTransactionProcessorTests.cs @@ -21,12 +21,15 @@ using Nethermind.Arbitrum.Arbos.Compression; using Nethermind.Consensus.Messages; using Nethermind.Logging; -using Nethermind.State; using Autofac; using Nethermind.Arbitrum.Core; using Nethermind.Arbitrum.Math; +using Nethermind.Blockchain.Tracing.GethStyle; +using Nethermind.Core.Specs; +using Nethermind.Core.Test; using Nethermind.Crypto; -using Nethermind.Evm.Tracing.GethStyle; +using Nethermind.Evm.State; +using Nethermind.State; namespace Nethermind.Arbitrum.Test.Execution; @@ -37,7 +40,11 @@ public class ArbitrumTransactionProcessorTests [Test] public void ProcessArbitrumRetryTransaction_RetryableExists_ReturnsOkTransactionResult() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); BlockTree blockTree = Build.A.BlockTree(genesis).OfChainLength(1).TestObject; FullChainSimulationSpecProvider fullChainSimulationSpecProvider = new(); @@ -50,7 +57,7 @@ public void ProcessArbitrumRetryTransaction_RetryableExists_ReturnsOkTransaction ulong baseFeePerGas = 10; genesis.Header.BaseFeePerGas = baseFeePerGas; - BlockExecutionContext blCtx = new(genesis.Header, 0); + BlockExecutionContext blCtx = new(genesis.Header, fullChainSimulationSpecProvider.GetSpec(genesis.Header)); virtualMachine.SetBlockExecutionContext(in blCtx); ArbitrumTransactionProcessor processor = new( @@ -59,7 +66,7 @@ public void ProcessArbitrumRetryTransaction_RetryableExists_ReturnsOkTransaction virtualMachine, blockTree, _logManager, - new CodeInfoRepository() + new EthereumCodeInfoRepository() ); SystemBurner burner = new(readOnly: false); @@ -120,7 +127,11 @@ public void ProcessArbitrumRetryTransaction_RetryableExists_ReturnsOkTransaction [Test] public void ProcessArbitrumRetryTransaction_RetryableDoesNotExist_ReturnsTransactionResultError() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); BlockTree blockTree = Build.A.BlockTree(genesis).OfChainLength(1).TestObject; FullChainSimulationSpecProvider fullChainSimulationSpecProvider = new(); @@ -132,7 +143,7 @@ public void ProcessArbitrumRetryTransaction_RetryableDoesNotExist_ReturnsTransac ulong baseFeePerGas = 10; genesis.Header.BaseFeePerGas = baseFeePerGas; - BlockExecutionContext blCtx = new(genesis.Header, 0); + BlockExecutionContext blCtx = new(genesis.Header, fullChainSimulationSpecProvider.GenesisSpec); virtualMachine.SetBlockExecutionContext(in blCtx); ArbitrumTransactionProcessor processor = new( @@ -141,7 +152,7 @@ public void ProcessArbitrumRetryTransaction_RetryableDoesNotExist_ReturnsTransac virtualMachine, blockTree, _logManager, - new CodeInfoRepository() + new EthereumCodeInfoRepository() ); Hash256 ticketIdHash = ArbRetryableTxTests.Hash256FromUlong(123); @@ -179,7 +190,11 @@ public void ProcessArbitrumRetryTransaction_RetryableDoesNotExist_ReturnsTransac [Test] public void ProcessArbitrumDepositTransaction_ValidTransaction_ReturnsOkTransactionResult() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); BlockTree blockTree = Build.A.BlockTree(genesis).OfChainLength(1).TestObject; FullChainSimulationSpecProvider fullChainSimulationSpecProvider = new(); @@ -190,7 +205,7 @@ public void ProcessArbitrumDepositTransaction_ValidTransaction_ReturnsOkTransact _logManager ); - BlockExecutionContext blCtx = new(genesis.Header, 0); + BlockExecutionContext blCtx = new(genesis.Header, fullChainSimulationSpecProvider.GenesisSpec); virtualMachine.SetBlockExecutionContext(in blCtx); ArbitrumTransactionProcessor processor = new( @@ -199,7 +214,7 @@ public void ProcessArbitrumDepositTransaction_ValidTransaction_ReturnsOkTransact virtualMachine, blockTree, _logManager, - new CodeInfoRepository() + new EthereumCodeInfoRepository() ); Address from = new("0x0000000000000000000000000000000000000123"); @@ -237,7 +252,11 @@ public void ProcessArbitrumDepositTransaction_ValidTransaction_ReturnsOkTransact [Test] public void ProcessArbitrumDepositTransaction_MalformedTx_ReturnsErroneousTransactionResult() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); BlockTree blockTree = Build.A.BlockTree(genesis).OfChainLength(1).TestObject; FullChainSimulationSpecProvider fullChainSimulationSpecProvider = new(); @@ -248,7 +267,7 @@ public void ProcessArbitrumDepositTransaction_MalformedTx_ReturnsErroneousTransa _logManager ); - BlockExecutionContext blCtx = new(genesis.Header, 0); + BlockExecutionContext blCtx = new(genesis.Header, fullChainSimulationSpecProvider.GenesisSpec); virtualMachine.SetBlockExecutionContext(in blCtx); ArbitrumTransactionProcessor processor = new( @@ -257,7 +276,7 @@ public void ProcessArbitrumDepositTransaction_MalformedTx_ReturnsErroneousTransa virtualMachine, blockTree, _logManager, - new CodeInfoRepository() + new EthereumCodeInfoRepository() ); ArbitrumDepositTransaction transaction = new ArbitrumDepositTransaction @@ -281,7 +300,11 @@ public void ProcessArbitrumDepositTransaction_MalformedTx_ReturnsErroneousTransa [Test] public void GasChargingHook_TxWithEnoughGas_TipsNetworkCorrectly() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); BlockTree blockTree = Build.A.BlockTree(genesis).OfChainLength(1).TestObject; FullChainSimulationSpecProvider fullChainSimulationSpecProvider = new(); @@ -294,7 +317,7 @@ public void GasChargingHook_TxWithEnoughGas_TipsNetworkCorrectly() ulong baseFeePerGas = 1_000; genesis.Header.BaseFeePerGas = baseFeePerGas; genesis.Header.Author = ArbosAddresses.BatchPosterAddress; // to set up Coinbase - BlockExecutionContext blCtx = new(genesis.Header, 0); + BlockExecutionContext blCtx = new(genesis.Header, fullChainSimulationSpecProvider.GetSpec(genesis.Header)); virtualMachine.SetBlockExecutionContext(in blCtx); ArbitrumTransactionProcessor txProcessor = new( @@ -303,7 +326,7 @@ public void GasChargingHook_TxWithEnoughGas_TipsNetworkCorrectly() virtualMachine, blockTree, _logManager, - new CodeInfoRepository() + new EthereumCodeInfoRepository() ); SystemBurner burner = new(readOnly: false); @@ -395,10 +418,15 @@ public void GasChargingHook_TxWithNotEnoughGas_Throws() builder.AddScoped(); }); + FullChainSimulationSpecProvider fullChainSimulationSpecProvider = new(); + UInt256 baseFeePerGas = 1_000; chain.BlockTree.Head!.Header.BaseFeePerGas = baseFeePerGas; chain.BlockTree.Head!.Header.Author = ArbosAddresses.BatchPosterAddress; // to set up Coinbase - chain.TxProcessor.SetBlockExecutionContext(new BlockExecutionContext(chain.BlockTree.Head!.Header, 0)); + chain.TxProcessor.SetBlockExecutionContext(new BlockExecutionContext(chain.BlockTree.Head!.Header, + fullChainSimulationSpecProvider.GetSpec(chain.BlockTree.Head!.Header))); + + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); SystemBurner burner = new(readOnly: false); ArbosState arbosState = ArbosState.OpenArbosState(chain.WorldStateManager.GlobalWorldState, burner, _logManager.GetClassLogger()); @@ -441,10 +469,11 @@ public void CalculateClaimableRefund_TxGetsRefundedSomeAmount_PosterGasDoesNotGe ulong baseFeePerGas = 1_000; chain.BlockTree.Head!.Header.BaseFeePerGas = baseFeePerGas; chain.BlockTree.Head!.Header.Author = ArbosAddresses.BatchPosterAddress; // to set up Coinbase - BlockExecutionContext blCtx = new(chain.BlockTree.Head!.Header, 0); + BlockExecutionContext blCtx = new(chain.BlockTree.Head!.Header, fullChainSimulationSpecProvider.GetSpec(chain.BlockTree.Head!.Header)); chain.TxProcessor.SetBlockExecutionContext(in blCtx); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var dispose = worldState.BeginScope(chain.BlockTree.Head!.Header); SystemBurner burner = new(readOnly: false); ArbosState arbosState = ArbosState.OpenArbosState( @@ -539,6 +568,8 @@ public void EndTxHook_RetryTransactionSuccess_DeletesRetryableAndRefundsCorrectl }); }); + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); + UInt256 baseFeePerGas = chain.BlockTree.Head!.Header.BaseFeePerGas; SystemBurner burner = new(readOnly: false); ArbosState arbosState = ArbosState.OpenArbosState(chain.WorldStateManager.GlobalWorldState, burner, _logManager.GetClassLogger()); @@ -613,6 +644,8 @@ public void EndTxHook_RetryTransactionFailure_ReturnsCallvalueToEscrow() }); }); + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); + UInt256 baseFeePerGas = chain.BlockTree.Head!.Header.BaseFeePerGas; SystemBurner burner = new(readOnly: false); ArbosState arbosState = ArbosState.OpenArbosState(chain.WorldStateManager.GlobalWorldState, burner, _logManager.GetClassLogger()); @@ -714,6 +747,8 @@ public void EndTxHook_NormalTransaction_DistributesFeesToNetworkAccount() .WithType(TxType.EIP1559) .TestObject; + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); + // Add sufficient balance to sender UInt256 initialBalance = baseFeePerGas * gasLimit * 3 + transaction.Value; chain.WorldStateManager.GlobalWorldState.AddToBalanceAndCreateIfNotExists(sender, initialBalance, chain.SpecProvider.GenesisSpec); @@ -755,6 +790,8 @@ public void EndTxHook_NormalTransactionWithInfraFees_DistributesFeesBetweenNetwo const ulong baseFeePerGas = 100_000_000; chain.BlockTree.Head!.Header.BaseFeePerGas = baseFeePerGas; + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header); + // Setup infrastructure fees SystemBurner burner = new(readOnly: false); ArbosState arbosState = ArbosState.OpenArbosState(chain.WorldStateManager.GlobalWorldState, burner, _logManager.GetClassLogger()); @@ -838,15 +875,18 @@ public void EndTxHook_FailedTransaction_SkipsEndHookAndDoesNotDistributeFees() .WithType(TxType.EIP1559) .TestObject; + IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var dispose = worldState.BeginScope(chain.BlockTree.Head!.Header); + // Add balance to sender but not enough to cover the transaction UInt256 insufficientBalance = baseFeePerGas * 1000; // Much less than needed - chain.WorldStateManager.GlobalWorldState.AddToBalanceAndCreateIfNotExists(sender, insufficientBalance, chain.SpecProvider.GenesisSpec); + worldState.AddToBalanceAndCreateIfNotExists(sender, insufficientBalance, chain.SpecProvider.GenesisSpec); // Get initial network fee account balance SystemBurner burner = new(readOnly: false); - ArbosState arbosState = ArbosState.OpenArbosState(chain.WorldStateManager.GlobalWorldState, burner, _logManager.GetClassLogger()); + ArbosState arbosState = ArbosState.OpenArbosState(worldState, burner, _logManager.GetClassLogger()); Address networkFeeAccount = arbosState.NetworkFeeAccount.Get(); - UInt256 initialNetworkBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(networkFeeAccount); + UInt256 initialNetworkBalance = worldState.GetBalance(networkFeeAccount); var tracer = new ArbitrumGethLikeTxTracer(GethTraceOptions.Default); TransactionResult result = ((ArbitrumTransactionProcessor)chain.TxProcessor).Execute(transaction, tracer); @@ -855,7 +895,7 @@ public void EndTxHook_FailedTransaction_SkipsEndHookAndDoesNotDistributeFees() result.Should().NotBe(TransactionResult.Ok); // EndTxHook must not run for early validation failures, so no fee distribution - UInt256 finalNetworkBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(networkFeeAccount); + UInt256 finalNetworkBalance = worldState.GetBalance(networkFeeAccount); UInt256 networkFeeIncrease = finalNetworkBalance - initialNetworkBalance; networkFeeIncrease.Should().Be(0); @@ -886,6 +926,7 @@ public void ProcessLegacyTransaction_DropsTip_Correctly(ulong arbosVersion, stri ArbitrumRpcTestBlockchain chain = ArbitrumRpcTestBlockchain.CreateDefault(preConfigurer); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var dispose = worldState.BeginScope(chain.BlockTree.Head!.Header); ArbosStorage backingStorage = new(worldState, new SystemBurner(), ArbosAddresses.ArbosSystemAccount); backingStorage.Set(ArbosStateOffsets.VersionOffset, arbosVersion); @@ -961,6 +1002,7 @@ public void ProcessEip1559Transaction_DropsTip_Correctly(ulong arbosVersion, str ArbitrumRpcTestBlockchain chain = ArbitrumRpcTestBlockchain.CreateDefault(preConfigurer); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var dispose = worldState.BeginScope(chain.BlockTree.Head!.Header); ArbosStorage backingStorage = new(worldState, new SystemBurner(), ArbosAddresses.ArbosSystemAccount); backingStorage.Set(ArbosStateOffsets.VersionOffset, arbosVersion); @@ -1038,6 +1080,7 @@ public void ProcessEip1559Transaction_WithCappedTip_DropsTip_Correctly(ulong arb ArbitrumRpcTestBlockchain chain = ArbitrumRpcTestBlockchain.CreateDefault(preConfigurer); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var dispose = worldState.BeginScope(chain.BlockTree.Head!.Header); ArbosStorage backingStorage = new(worldState, new SystemBurner(), ArbosAddresses.ArbosSystemAccount); backingStorage.Set(ArbosStateOffsets.VersionOffset, arbosVersion); @@ -1138,6 +1181,7 @@ public void ProcessArbitrumRetryTransaction_HasInvalidNonceAndSenderIsEoa_Return ArbitrumRpcTestBlockchain chain = ArbitrumRpcTestBlockchain.CreateDefault(preConfigurer); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var dispose = worldState.BeginScope(chain.BlockTree.Head!.Header); var arbosState = ArbosState.OpenArbosState(worldState, new SystemBurner(), LimboLogs.Instance.GetLogger("arbosState")); BlockHeader header = new BlockHeader(chain.BlockTree.HeadHash, null, TestItem.AddressF, UInt256.Zero, 0, @@ -1145,7 +1189,8 @@ public void ProcessArbitrumRetryTransaction_HasInvalidNonceAndSenderIsEoa_Return header.BaseFeePerGas = arbosState.L2PricingState.BaseFeeWeiStorage.Get(); Hash256 ticketIdHash = ArbRetryableTxTests.Hash256FromUlong(1); - var retryTx = TestTransaction.PrepareArbitrumRetryTx(worldState, header, ticketIdHash, TestItem.AddressA, TestItem.AddressB, header.Beneficiary!, 50.GWei()); + var retryTx = TestTransaction.PrepareArbitrumRetryTx(worldState, header, ticketIdHash, TestItem.AddressA, TestItem.AddressB, header.Beneficiary!, + 50.GWei()); retryTx.Nonce = 100; //nonce not matching to sender state //sender account @@ -1227,6 +1272,7 @@ public void ProcessTransactions_SubmitRetryable_TraceEntries() tx.Hash = tx.CalculateHash(); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var dispose = worldState.BeginScope(chain.BlockTree.Head!.Header); var arbosState = ArbosState.OpenArbosState(worldState, new SystemBurner(), LimboLogs.Instance.GetLogger("arbosState")); @@ -1254,7 +1300,11 @@ public void ArbitrumTransaction_WithArbitrumBlockHeader_ProcessesCorrectly() { // Test NEW ArbitrumBlockHeader approach: EVM sees 0, gas calculations use original base fee - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); BlockTree blockTree = Build.A.BlockTree(genesis).OfChainLength(1).TestObject; FullChainSimulationSpecProvider fullChainSimulationSpecProvider = new(); @@ -1274,7 +1324,7 @@ public void ArbitrumTransaction_WithArbitrumBlockHeader_ProcessesCorrectly() ArbitrumBlockHeader arbitrumHeader = new ArbitrumBlockHeader(genesis.Header, originalBaseFee); arbitrumHeader.BaseFeePerGas = 0; // Set to 0 for EVM execution (NoBaseFee behavior) - BlockExecutionContext blCtx = new(arbitrumHeader, 0); + BlockExecutionContext blCtx = new(arbitrumHeader, fullChainSimulationSpecProvider.GetSpec(arbitrumHeader)); virtualMachine.SetBlockExecutionContext(in blCtx); ArbitrumTransactionProcessor processor = new( @@ -1283,7 +1333,7 @@ public void ArbitrumTransaction_WithArbitrumBlockHeader_ProcessesCorrectly() virtualMachine, blockTree, _logManager, - new CodeInfoRepository() + new EthereumCodeInfoRepository() ); // Verify NoBaseFee behavior - EVM sees 0 @@ -1341,7 +1391,11 @@ public void ArbitrumTransaction_WithoutNoBaseFee_UsesBlockBaseFee() { // Test that without NoBaseFee, transactions should use the block's BaseFeePerGas - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); BlockTree blockTree = Build.A.BlockTree(genesis).OfChainLength(1).TestObject; FullChainSimulationSpecProvider fullChainSimulationSpecProvider = new(); @@ -1356,7 +1410,7 @@ public void ArbitrumTransaction_WithoutNoBaseFee_UsesBlockBaseFee() genesis.Header.BaseFeePerGas = blockBaseFee; // Use regular BlockHeader (not ArbitrumBlockHeader) - BlockExecutionContext blCtx = new(genesis.Header, 0); + BlockExecutionContext blCtx = new(genesis.Header, fullChainSimulationSpecProvider.GenesisSpec); virtualMachine.SetBlockExecutionContext(in blCtx); ArbitrumTransactionProcessor processor = new( @@ -1365,7 +1419,7 @@ public void ArbitrumTransaction_WithoutNoBaseFee_UsesBlockBaseFee() virtualMachine, blockTree, _logManager, - new CodeInfoRepository() + new EthereumCodeInfoRepository() ); Address sender = TestItem.AddressA; @@ -1416,7 +1470,11 @@ public void ArbitrumTransaction_WithArbitrumBlockHeader_UsesOriginalBaseFeeForGa // Test that with ArbitrumBlockHeader, transactions use original base fee for gas calculations // but EVM sees 0 base fee - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); BlockTree blockTree = Build.A.BlockTree(genesis).OfChainLength(1).TestObject; FullChainSimulationSpecProvider fullChainSimulationSpecProvider = new(); @@ -1434,7 +1492,7 @@ public void ArbitrumTransaction_WithArbitrumBlockHeader_UsesOriginalBaseFeeForGa ArbitrumBlockHeader arbitrumHeader = new ArbitrumBlockHeader(genesis.Header, originalBaseFee); arbitrumHeader.BaseFeePerGas = 0; // Set to 0 for EVM execution (NoBaseFee behavior) - BlockExecutionContext blCtx = new(arbitrumHeader, 0); + BlockExecutionContext blCtx = new(arbitrumHeader, fullChainSimulationSpecProvider.GetSpec(arbitrumHeader)); virtualMachine.SetBlockExecutionContext(in blCtx); ArbitrumTransactionProcessor processor = new( @@ -1443,7 +1501,7 @@ public void ArbitrumTransaction_WithArbitrumBlockHeader_UsesOriginalBaseFeeForGa virtualMachine, blockTree, _logManager, - new CodeInfoRepository() + new EthereumCodeInfoRepository() ); // Verify NoBaseFee behavior @@ -1497,7 +1555,11 @@ public void ArbitrumBlockHeader_StoresOriginalBaseFeeCorrectly() { // Test that ArbitrumBlockHeader properly stores and retrieves original base fee - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); UInt256 blockBaseFee = (UInt256)1500; UInt256 originalBaseFee = (UInt256)3000; diff --git a/src/Nethermind.Arbitrum.Test/Execution/ArbitrumVirtualMachineTests.cs b/src/Nethermind.Arbitrum.Test/Execution/ArbitrumVirtualMachineTests.cs index 435b9e25..47714dea 100644 --- a/src/Nethermind.Arbitrum.Test/Execution/ArbitrumVirtualMachineTests.cs +++ b/src/Nethermind.Arbitrum.Test/Execution/ArbitrumVirtualMachineTests.cs @@ -6,11 +6,11 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Test.Builders; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Evm.Test; using Nethermind.Evm.TransactionProcessing; using Nethermind.Int256; using Nethermind.Logging; -using Nethermind.State; namespace Nethermind.Arbitrum.Test.Execution; @@ -34,10 +34,11 @@ public void OpGasPriceOpCode_ArbosVersionIsGreaterThanTwoAndNotNine_ReturnsBaseF ulong baseFeePerGas = 1_000; chain.BlockTree.Head!.Header.BaseFeePerGas = baseFeePerGas; - BlockExecutionContext blCtx = new(chain.BlockTree.Head!.Header, 0); + BlockExecutionContext blCtx = new(chain.BlockTree.Head!.Header, fullChainSimulationSpecProvider.GenesisSpec); chain.TxProcessor.SetBlockExecutionContext(in blCtx); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(chain.BlockTree.Head!.Header); // Insert a contract inside the world state Address contractAddress = new("0x0000000000000000000000000000000000000123"); @@ -116,10 +117,11 @@ public void OpGasPriceOpCode_ArbosVersionIsNine_ReturnsTxGasPrice() // so that CalculateEffectiveGasPrice() returns effectiveGasPrice instead of effectiveBaseFee chain.BlockTree.Head!.Header.Author = ArbosAddresses.BatchPosterAddress; - BlockExecutionContext blCtx = new(chain.BlockTree.Head!.Header, 0); + BlockExecutionContext blCtx = new(chain.BlockTree.Head!.Header, fullChainSimulationSpecProvider.GenesisSpec); chain.TxProcessor.SetBlockExecutionContext(in blCtx); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(chain.BlockTree.Head!.Header); ArbosState arbosState = ArbosState.OpenArbosState( worldState, new ZeroGasBurner(), _logManager.GetClassLogger() @@ -200,11 +202,12 @@ public void OpNumberOpCode_Always_ReturnsL1BlockNumber() ulong baseFeePerGas = 1_000; chain.BlockTree.Head!.Header.BaseFeePerGas = baseFeePerGas; - BlockExecutionContext blCtx = new(chain.BlockTree.Head!.Header, 0); + BlockExecutionContext blCtx = new(chain.BlockTree.Head!.Header, fullChainSimulationSpecProvider.GenesisSpec); ulong l2BlockNumber = blCtx.Number; chain.TxProcessor.SetBlockExecutionContext(in blCtx); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(chain.BlockTree.Head!.Header); ArbosState arbosState = ArbosState.OpenArbosState( worldState, new ZeroGasBurner(), _logManager.GetClassLogger() @@ -259,7 +262,7 @@ public void OpNumberOpCode_Always_ReturnsL1BlockNumber() UInt256 returnedBlockNumber = new(tracer.ReturnValue, isBigEndian: true); returnedBlockNumber.IsUint64.Should().BeTrue(); returnedBlockNumber.ToUInt64(null).Should().Be(l1BlockNumber + 1); // blockHashes.RecordNewL1Block() adds + 1 - l2BlockNumber.Should().Be(0); + l2BlockNumber.Should().Be(blCtx.Number); returnedBlockNumber.ToUInt64(null).Should().NotBe(l2BlockNumber); } } diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/ArbOSInitialization.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/ArbOSInitialization.cs index 547f7dee..8dc2fd63 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/ArbOSInitialization.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/ArbOSInitialization.cs @@ -4,6 +4,7 @@ using Nethermind.Arbitrum.Genesis; using Nethermind.Core; using Nethermind.Core.Test; +using Nethermind.Evm.State; using Nethermind.Logging; using Nethermind.Specs.ChainSpecStyle; using Nethermind.State; @@ -12,10 +13,9 @@ namespace Nethermind.Arbitrum.Test.Infrastructure; public static class ArbOSInitialization { - public static (IWorldState, Block) Create() + public static Block Create(IWorldState worldState) { ChainSpec chainSpec = FullChainSimulationChainSpecProvider.Create(); - IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); ArbitrumChainSpecEngineParameters parameters = chainSpec.EngineChainSpecParametersProvider .GetChainSpecParameters(); IArbitrumSpecHelper specHelper = new ArbitrumSpecHelper(parameters); @@ -31,12 +31,12 @@ public static (IWorldState, Block) Create() chainSpec, FullChainSimulationSpecProvider.Instance, specHelper, - worldStateManager.GlobalWorldState, + worldState, parsedInitMessage, LimboLogs.Instance); Block genesisBlock = genesisLoader.Load(); - return (worldStateManager.GlobalWorldState, genesisBlock); + return genesisBlock; } } diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/ArbitrumRpcTestBlockchain.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/ArbitrumRpcTestBlockchain.cs index 0a1b8ed3..3e99484e 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/ArbitrumRpcTestBlockchain.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/ArbitrumRpcTestBlockchain.cs @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + using System.Text; using System.Text.Json; using Autofac; @@ -6,11 +9,23 @@ using Nethermind.Arbitrum.Config; using Nethermind.Arbitrum.Data; using Nethermind.Arbitrum.Execution.Transactions; +using Nethermind.Blockchain.Receipts; +using Nethermind.Config; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; +using Nethermind.Facade; +using Nethermind.Facade.Eth; using Nethermind.Int256; using Nethermind.JsonRpc; +using Nethermind.JsonRpc.Modules.Eth; +using Nethermind.JsonRpc.Modules.Eth.FeeHistory; +using Nethermind.JsonRpc.Modules.Eth.GasPrice; +using Nethermind.Network; using Nethermind.Specs.ChainSpecStyle; +using Nethermind.State; +using Nethermind.TxPool; +using Nethermind.Wallet; namespace Nethermind.Arbitrum.Test.Infrastructure; @@ -25,6 +40,7 @@ private ArbitrumRpcTestBlockchain(ChainSpec chainSpec) : base(chainSpec) { } + public IEthRpcModule ArbitrumEthRpcModule { get; private set; } = null!; public IArbitrumRpcModule ArbitrumRpcModule { get; private set; } = null!; public IArbitrumSpecHelper SpecHelper => Dependencies.SpecHelper; @@ -221,6 +237,25 @@ private static ArbitrumRpcTestBlockchain CreateInternal(ArbitrumRpcTestBlockchai chain.Container.Resolve()) .Create()); + chain.ArbitrumEthRpcModule = new ArbitrumEthRpcModule( + chain.Container.Resolve(), + chain.Container.Resolve(), + chain.BlockTree, + chain.Container.Resolve(), + chain.Container.Resolve(), + chain.Container.Resolve(), + chain.Container.Resolve(), + chain.Container.Resolve(), + chain.LogManager, + chain.Container.Resolve(), + chain.Container.Resolve(), + chain.Container.Resolve(), + chain.Container.Resolve(), + chain.Container.Resolve(), + chain.Container.Resolve(), + chain.Container.Resolve().SecondsPerSlot + ); + return chain; } @@ -297,16 +332,13 @@ public ResultWrapper MarkFeedStart(ulong to) public record TestEthDeposit(Hash256 RequestId, UInt256 L1BaseFee, Address Sender, Address Receiver, UInt256 Value); -public record TestSubmitRetryable(Hash256 RequestId, UInt256 L1BaseFee, Address Sender, Address Receiver, Address Beneficiary, UInt256 DepositValue, - UInt256 RetryValue, UInt256 GasFee, ulong GasLimit, UInt256 MaxSubmissionFee) +public record TestSubmitRetryable(Hash256 RequestId, UInt256 L1BaseFee, Address Sender, Address Receiver, Address Beneficiary, UInt256 DepositValue, UInt256 RetryValue, UInt256 GasFee, ulong GasLimit, UInt256 MaxSubmissionFee) { public byte[] RetryData { get; set; } = []; } -public record TestL2FundedByL1Transfer(Hash256 RequestId, UInt256 L1BaseFee, Address Sponsor, Address Sender, Address Receiver, - UInt256 TransferValue, UInt256 MaxFeePerGas, ulong GasLimit, UInt256 Nonce); +public record TestL2FundedByL1Transfer(Hash256 RequestId, UInt256 L1BaseFee, Address Sponsor, Address Sender, Address Receiver, UInt256 TransferValue, UInt256 MaxFeePerGas, ulong GasLimit, UInt256 Nonce); -public record TestL2FundedByL1Contract(Hash256 RequestId, UInt256 L1BaseFee, Address Sponsor, Address Sender, Address Contract, - UInt256 TransferValue, UInt256 MaxFeePerGas, ulong GasLimit, byte[] Data); +public record TestL2FundedByL1Contract(Hash256 RequestId, UInt256 L1BaseFee, Address Sponsor, Address Sender, Address Contract, UInt256 TransferValue, UInt256 MaxFeePerGas, ulong GasLimit, byte[] Data); public record TestL2Transactions(Hash256 RequestId, UInt256 L1BaseFee, Address Sender, params Transaction[] Transactions); diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/ArbitrumTestBlockchainBase.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/ArbitrumTestBlockchainBase.cs index c52d4192..56325acc 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/ArbitrumTestBlockchainBase.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/ArbitrumTestBlockchainBase.cs @@ -6,6 +6,7 @@ using Nethermind.Arbitrum.Execution; using Nethermind.Arbitrum.Execution.Transactions; using Nethermind.Arbitrum.Genesis; +using Nethermind.Arbitrum.Precompiles; using Nethermind.Blockchain; using Nethermind.Blockchain.BeaconBlockRoot; using Nethermind.Blockchain.Blocks; @@ -29,8 +30,10 @@ using Nethermind.Core.Utils; using Nethermind.Crypto; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade.Find; +using Nethermind.Init.Modules; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Serialization.Json; @@ -71,6 +74,7 @@ public abstract class ArbitrumTestBlockchainBase(ChainSpec chainSpec) : IDisposa public IBlockProducer BlockProducer { get; protected set; } = null!; public IBlockProducerRunner BlockProducerRunner { get; protected set; } = null!; public IBlockProcessor BlockProcessor { get; protected set; } = null!; + public IBranchProcessor BranchProcessor => Dependencies.MainProcessingContext.BranchProcessor; public IBlockchainProcessor BlockchainProcessor { get; protected set; } = null!; public IBlockProcessingQueue BlockProcessingQueue { get; protected set; } = null!; @@ -78,7 +82,7 @@ public abstract class ArbitrumTestBlockchainBase(ChainSpec chainSpec) : IDisposa public ArbitrumRpcTxSource ArbitrumRpcTxSource { get; protected set; } = null!; public IReadOnlyTxProcessingEnvFactory ReadOnlyTxProcessingEnvFactory => Dependencies.ReadOnlyTxProcessingEnvFactory; public ITransactionProcessor TxProcessor => Dependencies.MainProcessingContext.TransactionProcessor; - public IExecutionRequestsProcessor MainExecutionRequestsProcessor => ((MainBlockProcessingContext)Dependencies.MainProcessingContext) + public IExecutionRequestsProcessor MainExecutionRequestsProcessor => ((MainProcessingContext)Dependencies.MainProcessingContext) .LifetimeScope.Resolve(); public IBlockFinder BlockFinder => Dependencies.BlockFinder; @@ -136,9 +140,10 @@ protected virtual ArbitrumTestBlockchainBase Build(Action? con Dependencies = Container.Resolve(); BlockProcessor = CreateBlockProcessor(Dependencies.WorldStateManager.GlobalWorldState); + BlockchainProcessor chainProcessor = new( BlockTree, - BlockProcessor, + BranchProcessor, Dependencies.BlockPreprocessorStep, StateReader, LogManager, @@ -159,20 +164,23 @@ protected virtual ArbitrumTestBlockchainBase Build(Action? con RegisterTransactionDecoders(); Cts = AutoCancelTokenSource.ThatCancelAfter(TimeSpan.FromMilliseconds(TestTimout)); - TestUtil = new TestBlockchainUtil( - BlockProducerRunner, - BlockProductionTrigger, - Timestamper, - BlockTree, - TxPool, - 1 - ); + //TestUtil = new TestBlockchainUtil( + // BlockProducerRunner, + // BlockProductionTrigger, + // Timestamper, + // BlockTree, + // TxPool, + // 1 + //); Configuration testConfig = Container.Resolve(); IWorldState worldState = WorldStateManager.GlobalWorldState; + Block? genesisBlock = null; + if (testConfig.SuggestGenesisOnStart) { + using var dispose = worldState.BeginScope(IWorldState.PreGenesis); ManualResetEvent resetEvent = new(false); BlockTree.OnUpdateMainChain += (sender, args) => { resetEvent.Set(); }; @@ -191,7 +199,7 @@ protected virtual ArbitrumTestBlockchainBase Build(Action? con parsedInitMessage, LimboLogs.Instance); - Block genesisBlock = genesisLoader.Load(); + genesisBlock = genesisLoader.Load(); BlockTree.SuggestBlock(genesisBlock); var genesisResult = resetEvent.WaitOne(TimeSpan.FromMilliseconds(DefaultTimeout)); @@ -202,6 +210,8 @@ protected virtual ArbitrumTestBlockchainBase Build(Action? con if (testConfig.FillWithTestDataOnStart) { + using var dispose = worldState.BeginScope(genesisBlock?.Header ?? IWorldState.PreGenesis); + worldState.CreateAccount(TestItem.AddressA, 100.Ether()); worldState.CreateAccount(TestItem.AddressB, 200.Ether()); worldState.CreateAccount(TestItem.AddressC, 300.Ether()); @@ -218,7 +228,7 @@ protected virtual ArbitrumTestBlockchainBase Build(Action? con parentBlockHeader.TotalDifficulty = (parentBlockHeader.TotalDifficulty ?? 0) + 1; var newBlock = BlockTree.Head!.WithReplacedHeader(parentBlockHeader); BlockTree.SuggestBlock(newBlock, BlockTreeSuggestOptions.ForceSetAsMain); - BlockTree.UpdateHeadBlock(newBlock.Hash!); + BlockTree.UpdateMainChain([newBlock], true, true); } return this; } @@ -235,6 +245,13 @@ protected virtual ContainerBuilder ConfigureContainer(ContainerBuilder builder, .AddSingleton() .AddSingleton() + .AddDecorator() + + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped((specProvider, blocksConfig) => + new ArbitrumBlockProductionTransactionPicker(specProvider)) // Some validator configurations .AddSingleton(Always.Valid) @@ -258,8 +275,7 @@ protected virtual IBlockProcessor CreateBlockProcessor(IWorldState worldState) new BeaconBlockRootHandler(TxProcessor, worldState), LogManager, new WithdrawalProcessor(worldState, LogManager), - new ExecutionRequestsProcessor(TxProcessor), - preWarmer: null); + new ExecutionRequestsProcessor(TxProcessor)); } protected IBlockCachePreWarmer CreateBlockCachePreWarmer() @@ -267,7 +283,6 @@ protected IBlockCachePreWarmer CreateBlockCachePreWarmer() return new BlockCachePreWarmer( ReadOnlyTxProcessingEnvFactory, WorldStateManager.GlobalWorldState, - Dependencies.SpecProvider, 4, LogManager, (WorldStateManager.GlobalWorldState as IPreBlockCaches)?.Caches); @@ -275,7 +290,7 @@ protected IBlockCachePreWarmer CreateBlockCachePreWarmer() protected virtual IBlockProducer CreateTestBlockProducer(ISealer sealer, ITransactionComparerProvider comparerProvider) { - BlockProducerEnv blockProducerEnv = Dependencies.BlockProducerEnvFactory.Create(); + IBlockProducerEnv blockProducerEnv = Dependencies.BlockProducerEnvFactory.Create(); return new ArbitrumBlockProducer( blockProducerEnv.TxSource, diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/BlockProcessingUtilities.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/BlockProcessingUtilities.cs index d1a05305..6be65b6e 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/BlockProcessingUtilities.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/BlockProcessingUtilities.cs @@ -4,16 +4,17 @@ using Nethermind.Arbitrum.Execution; using Nethermind.Arbitrum.Execution.Receipts; using Nethermind.Arbitrum.Execution.Transactions; +using Nethermind.Blockchain.Tracing; using Nethermind.Consensus.Processing; using Nethermind.Consensus.Producers; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Crypto; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Serialization.Rlp; -using Nethermind.State; namespace Nethermind.Arbitrum.Test.Infrastructure; @@ -49,8 +50,7 @@ public static IReadOnlyList ProcessBlockWithInternalTx(ArbitrumRpcTes var blockReceiptsTracer = new ArbitrumBlockReceiptTracer((chain.TxProcessor as ArbitrumTransactionProcessor)!.TxExecContext); blockReceiptsTracer.StartNewBlockTrace(block); - chain.BlockProcessor.Process(chain.BlockTree.Head?.StateRoot ?? Keccak.EmptyTreeHash, - [block], ProcessingOptions.ProducingBlock, blockReceiptsTracer); + chain.BlockProcessor.ProcessOne(block, ProcessingOptions.ProducingBlock, blockReceiptsTracer, chain.SpecProvider.GenesisSpec); blockReceiptsTracer.EndBlockTrace(); diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/FullChainSimulationAccounts.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/FullChainSimulationAccounts.cs index 4d16823a..8a2bbd30 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/FullChainSimulationAccounts.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/FullChainSimulationAccounts.cs @@ -1,3 +1,4 @@ +using Nethermind.Core.Test.Builders; using Nethermind.Crypto; namespace Nethermind.Arbitrum.Test.Infrastructure; diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/FullChainSimulationSpecProvider.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/FullChainSimulationSpecProvider.cs index 9585bdce..0d101609 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/FullChainSimulationSpecProvider.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/FullChainSimulationSpecProvider.cs @@ -22,7 +22,7 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD public ulong ChainId => NetworkId; public ForkActivation[] TransitionActivations => []; - public IReleaseSpec GetSpec(ForkActivation forkActivation) + public IReleaseSpec GetSpecInternal(ForkActivation forkActivation) { return new FullChainSimulationReleaseSpec(); } diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/PrecompileTestContextBuilder.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/PrecompileTestContextBuilder.cs index 155c1322..56140007 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/PrecompileTestContextBuilder.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/PrecompileTestContextBuilder.cs @@ -3,12 +3,13 @@ using Nethermind.Arbitrum.Precompiles; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Specs.Forks; -using Nethermind.State; namespace Nethermind.Arbitrum.Test.Infrastructure; @@ -88,7 +89,7 @@ public PrecompileTestContextBuilder WithCallDepth(int depth) return this with { CallDepth = depth }; } - public PrecompileTestContextBuilder WithOrigin(Address origin) + public PrecompileTestContextBuilder WithOrigin(ValueHash256 origin) { return this with { Origin = origin }; } @@ -165,9 +166,14 @@ public void SetBlockhash(long blockNumber, Hash256 hash) _blockHashes[blockNumber] = hash; } - public Hash256? GetBlockhash(BlockHeader currentBlock, in long blockNumber) + public Hash256? GetBlockhash(BlockHeader currentBlock, long number) { - return _blockHashes.TryGetValue(blockNumber, out Hash256? hash) ? hash : null; + return _blockHashes.TryGetValue(number, out Hash256? hash) ? hash : null; + } + + public Hash256? GetBlockhash(BlockHeader currentBlock, long number, IReleaseSpec? spec) + { + return _blockHashes.TryGetValue(number, out Hash256? hash) ? hash : null; } } diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/PrecompileTestContextBuilderTests.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/PrecompileTestContextBuilderTests.cs index 56ac2c18..ba107ba1 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/PrecompileTestContextBuilderTests.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/PrecompileTestContextBuilderTests.cs @@ -1,11 +1,13 @@ using FluentAssertions; using Nethermind.Arbitrum.Arbos; using Nethermind.Arbitrum.Execution.Transactions; -using Nethermind.State; using Nethermind.Core.Crypto; +using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Int256; +using Nethermind.State; namespace Nethermind.Arbitrum.Test.Infrastructure; @@ -15,7 +17,11 @@ public class PrecompileTestContextBuilderTests [Test] public void ExtendedMethods_WithValidParameters_ConfigureContextCorrectly() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ulong gasSupplied = 1_000_000; PrecompileTestContextBuilder context = new PrecompileTestContextBuilder(worldState, gasSupplied) @@ -23,7 +29,7 @@ public void ExtendedMethods_WithValidParameters_ConfigureContextCorrectly() .WithArbosVersion(ArbosVersion.Forty) .WithBlockNumber(123) .WithCallDepth(2) - .WithOrigin(TestItem.AddressA) + .WithOrigin(TestItem.AddressA.ToHash()) .WithGrandCaller(TestItem.AddressB) .WithValue(UInt256.One) .WithTopLevelTxType(ArbitrumTxType.ArbitrumRetry) @@ -33,7 +39,7 @@ public void ExtendedMethods_WithValidParameters_ConfigureContextCorrectly() context.ArbosState.CurrentArbosVersion.Should().Be(ArbosVersion.Forty); context.BlockExecutionContext.Header.Number.Should().Be(123); context.CallDepth.Should().Be(2); - context.Origin.Should().Be(TestItem.AddressA); + context.Origin.Should().Be(TestItem.AddressA.ToHash()); context.GrandCaller.Should().Be(TestItem.AddressB); context.Value.Should().Be(UInt256.One); context.TopLevelTxType.Should().Be(ArbitrumTxType.ArbitrumRetry); @@ -43,7 +49,11 @@ public void ExtendedMethods_WithValidParameters_ConfigureContextCorrectly() [Test] public void WithBlockHashProvider_WithTestHashes_ReturnsCorrectHashes() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); Hash256 expectedHash = TestItem.KeccakA; long blockNumber = 100; @@ -62,7 +72,11 @@ public void WithBlockHashProvider_WithTestHashes_ReturnsCorrectHashes() [Test] public void WithArbosVersion_WithoutExistingArbosState_CreatesArbosStateFirst() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosVersion(ArbosVersion.Thirty); diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/TestArbosStorage.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/TestArbosStorage.cs index ad55361f..ec5218ed 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/TestArbosStorage.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/TestArbosStorage.cs @@ -2,6 +2,7 @@ using Nethermind.Arbitrum.Arbos.Storage; using Nethermind.Arbitrum.Tracing; using Nethermind.Core; +using Nethermind.Evm.State; using Nethermind.Int256; namespace Nethermind.Arbitrum.Test.Infrastructure; @@ -10,17 +11,30 @@ public static class TestArbosStorage { public static readonly Address DefaultTestAccount = new("0xA4B05FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); - public static (ArbosStorage, TrackingWorldState) Create(Address? testAccount = null, IBurner? burner = null) + public static ArbosStorage Create(IWorldState worldState, Address? testAccount = null, IBurner? burner = null) { Address currentTestAccount = testAccount ?? DefaultTestAccount; IBurner currentBurner = burner ?? new SystemBurner(); - TrackingWorldState worldState = TrackingWorldState.CreateNewInMemory(); worldState.CreateAccountIfNotExists(currentTestAccount, UInt256.Zero, UInt256.One); ArbosStorage storage = new(worldState, currentBurner, currentTestAccount); - return (storage, worldState); + return storage; + } + + public static IDisposable Create(out TrackingWorldState worldState, out ArbosStorage arbosStorage, Address? testAccount = null, IBurner? burner = null) + { + Address currentTestAccount = testAccount ?? DefaultTestAccount; + IBurner currentBurner = burner ?? new SystemBurner(); + + worldState = TrackingWorldState.CreateNewInMemory(); + var dispose = worldState.BeginScope(IWorldState.PreGenesis); + worldState.CreateAccountIfNotExists(currentTestAccount, UInt256.Zero, UInt256.One); + + arbosStorage = new(worldState, currentBurner, currentTestAccount); + + return dispose; } public class TestBurner(ulong availableGas, TracingInfo? tracingInfo = null) : IBurner diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/TestTransaction.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/TestTransaction.cs index ac2eb792..5a0c2a22 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/TestTransaction.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/TestTransaction.cs @@ -4,9 +4,8 @@ using Nethermind.Core.Crypto; using Nethermind.Evm; using Nethermind.Int256; -using Nethermind.State; -using Nethermind.Arbitrum.Math; using Nethermind.Crypto; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Test.Infrastructure { diff --git a/src/Nethermind.Arbitrum.Test/Infrastructure/TrackingWorldState.cs b/src/Nethermind.Arbitrum.Test/Infrastructure/TrackingWorldState.cs index 9e53b50f..09fc583d 100644 --- a/src/Nethermind.Arbitrum.Test/Infrastructure/TrackingWorldState.cs +++ b/src/Nethermind.Arbitrum.Test/Infrastructure/TrackingWorldState.cs @@ -4,9 +4,9 @@ using Nethermind.Core.Eip2930; using Nethermind.Core.Specs; using Nethermind.Core.Test; +using Nethermind.Evm.State; +using Nethermind.Evm.Tracing.State; using Nethermind.Int256; -using Nethermind.State; -using Nethermind.State.Tracing; using Nethermind.Trie; namespace Nethermind.Arbitrum.Test.Infrastructure; @@ -47,6 +47,13 @@ public bool TryGetAccount(Address address, out AccountStruct account) return worldState.TryGetAccount(address, out account); } + public IDisposable BeginScope(BlockHeader? baseBlock) + { + return worldState.BeginScope(baseBlock); + } + + public bool IsInScope { get; } + public ref readonly UInt256 GetBalance(Address address) { return ref worldState.GetBalance(address); @@ -57,6 +64,11 @@ public ref readonly ValueHash256 GetCodeHash(Address address) return ref worldState.GetCodeHash(address); } + public bool HasStateForBlock(BlockHeader? baseBlock) + { + return worldState.HasStateForBlock(baseBlock); + } + public byte[] GetOriginal(in StorageCell storageCell) { return worldState.GetOriginal(in storageCell); @@ -105,7 +117,7 @@ public void RecalculateStateRoot() public Hash256 StateRoot { get => worldState.StateRoot; - set => worldState.StateRoot = value; + //set => worldState.StateRoot = value; } public void DeleteAccount(Address address) @@ -143,11 +155,6 @@ public void SubtractFromBalance(Address address, in UInt256 balanceChange, IRele worldState.SubtractFromBalance(address, in balanceChange, spec); } - public void UpdateStorageRoot(Address address, Hash256 storageRoot) - { - worldState.UpdateStorageRoot(address, storageRoot); - } - public void IncrementNonce(Address address, UInt256 delta) { worldState.IncrementNonce(address, delta); @@ -213,11 +220,6 @@ public bool IsContract(Address address) return worldState.IsContract(address); } - public void Accept(ITreeVisitor visitor, Hash256 stateRoot, VisitingOptions? visitingOptions = null) where TCtx : struct, INodeContext - { - worldState.Accept(visitor, stateRoot, visitingOptions); - } - public bool AccountExists(Address address) { return worldState.AccountExists(address); @@ -227,16 +229,5 @@ public bool IsDeadAccount(Address address) { return worldState.IsDeadAccount(address); } - - public bool IsEmptyAccount(Address address) - { - return worldState.IsEmptyAccount(address); - } - - public bool HasStateForRoot(Hash256 stateRoot) - { - return worldState.HasStateForRoot(stateRoot); - } - #endregion } diff --git a/src/Nethermind.Arbitrum.Test/Nethermind.Arbitrum.Test.csproj b/src/Nethermind.Arbitrum.Test/Nethermind.Arbitrum.Test.csproj index 51a8e355..c3422722 100644 --- a/src/Nethermind.Arbitrum.Test/Nethermind.Arbitrum.Test.csproj +++ b/src/Nethermind.Arbitrum.Test/Nethermind.Arbitrum.Test.csproj @@ -11,16 +11,15 @@ - + - runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/ArbAddressTableTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/ArbAddressTableTests.cs index 840a766c..5479d664 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/ArbAddressTableTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/ArbAddressTableTests.cs @@ -3,7 +3,9 @@ using Nethermind.Arbitrum.Precompiles; using Nethermind.Arbitrum.Test.Infrastructure; using Nethermind.Core; +using Nethermind.Core.Test; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.State; @@ -18,20 +20,26 @@ public sealed class ArbAddressTableTests private IWorldState _worldState = null!; private ArbosState _arbosState = null!; + private BlockHeader _genesisBlockHeader; private PrecompileTestContextBuilder _context = null!; [SetUp] public void SetUp() { - (_worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + _worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = _worldState.BeginScope(IWorldState.PreGenesis); + Block b = ArbOSInitialization.Create(_worldState); _arbosState = ArbosState.OpenArbosState(_worldState, new SystemBurner(), LimboLogs.Instance.GetClassLogger()); _context = new PrecompileTestContextBuilder(_worldState, DefaultGasSupplied) { ArbosState = _arbosState }; + _genesisBlockHeader = b.Header; } [Test] public void AddressExists_WithRegisteredAddress_ReturnsTrue() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); _arbosState.AddressTable.Register(TestAddress); bool exists = ArbAddressTable.AddressExists(_context, TestAddress); @@ -42,6 +50,7 @@ public void AddressExists_WithRegisteredAddress_ReturnsTrue() [Test] public void AddressExists_WithUnregisteredAddress_ReturnsFalse() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); bool exists = ArbAddressTable.AddressExists(_context, TestAddress); exists.Should().BeFalse(); @@ -50,6 +59,7 @@ public void AddressExists_WithUnregisteredAddress_ReturnsFalse() [Test] public void Compress_WithUnregisteredAddress_ReturnsFullAddress() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] compressed = ArbAddressTable.Compress(_context, TestAddress); compressed.Should().NotBeNull(); @@ -59,6 +69,7 @@ public void Compress_WithUnregisteredAddress_ReturnsFullAddress() [Test] public void Compress_WithRegisteredAddress_ReturnsCompressedIndex() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); _arbosState.AddressTable.Register(TestAddress); byte[] compressed = ArbAddressTable.Compress(_context, TestAddress); @@ -70,6 +81,7 @@ public void Compress_WithRegisteredAddress_ReturnsCompressedIndex() [Test] public void Decompress_WithValidData_ReturnsAddressAndBytesRead() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] compressed = _arbosState.AddressTable.Compress(TestAddress); (Address address, UInt256 bytesRead) = ArbAddressTable.Decompress(_context, compressed, UInt256.Zero); @@ -93,6 +105,7 @@ public void Decompress_WithInvalidOffset_ThrowsArgumentException() [Test] public void Lookup_WithRegisteredAddress_ReturnsIndex() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); ulong expectedIndex = _arbosState.AddressTable.Register(TestAddress); UInt256 index = ArbAddressTable.Lookup(_context, TestAddress); @@ -103,6 +116,7 @@ public void Lookup_WithRegisteredAddress_ReturnsIndex() [Test] public void Lookup_WithUnregisteredAddress_ThrowsArgumentException() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); Action action = () => ArbAddressTable.Lookup(_context, TestAddress); action.Should().Throw() @@ -112,6 +126,7 @@ public void Lookup_WithUnregisteredAddress_ThrowsArgumentException() [Test] public void LookupIndex_WithValidIndex_ReturnsAddress() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); ulong index = _arbosState.AddressTable.Register(TestAddress); Address address = ArbAddressTable.LookupIndex(_context, new UInt256(index)); @@ -124,6 +139,7 @@ public void LookupIndex_WithInvalidIndex_ThrowsArgumentException() { UInt256 invalidIndex = new(999); + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); Action action = () => ArbAddressTable.LookupIndex(_context, invalidIndex); action.Should().Throw() @@ -144,6 +160,7 @@ public void LookupIndex_WithIndexTooLarge_ThrowsArgumentException() [Test] public void Register_WithNewAddress_ReturnsIndex() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); UInt256 index = ArbAddressTable.Register(_context, TestAddress); index.Should().Be(UInt256.Zero); // The first registered address gets index 0 @@ -152,6 +169,7 @@ public void Register_WithNewAddress_ReturnsIndex() [Test] public void Register_WithExistingAddress_ReturnsSameIndex() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); ulong expectedIndex = _arbosState.AddressTable.Register(TestAddress); UInt256 index = ArbAddressTable.Register(_context, TestAddress); @@ -162,6 +180,7 @@ public void Register_WithExistingAddress_ReturnsSameIndex() [Test] public void Size_OnEmptyTable_ReturnsZero() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); UInt256 size = ArbAddressTable.Size(_context); size.Should().Be(UInt256.Zero); @@ -174,6 +193,8 @@ public void Size_WithRegisteredAddresses_ReturnsCorrectCount() Address address2 = new("0x2222222222222222222222222222222222222222"); Address address3 = new("0x3333333333333333333333333333333333333333"); + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + _arbosState.AddressTable.Register(address1); _arbosState.AddressTable.Register(address2); _arbosState.AddressTable.Register(address3); @@ -189,6 +210,7 @@ public void CompressAndDecompress_RoundTrip_PreservesAddress() Address unregisteredAddress = new("0x9876543210987654321098765432109876543210"); Address[] testAddresses = [TestAddress, unregisteredAddress]; + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); // Register only the first address _arbosState.AddressTable.Register(testAddresses[0]); diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/ArbInfoTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/ArbInfoTests.cs index f0aa4366..cfb6a1e1 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/ArbInfoTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/ArbInfoTests.cs @@ -1,19 +1,21 @@ -using System.Security.Cryptography; using FluentAssertions; using Nethermind.Arbitrum.Arbos; using Nethermind.Arbitrum.Data; using Nethermind.Arbitrum.Precompiles; -using Nethermind.Evm; -using Nethermind.Logging; -using Nethermind.State; -using Nethermind.Specs.Forks; +using Nethermind.Arbitrum.Test.Infrastructure; using Nethermind.Core; -using Nethermind.Int256; -using Nethermind.Core.Extensions; using Nethermind.Core.Crypto; -using Nethermind.Arbitrum.Test.Infrastructure; +using Nethermind.Core.Extensions; +using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; +using Nethermind.Evm; +using Nethermind.Evm.State; +using Nethermind.Int256; using Nethermind.JsonRpc; +using Nethermind.Logging; +using Nethermind.Specs.Forks; +using Nethermind.State; +using System.Security.Cryptography; namespace Nethermind.Arbitrum.Test.Precompiles; @@ -25,7 +27,11 @@ public class ArbInfoTests public void GetBalance_PositiveBalanceAndEnoughGas_ReturnsBalance() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); // Create test account Address testAccount = new("0x0000000000000000000000000000000000000123"); @@ -47,7 +53,11 @@ public void GetBalance_PositiveBalanceAndEnoughGas_ReturnsBalance() public void GetBalance_NotEnoughGas_ThrowsOutOfGasException() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); // Create test account Address testAccount = new("0x0000000000000000000000000000000000000123"); @@ -67,7 +77,11 @@ public void GetBalance_NotEnoughGas_ThrowsOutOfGasException() public void GetBalance_NonExistentAccount_Returns0() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); Address unsetTestAccount = new("0x0000000000000000000000000000000000000123"); @@ -89,7 +103,11 @@ public async Task GetBalance_DoesntHaveEnoughBalance_Fails() Hash256 requestId = new(RandomNumberGenerator.GetBytes(Hash256.Size)); Address sender = FullChainSimulationAccounts.Owner.Address; - UInt256 nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + UInt256 nonce = UInt256.Zero; + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + } // Calldata to call getBalance(address) on ArbInfo precompile byte[] addressBytes = new byte[32]; @@ -117,7 +135,11 @@ public async Task GetBalance_DoesntHaveEnoughBalance_Fails() public void GetCode_ExistingContractAndEnoughGas_ReturnsCode() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); // Create some contract whose code to get within the world state Address someContract = new("0x0000000000000000000000000000000000000123"); @@ -140,7 +162,11 @@ public void GetCode_ExistingContractAndEnoughGas_ReturnsCode() public void GetCode_NotEnoughGas_ThrowsOutOfGasException() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); // Create some contract whose code to get within the world state Address someContract = new("0x0000000000000000000000000000000000000123"); @@ -159,7 +185,11 @@ public void GetCode_NotEnoughGas_ThrowsOutOfGasException() public void GetCode_NonExistentContract_ReturnsEmptyCode() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); Address unsetContract = new("0x0000000000000000000000000000000000000123"); diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/ArbRetryableTxTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/ArbRetryableTxTests.cs index 014a3ff5..112b403a 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/ArbRetryableTxTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/ArbRetryableTxTests.cs @@ -1,17 +1,19 @@ -using Nethermind.Arbitrum.Precompiles; -using Nethermind.Evm; -using Nethermind.State; -using Nethermind.Core; -using Nethermind.Int256; -using Nethermind.Core.Crypto; using FluentAssertions; using Nethermind.Abi; using Nethermind.Arbitrum.Arbos.Storage; +using Nethermind.Arbitrum.Execution; using Nethermind.Arbitrum.Execution.Transactions; +using Nethermind.Arbitrum.Precompiles; using Nethermind.Arbitrum.Precompiles.Events; -using Nethermind.Crypto; using Nethermind.Arbitrum.Test.Infrastructure; -using Nethermind.Arbitrum.Execution; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Test; +using Nethermind.Crypto; +using Nethermind.Evm; +using Nethermind.Evm.State; +using Nethermind.Int256; +using Nethermind.State; namespace Nethermind.Arbitrum.Test.Precompiles; @@ -21,7 +23,11 @@ public class ArbRetryableTxTests public void TicketCreated_EmitsEvent() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); string eventSignature = "TicketCreated(bytes32)"; UInt256 ticketId = 123; @@ -42,7 +48,11 @@ public void TicketCreated_EmitsEvent() public void RedeemScheduled_EmitsEvent() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); string eventSignature = "RedeemScheduled(bytes32,bytes32,uint64,uint64,address,uint256,uint256)"; @@ -86,7 +96,11 @@ public void RedeemScheduled_EmitsEvent() public void LifetimeExtended_EmitsEvent() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); string eventSignature = "LifetimeExtended(bytes32,uint256)"; @@ -121,7 +135,11 @@ public void LifetimeExtended_EmitsEvent() public void Canceled_EmitsEvent() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); string eventSignature = "Canceled(bytes32)"; @@ -166,7 +184,11 @@ public void NotCallableSolidityError_ReturnsError() public void Redeem_RetryableExists_ReturnsCreatedRetryTxHash() { // Initialize ArbOS state - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + var genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; ulong gasSupplied = ulong.MaxValue; @@ -283,7 +305,11 @@ public static ulong ComputeRedeemCost(out ulong gasToDonate, ulong gasSupplied, [Test] public void Redeem_SelfModifyingRetryable_Throws() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); Hash256 ticketIdHash = Hash256FromUlong(123); PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue) @@ -299,7 +325,12 @@ public void Redeem_SelfModifyingRetryable_Throws() [Test] public void Redeem_RetryableDoesNotExists_Throws() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); + PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue) { CurrentRetryable = Hash256FromUlong(123) @@ -323,7 +354,11 @@ public void GetLifetime_Always_ReturnsDefaultLifetime() [Test] public void GetTimeout_RetryableExists_ReturnsCalculatedTimeout() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue); context.WithArbosState().WithBlockExecutionContext(genesis.Header); @@ -344,7 +379,11 @@ public void GetTimeout_RetryableExists_ReturnsCalculatedTimeout() [Test] public void GetTimeout_RetryableExpired_Throws() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue); context.WithArbosState().WithBlockExecutionContext(genesis.Header); @@ -366,7 +405,12 @@ public void GetTimeout_RetryableExpired_Throws() [Test] public void KeepAlive_RetryableExpiresBefore1Lifetime_ReturnsNewTimeout() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + var genesis = ArbOSInitialization.Create(worldState); + genesis.Header.Timestamp = 100; ulong gasSupplied = ulong.MaxValue; ulong gasLeft = gasSupplied; @@ -423,7 +467,11 @@ public void KeepAlive_RetryableExpiresBefore1Lifetime_ReturnsNewTimeout() [Test] public void KeepAlive_RetryableDoesNotExist_Throws() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue); @@ -439,7 +487,11 @@ public void KeepAlive_RetryableDoesNotExist_Throws() [Test] public void KeepAlive_RetryableExpiresAfter1Lifetime_Throws() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; ulong gasSupplied = ulong.MaxValue; @@ -461,7 +513,11 @@ public void KeepAlive_RetryableExpiresAfter1Lifetime_Throws() [Test] public void GetBeneficiary_RetryableExists_ReturnsBeneficiary() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue); context.WithArbosState().WithBlockExecutionContext(genesis.Header); @@ -480,7 +536,11 @@ public void GetBeneficiary_RetryableExists_ReturnsBeneficiary() [Test] public void GetBeneficiary_RetryableExpired_Throws() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue); context.WithArbosState().WithBlockExecutionContext(genesis.Header); @@ -501,7 +561,11 @@ public void GetBeneficiary_RetryableExpired_Throws() [Test] public void Cancel_RetryableExists_DeletesIt() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; ulong gasSupplied = ulong.MaxValue; ulong gasLeft = gasSupplied; @@ -569,7 +633,11 @@ public void Cancel_RetryableExists_DeletesIt() [Test] public void Cancel_SelfModifyingRetryable_Throws() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); Hash256 ticketId = Hash256FromUlong(123); PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue) @@ -586,7 +654,11 @@ public void Cancel_SelfModifyingRetryable_Throws() [Test] public void Cancel_NotBeneficiary_Throws() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue) { @@ -611,7 +683,11 @@ public void Cancel_NotBeneficiary_Throws() [Test] public void GetCurrentRedeemer_RedeemTransaction_ReturnsRedeemer() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); Address redeemer = new(Hash256FromUlong(123)); PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue) @@ -626,7 +702,11 @@ public void GetCurrentRedeemer_RedeemTransaction_ReturnsRedeemer() [Test] public void GetCurrentRedeemer_NotARedeemTransaction_ReturnsZeroAddress() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue); Address returnedRedeemer = ArbRetryableTx.GetCurrentRedeemer(context); diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/ArbSysTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/ArbSysTests.cs index ef40e8a4..94e833e8 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/ArbSysTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/ArbSysTests.cs @@ -9,8 +9,10 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; +using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Int256; using Nethermind.State; @@ -23,7 +25,11 @@ public class ArbSysTests public void ArbBlockNumber_WithValidContext_ReturnsCurrentBlockNumber() { const long expectedBlockNumber = 12345; - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithBlockNumber(expectedBlockNumber); @@ -44,7 +50,11 @@ public void ArbBlockHash_WithValidBlockNumber_ReturnsHash() (targetBlock, expectedHash) ); - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithArbosVersion(ArbosVersion.Eleven) @@ -62,7 +72,11 @@ public void ArbBlockHash_WithBlockNumberTooOld_ThrowsException() const long currentBlock = 500; const long targetBlock = 100; // More than 256 blocks old - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithArbosVersion(ArbosVersion.Eleven) @@ -78,7 +92,11 @@ public void ArbBlockHash_WithBlockNumberInFuture_ThrowsException() const long currentBlock = 100; const long targetBlock = 200; // Future block - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithArbosVersion(ArbosVersion.Eleven) @@ -94,7 +112,11 @@ public void ArbBlockHash_WithArbosVersion11OrHigher_ThrowsSolidityError() const long currentBlock = 500; const long targetBlock = 100; - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithBlockNumber(currentBlock) @@ -109,7 +131,11 @@ public void ArbBlockHash_WithNonUint64Value_ThrowsException() { UInt256 hugeBlockNumber = UInt256.MaxValue; - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithBlockNumber(100) @@ -123,7 +149,11 @@ public void ArbBlockHash_WithNonUint64Value_ThrowsException() public void ArbChainID_WithValidContext_ReturnsCorrectChainId() { const ulong expectedChainId = 42161; // Arbitrum One - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithChainId(expectedChainId); @@ -139,7 +169,11 @@ public void ArbOSVersion_WithValidContext_ReturnsCorrectVersion() ulong arbosVersion = ArbosVersion.Thirty; UInt256 expectedVersion = arbosVersion + 55; // Nitro starts at version 56 - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithArbosVersion(arbosVersion); @@ -160,7 +194,11 @@ public void GetStorageGasAvailable_Always_ReturnsZero() [Test] public void IsTopLevelCall_WithCallDepthLessThanOrEqualTo2_ReturnsTrue() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(2); @@ -173,7 +211,11 @@ public void IsTopLevelCall_WithCallDepthLessThanOrEqualTo2_ReturnsTrue() [Test] public void IsTopLevelCall_WithCallDepthGreaterThan2_ReturnsFalse() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(3); @@ -187,11 +229,15 @@ public void IsTopLevelCall_WithCallDepthGreaterThan2_ReturnsFalse() public void WasMyCallersAddressAliased_WithArbosVersionSixAndOriginEqualsGrandCaller_UsesComplexLogic() { Address commonAddress = TestItem.AddressC; - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(5) // Deep call, but should still be top level due to origin == grandCaller - .WithOrigin(commonAddress) + .WithOrigin(commonAddress.ToHash()) .WithGrandCaller(commonAddress) .WithArbosVersion(ArbosVersion.Six) .WithTopLevelTxType(ArbitrumTxType.ArbitrumUnsigned); @@ -216,10 +262,14 @@ public void MapL1SenderContractAddressToL2Alias_WithValidAddress_AppliesCorrectO [Test] public void WasMyCallersAddressAliased_WithTopLevelAndAliasingTxType_ReturnsTrue() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() - .WithCallDepth(2) // Top level in ArbOS < 6 requires CallDepth == 2 + .WithCallDepth(2) // Top level in ArbOS < 6 requires CallDepth == 2 .WithGrandCaller(TestItem.AddressB) // Need valid GrandCaller for CallDepth = 2 .WithTopLevelTxType(ArbitrumTxType.ArbitrumUnsigned) .WithArbosVersion(ArbosVersion.Five); @@ -232,7 +282,11 @@ public void WasMyCallersAddressAliased_WithTopLevelAndAliasingTxType_ReturnsTrue [Test] public void WasMyCallersAddressAliased_WithNotTopLevelCall_ReturnsFalse() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(3) @@ -247,7 +301,11 @@ public void WasMyCallersAddressAliased_WithNotTopLevelCall_ReturnsFalse() [Test] public void WasMyCallersAddressAliased_WithNonAliasingTxType_ReturnsFalse() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(2) // Top level in ArbOS < 6 requires CallDepth == 2 @@ -265,12 +323,16 @@ public void MyCallersAddressWithoutAliasing_WithAliasedGrandCaller_ReturnsUnalia Address aliasedAddress = new("0x1111000000000000000000000000000000002345"); Address expectedUnaliased = new("0x0000000000000000000000000000000000001234"); - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(2) // Need CallDepth > 1 to use GrandCaller, and == 2 for IsTopLevel in ArbOS < 6 .WithGrandCaller(aliasedAddress) - .WithOrigin(TestItem.AddressA) // Ensure Origin is set + .WithOrigin(TestItem.AddressA.ToHash()) // Ensure Origin is set .WithTopLevelTxType(ArbitrumTxType.ArbitrumUnsigned) .WithArbosVersion(ArbosVersion.Five); @@ -282,7 +344,11 @@ public void MyCallersAddressWithoutAliasing_WithAliasedGrandCaller_ReturnsUnalia [Test] public void MyCallersAddressWithoutAliasing_WithNoGrandCaller_ReturnsZeroAddress() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(1) @@ -300,7 +366,11 @@ public void SendTxToL1_WithValidParameters_EmitsEventsAndReturnsLeafNum() byte[] callDataForL1 = Bytes.FromHexString("0x1234567890"); UInt256 value = new(100); - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 10_000_000) .WithArbosState() .WithValue(value) @@ -329,7 +399,11 @@ public void SendTxToL1_WithNativeTokenOwners_ThrowsException() Address destination = TestItem.AddressB; byte[] callDataForL1 = []; - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithArbosVersion(ArbosVersion.FortyOne) // > ArbosVersion.Forty (40), so 41 works @@ -346,7 +420,11 @@ public void WithdrawEth_WithValidParameters_CallsSendTxToL1WithEmptyData() Address destination = TestItem.AddressB; UInt256 value = new(1000); - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 10_000_000) .WithArbosState() .WithValue(value) @@ -373,7 +451,11 @@ public void WithdrawEth_WithValidParameters_CallsSendTxToL1WithEmptyData() [Test] public void SendMerkleTreeState_WithCallerNotZeroAddress_ThrowsException() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCaller(TestItem.AddressA); @@ -386,7 +468,11 @@ public void SendMerkleTreeState_WithCallerNotZeroAddress_ThrowsException() [Test] public void SendMerkleTreeState_WithZeroAddressCaller_ReturnsState() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCaller(Address.Zero); @@ -417,7 +503,7 @@ public void DecodeL2ToL1TransactionEvent_WithValidLogEntry_DecodesCorrectly() ArbSys.Address, caller, destination, - uniqueId, // uniqueId comes before batchNumber in the event + uniqueId, // uniqueId comes before batchNumber in the event batchNumber, indexInBatch, arbBlockNum, @@ -518,7 +604,11 @@ public void EmitSendMerkleUpdateEvent_WithValidParameters_AddsCorrectEventToLogs Hash256 hash = TestItem.KeccakA; UInt256 position = new(123); - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState(); @@ -543,7 +633,11 @@ public void EmitL2ToL1TxEvent_WithValidParameters_AddsCorrectEventToLogs() UInt256 callValue = new(100); byte[] data = Bytes.FromHexString("0x1234"); - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState(); @@ -572,7 +666,11 @@ public void IsTopLevel_WithDifferentArbosVersions_BehavesCorrectly() // Test that IsTopLevel behaves differently for ArbOS versions < 6 and >= 6 // ArbOS < 6: top level when callDepth == 2 - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext contextV5 = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(2) @@ -598,7 +696,7 @@ public void IsTopLevel_WithDifferentArbosVersions_BehavesCorrectly() ArbitrumPrecompileExecutionContext contextV6Origin = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(3) // Deep call - .WithOrigin(commonAddress) + .WithOrigin(commonAddress.ToHash()) .WithGrandCaller(commonAddress) .WithTopLevelTxType(ArbitrumTxType.ArbitrumUnsigned) .WithArbosVersion(ArbosVersion.Six); @@ -628,7 +726,11 @@ public void WasMyCallersAddressAliased_WithAliasingTxTypes_ReturnsTrue() foreach (ArbitrumTxType txType in aliasingTypes) { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(2) // For ArbOS < 6, IsTopLevel requires CallDepth == 2 @@ -642,7 +744,11 @@ public void WasMyCallersAddressAliased_WithAliasingTxTypes_ReturnsTrue() foreach (ArbitrumTxType txType in nonAliasingTypes) { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(1) @@ -665,7 +771,11 @@ public void SendTxToL1_Always_BurnsCorrectAmountOfGas() // Calculate expected gas burn: 30 + 6 * ceil(data_length / 32) ulong expectedGasBurn = 30 + 6 * ((ulong)(dataLength + 31) / 32); - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 10_000_000) .WithArbosState() .WithValue(value) @@ -686,7 +796,11 @@ public void SendTxToL1_Always_BurnsCorrectAmountOfGas() [Test] public void MyCallersAddressWithoutAliasing_WithNoGrandCallerAndAliasingTxType_ReturnsUnaliasedZeroAddress() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCallDepth(2) // Top level for ArbOS < 6 @@ -708,7 +822,11 @@ public void SendTxToL1_WithValidParameters_EmitsCorrectEventFields() { Address destination = TestItem.AddressB; byte[] callDataForL1 = [1, 2, 3, 4]; - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithBlockNumber(12345) @@ -737,7 +855,11 @@ public void SendTxToL1_WithValidParameters_EmitsCorrectEventFields() [Test] public void SendMerkleTreeState_WithActualMerkleData_ReturnsCorrectValues() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); ArbitrumPrecompileExecutionContext context = new PrecompileTestContextBuilder(worldState, 1_000_000) .WithArbosState() .WithCaller(Address.Zero) // Only zero address can call SendMerkleTreeState diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/ArbWasmTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/ArbWasmTests.cs index c4cd1edb..57ac4c95 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/ArbWasmTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/ArbWasmTests.cs @@ -4,9 +4,12 @@ using FluentAssertions; using Nethermind.Arbitrum.Arbos; using Nethermind.Arbitrum.Test.Infrastructure; +using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Logging; using Nethermind.State; using static Nethermind.Arbitrum.Precompiles.ArbWasm; @@ -26,11 +29,16 @@ public sealed class ArbWasmTests private IWorldState _worldState = null!; private ArbosState _arbosState = null!; private PrecompileTestContextBuilder _context = null!; + private BlockHeader _genesisBlockHeader; [SetUp] public void SetUp() { - (_worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + _worldState = worldStateManager.GlobalWorldState; + using IDisposable worldStateDisposer = _worldState.BeginScope(IWorldState.PreGenesis); + + _genesisBlockHeader = ArbOSInitialization.Create(_worldState).Header; _arbosState = ArbosState.OpenArbosState( _worldState, new SystemBurner(), @@ -45,6 +53,8 @@ public void SetUp() [Test] public void StylusVersion_Always_ReturnsCurrentVersion() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ushort version = StylusVersion(_context); version.Should().Be(2); @@ -53,6 +63,8 @@ public void StylusVersion_Always_ReturnsCurrentVersion() [Test] public void InkPrice_Always_ReturnsPositiveValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + uint price = InkPrice(_context); price.Should().Be(10_000); // InitialInkPrice = 10,000 @@ -61,6 +73,8 @@ public void InkPrice_Always_ReturnsPositiveValue() [Test] public void MaxStackDepth_Always_ReturnsPositiveValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + uint depth = MaxStackDepth(_context); depth.Should().Be(262_144); // InitialStackDepth = 4 * 65,536 = 262,144 @@ -69,6 +83,8 @@ public void MaxStackDepth_Always_ReturnsPositiveValue() [Test] public void FreePages_Always_ReturnsNonNegativeValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ushort pages = FreePages(_context); pages.Should().Be(2); // InitialFreePages = 2 @@ -77,6 +93,8 @@ public void FreePages_Always_ReturnsNonNegativeValue() [Test] public void PageGas_Always_ReturnsPositiveValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ushort gas = PageGas(_context); gas.Should().Be(1_000); // InitialPageGas = 1,000 @@ -85,6 +103,8 @@ public void PageGas_Always_ReturnsPositiveValue() [Test] public void PageRamp_Always_ReturnsPositiveValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ulong ramp = PageRamp(_context); ramp.Should().Be(620_674_314); // InitialPageRamp = 620,674,314 @@ -93,6 +113,8 @@ public void PageRamp_Always_ReturnsPositiveValue() [Test] public void PageLimit_Always_ReturnsPositiveValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ushort limit = PageLimit(_context); limit.Should().Be(128); // InitialPageLimit = 128 @@ -101,9 +123,8 @@ public void PageLimit_Always_ReturnsPositiveValue() [Test] public void MinInitGas_WithSupportedVersion_ReturnsValidValues() { - PrecompileTestContextBuilder context = new PrecompileTestContextBuilder(_worldState, DefaultGasSupplied) - .WithArbosState() - .WithArbosVersion(ArbosVersion.StylusChargingFixes); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + PrecompileTestContextBuilder context = _context.WithArbosVersion(ArbosVersion.StylusChargingFixes); (ulong gas, ulong cached) = MinInitGas(context); @@ -114,9 +135,8 @@ public void MinInitGas_WithSupportedVersion_ReturnsValidValues() [Test] public void MinInitGas_WithUnsupportedVersion_ThrowsException() { - PrecompileTestContextBuilder context = new PrecompileTestContextBuilder(_worldState, DefaultGasSupplied) - .WithArbosState() - .WithArbosVersion(ArbosVersion.StylusChargingFixes - 1); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + PrecompileTestContextBuilder context = _context.WithArbosVersion(ArbosVersion.StylusChargingFixes - 1); Action act = () => MinInitGas(context); @@ -127,6 +147,8 @@ public void MinInitGas_WithUnsupportedVersion_ThrowsException() [Test] public void InitCostScalar_Always_ReturnsPositiveValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ulong percent = InitCostScalar(_context); percent.Should().Be(100); @@ -135,6 +157,8 @@ public void InitCostScalar_Always_ReturnsPositiveValue() [Test] public void ExpiryDays_Always_ReturnsPositiveValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ushort days = ExpiryDays(_context); days.Should().Be(InitialExpiryDays); @@ -143,6 +167,8 @@ public void ExpiryDays_Always_ReturnsPositiveValue() [Test] public void KeepaliveDays_Always_ReturnsPositiveValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ushort days = KeepaliveDays(_context); days.Should().Be(31); // InitialKeepaliveDays = 31 @@ -151,6 +177,7 @@ public void KeepaliveDays_Always_ReturnsPositiveValue() [Test] public void BlockCacheSize_Always_ReturnsNonNegativeValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); ushort count = BlockCacheSize(_context); count.Should().Be(32); // InitialRecentCacheSize = 32 @@ -159,6 +186,8 @@ public void BlockCacheSize_Always_ReturnsNonNegativeValue() [Test] public void CodeHashVersion_WithNonExistentCodeHash_ReturnsZero() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + Hash256 nonExistentCodeHash = Hash256.Zero; ushort version = CodeHashVersion(_context, nonExistentCodeHash); @@ -169,6 +198,8 @@ public void CodeHashVersion_WithNonExistentCodeHash_ReturnsZero() [Test] public void ProgramVersion_WithNonExistentProgram_ReturnsZero() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + Address nonExistentProgram = Address.Zero; ushort version = ProgramVersion(_context, nonExistentProgram); @@ -179,6 +210,8 @@ public void ProgramVersion_WithNonExistentProgram_ReturnsZero() [Test] public void CodeHashAsmSize_WithNonActivatedProgram_ThrowsInvalidOperation() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + Action act = () => CodeHashAsmSize(_context, NonActivatedCodeHash); act.Should().Throw() @@ -188,6 +221,8 @@ public void CodeHashAsmSize_WithNonActivatedProgram_ThrowsInvalidOperation() [Test] public void ProgramInitGas_WithNonActivatedProgram_ThrowsInvalidOperation() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + Action act = () => ProgramInitGas(_context, NonActivatedProgram); act.Should().Throw() @@ -197,6 +232,8 @@ public void ProgramInitGas_WithNonActivatedProgram_ThrowsInvalidOperation() [Test] public void ProgramMemoryFootprint_WithNonActivatedProgram_ThrowsInvalidOperation() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + Action act = () => ProgramMemoryFootprint(_context, NonActivatedProgram); act.Should().Throw() @@ -206,6 +243,8 @@ public void ProgramMemoryFootprint_WithNonActivatedProgram_ThrowsInvalidOperatio [Test] public void ProgramTimeLeft_WithNonActivatedProgram_ThrowsInvalidOperation() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + Action act = () => ProgramTimeLeft(_context, NonActivatedProgram); act.Should().Throw() @@ -215,6 +254,8 @@ public void ProgramTimeLeft_WithNonActivatedProgram_ThrowsInvalidOperation() [Test] public void CodeHashKeepalive_WithTooEarlyKeepalive_ThrowsInvalidOperation() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + Hash256 codeHash = Hash256.Zero; Action act = () => CodeHashKeepAlive(_context, codeHash); @@ -276,6 +317,8 @@ public void ActivateProgram_WithZeroValue_ThrowsOutOfGas() [Test] public void CodeHashKeepAlive_WithNonActivatedProgram_ThrowsInvalidOperation() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + Hash256 nonActivatedCodeHash = Hash256.Zero; Action act = () => CodeHashKeepAlive(_context, nonActivatedCodeHash); @@ -287,6 +330,8 @@ public void CodeHashKeepAlive_WithNonActivatedProgram_ThrowsInvalidOperation() [Test] public void CodeHashKeepAlive_WithInsufficientValue_ThrowsInvalidOperation() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + Hash256 codeHash = Hash256.Zero; Action act = () => CodeHashKeepAlive(_context, codeHash); @@ -298,6 +343,8 @@ public void CodeHashKeepAlive_WithInsufficientValue_ThrowsInvalidOperation() [Test] public void MinInitGas_WithDifferentVersions_ReturnsCorrectValues() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + PrecompileTestContextBuilder contextV1 = new PrecompileTestContextBuilder(_worldState, DefaultGasSupplied) .WithArbosState() .WithArbosVersion(ArbosVersion.StylusChargingFixes - 1); @@ -311,6 +358,8 @@ public void MinInitGas_WithDifferentVersions_ReturnsCorrectValues() [Test] public void ExpiryDays_WithDefaultParams_ReturnsPositiveValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ushort days = ExpiryDays(_context); days.Should().Be(InitialExpiryDays); @@ -319,6 +368,8 @@ public void ExpiryDays_WithDefaultParams_ReturnsPositiveValue() [Test] public void KeepaliveDays_WithDefaultParams_ReturnsPositiveValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ushort days = KeepaliveDays(_context); days.Should().Be(31); @@ -327,6 +378,8 @@ public void KeepaliveDays_WithDefaultParams_ReturnsPositiveValue() [Test] public void BlockCacheSize_WithDefaultParams_ReturnsNonNegativeValue() { + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + ushort size = BlockCacheSize(_context); size.Should().Be(32); diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbAddressTableParserTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbAddressTableParserTests.cs index 7f141c68..fc484e04 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbAddressTableParserTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbAddressTableParserTests.cs @@ -4,6 +4,8 @@ using Nethermind.Arbitrum.Precompiles.Parser; using Nethermind.Arbitrum.Test.Infrastructure; using Nethermind.Core; +using Nethermind.Core.Test; +using Nethermind.Evm.State; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.State; @@ -27,16 +29,22 @@ public sealed class ArbAddressTableParserTests private ArbosState _arbosState = null!; private PrecompileTestContextBuilder _context = null!; private ArbAddressTableParser _parser = null!; + private IWorldState _worldState = null!; + private BlockHeader _genesisBlockHeader = null!; [SetUp] public void SetUp() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); - _arbosState = ArbosState.OpenArbosState(worldState, new SystemBurner(), + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + _worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = _worldState.BeginScope(IWorldState.PreGenesis); + Block b = ArbOSInitialization.Create(_worldState); + _arbosState = ArbosState.OpenArbosState(_worldState, new SystemBurner(), LimboLogs.Instance.GetClassLogger()); - _context = new PrecompileTestContextBuilder(worldState, DefaultGasSupplied) + _context = new PrecompileTestContextBuilder(_worldState, DefaultGasSupplied) .WithArbosState(); _parser = new ArbAddressTableParser(); + _genesisBlockHeader = b.Header; } @@ -44,6 +52,7 @@ public void SetUp() [Test] public void ParsesAddressExists_ValidInputData_ReturnsTrue() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); _arbosState.AddressTable.Register(TestAddress); byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, AddressExistsSignature, TestAddress); @@ -58,6 +67,7 @@ public void ParsesAddressExists_ValidInputData_ReturnsTrue() [Test] public void ParsesAddressExists_ValidInputData_ReturnsFalse() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); // Don't register the address byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, AddressExistsSignature, TestAddress); @@ -72,6 +82,7 @@ public void ParsesAddressExists_ValidInputData_ReturnsFalse() [Test] public void ParsesCompress_ValidInputData_ReturnsCompressedBytes() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, CompressSignature, TestAddress); byte[] result = _parser.RunAdvanced(_context, inputData); @@ -83,6 +94,7 @@ public void ParsesCompress_ValidInputData_ReturnsCompressedBytes() [Test] public void ParsesLookup_ValidInputData_ReturnsIndex() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); ulong expectedIndex = _arbosState.AddressTable.Register(TestAddress); byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, LookupSignature, TestAddress); @@ -98,6 +110,7 @@ public void ParsesLookup_ValidInputData_ReturnsIndex() [Test] public void ParsesLookup_WithUnregisteredAddress_Throws() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, LookupSignature, TestAddress); Action action = () => _parser.RunAdvanced(_context, inputData); @@ -109,6 +122,7 @@ public void ParsesLookup_WithUnregisteredAddress_Throws() [Test] public void ParsesLookupIndex_ValidInputData_ReturnsAddress() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); ulong index = _arbosState.AddressTable.Register(TestAddress); byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, LookupIndexSignature, new UInt256(index)); @@ -125,6 +139,7 @@ public void ParsesLookupIndex_ValidInputData_ReturnsAddress() [Test] public void ParsesRegister_ValidInputData_ReturnsIndex() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, RegisterSignature, TestAddress); byte[] result = _parser.RunAdvanced(_context, inputData); @@ -138,6 +153,8 @@ public void ParsesRegister_ValidInputData_ReturnsIndex() [Test] public void ParsesSize_ValidInputData_ReturnsSize() { + using var worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); + // Register some addresses _arbosState.AddressTable.Register(new Address("0x1111111111111111111111111111111111111111")); _arbosState.AddressTable.Register(new Address("0x2222222222222222222222222222222222222222")); diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbGasInfoParserTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbGasInfoParserTests.cs index 8b56b966..4a453f04 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbGasInfoParserTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbGasInfoParserTests.cs @@ -18,6 +18,8 @@ using System.Security.Cryptography; using Nethermind.JsonRpc; using Nethermind.Arbitrum.Data; +using Nethermind.Core.Test; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Test.Precompiles.Parser; @@ -30,6 +32,8 @@ public class ArbGasInfoParserTests private PrecompileTestContextBuilder _context = null!; private ArbosState _freeArbosState = null!; private ArbGasInfoParser _parser = null!; + private IDisposable _worldStateScope = null!; + private IWorldState _worldState = null!; private static readonly Dictionary precompileFunctions = AbiMetadata.GetAllFunctionDescriptions(ArbGasInfo.Abi); @@ -37,12 +41,16 @@ public class ArbGasInfoParserTests [SetUp] public void SetUp() { - (IWorldState worldState, _genesisBlock) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + _worldState = worldStateManager.GlobalWorldState; + _worldStateScope = _worldState.BeginScope(IWorldState.PreGenesis); // Store the scope - _context = new PrecompileTestContextBuilder(worldState, DefaultGasSupplied).WithArbosState(); + _genesisBlock = ArbOSInitialization.Create(_worldState); + + _context = new PrecompileTestContextBuilder(_worldState, DefaultGasSupplied).WithArbosState(); _context.ResetGasLeft(); - _freeArbosState = ArbosState.OpenArbosState(worldState, new ZeroGasBurner(), LimboLogs.Instance.GetClassLogger()); + _freeArbosState = ArbosState.OpenArbosState(_worldState, new ZeroGasBurner(), LimboLogs.Instance.GetClassLogger()); _parser = new ArbGasInfoParser(); } @@ -672,12 +680,14 @@ public async Task GetMinimumGasPrice_Always_ConsumesRightAmountOfGas() .WithRecording(new FullChainSimulationRecordingFile("./Recordings/1__arbos32_basefee92.jsonl")) .Build(); - IWorldState worldState = chain.WorldStateManager.GlobalWorldState; - ArbosState arbosState = ArbosState.OpenArbosState(worldState, new ZeroGasBurner(), NullLogger.Instance); - Hash256 requestId = new(RandomNumberGenerator.GetBytes(Hash256.Size)); Address sender = FullChainSimulationAccounts.Owner.Address; - UInt256 nonce = worldState.GetNonce(sender); + UInt256 nonce; + + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + } // Calldata to call getMinimumGasPrice() on ArbGasInfo precompile byte[] calldata = KeccakHash.ComputeHashBytes("getMinimumGasPrice()"u8)[..4]; @@ -711,12 +721,14 @@ public async Task GetGasAccountingParams_Always_ConsumesRightAmountOfGas() .WithRecording(new FullChainSimulationRecordingFile("./Recordings/1__arbos32_basefee92.jsonl")) .Build(); - IWorldState worldState = chain.WorldStateManager.GlobalWorldState; - ArbosState arbosState = ArbosState.OpenArbosState(worldState, new ZeroGasBurner(), NullLogger.Instance); - Hash256 requestId = new(RandomNumberGenerator.GetBytes(Hash256.Size)); Address sender = FullChainSimulationAccounts.Owner.Address; - UInt256 nonce = worldState.GetNonce(sender); + UInt256 nonce; + + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + } // Calldata to call getGasAccountingParams() on ArbGasInfo precompile byte[] calldata = KeccakHash.ComputeHashBytes("getGasAccountingParams()"u8)[..4]; @@ -742,4 +754,10 @@ public async Task GetGasAccountingParams_Always_ConsumesRightAmountOfGas() long expectedCost = GasCostOf.Transaction + (long)ArbosStorage.StorageReadCost * 3 + txDataCost + precompileOutputCost; receipts[1].GasUsed.Should().Be(expectedCost); } + + [TearDown] + public void TearDown() + { + _worldStateScope?.Dispose(); + } } diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbInfoParserTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbInfoParserTests.cs index 3e8110c4..5265dbf9 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbInfoParserTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbInfoParserTests.cs @@ -1,5 +1,4 @@ using Nethermind.Evm; -using Nethermind.State; using Nethermind.Specs.Forks; using Nethermind.Core; using Nethermind.Int256; @@ -8,6 +7,9 @@ using Nethermind.Arbitrum.Precompiles.Parser; using FluentAssertions; using Nethermind.Arbitrum.Test.Infrastructure; +using Nethermind.Core.Test; +using Nethermind.Evm.State; +using Nethermind.State; namespace Nethermind.Arbitrum.Test.Precompiles.Parser; @@ -17,7 +19,11 @@ public class ArbInfoParserTests public void ParsesGetBalance_ValidInputData_ReturnsBalance() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); // Create test account Address testAccount = new("0x0000000000000000000000000000000000000123"); @@ -44,7 +50,11 @@ public void ParsesGetBalance_ValidInputData_ReturnsBalance() public void ParsesGetBalance_WithInvalidInputData_Throws() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); Address testAccount = new("0x0000000000000000000000000000000000000123"); @@ -63,7 +73,11 @@ public void ParsesGetBalance_WithInvalidInputData_Throws() public void ParsesGetCode_ValidInputData_ReturnsCode() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); // Create some contract whose code to get within the world state Address someContract = new("0x0000000000000000000000000000000000000123"); @@ -100,7 +114,11 @@ public void ParsesGetCode_ValidInputData_ReturnsCode() public void ParsesGetCode_WithInvalidInputData_Throws() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); Address someContract = new("0x0000000000000000000000000000000000000123"); diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbOwnerParserTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbOwnerParserTests.cs index db884f10..768bf3a0 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbOwnerParserTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbOwnerParserTests.cs @@ -1,6 +1,5 @@ using FluentAssertions; using Nethermind.Logging; -using Nethermind.State; using Nethermind.Core; using Nethermind.Int256; using Nethermind.Core.Extensions; @@ -16,6 +15,9 @@ using Nethermind.Arbitrum.Data; using System.Text.Json; using System.Text; +using Nethermind.Core.Test; +using Nethermind.Evm.State; +using Nethermind.State; namespace Nethermind.Arbitrum.Test.Precompiles.Parser; @@ -27,7 +29,11 @@ public class ArbOwnerParserTests [Test] public void ParsesAddChainOwner_Always_AddsToState() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -48,7 +54,11 @@ public void ParsesAddChainOwner_Always_AddsToState() [Test] public void ParsesRemoveChainOwner_IsNotOwner_ThrowsError() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -68,7 +78,11 @@ public void ParsesRemoveChainOwner_IsNotOwner_ThrowsError() [Test] public void ParsesRemoveChainOwner_IsOwner_RemovesFromState() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -92,7 +106,11 @@ public void ParsesRemoveChainOwner_IsOwner_RemovesFromState() [Test] public void ParsesIsChainOwner_IsOwner_ReturnsTrue() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -117,7 +135,11 @@ public void ParsesIsChainOwner_IsOwner_ReturnsTrue() [Test] public void ParsesIsChainOwner_IsNotOwner_ReturnsFalse() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -147,6 +169,8 @@ public void ParsesGetAllChainOwners_Always_ReturnsAllOwners() }; ArbitrumRpcTestBlockchain chain = ArbitrumRpcTestBlockchain.CreateDefault(preConfigurer); + using var dispose = chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head?.Header); + PrecompileTestContextBuilder context = new(chain.WorldStateManager.GlobalWorldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -179,7 +203,11 @@ public void ParsesGetAllChainOwners_Always_ReturnsAllOwners() [Test] public void ParsesSetNativeTokenManagementFrom_EnableTimeIsZero_DisablesFeature() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -203,7 +231,11 @@ public void ParsesSetNativeTokenManagementFrom_EnableTimeIsZero_DisablesFeature( [Test] public void ParsesSetNativeTokenManagementFrom_CurrentEnableTimeIsGreaterThan7DaysFromNowButNewOneIsNot_Throws() { - (IWorldState worldState, Block genesisBlock) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesisBlock = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); ulong now = 100; @@ -232,7 +264,11 @@ public void ParsesSetNativeTokenManagementFrom_CurrentEnableTimeIsGreaterThan7Da [Test] public void ParsesSetNativeTokenManagementFrom_CurrentEnableTimeIsLowerThan7DaysFromNowAndNewOneIsEvenSooner_Throws() { - (IWorldState worldState, Block genesisBlock) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesisBlock = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); ulong now = 1; @@ -260,7 +296,11 @@ public void ParsesSetNativeTokenManagementFrom_CurrentEnableTimeIsLowerThan7Days [Test] public void ParsesSetNativeTokenManagementFrom_CorrectNewEnableTimeComparedToCurrentOne_SetsNewEnableTime() { - (IWorldState worldState, Block genesisBlock) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesisBlock = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); ulong now = 0; // currently disabled @@ -284,7 +324,11 @@ public void ParsesSetNativeTokenManagementFrom_CorrectNewEnableTimeComparedToCur [Test] public void ParsesAddNativeTokenOwner_NativeTokenManagementCurrentlyDisabled_Throws() { - (IWorldState worldState, Block genesisBlock) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesisBlock = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); ulong now = 1; @@ -312,7 +356,11 @@ public void ParsesAddNativeTokenOwner_NativeTokenManagementCurrentlyDisabled_Thr [Test] public void ParsesAddNativeTokenOwner_NativeTokenManagementIsEnabled_AddsNativeTokenOwner() { - (IWorldState worldState, Block genesisBlock) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesisBlock = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); ulong now = 2; @@ -338,7 +386,11 @@ public void ParsesAddNativeTokenOwner_NativeTokenManagementIsEnabled_AddsNativeT [Test] public void ParsesRemoveNativeTokenOwner_NotAnOwner_Throws() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -361,7 +413,11 @@ public void ParsesRemoveNativeTokenOwner_NotAnOwner_Throws() [Test] public void ParsesRemoveNativeTokenOwner_IsAnOwner_RemovesNativeTokenOwner() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -384,7 +440,11 @@ public void ParsesRemoveNativeTokenOwner_IsAnOwner_RemovesNativeTokenOwner() [Test] public void ParsesIsNativeTokenOwner_IsAnOwner_ReturnsTrue() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -408,7 +468,11 @@ public void ParsesIsNativeTokenOwner_IsAnOwner_ReturnsTrue() [Test] public void ParsesIsNativeTokenOwner_NotAnOwner_ReturnsFalse() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -429,7 +493,11 @@ public void ParsesIsNativeTokenOwner_NotAnOwner_ReturnsFalse() [Test] public void ParsesGetAllNativeTokenOwners_Always_ReturnsAllOwners() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -463,7 +531,11 @@ public void ParsesGetAllNativeTokenOwners_Always_ReturnsAllOwners() [Test] public void ParsesSetL1BaseFeeEstimateInertia_Always_SetsInertia() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -485,7 +557,11 @@ public void ParsesSetL1BaseFeeEstimateInertia_Always_SetsInertia() [Test] public void ParsesSetL2BaseFee_Always_SetsL2BaseFee() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -506,7 +582,11 @@ public void ParsesSetL2BaseFee_Always_SetsL2BaseFee() [Test] public void ParsesSetMinimumL2BaseFee_CallIsMutating_SetsMinimumL2BaseFee() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -527,7 +607,11 @@ public void ParsesSetMinimumL2BaseFee_CallIsMutating_SetsMinimumL2BaseFee() [Test] public void ParsesSetSpeedLimit_IsZero_Throws() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -547,7 +631,11 @@ public void ParsesSetSpeedLimit_IsZero_Throws() [Test] public void ParsesSetSpeedLimit_IsNonZero_SetsSpeedLimit() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -568,7 +656,11 @@ public void ParsesSetSpeedLimit_IsNonZero_SetsSpeedLimit() [Test] public void ParsesSetMaxTxGasLimit_Always_SetsMaxTxGasLimit() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -589,7 +681,11 @@ public void ParsesSetMaxTxGasLimit_Always_SetsMaxTxGasLimit() [Test] public void ParsesSetL2GasPricingInertia_IsZero_Throws() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -609,7 +705,11 @@ public void ParsesSetL2GasPricingInertia_IsZero_Throws() [Test] public void ParsesSetL2GasPricingInertia_IsNonZero_SetsL2GasPricingInertia() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -630,7 +730,11 @@ public void ParsesSetL2GasPricingInertia_IsNonZero_SetsL2GasPricingInertia() [Test] public void ParsesSetL2GasBacklogTolerance_Always_SetsL2GasBacklogTolerance() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -651,7 +755,11 @@ public void ParsesSetL2GasBacklogTolerance_Always_SetsL2GasBacklogTolerance() [Test] public void ParsesGetNetworkFeeAccount_Always_ReturnsNetworkFeeAccount() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -673,7 +781,11 @@ public void ParsesGetNetworkFeeAccount_Always_ReturnsNetworkFeeAccount() [Test] public void ParsesGetInfraFeeAccount_Always_ReturnsInfraFeeAccount() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -695,7 +807,11 @@ public void ParsesGetInfraFeeAccount_Always_ReturnsInfraFeeAccount() [Test] public void ParsesSetNetworkFeeAccount_Always_SetsNetworkFeeAccount() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -716,7 +832,11 @@ public void ParsesSetNetworkFeeAccount_Always_SetsNetworkFeeAccount() [Test] public void ParsesSetInfraFeeAccount_Always_SetsInfraFeeAccount() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -737,7 +857,11 @@ public void ParsesSetInfraFeeAccount_Always_SetsInfraFeeAccount() [Test] public void ParsesScheduleArbOSUpgrade_Always_SetsArbosUpgrade() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -760,7 +884,11 @@ public void ParsesScheduleArbOSUpgrade_Always_SetsArbosUpgrade() [Test] public void ParsesSetL1PricingEquilibrationUnits_Always_SetsL1PricingEquilibrationUnits() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -781,7 +909,11 @@ public void ParsesSetL1PricingEquilibrationUnits_Always_SetsL1PricingEquilibrati [Test] public void ParsesSetL1PricingInertia_Always_SetsL1PricingInertia() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -802,7 +934,11 @@ public void ParsesSetL1PricingInertia_Always_SetsL1PricingInertia() [Test] public void ParsesSetL1PricingRewardRecipient_Always_SetsL1PricingRewardRecipient() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -823,7 +959,11 @@ public void ParsesSetL1PricingRewardRecipient_Always_SetsL1PricingRewardRecipien [Test] public void ParsesSetL1PricingRewardRate_Always_SetsL1PricingRewardRate() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -844,7 +984,11 @@ public void ParsesSetL1PricingRewardRate_Always_SetsL1PricingRewardRate() [Test] public void ParsesSetL1PricePerUnit_Always_SetsL1PricePerUnit() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -865,7 +1009,11 @@ public void ParsesSetL1PricePerUnit_Always_SetsL1PricePerUnit() [Test] public void ParsesSetPerBatchGasCharge_Always_SetsPerBatchGasCharge() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -886,7 +1034,11 @@ public void ParsesSetPerBatchGasCharge_Always_SetsPerBatchGasCharge() [Test] public void ParsesSetAmortizedCostCapBips_Always_SetsAmortizedCostCapBips() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -907,7 +1059,11 @@ public void ParsesSetAmortizedCostCapBips_Always_SetsAmortizedCostCapBips() [Test] public void ParsesSetBrotliCompressionLevel_Always_SetsBrotliCompressionLevel() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -928,7 +1084,11 @@ public void ParsesSetBrotliCompressionLevel_Always_SetsBrotliCompressionLevel() [Test] public void ParsesReleaseL1PricerSurplusFunds_RecognizedFundsGreaterThanPoolBalance_ReturnsZero() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -954,7 +1114,11 @@ public void ParsesReleaseL1PricerSurplusFunds_RecognizedFundsGreaterThanPoolBala [Test] public void ParsesReleaseL1PricerSurplusFunds_RecognizedFundsLowerThanPoolBalance_ReturnsWeiToTransfer() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -982,7 +1146,11 @@ public void ParsesReleaseL1PricerSurplusFunds_RecognizedFundsLowerThanPoolBalanc [Test] public void ParsesSetInkPrice_PriceGreaterThanUint24_Throws() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1002,7 +1170,11 @@ public void ParsesSetInkPrice_PriceGreaterThanUint24_Throws() [Test] public void ParsesSetInkPrice_PriceFitsWithinUint24_SetsInkPrice() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1023,7 +1195,11 @@ public void ParsesSetInkPrice_PriceFitsWithinUint24_SetsInkPrice() [Test] public void ParsesSetWasmMaxStackDepth_Always_SetsWasmMaxStackDepth() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1044,7 +1220,11 @@ public void ParsesSetWasmMaxStackDepth_Always_SetsWasmMaxStackDepth() [Test] public void ParsesSetWasmFreePages_Always_SetsWasmFreePages() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1065,7 +1245,11 @@ public void ParsesSetWasmFreePages_Always_SetsWasmFreePages() [Test] public void ParsesSetWasmPageGas_Always_SetsWasmPageGas() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1086,7 +1270,11 @@ public void ParsesSetWasmPageGas_Always_SetsWasmPageGas() [Test] public void ParsesSetWasmPageLimit_Always_SetsWasmPageLimit() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1107,7 +1295,11 @@ public void ParsesSetWasmPageLimit_Always_SetsWasmPageLimit() [Test] public void ParsesSetWasmMinInitGas_Always_SetsWasmMinInitGas() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1131,7 +1323,11 @@ public void ParsesSetWasmMinInitGas_Always_SetsWasmMinInitGas() [Test] public void ParsesSetWasmInitCostScalar_Always_SetsWasmInitCostScalar() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1152,7 +1348,11 @@ public void ParsesSetWasmInitCostScalar_Always_SetsWasmInitCostScalar() [Test] public void ParsesSetWasmExpiryDays_Always_SetsWasmExpiryDays() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1173,7 +1373,11 @@ public void ParsesSetWasmExpiryDays_Always_SetsWasmExpiryDays() [Test] public void ParsesSetWasmKeepaliveDays_Always_SetsWasmKeepaliveDays() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1194,7 +1398,11 @@ public void ParsesSetWasmKeepaliveDays_Always_SetsWasmKeepaliveDays() [Test] public void ParsesSetWasmBlockCacheSize_Always_SetsWasmBlockCacheSize() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1225,6 +1433,7 @@ public void ParsesSetWasmMaxSize_Always_SetsWasmMaxSize() ArbitrumRpcTestBlockchain chain = ArbitrumRpcTestBlockchain.CreateDefault(preConfigurer); IWorldState worldState = chain.WorldStateManager.GlobalWorldState; + using var dispose = worldState.BeginScope(chain.BlockTree.Genesis); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1248,7 +1457,11 @@ public void ParsesSetWasmMaxSize_Always_SetsWasmMaxSize() [Test] public void ParsesAddWasmCacheManager_Always_AddsWasmCacheManager() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1269,7 +1482,11 @@ public void ParsesAddWasmCacheManager_Always_AddsWasmCacheManager() [Test] public void ParsesRemoveWasmCacheManager_IsNotManager_Throws() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1289,7 +1506,11 @@ public void ParsesRemoveWasmCacheManager_IsNotManager_Throws() [Test] public void ParsesRemoveWasmCacheManager_IsManager_RemovesWasmCacheManager() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1313,7 +1534,11 @@ public void ParsesRemoveWasmCacheManager_IsManager_RemovesWasmCacheManager() [Test] public void ParsesSetChainConfig_CallIsNonMutating_ReplacesChainConfig() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1345,7 +1570,11 @@ public void ParsesSetChainConfig_CallIsNonMutating_ReplacesChainConfig() [Test] public void ParsesSetCalldataPriceIncrease_ToEnable_EnablesCalldataPriceIncrease() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -1377,7 +1606,11 @@ public void ParsesSetCalldataPriceIncrease_ToEnable_EnablesCalldataPriceIncrease [Test] public void ParsesSetCalldataPriceIncrease_ToDisable_DisablesCalldataPriceIncrease() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbRetryableTxParserTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbRetryableTxParserTests.cs index aee1d16f..6a7f1b67 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbRetryableTxParserTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbRetryableTxParserTests.cs @@ -1,6 +1,5 @@ using FluentAssertions; using Nethermind.Logging; -using Nethermind.State; using Nethermind.Core; using Nethermind.Int256; using Nethermind.Core.Extensions; @@ -11,6 +10,9 @@ using Nethermind.Arbitrum.Arbos.Storage; using Nethermind.Crypto; using Nethermind.Arbitrum.Precompiles; +using Nethermind.Core.Test; +using Nethermind.Evm.State; +using Nethermind.State; namespace Nethermind.Arbitrum.Test.Precompiles.Parser; @@ -22,7 +24,11 @@ public class ArbRetryableTxParserTests public void ParsesRedeem_ValidInputData_ReturnsCreatedRetryTxHash() { // Initialize ArbOS state - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; Hash256 ticketIdHash = ArbRetryableTxTests.Hash256FromUlong(123); @@ -87,7 +93,11 @@ public void ParsesRedeem_ValidInputData_ReturnsCreatedRetryTxHash() public void ParsesRedeem_WithInvalidInputData_Throws() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); byte[] redeemMethodId = Bytes.FromHexString("0xeda1122c"); // too small ticketId parameter @@ -106,7 +116,11 @@ public void ParsesRedeem_WithInvalidInputData_Throws() public void ParsesGetLifetime_Always_ReturnsDefaultLifetime() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, 0); byte[] getLifetimeMethodId = Bytes.FromHexString("0x81e6e083"); @@ -122,7 +136,11 @@ public void ParsesGetLifetime_Always_ReturnsDefaultLifetime() public void ParsesGetTimeout_RetryableExists_ReturnsCalculatedTimeout() { // Initialize ArbOS state - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue); @@ -152,7 +170,11 @@ public void ParsesGetTimeout_RetryableExists_ReturnsCalculatedTimeout() public void ParsesGetTimeout_WithInvalidInputData_Throws() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); byte[] getTimeoutMethodId = Bytes.FromHexString("0x9f1025c6"); // too small ticketId parameter @@ -171,7 +193,11 @@ public void ParsesGetTimeout_WithInvalidInputData_Throws() public void ParsesKeepAlive_RetryableExpiresBefore1Lifetime_ReturnsNewTimeout() { // Initialize ArbOS state - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; ulong gasSupplied = ulong.MaxValue; @@ -205,7 +231,11 @@ public void ParsesKeepAlive_RetryableExpiresBefore1Lifetime_ReturnsNewTimeout() public void ParsesKeepAlive_WithInvalidInputData_Throws() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); byte[] keepAliveMethodId = Bytes.FromHexString("0xf0b21a41"); // too small ticketId parameter @@ -223,7 +253,11 @@ public void ParsesKeepAlive_WithInvalidInputData_Throws() [Test] public void ParsesGetBeneficiary_RetryableExists_ReturnsBeneficiary() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue); context.WithArbosState().WithBlockExecutionContext(genesis.Header); @@ -251,7 +285,11 @@ public void ParsesGetBeneficiary_RetryableExists_ReturnsBeneficiary() public void ParsesGetBeneficiary_WithInvalidInputData_Throws() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); byte[] getBeneficiaryMethodId = Bytes.FromHexString("0xba20dda4"); // too small ticketId parameter @@ -269,7 +307,11 @@ public void ParsesGetBeneficiary_WithInvalidInputData_Throws() [Test] public void ParsesCancel_RetryableExists_ReturnsEmptyOutput() { - (IWorldState worldState, Block genesis) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesis = ArbOSInitialization.Create(worldState); genesis.Header.Timestamp = 100; ulong gasSupplied = ulong.MaxValue; @@ -312,7 +354,11 @@ public void ParsesCancel_RetryableExists_ReturnsEmptyOutput() public void ParsesCancel_WithInvalidInputData_Throws() { // Initialize ArbOS state - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); byte[] cancelMethodId = Bytes.FromHexString("0xc4d252f5"); // too small ticketId parameter @@ -330,7 +376,11 @@ public void ParsesCancel_WithInvalidInputData_Throws() [Test] public void ParsesGetCurrentRedeemer_Always_ReturnsRedeemerOrZeroAddress() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); Address redeemer = new(ArbRetryableTxTests.Hash256FromUlong(123)); PrecompileTestContextBuilder context = new(worldState, ulong.MaxValue) diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbSysParserTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbSysParserTests.cs index 7586a617..e79399bf 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbSysParserTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbSysParserTests.cs @@ -1,7 +1,6 @@ using System.Text; using FluentAssertions; using Nethermind.Arbitrum.Execution.Transactions; -using Nethermind.State; using Nethermind.Core; using Nethermind.Int256; using Nethermind.Core.Extensions; @@ -9,6 +8,9 @@ using Nethermind.Arbitrum.Precompiles.Parser; using Nethermind.Arbitrum.Precompiles; using Nethermind.Core.Crypto; +using Nethermind.Core.Test; +using Nethermind.Evm.State; +using Nethermind.State; namespace Nethermind.Arbitrum.Test.Precompiles.Parser; @@ -32,7 +34,11 @@ public void Address_WhenQueried_ReturnsArbSysAddress() [Test] public void RunAdvanced_WhenInvalidMethodId_ThrowsArgumentException() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -47,7 +53,11 @@ public void RunAdvanced_WhenInvalidMethodId_ThrowsArgumentException() [Test] public void RunAdvanced_WhenInsufficientInput_ThrowsEndOfStreamException() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -67,7 +77,11 @@ public void RunAdvanced_WhenInsufficientInput_ThrowsEndOfStreamException() [TestCase(100000L)] public void ArbBlockNumber_WhenDifferentBlockNumbers_ReturnsCorrectSerialization(long blockNumber) { - (IWorldState worldState, Block genesisBlock) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + Block genesisBlock = ArbOSInitialization.Create(worldState); genesisBlock.Header.Number = blockNumber; PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); @@ -85,7 +99,11 @@ public void ArbBlockNumber_WhenDifferentBlockNumbers_ReturnsCorrectSerialization [Test] public void ArbBlockHash_WhenMissingParameter_ThrowsEndOfStreamException() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -100,7 +118,11 @@ public void ArbBlockHash_WhenMissingParameter_ThrowsEndOfStreamException() [Test] public void ArbChainID_WhenCalled_ReturnsSerializedChainId() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -116,7 +138,11 @@ public void ArbChainID_WhenCalled_ReturnsSerializedChainId() [Test] public void ArbOSVersion_WhenCalled_ReturnsSerializedVersionPlus55() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -133,7 +159,11 @@ public void ArbOSVersion_WhenCalled_ReturnsSerializedVersionPlus55() [Test] public void GetStorageGasAvailable_WhenCalled_ReturnsSerializedZero() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -153,7 +183,11 @@ public void GetStorageGasAvailable_WhenCalled_ReturnsSerializedZero() [TestCase(10, false)] public void IsTopLevelCall_WhenDifferentCallDepths_ReturnsCorrectSerialization(int callDepth, bool expectedResult) { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue) { CallDepth = callDepth @@ -177,7 +211,11 @@ public void IsTopLevelCall_WhenDifferentCallDepths_ReturnsCorrectSerialization(i [TestCase("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "0x1111000000000000000000000000000000001110")] public void MapL1SenderContractAddressToL2Alias_WhenValidAddress_ReturnsSerializedAlias(string senderHex, string expectedAliasHex) { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -199,7 +237,11 @@ public void MapL1SenderContractAddressToL2Alias_WhenValidAddress_ReturnsSerializ [Test] public void WasMyCallersAddressAliased_TxTypeNotAliasable_ReturnsFalse() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -215,7 +257,11 @@ public void WasMyCallersAddressAliased_TxTypeNotAliasable_ReturnsFalse() [Test] public void WasMyCallersAddressAliased_WasAliased_ReturnsTrue() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue) { TopLevelTxType = ArbitrumTxType.ArbitrumUnsigned, @@ -237,7 +283,11 @@ public void WasMyCallersAddressAliased_WasAliased_ReturnsTrue() [Test] public void MyCallersAddressWithoutAliasing_CallDepthIsZero_ReturnsZeroAddress() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue) { CallDepth = 0 @@ -256,7 +306,11 @@ public void MyCallersAddressWithoutAliasing_CallDepthIsZero_ReturnsZeroAddress() [Test] public void SendTxToL1_WhenMissingParameters_ThrowsEndOfStreamException() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -270,7 +324,11 @@ public void SendTxToL1_WhenMissingParameters_ThrowsEndOfStreamException() [Test] public void WithdrawEth_WhenMissingParameter_ThrowsEndOfStreamException() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); @@ -285,7 +343,11 @@ public void WithdrawEth_WhenMissingParameter_ThrowsEndOfStreamException() [Test] public void SendMerkleTreeState_InvalidInputData_ReturnsSerializedState() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); context.WithArbosState(); diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbWasmParserTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbWasmParserTests.cs index 1963b9bf..a9843846 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbWasmParserTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/ArbWasmParserTests.cs @@ -8,8 +8,10 @@ using Nethermind.Arbitrum.Test.Infrastructure; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.State; @@ -26,6 +28,8 @@ public sealed class ArbWasmParserTests private PrecompileTestContextBuilder _context = null!; private ArbWasmParser _parser = null!; + private IWorldState _worldState; + private BlockHeader _genesisBlockHeader; // ABI signatures for ArbWasm methods private static readonly AbiSignature StylusVersionSignature = new("stylusVersion"); @@ -52,10 +56,13 @@ public sealed class ArbWasmParserTests [SetUp] public void SetUp() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); - ArbosState.OpenArbosState(worldState, new SystemBurner(), + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + _worldState = worldStateManager.GlobalWorldState; + using IDisposable worldStateDisposer = _worldState.BeginScope(IWorldState.PreGenesis); + _genesisBlockHeader = ArbOSInitialization.Create(_worldState).Header; + ArbosState.OpenArbosState(_worldState, new SystemBurner(), LimboLogs.Instance.GetClassLogger()); - _context = new PrecompileTestContextBuilder(worldState, DefaultGasSupplied) + _context = new PrecompileTestContextBuilder(_worldState, DefaultGasSupplied) .WithArbosState() .WithBlockExecutionContext(Build.A.BlockHeader.TestObject) .WithReleaseSpec(); @@ -67,6 +74,7 @@ public void StylusVersion_WithValidInput_ReturnsEncodedVersion() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, StylusVersionSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -80,6 +88,7 @@ public void InkPrice_WithValidInput_ReturnsEncodedPrice() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, InkPriceSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -93,6 +102,7 @@ public void MaxStackDepth_WithValidInput_ReturnsEncodedDepth() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, MaxStackDepthSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -106,6 +116,7 @@ public void FreePages_WithValidInput_ReturnsEncodedPages() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, FreePagesSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -119,6 +130,7 @@ public void PageGas_WithValidInput_ReturnsEncodedGas() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, PageGasSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -132,6 +144,7 @@ public void PageLimit_WithValidInput_ReturnsEncodedLimit() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, PageLimitSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -155,6 +168,7 @@ public void CodeHashVersion_WithValidCodeHash_ReturnsVersion() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, CodeHashVersionSignature, TestCodeHash); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -241,6 +255,7 @@ public void PageRamp_WithValidInput_ReturnsEncodedRamp() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, PageRampSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -254,6 +269,7 @@ public void MinInitGas_WithValidInput_ReturnsEncodedGas() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, MinInitGasSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -270,6 +286,7 @@ public void InitCostScalar_WithValidInput_ReturnsEncodedScalar() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, InitCostScalarSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -283,6 +300,7 @@ public void ExpiryDays_WithValidInput_ReturnsEncodedDays() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, ExpiryDaysSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -296,6 +314,7 @@ public void KeepaliveDays_WithValidInput_ReturnsEncodedDays() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, KeepaliveDaysSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -309,6 +328,7 @@ public void BlockCacheSize_WithValidInput_ReturnsEncodedSize() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, BlockCacheSizeSignature); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -322,6 +342,7 @@ public void ProgramVersion_WithValidAddress_ReturnsVersion() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, ProgramVersionSignature, TestProgram); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -346,6 +367,7 @@ public void CodeHashVersion_WithNonExistentCodeHash_ReturnsZero() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, CodeHashVersionSignature, TestCodeHash.Bytes.ToArray()); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); byte[] result = _parser.RunAdvanced(_context, inputData); result.Should().NotBeNull(); @@ -359,6 +381,7 @@ public void ProgramInitGas_WithNonActivatedProgram_ThrowsInvalidOperation() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, ProgramInitGasSignature, TestProgram); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); Action action = () => _parser.RunAdvanced(_context, inputData); action.Should().Throw() @@ -370,6 +393,7 @@ public void ProgramMemoryFootprint_WithNonActivatedProgram_ThrowsInvalidOperatio { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, ProgramMemoryFootprintSignature, TestProgram); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); Action action = () => _parser.RunAdvanced(_context, inputData); action.Should().Throw() @@ -381,6 +405,7 @@ public void ProgramTimeLeft_WithNonActivatedProgram_ThrowsInvalidOperation() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, ProgramTimeLeftSignature, TestProgram); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); Action action = () => _parser.RunAdvanced(_context, inputData); action.Should().Throw() @@ -392,6 +417,7 @@ public void CodeHashKeepalive_WithNonActivatedProgram_ThrowsInvalidOperation() { byte[] inputData = AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, CodeHashKeepaliveSignature, TestCodeHash.Bytes.ToArray()); + using IDisposable worldStateDisposer = _worldState.BeginScope(_genesisBlockHeader); Action action = () => _parser.RunAdvanced(_context, inputData); action.Should().Throw() diff --git a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/OwnerWrapperTests.cs b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/OwnerWrapperTests.cs index 7b34bb9a..165ed336 100644 --- a/src/Nethermind.Arbitrum.Test/Precompiles/Parser/OwnerWrapperTests.cs +++ b/src/Nethermind.Arbitrum.Test/Precompiles/Parser/OwnerWrapperTests.cs @@ -1,6 +1,5 @@ using FluentAssertions; using Nethermind.Logging; -using Nethermind.State; using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Arbitrum.Test.Infrastructure; @@ -8,7 +7,10 @@ using Nethermind.Arbitrum.Arbos.Storage; using Nethermind.Arbitrum.Precompiles; using Nethermind.Arbitrum.Precompiles.Events; +using Nethermind.Core.Test; using Nethermind.Evm; +using Nethermind.Evm.State; +using Nethermind.State; namespace Nethermind.Arbitrum.Test.Precompiles.Parser; @@ -19,7 +21,11 @@ public class OwnerWrapperTests [Test] public void ParsesArbOwnerAddChainOwner_CallerIsNotOwner_Throws() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); Address caller = new("0x0000000000000000000000000000000000000001"); // not a chain owner context.WithCaller(caller); @@ -46,7 +52,11 @@ public void ParsesArbOwnerAddChainOwner_CallerIsNotOwner_Throws() [Test] public void ParsesArbOwnerAddChainOwner_CallerIsOwner_AddsOwner() { - (IWorldState worldState, _) = ArbOSInitialization.Create(); + IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(); + IWorldState worldState = worldStateManager.GlobalWorldState; + using var worldStateDisposer = worldState.BeginScope(IWorldState.PreGenesis); + + _ = ArbOSInitialization.Create(worldState); PrecompileTestContextBuilder context = new(worldState, GasSupplied: ulong.MaxValue); Address caller = new("0x0000000000000000000000000000000000000001"); context.WithCaller(caller); diff --git a/src/Nethermind.Arbitrum.Test/Rpc/ArbitrumEthRpcModuleTests.cs b/src/Nethermind.Arbitrum.Test/Rpc/ArbitrumEthRpcModuleTests.cs new file mode 100644 index 00000000..66d20f57 --- /dev/null +++ b/src/Nethermind.Arbitrum.Test/Rpc/ArbitrumEthRpcModuleTests.cs @@ -0,0 +1,327 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using FluentAssertions; +using Nethermind.Abi; +using Nethermind.Arbitrum.Data; +using Nethermind.Arbitrum.Test.Infrastructure; +using Nethermind.Blockchain.Find; +using Nethermind.Core; +using Nethermind.Core.Extensions; +using Nethermind.Core.Test.Builders; +using Nethermind.Crypto; +using Nethermind.Evm; +using Nethermind.Facade.Eth.RpcTransaction; +using Nethermind.Int256; +using Nethermind.JsonRpc; +using Nethermind.JsonRpc.Data; + +namespace Nethermind.Arbitrum.Test.Rpc; + +[TestFixture] +public class ArbitrumEthRpcModuleTests +{ + private static readonly AbiSignature TransferSignature = new("transfer", AbiType.Address, AbiType.UInt256); + private static readonly AbiSignature BalanceOfSignature = new("balanceOf", AbiType.Address); + + private ArbitrumRpcTestBlockchain _chain = null!; + private EthereumEcdsa _ethereumEcdsa = null!; + + [SetUp] + public void Setup() + { + _chain = ArbitrumRpcTestBlockchain.CreateDefault(); + + var initMessage = FullChainSimulationInitMessage.CreateDigestInitMessage(92); + _chain.ArbitrumRpcModule.DigestInitMessage(initMessage); + + _ethereumEcdsa = new EthereumEcdsa(_chain.SpecProvider.ChainId); + } + + [TearDown] + public void TearDown() + { + _chain?.Dispose(); + } + + [Test] + public async Task EthCall_WithNonZeroBaseFee_ExecutesWithZeroBaseFee() + { + await ProduceBlockWithBaseFee(1000.Wei()); + + Transaction tx = Build.A.Transaction + .WithSenderAddress(FullChainSimulationAccounts.AccountA.Address) + .WithTo(FullChainSimulationAccounts.AccountB.Address) + .WithValue(100.Wei()) + .WithGasLimit(Transaction.BaseTxGasCost) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + + ResultWrapper result = _chain.ArbitrumEthRpcModule.eth_call(txCall, BlockParameter.Latest); + + result.Result.ResultType.Should().Be(ResultType.Success); + result.Data.Should().Be("0x"); + } + + [Test] + public async Task EthCall_WithStateOverride_AppliesOverridesCorrectly() + { + await ProduceBlockWithBaseFee(500.Wei()); + + Transaction tx = Build.A.Transaction + .WithTo(FullChainSimulationAccounts.AccountB.Address) + .WithValue(100.Wei()) + .WithGasLimit(50000) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + + Dictionary stateOverride = new() + { + [FullChainSimulationAccounts.AccountA.Address] = new AccountOverride { Balance = 999.Ether() } + }; + + ResultWrapper result = _chain.ArbitrumEthRpcModule.eth_call(txCall, BlockParameter.Latest, stateOverride); + + result.Result.ResultType.Should().Be(ResultType.Success); + result.Data.Should().Be("0x"); + } + + [Test] + public async Task EthCall_ContractCreationWithoutData_ReturnsInvalidInputError() + { + await ProduceBlockWithBaseFee(100.Wei()); + + Transaction tx = Build.A.Transaction + .WithSenderAddress(FullChainSimulationAccounts.AccountA.Address) + .WithTo(null) + .WithData(Array.Empty()) + .WithGasLimit(Transaction.BaseTxGasCost) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + + ResultWrapper result = _chain.ArbitrumEthRpcModule.eth_call(txCall, BlockParameter.Latest); + + result.Result.ResultType.Should().Be(ResultType.Failure); + result.ErrorCode.Should().Be(ErrorCodes.InvalidInput); + result.Result.Error.Should().Contain("Contract creation without any data provided"); + } + + [Test] + public async Task EthEstimateGas_ContractCreationWithoutData_ReturnsInvalidInputError() + { + await ProduceBlockWithBaseFee(100.Wei()); + + Transaction tx = Build.A.Transaction + .WithSenderAddress(FullChainSimulationAccounts.AccountA.Address) + .WithTo(null) + .WithData(Array.Empty()) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + + ResultWrapper result = _chain.ArbitrumEthRpcModule.eth_estimateGas(txCall, BlockParameter.Latest); + + result.Result.ResultType.Should().Be(ResultType.Failure); + result.ErrorCode.Should().Be(ErrorCodes.InvalidInput); + result.Result.Error.Should().Contain("Contract creation without any data provided"); + } + + [Test] + public async Task EthEstimateGas_WhenInsufficientBalance_ReturnsExecutionError() + { + await ProduceBlockWithBaseFee(1000.Wei()); + + Transaction tx = Build.A.Transaction + .WithSenderAddress(FullChainSimulationAccounts.AccountA.Address) + .WithTo(FullChainSimulationAccounts.AccountB.Address) + .WithValue(10000.Ether()) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + + ResultWrapper result = _chain.ArbitrumEthRpcModule.eth_estimateGas(txCall, BlockParameter.Latest); + + result.Result.ResultType.Should().Be(ResultType.Failure); + result.ErrorCode.Should().Be(ErrorCodes.InvalidInput); + } + + [Test] + public async Task EthCreateAccessList_WithNonZeroBaseFee_CreatesWithZeroBaseFee() + { + Address contractAddress = await DeployTestContract(); + await ProduceBlockWithBaseFee(3000.Wei()); + + Transaction tx = Build.A.Transaction + .WithSenderAddress(FullChainSimulationAccounts.AccountA.Address) + .WithTo(contractAddress) + .WithData(AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, BalanceOfSignature, FullChainSimulationAccounts.AccountA.Address)) + .WithGasLimit(50000) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + + ResultWrapper result = _chain.ArbitrumEthRpcModule.eth_createAccessList(txCall, BlockParameter.Latest); + + result.Result.ResultType.Should().Be(ResultType.Success); + result.Data.Should().NotBeNull(); + result.Data?.AccessList.Should().NotBeNull(); + result.Data?.GasUsed.Should().BeGreaterThan(UInt256.Zero); + } + + [Test] + public async Task EthCreateAccessList_WithOptimizationEnabled_ReturnsOptimizedAccessList() + { + Address contractAddress = await DeployTestContract(); + await ProduceBlockWithBaseFee(1000.Wei()); + + Transaction tx = Build.A.Transaction + .WithSenderAddress(FullChainSimulationAccounts.AccountA.Address) + .WithTo(contractAddress) + .WithData(AbiEncoder.Instance.Encode(AbiEncodingStyle.IncludeSignature, TransferSignature, FullChainSimulationAccounts.AccountB.Address, 100.Wei())) + .WithGasLimit(50000) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + + ResultWrapper optimizedResult = _chain.ArbitrumEthRpcModule.eth_createAccessList(txCall, BlockParameter.Latest, optimize: true); + ResultWrapper nonOptimizedResult = _chain.ArbitrumEthRpcModule.eth_createAccessList(txCall, BlockParameter.Latest, optimize: false); + + optimizedResult.Result.ResultType.Should().Be(ResultType.Success); + nonOptimizedResult.Result.ResultType.Should().Be(ResultType.Success); + optimizedResult.Data.Should().NotBeNull(); + nonOptimizedResult.Data.Should().NotBeNull(); + } + + [Test] + public async Task EthCreateAccessList_ContractCreationWithoutData_ReturnsInvalidInputError() + { + await ProduceBlockWithBaseFee(100.Wei()); + + Transaction tx = Build.A.Transaction + .WithSenderAddress(FullChainSimulationAccounts.AccountA.Address) + .WithTo(null) + .WithData(Array.Empty()) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + + ResultWrapper result = _chain.ArbitrumEthRpcModule.eth_createAccessList(txCall, BlockParameter.Latest); + + result.Result.ResultType.Should().Be(ResultType.Failure); + result.ErrorCode.Should().Be(ErrorCodes.InvalidInput); + result.Result.Error.Should().Contain("Contract creation without any data provided"); + } + + [Test] + public async Task EthCall_WithNullGas_UsesBlockGasLimit() + { + await ProduceBlockWithBaseFee(500.Wei()); + + Transaction tx = Build.A.Transaction + .WithSenderAddress(FullChainSimulationAccounts.AccountA.Address) + .WithTo(FullChainSimulationAccounts.AccountB.Address) + .WithValue(50.Wei()) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + txCall.Gas = null; + + ResultWrapper result = _chain.ArbitrumEthRpcModule.eth_call(txCall, BlockParameter.Latest); + + result.Result.ResultType.Should().Be(ResultType.Success); + result.Data.Should().Be("0x"); + } + + [Test] + public async Task EthCall_AtSpecificBlockNumber_UsesCorrectBaseFee() + { + await ProduceBlockWithBaseFee(100.Wei()); + await ProduceBlockWithBaseFee(200.Wei()); + await ProduceBlockWithBaseFee(300.Wei()); + + Transaction tx = Build.A.Transaction + .WithSenderAddress(FullChainSimulationAccounts.AccountA.Address) + .WithTo(FullChainSimulationAccounts.AccountB.Address) + .WithValue(10.Wei()) + .WithGasLimit(Transaction.BaseTxGasCost) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + + ResultWrapper result = _chain.ArbitrumEthRpcModule.eth_call(txCall, new BlockParameter(2)); + + result.Result.ResultType.Should().Be(ResultType.Success); + result.Data.Should().Be("0x"); + } + + [Test] + public async Task EthEstimateGas_WhenInvalidCallData_ReturnsExecutionError() + { + await ProduceBlockWithBaseFee(1000.Wei()); + + Transaction tx = Build.A.Transaction + .WithSenderAddress(FullChainSimulationAccounts.AccountA.Address) + .WithTo(Address.Zero) // Sending to zero address with data should fail + .WithData(new byte[] { 0xff, 0xff, 0xff, 0xff }) + .TestObject; + + TransactionForRpc txCall = TransactionForRpc.FromTransaction(tx); + + ResultWrapper result = _chain.ArbitrumEthRpcModule.eth_estimateGas(txCall, BlockParameter.Latest); + + result.Result.ResultType.Should().Be(ResultType.Failure); + } + + private async Task ProduceBlockWithBaseFee(UInt256 baseFee) + { + TestEthDeposit deposit = new( + TestItem.KeccakA, + baseFee, + FullChainSimulationAccounts.Owner.Address, // Any random account + FullChainSimulationAccounts.AccountA.Address, + 1.Ether() + ); + + ResultWrapper result = await _chain.Digest(deposit); + result.Result.ResultType.Should().Be(ResultType.Success); + } + + private async Task
DeployTestContract() + { + // Simple storage contract bytecode (just stores and retrieves values) + byte[] bytecode = Bytes.FromHexString("0x608060405234801561001057600080fd5b5060405161011a38038061011a8339818101604052602081101561003357600080fd5b505160005560c0806100446000396000f3fe608060405260043610601f5760003560e01c806306fdde031460245780630a9059cbb14604e575b600080fd5b602a6054565b6040518082815260200191505060405180910390f35b6064607c565b6040518082815260200191505060405180910390f35b60005481565b600055565b6000548156fea26469706673582212207f2d42b9b2c2b4c02ed89d63dd13d2a13637c6ac476fc113e6c4a3e33f948f79c64736f6c63430008000033"); + + TestEthDeposit deposit = new( + TestItem.KeccakB, + 100.Wei(), + FullChainSimulationAccounts.AccountA.Address, + FullChainSimulationAccounts.AccountA.Address, + 10.Ether() + ); + await _chain.Digest(deposit); + + Transaction deployTx = Build.A.Transaction + .WithTo(null) + .WithData(bytecode) + .WithGasLimit(1000000) + .WithGasPrice(100.Wei()) + .WithValue(0) + .WithNonce(0) + .SignedAndResolved(_ethereumEcdsa, FullChainSimulationAccounts.AccountA) + .TestObject; + + TestL2Transactions l2Txs = new( + TestItem.KeccakC, + 100.Wei(), + FullChainSimulationAccounts.AccountA.Address, + deployTx + ); + + await _chain.Digest(l2Txs); + + return ContractAddress.From(FullChainSimulationAccounts.AccountA.Address, 0); + } +} diff --git a/src/Nethermind.Arbitrum.Test/Rpc/ArbitrumRpcModuleTests.DigestMessage.cs b/src/Nethermind.Arbitrum.Test/Rpc/ArbitrumRpcModuleTests.DigestMessage.cs index 0ae47089..49f5e905 100644 --- a/src/Nethermind.Arbitrum.Test/Rpc/ArbitrumRpcModuleTests.DigestMessage.cs +++ b/src/Nethermind.Arbitrum.Test/Rpc/ArbitrumRpcModuleTests.DigestMessage.cs @@ -35,8 +35,11 @@ public async Task DigestMessage_DepositEth_Deposits() ResultWrapper result = await chain.Digest(new TestEthDeposit(requestId, L1BaseFee, sender, receiver, value)); result.Result.ResultType.Should().Be(ResultType.Success); - UInt256 balance = chain.WorldStateManager.GlobalWorldState.GetBalance(receiver); - balance.Should().Be(value); + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + UInt256 balance = chain.WorldStateManager.GlobalWorldState.GetBalance(receiver); + balance.Should().Be(value); + } } [Test] @@ -59,18 +62,24 @@ public async Task DigestMessage_SubmitRetryable_DepositsAndSends() UInt256 maxSubmissionFee = 128800; - UInt256 initialSenderBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(sender); - (initialSenderBalance / Unit.Ether).Should().Be(100); // Initially ~100 ETH + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + UInt256 initialSenderBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(sender); + (initialSenderBalance / Unit.Ether).Should().Be(100); // Initially ~100 ETH + } TestSubmitRetryable retryable = new(requestId, L1BaseFee, sender, receiver, beneficiary, depositValue, retryValue, gasFee, gasLimit, maxSubmissionFee); ResultWrapper result = await chain.Digest(retryable); result.Result.Should().Be(Result.Success); - UInt256 receiverBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(receiver); - (receiverBalance / Unit.Ether).Should().Be(10); // Receiver gets ~10 ETH + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + UInt256 receiverBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(receiver); + (receiverBalance / Unit.Ether).Should().Be(10); // Receiver gets ~10 ETH - UInt256 senderBalanceAfter = chain.WorldStateManager.GlobalWorldState.GetBalance(sender); - (senderBalanceAfter / Unit.Ether).Should().Be(110); // Sender has ~100 - 10 + 20 ETH + UInt256 senderBalanceAfter = chain.WorldStateManager.GlobalWorldState.GetBalance(sender); + (senderBalanceAfter / Unit.Ether).Should().Be(110); // Sender has ~100 - 10 + 20 ETH + } } [Test] @@ -90,21 +99,29 @@ public async Task DigestMessage_L2FundedByL1Unsigned_DepositsAndExecutes() UInt256 maxFeePerGas = 1.GWei(); // Fits the default BlockHeader.BaseFeePerGas = ArbosState.L2PricingState.BaseFeeWeiStorage ulong gasLimit = 21000; - UInt256 nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sponsor); - UInt256 sponsorBalanceBefore = chain.WorldStateManager.GlobalWorldState.GetBalance(sponsor); + UInt256 nonce; + UInt256 sponsorBalanceBefore; + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sponsor); + sponsorBalanceBefore = chain.WorldStateManager.GlobalWorldState.GetBalance(sponsor); + } ResultWrapper result = await chain.Digest(new TestL2FundedByL1Transfer(requestId, L1BaseFee, sponsor, sender, receiver, transferValue, maxFeePerGas, gasLimit, nonce)); result.Result.Should().Be(Result.Success); - UInt256 sponsorBalanceAfter = chain.WorldStateManager.GlobalWorldState.GetBalance(sponsor); - UInt256 senderBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(sender); - UInt256 receiverBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(receiver); + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + UInt256 sponsorBalanceAfter = chain.WorldStateManager.GlobalWorldState.GetBalance(sponsor); + UInt256 senderBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(sender); + UInt256 receiverBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(receiver); - sponsorBalanceAfter.Should().Be(sponsorBalanceBefore); - senderBalance.Should().Be(0); - receiverBalance.Should().Be(transferValue); + sponsorBalanceAfter.Should().Be(sponsorBalanceBefore); + senderBalance.Should().Be(0); + receiverBalance.Should().Be(transferValue); + } } [Test] @@ -129,22 +146,29 @@ public async Task DigestMessage_L2FundedByL1Contract_DepositsAndExecutes() sponsor.Bytes.CopyTo(addressBytes, 12); byte[] calldata = [.. KeccakHash.ComputeHashBytes("getBalance(address)"u8)[..4], .. addressBytes]; - UInt256 sponsorBalanceBefore = chain.WorldStateManager.GlobalWorldState.GetBalance(sponsor); + UInt256 sponsorBalanceBefore = UInt256.Zero; + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + sponsorBalanceBefore = chain.WorldStateManager.GlobalWorldState.GetBalance(sponsor); + } ResultWrapper result = await chain.Digest(new TestL2FundedByL1Contract(requestId, L1BaseFee, sponsor, sender, contract, transferValue, maxFeePerGas, gasLimit, calldata)); result.Result.Should().Be(Result.Success); - UInt256 sponsorBalanceAfter = chain.WorldStateManager.GlobalWorldState.GetBalance(sponsor); - UInt256 senderBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(sender); - TxReceipt[] receipts = chain.ReceiptStorage.Get(chain.BlockTree.Head!.Hash!); + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + UInt256 sponsorBalanceAfter = chain.WorldStateManager.GlobalWorldState.GetBalance(sponsor); + UInt256 senderBalance = chain.WorldStateManager.GlobalWorldState.GetBalance(sender); + TxReceipt[] receipts = chain.ReceiptStorage.Get(chain.BlockTree.Head!.Hash!); - receipts.Should().HaveCount(3); // 3 transactions: internal, deposit, contract call - receipts[2].GasUsedTotal.Should().Be(22938); // Contract call consumed gas + receipts.Should().HaveCount(3); // 3 transactions: internal, deposit, contract call + receipts[2].GasUsedTotal.Should().Be(22938); // Contract call consumed gas - sponsorBalanceAfter.Should().Be(sponsorBalanceBefore); - senderBalance.Should().Be(0); + sponsorBalanceAfter.Should().Be(sponsorBalanceBefore); + senderBalance.Should().Be(0); + } } [Test] @@ -156,7 +180,12 @@ public async Task DigestMessage_L2MessageCallContract_CallsContract() Hash256 requestId = new(RandomNumberGenerator.GetBytes(Hash256.Size)); Address sender = FullChainSimulationAccounts.Owner.Address; - UInt256 nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + + UInt256 nonce; + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + } // Calldata to call getBalance(address) on ArbInfo precompile byte[] addressBytes = new byte[32]; @@ -214,7 +243,12 @@ public async Task AddressExists_WithUnregisteredAddress_ReturnsSuccessfulExecuti Hash256 requestId = new(RandomNumberGenerator.GetBytes(Hash256.Size)); Address sender = FullChainSimulationAccounts.Owner.Address; - UInt256 nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + + UInt256 nonce; + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + } Address testAddress = new(RandomNumberGenerator.GetBytes(Address.Size)); @@ -255,7 +289,11 @@ public async Task Register_WithNewAddress_ReturnsSuccessfulExecution() Hash256 requestId = new(RandomNumberGenerator.GetBytes(Hash256.Size)); Address sender = FullChainSimulationAccounts.Owner.Address; - UInt256 nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + UInt256 nonce; + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + } Address testAddress = new(RandomNumberGenerator.GetBytes(Address.Size)); @@ -293,7 +331,11 @@ public async Task Lookup_WithRegisteredAddress_ReturnsSuccessfulExecution() Hash256 requestId = new(RandomNumberGenerator.GetBytes(Hash256.Size)); Address sender = FullChainSimulationAccounts.Owner.Address; - UInt256 nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + UInt256 nonce; + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + } Address testAddress = new(RandomNumberGenerator.GetBytes(Address.Size)); @@ -314,7 +356,10 @@ public async Task Lookup_WithRegisteredAddress_ReturnsSuccessfulExecution() await chain.Digest(new TestL2Transactions(requestId, L1BaseFee, sender, registerTx)); // Now lookup the registered address - nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + } byte[] lookupCalldata = [.. KeccakHash.ComputeHashBytes("lookup(address)"u8)[..4], .. addressBytes]; Transaction lookupTx = Build.A.Transaction @@ -347,7 +392,11 @@ public async Task Size_WithAddressTable_ReturnsSuccessfulExecution() Hash256 requestId = new(RandomNumberGenerator.GetBytes(Hash256.Size)); Address sender = FullChainSimulationAccounts.Owner.Address; - UInt256 nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + UInt256 nonce; + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + } // Calldata to call size() on ArbAddressTable precompile (no parameters) byte[] calldata = KeccakHash.ComputeHashBytes("size()"u8)[..4]; @@ -381,7 +430,11 @@ public async Task Compress_WithAddress_ReturnsSuccessfulExecution() Hash256 requestId = new(RandomNumberGenerator.GetBytes(Hash256.Size)); Address sender = FullChainSimulationAccounts.Owner.Address; - UInt256 nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + UInt256 nonce; + using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header)) + { + nonce = chain.WorldStateManager.GlobalWorldState.GetNonce(sender); + } Address testAddress = new(RandomNumberGenerator.GetBytes(Address.Size)); diff --git a/src/Nethermind.Arbitrum/ArbitrumNethermindApi.cs b/src/Nethermind.Arbitrum/ArbitrumNethermindApi.cs index 809d48b3..abb41db1 100644 --- a/src/Nethermind.Arbitrum/ArbitrumNethermindApi.cs +++ b/src/Nethermind.Arbitrum/ArbitrumNethermindApi.cs @@ -1,53 +1,7 @@ -using Autofac; using Nethermind.Api; -using Nethermind.Arbitrum.TransactionProcessing; -using Nethermind.Blockchain; -using Nethermind.Config; -using Nethermind.Consensus; -using Nethermind.Evm; -using Nethermind.Facade; -using Nethermind.Facade.Simulate; using static Nethermind.Api.NethermindApi; +// Overrides moved to IOC public class ArbitrumNethermindApi(Dependencies dependencies) : NethermindApi(dependencies) { - public IBlockhashProvider BlockHashProvider => Context.Resolve(); - - public override IBlockchainBridge CreateBlockchainBridge() - { - ReadOnlyBlockTree readOnlyTree = BlockTree!.AsReadOnly(); - - ArbitrumOverridableTxProcessingEnv txProcessingEnv = new( - WorldStateManager!.CreateOverridableWorldScope(), - readOnlyTree, - SpecProvider!, - LogManager); - - SimulateReadOnlyBlocksProcessingEnvFactory simulateReadOnlyBlocksProcessingEnvFactory = - new SimulateReadOnlyBlocksProcessingEnvFactory( - WorldStateManager!, - readOnlyTree, - DbProvider!, - SpecProvider!, - SimulateTransactionProcessorFactory, - LogManager); - - IMiningConfig miningConfig = ConfigProvider.GetConfig(); - IBlocksConfig blocksConfig = ConfigProvider.GetConfig(); - - return new BlockchainBridge( - txProcessingEnv, - simulateReadOnlyBlocksProcessingEnvFactory, - TxPool, - ReceiptFinder, - FilterStore, - FilterManager, - EthereumEcdsa, - Timestamper, - LogFinder, - SpecProvider!, - blocksConfig, - miningConfig.Enabled - ); - } } diff --git a/src/Nethermind.Arbitrum/ArbitrumPlugin.cs b/src/Nethermind.Arbitrum/ArbitrumPlugin.cs index 8a6d778f..bfab608d 100644 --- a/src/Nethermind.Arbitrum/ArbitrumPlugin.cs +++ b/src/Nethermind.Arbitrum/ArbitrumPlugin.cs @@ -6,30 +6,31 @@ using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Api.Steps; -using Nethermind.Arbitrum.Arbos.Stylus; using Nethermind.Arbitrum.Arbos; +using Nethermind.Arbitrum.Arbos.Stylus; using Nethermind.Arbitrum.Config; using Nethermind.Arbitrum.Evm; using Nethermind.Arbitrum.Execution; using Nethermind.Arbitrum.Execution.Transactions; using Nethermind.Arbitrum.Genesis; using Nethermind.Arbitrum.Modules; +using Nethermind.Arbitrum.Precompiles; using Nethermind.Config; using Nethermind.Consensus; +using Nethermind.Consensus.Processing; using Nethermind.Consensus.Producers; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Specs; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Evm.TransactionProcessing; -using Nethermind.HealthChecks; using Nethermind.Init.Steps; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; -using Nethermind.JsonRpc.Modules.Eth.FeeHistory; -using Nethermind.Logging; +using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Serialization.Rlp; using Nethermind.Specs.ChainSpecStyle; -using Nethermind.State; namespace Nethermind.Arbitrum; @@ -46,12 +47,6 @@ public class ArbitrumPlugin(ChainSpec chainSpec) : IConsensusPlugin public IModule Module => new ArbitrumModule(chainSpec); public Type ApiType => typeof(ArbitrumNethermindApi); - public IEnumerable GetSteps() - { - yield return typeof(ArbitrumLoadGenesisBlockStep); - yield return typeof(ArbitrumInitializeBlockchain); - } - public Task Init(INethermindApi api) { _api = (ArbitrumNethermindApi)api; @@ -64,7 +59,7 @@ public Task Init(INethermindApi api) // Only enable Arbitrum module if explicitly enabled in config if (_specHelper.Enabled) - _jsonRpcConfig.EnabledModules = _jsonRpcConfig.EnabledModules.Append(ModuleType.Arbitrum).ToArray(); + _jsonRpcConfig.EnabledModules = _jsonRpcConfig.EnabledModules.Append(Name).ToArray(); StylusTargets.PopulateStylusTargetCache(new StylusTargetConfig()); // TODO: Load StylusTargetConfig from ArbitrumConfig file @@ -96,32 +91,11 @@ public Task InitRpcModules() _api.RpcModuleProvider.RegisterBounded(arbitrumRpcModule, 1, _jsonRpcConfig.Timeout); - FeeHistoryOracle feeHistoryOracle = new FeeHistoryOracle( - _api.BlockTree, _api.ReceiptStorage, _api.SpecProvider); - - ArbitrumEthModuleFactory arbitrumEthFactory = new( - _api.TxPool, - _api.TxSender, - _api.Wallet, - _api.BlockTree, - _jsonRpcConfig, - _api.LogManager, - _api.StateReader, - _api, - _api.SpecProvider, - _api.ReceiptStorage, - _api.GasPriceOracle, - _api.EthSyncingInfo, - feeHistoryOracle, - _api.ProtocolsManager, - _api.Config().SecondsPerSlot); - - _api.RpcModuleProvider.RegisterBounded(arbitrumEthFactory, + _api.RpcModuleProvider.RegisterBounded( + _api.Context.Resolve>(), _jsonRpcConfig.EthModuleConcurrentInstances ?? Environment.ProcessorCount, _jsonRpcConfig.Timeout); - _api.RpcCapabilitiesProvider = new EngineRpcCapabilitiesProvider(_api.SpecProvider); - return Task.CompletedTask; } @@ -131,11 +105,9 @@ public IBlockProducer InitBlockProducer() StepDependencyException.ThrowIfNull(_api.WorldStateManager); StepDependencyException.ThrowIfNull(_api.BlockTree); StepDependencyException.ThrowIfNull(_api.SpecProvider); - StepDependencyException.ThrowIfNull(_api.BlockValidator); - StepDependencyException.ThrowIfNull(_api.RewardCalculatorSource); StepDependencyException.ThrowIfNull(_api.TransactionComparerProvider); - BlockProducerEnv producerEnv = _api.BlockProducerEnvFactory.Create(); + IBlockProducerEnv producerEnv = _api.BlockProducerEnvFactory.Create(); return new ArbitrumBlockProducer( producerEnv.TxSource, @@ -189,29 +161,50 @@ protected override void Load(ContainerBuilder builder) .AddSingleton() .AddSingleton(chainSpecParams) .AddSingleton() + + .AddStep(typeof(ArbitrumLoadGenesisBlockStep)) + .AddStep(typeof(ArbitrumInitializeBlockchain)) + .AddSingleton() + + .AddSingleton() .AddScoped() + .AddScoped() .AddScoped() + .AddScoped((specProvider, blocksConfig) => + new ArbitrumBlockProductionTransactionPicker(specProvider)) + .AddSingleton() .AddSingleton() + .AddDecorator() .AddWithAccessToPreviousRegistration((ctx, factory) => { ArbosState? arbosState = ctx.ResolveOptional(); + ISpecProvider baseSpecProvider = factory.Invoke(ctx); if (arbosState is not null) { IWorldState worldState = ctx.Resolve(); ArbosStateVersionProvider arbosVersionProvider = new(worldState); - return new ArbitrumChainSpecBasedSpecProvider(chainSpec, arbosVersionProvider, ctx.Resolve()); - } - else - { - ArbitrumChainSpecEngineParameters chainSpecParams = ctx.Resolve(); - ChainSpecVersionProvider arbosVersionProviderFactory = new(chainSpecParams); - return new ArbitrumChainSpecBasedSpecProvider(chainSpec, arbosVersionProviderFactory, ctx.Resolve()); + return new ArbitrumChainSpecBasedSpecProvider(baseSpecProvider, arbosVersionProvider); } + + ArbitrumChainSpecEngineParameters chainSpecParams = ctx.Resolve(); + ChainSpecVersionProvider arbosVersionProviderFactory = new(chainSpecParams); + return new ArbitrumChainSpecBasedSpecProvider(baseSpecProvider, arbosVersionProviderFactory); }) - .AddSingleton(); + .AddSingleton() + + // Rpcs + .AddSingleton() + .Bind, ArbitrumEthModuleFactory>(); + } + + private class ArbitrumBlockValidationModule : Module, IBlockValidationModule + { + protected override void Load(ContainerBuilder builder) => builder + .AddScoped() + .AddScoped(); } } diff --git a/src/Nethermind.Arbitrum/Arbos/ArbosState.cs b/src/Nethermind.Arbitrum/Arbos/ArbosState.cs index 361f9185..3aae2425 100644 --- a/src/Nethermind.Arbitrum/Arbos/ArbosState.cs +++ b/src/Nethermind.Arbitrum/Arbos/ArbosState.cs @@ -5,11 +5,11 @@ using Nethermind.Core; using Nethermind.Core.Specs; using Nethermind.Int256; -using Nethermind.State; using Nethermind.Logging; using Nethermind.Arbitrum.Arbos.Compression; using Nethermind.Arbitrum.Arbos.Programs; using Nethermind.Core.Crypto; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Arbos; diff --git a/src/Nethermind.Arbitrum/Arbos/ArbosVersionProvider.cs b/src/Nethermind.Arbitrum/Arbos/ArbosVersionProvider.cs index 5307cbef..50ad104a 100644 --- a/src/Nethermind.Arbitrum/Arbos/ArbosVersionProvider.cs +++ b/src/Nethermind.Arbitrum/Arbos/ArbosVersionProvider.cs @@ -1,6 +1,6 @@ using Nethermind.Arbitrum.Arbos.Storage; using Nethermind.Arbitrum.Config; -using Nethermind.State; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Arbos; diff --git a/src/Nethermind.Arbitrum/Arbos/Programs/StylusEvmApi.cs b/src/Nethermind.Arbitrum/Arbos/Programs/StylusEvmApi.cs index 2a515fc2..b3e793d6 100644 --- a/src/Nethermind.Arbitrum/Arbos/Programs/StylusEvmApi.cs +++ b/src/Nethermind.Arbitrum/Arbos/Programs/StylusEvmApi.cs @@ -4,8 +4,8 @@ using System.Runtime.InteropServices; using Nethermind.Arbitrum.Arbos.Stylus; using Nethermind.Core; +using Nethermind.Evm.State; using Nethermind.Int256; -using Nethermind.State; namespace Nethermind.Arbitrum.Arbos.Programs; diff --git a/src/Nethermind.Arbitrum/Arbos/Programs/StylusPrograms.cs b/src/Nethermind.Arbitrum/Arbos/Programs/StylusPrograms.cs index fcc48e85..85223bfa 100644 --- a/src/Nethermind.Arbitrum/Arbos/Programs/StylusPrograms.cs +++ b/src/Nethermind.Arbitrum/Arbos/Programs/StylusPrograms.cs @@ -12,8 +12,8 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Int256; -using Nethermind.State; using Bytes32 = Nethermind.Arbitrum.Arbos.Stylus.Bytes32; namespace Nethermind.Arbitrum.Arbos.Programs; @@ -171,7 +171,7 @@ public OperationResult CallProgram(EvmState evmState, in BlockExecutionC storage.Burner.Burn(callCost); using CloseOpenedPages _ = _wasmStorage.AddStylusPages(program.Value.Footprint); - OperationResult localAsm = GetLocalAsm(program.Value, codeSource, in moduleHash, in codeHash, evmState.Env.CodeInfo.MachineCode.Span, + OperationResult localAsm = GetLocalAsm(program.Value, codeSource, in moduleHash, in codeHash, evmState.Env.CodeInfo.CodeSpan, stylusParams, blockContext.Header.Timestamp, debugMode); if (!localAsm.IsSuccess) { @@ -193,7 +193,7 @@ public OperationResult CallProgram(EvmState evmState, in BlockExecutionC MsgSender = new Bytes20(evmState.Env.ExecutingAccount.Bytes), MsgValue = new Bytes32(evmState.Env.Value.ToBigEndian()), TxGasPrice = new Bytes32(transactionContext.GasPrice.ToBigEndian()), - TxOrigin = new Bytes20(transactionContext.Origin.Bytes), + TxOrigin = new Bytes20(transactionContext.Origin.Bytes[12..]), Reentrant = reentrant ? 1u : 0u, Cached = program.Value.Cached, Tracing = tracingInfo != null diff --git a/src/Nethermind.Arbitrum/Arbos/Storage/ArbosStorage.cs b/src/Nethermind.Arbitrum/Arbos/Storage/ArbosStorage.cs index 34212e0b..d92099cd 100644 --- a/src/Nethermind.Arbitrum/Arbos/Storage/ArbosStorage.cs +++ b/src/Nethermind.Arbitrum/Arbos/Storage/ArbosStorage.cs @@ -5,8 +5,8 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Int256; -using Nethermind.State; using System.Numerics; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Arbos.Storage; diff --git a/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState.cs b/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState.cs index 598a27f9..3ca87340 100644 --- a/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState.cs +++ b/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState.cs @@ -9,6 +9,7 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Evm.TransactionProcessing; using Nethermind.Int256; using Nethermind.Serialization.Rlp; diff --git a/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState_v10.cs b/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState_v10.cs index 6d57df75..cbdba706 100644 --- a/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState_v10.cs +++ b/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState_v10.cs @@ -4,9 +4,9 @@ using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; using Nethermind.Int256; -using Nethermind.State; using System.Numerics; using Nethermind.Arbitrum.Tracing; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Arbos.Storage; diff --git a/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState_v2.cs b/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState_v2.cs index b687e6e1..93d431bd 100644 --- a/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState_v2.cs +++ b/src/Nethermind.Arbitrum/Arbos/Storage/L1PricingState_v2.cs @@ -5,8 +5,8 @@ using Nethermind.Core.Specs; using Nethermind.Evm.TransactionProcessing; using Nethermind.Int256; -using Nethermind.State; using System.Numerics; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Arbos.Storage; diff --git a/src/Nethermind.Arbitrum/Arbos/Storage/RetryableState.cs b/src/Nethermind.Arbitrum/Arbos/Storage/RetryableState.cs index f45cbd4d..2e75f76a 100644 --- a/src/Nethermind.Arbitrum/Arbos/Storage/RetryableState.cs +++ b/src/Nethermind.Arbitrum/Arbos/Storage/RetryableState.cs @@ -1,12 +1,7 @@ -using Nethermind.Arbitrum.Evm; -using Nethermind.Arbitrum.Execution; -using Nethermind.Arbitrum.Execution.Transactions; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Evm; -using Nethermind.Evm.Tracing.GethStyle.Custom.JavaScript; using Nethermind.Int256; -using Nethermind.State; namespace Nethermind.Arbitrum.Arbos.Storage; diff --git a/src/Nethermind.Arbitrum/Config/ArbitrumBlockProducerEnvFactory.cs b/src/Nethermind.Arbitrum/Config/ArbitrumBlockProducerEnvFactory.cs index 86e66906..112b8e8d 100644 --- a/src/Nethermind.Arbitrum/Config/ArbitrumBlockProducerEnvFactory.cs +++ b/src/Nethermind.Arbitrum/Config/ArbitrumBlockProducerEnvFactory.cs @@ -1,17 +1,8 @@ +using Autofac; using Nethermind.Arbitrum.Execution; -using Nethermind.Blockchain; -using Nethermind.Blockchain.BeaconBlockRoot; -using Nethermind.Blockchain.Blocks; -using Nethermind.Config; -using Nethermind.Consensus.ExecutionRequests; using Nethermind.Consensus.Processing; using Nethermind.Consensus.Producers; -using Nethermind.Consensus.Rewards; -using Nethermind.Consensus.Validators; -using Nethermind.Consensus.Withdrawals; -using Nethermind.Core.Specs; -using Nethermind.Evm.TransactionProcessing; -using Nethermind.Logging; +using Nethermind.Core; using Nethermind.State; using static Nethermind.Arbitrum.Execution.ArbitrumBlockProcessor; @@ -19,53 +10,16 @@ namespace Nethermind.Arbitrum.Config; public class ArbitrumBlockProducerEnvFactory : BlockProducerEnvFactory { - private readonly CachedL1PriceData _cachedL1PriceData; - public ArbitrumBlockProducerEnvFactory( + ILifetimeScope rootLifetime, IWorldStateManager worldStateManager, - IReadOnlyTxProcessingEnvFactory txProcessingEnvFactory, - IBlockTree blockTree, - ISpecProvider specProvider, - IBlockValidator blockValidator, - IRewardCalculatorSource rewardCalculatorSource, - IBlockPreprocessorStep blockPreprocessorStep, - IBlocksConfig blocksConfig, - IBlockProducerTxSourceFactory blockProducerTxSourceFactory, - CachedL1PriceData cachedL1PriceData, - ILogManager logManager) : base( - worldStateManager, - txProcessingEnvFactory, - blockTree, - specProvider, - blockValidator, - rewardCalculatorSource, - blockPreprocessorStep, - blocksConfig, - blockProducerTxSourceFactory, - logManager) + IBlockProducerTxSourceFactory txSourceFactory) : base(rootLifetime, worldStateManager, txSourceFactory) { - _cachedL1PriceData = cachedL1PriceData; } - protected override BlockProcessor CreateBlockProcessor(IReadOnlyTxProcessingScope readOnlyTxProcessingEnv) + protected override ContainerBuilder ConfigureBuilder(ContainerBuilder builder) { - var transactionExecutor = new ArbitrumBlockProductionTransactionsExecutor( - readOnlyTxProcessingEnv.TransactionProcessor, readOnlyTxProcessingEnv.WorldState, - new ArbitrumBlockProductionTransactionPicker(_specProvider), _logManager); - - return new ArbitrumBlockProcessor( - _specProvider, - _blockValidator, - _rewardCalculatorSource.Get(readOnlyTxProcessingEnv.TransactionProcessor), - transactionExecutor, - readOnlyTxProcessingEnv.TransactionProcessor, - _cachedL1PriceData, - readOnlyTxProcessingEnv.WorldState, - _receiptStorage, - new BlockhashStore(_specProvider, readOnlyTxProcessingEnv.WorldState), - new BeaconBlockRootHandler(readOnlyTxProcessingEnv.TransactionProcessor, readOnlyTxProcessingEnv.WorldState), - _logManager, - new BlockProductionWithdrawalProcessor(new WithdrawalProcessor(readOnlyTxProcessingEnv.WorldState, _logManager)), - new ExecutionRequestsProcessor(readOnlyTxProcessingEnv.TransactionProcessor)); + return base.ConfigureBuilder(builder) + .AddScoped(); } } diff --git a/src/Nethermind.Arbitrum/Config/ArbitrumChainSpecBasedSpecProvider.cs b/src/Nethermind.Arbitrum/Config/ArbitrumChainSpecBasedSpecProvider.cs index 0e807f98..00e92ddb 100644 --- a/src/Nethermind.Arbitrum/Config/ArbitrumChainSpecBasedSpecProvider.cs +++ b/src/Nethermind.Arbitrum/Config/ArbitrumChainSpecBasedSpecProvider.cs @@ -3,22 +3,17 @@ using Nethermind.Arbitrum.Arbos; using Nethermind.Core.Specs; -using Nethermind.Logging; using Nethermind.Specs; -using Nethermind.Specs.ChainSpecStyle; namespace Nethermind.Arbitrum.Config; -public sealed class ArbitrumChainSpecBasedSpecProvider( - ChainSpec chainSpec, - IArbosVersionProvider arbosVersionProvider, - ILogManager logManager = null!) - : ChainSpecBasedSpecProvider(chainSpec, logManager) +public sealed class ArbitrumChainSpecBasedSpecProvider(ISpecProvider baseSpecProvider, IArbosVersionProvider arbosVersionProvider) : SpecProviderDecorator(baseSpecProvider) { // Even though we mutate the spec, this is fine as each scope has its own spec provider instance - public sealed override IReleaseSpec GetSpec(ForkActivation activation) + public override IReleaseSpec GetSpecInternal(ForkActivation activation) { - IReleaseSpec spec = base.GetSpec(activation); + IReleaseSpec spec = base.GetSpecInternal(activation); + ReleaseSpec mutableSpec = (ReleaseSpec)spec; ulong currentArbosVersion = arbosVersionProvider.Get(); @@ -43,6 +38,10 @@ public sealed override IReleaseSpec GetSpec(ForkActivation activation) mutableSpec.IsEip7002Enabled = pragueEnabled; mutableSpec.IsEip6110Enabled = pragueEnabled; + // Precompiles + ((IReleaseSpec)mutableSpec).Precompiles.Add(ArbosAddresses.ArbSysAddress); + ((IReleaseSpec)mutableSpec).Precompiles.Add(ArbosAddresses.ArbGasInfoAddress); + return mutableSpec; } } diff --git a/src/Nethermind.Arbitrum/Config/ArbitrumInitializeBlockchain.cs b/src/Nethermind.Arbitrum/Config/ArbitrumInitializeBlockchain.cs index 10ff1d47..f0c6dcdb 100644 --- a/src/Nethermind.Arbitrum/Config/ArbitrumInitializeBlockchain.cs +++ b/src/Nethermind.Arbitrum/Config/ArbitrumInitializeBlockchain.cs @@ -1,23 +1,5 @@ -using Autofac; -using Nethermind.Arbitrum.Arbos; -using Nethermind.Arbitrum.Evm; -using Nethermind.Arbitrum.Execution; -using Nethermind.Arbitrum.Precompiles; -using Nethermind.Blockchain; -using Nethermind.Blockchain.BeaconBlockRoot; -using Nethermind.Blockchain.Blocks; -using Nethermind.Consensus.ExecutionRequests; -using Nethermind.Consensus.Processing; using Nethermind.Consensus.Producers; -using Nethermind.Consensus.Withdrawals; -using Nethermind.Evm; -using Nethermind.Evm.TransactionProcessing; using Nethermind.Init.Steps; -using Nethermind.Specs.ChainSpecStyle; -using Nethermind.State; -using System.Collections.Concurrent; -using static Nethermind.Arbitrum.Execution.ArbitrumBlockProcessor; -using static Nethermind.State.PreBlockCaches; namespace Nethermind.Arbitrum.Config; @@ -25,80 +7,4 @@ public class ArbitrumInitializeBlockchain(ArbitrumNethermindApi api) : Initializ { protected override IBlockProductionPolicy CreateBlockProductionPolicy() => AlwaysStartBlockProductionPolicy.Instance; - protected override ICodeInfoRepository CreateCodeInfoRepository( - ConcurrentDictionary? precompileCache - ) - { - return new ArbitrumCodeInfoRepository(new CodeInfoRepository(precompileCache)); - } - - protected override IVirtualMachine CreateVirtualMachine(IWorldState worldState) - { - if (api.BlockTree is null) throw new StepDependencyException(nameof(api.BlockTree)); - if (api.WorldStateManager is null) throw new StepDependencyException(nameof(api.WorldStateManager)); - - ArbitrumChainSpecBasedSpecProvider specProvider = new( - api.Context.Resolve(), - new ArbosStateVersionProvider(worldState), - api.LogManager); - - BlockhashProvider blockhashProvider = new( - api.BlockTree, specProvider, worldState, api.LogManager); - - ArbitrumVirtualMachine virtualMachine = new( - blockhashProvider, - specProvider, - api.LogManager); - - return virtualMachine; - } - - protected override ITransactionProcessor CreateTransactionProcessor(ICodeInfoRepository codeInfoRepository, IVirtualMachine virtualMachine, IWorldState worldState) - { - if (api.BlockTree is null) throw new StepDependencyException(nameof(api.BlockTree)); - - ArbitrumChainSpecBasedSpecProvider specProvider = new( - api.Context.Resolve(), - new ArbosStateVersionProvider(worldState), - api.LogManager); - - return new ArbitrumTransactionProcessor( - specProvider, - worldState, - virtualMachine, - api.BlockTree, - api.LogManager, - codeInfoRepository); - } - - protected override BlockProcessor CreateBlockProcessor(BlockCachePreWarmer? preWarmer, ITransactionProcessor transactionProcessor, IWorldState worldState) - { - if (api.DbProvider is null) throw new StepDependencyException(nameof(api.DbProvider)); - if (api.RewardCalculatorSource is null) throw new StepDependencyException(nameof(api.RewardCalculatorSource)); - if (api.BlockTree is null) throw new StepDependencyException(nameof(api.BlockTree)); - if (api.ReceiptStorage is null) throw new StepDependencyException(nameof(api.ReceiptStorage)); - - ArbitrumChainSpecBasedSpecProvider specProvider = new( - api.Context.Resolve(), - new ArbosStateVersionProvider(worldState), - api.LogManager - ); - - return new ArbitrumBlockProcessor( - specProvider, - api.BlockValidator, - api.RewardCalculatorSource.Get(transactionProcessor), - //TODO: should use production or validation executor? - new ArbitrumBlockProductionTransactionsExecutor(transactionProcessor, worldState, new ArbitrumBlockProductionTransactionPicker(specProvider), api.LogManager), - transactionProcessor, - api.Context.Resolve(), - worldState, - api.ReceiptStorage, - new BlockhashStore(specProvider, worldState), - new BeaconBlockRootHandler(transactionProcessor, worldState), - api.LogManager, - new WithdrawalProcessor(api.WorldStateManager!.GlobalWorldState, api.LogManager), - new ExecutionRequestsProcessor(transactionProcessor), - preWarmer: preWarmer); - } } diff --git a/src/Nethermind.Arbitrum/Core/ArbitrumBlockHeader.cs b/src/Nethermind.Arbitrum/Core/ArbitrumBlockHeader.cs index f828298a..4a93f17d 100644 --- a/src/Nethermind.Arbitrum/Core/ArbitrumBlockHeader.cs +++ b/src/Nethermind.Arbitrum/Core/ArbitrumBlockHeader.cs @@ -27,7 +27,6 @@ public ArbitrumBlockHeader(BlockHeader original, UInt256 originalBaseFee) : base { OriginalBaseFee = originalBaseFee; - MaybeParent = original.MaybeParent; Author = original.Author; StateRoot = original.StateRoot; TxRoot = original.TxRoot; diff --git a/src/Nethermind.Arbitrum/Evm/ArbitrumEvmInstructions.Environment.cs b/src/Nethermind.Arbitrum/Evm/ArbitrumEvmInstructions.Environment.cs index f42f9aae..1a12e88b 100644 --- a/src/Nethermind.Arbitrum/Evm/ArbitrumEvmInstructions.Environment.cs +++ b/src/Nethermind.Arbitrum/Evm/ArbitrumEvmInstructions.Environment.cs @@ -17,7 +17,7 @@ internal static class ArbitrumEvmInstructions /// The program counter. /// An EVM exception type if an error occurs. [SkipLocalsInit] - public static EvmExceptionType InstructionBlkUInt256(VirtualMachineBase vm, ref EvmStack stack, ref long gasAvailable, ref int programCounter) + public static EvmExceptionType InstructionBlkUInt256(VirtualMachine vm, ref EvmStack stack, ref long gasAvailable, ref int programCounter) where TTracingInst : struct, IFlag { gasAvailable -= OpGasPrice.GasCost; @@ -58,7 +58,7 @@ public static ref readonly UInt256 Operation(ArbitrumVirtualMachine vm) /// The program counter. /// An EVM exception type if an error occurs. [SkipLocalsInit] - public static EvmExceptionType InstructionBlkUInt64(VirtualMachineBase vm, ref EvmStack stack, ref long gasAvailable, ref int programCounter) + public static EvmExceptionType InstructionBlkUInt64(VirtualMachine vm, ref EvmStack stack, ref long gasAvailable, ref int programCounter) where TTracingInst : struct, IFlag { gasAvailable -= OpNumber.GasCost; diff --git a/src/Nethermind.Arbitrum/Evm/ArbitrumVirtualMachine.cs b/src/Nethermind.Arbitrum/Evm/ArbitrumVirtualMachine.cs index 2002ce44..f76f00c9 100644 --- a/src/Nethermind.Arbitrum/Evm/ArbitrumVirtualMachine.cs +++ b/src/Nethermind.Arbitrum/Evm/ArbitrumVirtualMachine.cs @@ -8,20 +8,20 @@ using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Logging; -using Nethermind.State; using Nethermind.Evm.Tracing; [assembly: InternalsVisibleTo("Nethermind.Arbitrum.Evm.Test")] namespace Nethermind.Arbitrum.Evm; -using unsafe OpCode = delegate*; +using unsafe OpCode = delegate*; public sealed unsafe class ArbitrumVirtualMachine( IBlockhashProvider? blockHashProvider, ISpecProvider? specProvider, ILogManager? logManager -) : VirtualMachineBase(blockHashProvider, specProvider, logManager) +) : VirtualMachine(blockHashProvider, specProvider, logManager) { public ArbosState FreeArbosState { get; private set; } = null!; public ArbitrumTxExecutionContext ArbitrumTxExecutionContext { get; set; } = new(); diff --git a/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProcessor.cs b/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProcessor.cs index ab808a9e..b3be7a2d 100644 --- a/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProcessor.cs +++ b/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProcessor.cs @@ -21,9 +21,7 @@ using Nethermind.Evm; using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; -using Nethermind.Int256; using Nethermind.Logging; -using Nethermind.State; using Nethermind.State.Proofs; using Nethermind.TxPool.Comparison; using System.Runtime.CompilerServices; @@ -33,6 +31,8 @@ using System.Text.Json; using Nethermind.Arbitrum.Execution.Receipts; using System.Numerics; +using Nethermind.Blockchain.Tracing; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Execution { @@ -56,8 +56,7 @@ public ArbitrumBlockProcessor( IBeaconBlockRootHandler beaconBlockRootHandler, ILogManager logManager, IWithdrawalProcessor withdrawalProcessor, - IExecutionRequestsProcessor executionRequestsProcessor, - IBlockCachePreWarmer? preWarmer = null) + IExecutionRequestsProcessor executionRequestsProcessor) : base( specProvider, blockValidator, @@ -69,8 +68,7 @@ public ArbitrumBlockProcessor( blockhashStore, logManager, withdrawalProcessor, - executionRequestsProcessor, - preWarmer) + executionRequestsProcessor) { _specProvider = specProvider; _blockTransactionsExecutor = blockTransactionsExecutor; @@ -83,9 +81,10 @@ protected override TxReceipt[] ProcessBlock( Block block, IBlockTracer blockTracer, ProcessingOptions options, + IReleaseSpec releaseSpec, CancellationToken token) { - TxReceipt[] receipts = base.ProcessBlock(block, blockTracer, options, token); + TxReceipt[] receipts = base.ProcessBlock(block, blockTracer, options, releaseSpec, token); _cachedL1PriceData.CacheL1PriceDataOfMsg( (ulong)block.Number, receipts, block, blockBuiltUsingDelayedMessage: false ); @@ -102,15 +101,6 @@ public class ArbitrumBlockProductionTransactionsExecutor( private readonly ITransactionProcessorAdapter _transactionProcessor = new BuildUpTransactionProcessorAdapter(txProcessor); private readonly ILogger _logger = logManager.GetClassLogger(); - public ArbitrumBlockProductionTransactionsExecutor( - ITransactionProcessor transactionProcessor, - IWorldState stateProvider, - ISpecProvider specProvider, - ILogManager logManager) : this(transactionProcessor, stateProvider, - new ArbitrumBlockProductionTransactionPicker(specProvider), logManager) - { - } - protected EventHandler? _transactionProcessed; event EventHandler? IBlockTransactionsExecutor.TransactionProcessed @@ -129,7 +119,7 @@ public void SetBlockExecutionContext(in BlockExecutionContext blockExecutionCont => _transactionProcessor.SetBlockExecutionContext(in blockExecutionContext); public virtual TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processingOptions, - BlockReceiptsTracer receiptsTracer, IReleaseSpec spec, CancellationToken token = default) + BlockReceiptsTracer receiptsTracer, CancellationToken token = default) { // We start with high number as don't want to resize too much const int defaultTxCount = 512; @@ -151,7 +141,7 @@ public virtual TxReceipt[] ProcessTransactions(Block block, ProcessingOptions pr int i = 0; var redeems = new Queue(); - using var transactionsEnumerator = (blockToProduce?.Transactions ?? block.Transactions).GetEnumerator(); + using IEnumerator transactionsEnumerator = (blockToProduce?.Transactions ?? block.Transactions).GetEnumerator(); while (true) { diff --git a/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProducer.cs b/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProducer.cs index 085b20b1..4ae924e2 100644 --- a/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProducer.cs +++ b/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProducer.cs @@ -15,10 +15,9 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Crypto; -using Nethermind.Int256; +using Nethermind.Evm.State; using Nethermind.Logging; using Nethermind.Merge.Plugin.BlockProduction; -using Nethermind.State; namespace Nethermind.Arbitrum.Execution { @@ -83,7 +82,7 @@ protected BlockHeader PrepareBlockHeader(BlockHeader parent, ArbitrumPayloadAttr return header; } - protected override Block PrepareBlock(BlockHeader parent, PayloadAttributes? payloadAttributes = null) + protected override BlockToProduce PrepareBlock(BlockHeader parent, PayloadAttributes? payloadAttributes = null, IBlockProducer.Flags flags = IBlockProducer.Flags.None) { if (payloadAttributes is not ArbitrumPayloadAttributes) throw new ArgumentException("Invalid payload attributes"); @@ -92,6 +91,8 @@ protected override Block PrepareBlock(BlockHeader parent, PayloadAttributes? pay var burner = new SystemBurner(); + using IDisposable worldStateDisposer = _worldState.BeginScope(parent); + ArbosState arbosState = ArbosState.OpenArbosState(_worldState, burner, Logger); diff --git a/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProductionTransactionPicker.cs b/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProductionTransactionPicker.cs index 57f598d0..abf36f46 100644 --- a/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProductionTransactionPicker.cs +++ b/src/Nethermind.Arbitrum/Execution/ArbitrumBlockProductionTransactionPicker.cs @@ -4,7 +4,7 @@ using Nethermind.Consensus.Processing; using Nethermind.Core; using Nethermind.Core.Specs; -using Nethermind.State; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Execution; diff --git a/src/Nethermind.Arbitrum/Execution/ArbitrumOverridableTxProcessingEnv.cs b/src/Nethermind.Arbitrum/Execution/ArbitrumOverridableTxProcessingEnv.cs deleted file mode 100644 index 224feef6..00000000 --- a/src/Nethermind.Arbitrum/Execution/ArbitrumOverridableTxProcessingEnv.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Nethermind.Arbitrum.Evm; -using Nethermind.Arbitrum.Execution; -using Nethermind.Blockchain; -using Nethermind.Consensus.Processing; -using Nethermind.Core.Specs; -using Nethermind.Evm.TransactionProcessing; -using Nethermind.Logging; -using Nethermind.State; - -namespace Nethermind.Arbitrum.TransactionProcessing; - -public class ArbitrumOverridableTxProcessingEnv( - IOverridableWorldScope worldStateManager, - IReadOnlyBlockTree readOnlyBlockTree, - ISpecProvider specProvider, - ILogManager logManager) - : OverridableTxProcessingEnv(worldStateManager, readOnlyBlockTree, specProvider, logManager) -{ - protected override ITransactionProcessor CreateTransactionProcessor() - { - BlockhashProvider blockhashProvider = new(BlockTree, SpecProvider, StateProvider, LogManager); - ArbitrumVirtualMachine virtualMachine = new(blockhashProvider, SpecProvider, LogManager); - return new ArbitrumTransactionProcessor(SpecProvider, StateProvider, virtualMachine, readOnlyBlockTree, LogManager, CodeInfoRepository); - } -} diff --git a/src/Nethermind.Arbitrum/Execution/ArbitrumTransactionProcessor.cs b/src/Nethermind.Arbitrum/Execution/ArbitrumTransactionProcessor.cs index 66ac62d3..01e1cd5b 100644 --- a/src/Nethermind.Arbitrum/Execution/ArbitrumTransactionProcessor.cs +++ b/src/Nethermind.Arbitrum/Execution/ArbitrumTransactionProcessor.cs @@ -20,11 +20,11 @@ using Nethermind.Evm.TransactionProcessing; using Nethermind.Int256; using Nethermind.Logging; -using Nethermind.State; -using Nethermind.State.Tracing; using Nethermind.Crypto; using Nethermind.Evm.CodeAnalysis; using Nethermind.Consensus.Messages; +using Nethermind.Evm.State; +using Nethermind.Evm.Tracing.State; namespace Nethermind.Arbitrum.Execution { @@ -35,7 +35,7 @@ public class ArbitrumTransactionProcessor( IBlockTree blockTree, ILogManager logManager, ICodeInfoRepository? codeInfoRepository - ) : TransactionProcessorBase(specProvider, worldState, virtualMachine, new ArbitrumCodeInfoRepository(codeInfoRepository), logManager) + ) : TransactionProcessorBase(specProvider, worldState, virtualMachine, codeInfoRepository, logManager) { public ArbitrumTxExecutionContext TxExecContext => (VirtualMachine as ArbitrumVirtualMachine)!.ArbitrumTxExecutionContext; @@ -105,7 +105,7 @@ private void InitializeTransactionState(Transaction tx, IArbitrumTxTracer tracer ArbosState.OpenArbosState(WorldState, new SystemBurner(_tracingInfo, readOnly: false), _logger); TxExecContext.Reset(); _currentHeader = VirtualMachine.BlockExecutionContext.Header; - _currentSpec = GetSpec(null!, _currentHeader); + _currentSpec = GetSpec(_currentHeader); } private ArbitrumTransactionProcessorResult PreProcessArbitrumTransaction(Transaction tx, diff --git a/src/Nethermind.Arbitrum/Execution/Receipts/ArbitrumBlockReceiptTracer.cs b/src/Nethermind.Arbitrum/Execution/Receipts/ArbitrumBlockReceiptTracer.cs index 15bde37c..c27c7b9a 100644 --- a/src/Nethermind.Arbitrum/Execution/Receipts/ArbitrumBlockReceiptTracer.cs +++ b/src/Nethermind.Arbitrum/Execution/Receipts/ArbitrumBlockReceiptTracer.cs @@ -1,7 +1,7 @@ using Nethermind.Arbitrum.Execution.Transactions; +using Nethermind.Blockchain.Tracing; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Evm.Tracing; namespace Nethermind.Arbitrum.Execution.Receipts; diff --git a/src/Nethermind.Arbitrum/Genesis/ArbitrumBlockTreeInitializer.cs b/src/Nethermind.Arbitrum/Genesis/ArbitrumBlockTreeInitializer.cs index ba5f9b7b..d40b0496 100644 --- a/src/Nethermind.Arbitrum/Genesis/ArbitrumBlockTreeInitializer.cs +++ b/src/Nethermind.Arbitrum/Genesis/ArbitrumBlockTreeInitializer.cs @@ -5,6 +5,7 @@ using Nethermind.Core; using Nethermind.Core.Events; using Nethermind.Core.Specs; +using Nethermind.Evm.State; using Nethermind.Logging; using Nethermind.Specs.ChainSpecStyle; using Nethermind.State; @@ -32,6 +33,8 @@ public BlockHeader Initialize(ParsedInitMessage initMessage) return genesisHeader; } + using IDisposable worldStateCloser = worldStateManager.GlobalWorldState.BeginScope(IWorldState.PreGenesis); + ArbitrumGenesisLoader genesisLoader = new( chainSpec, specProvider, diff --git a/src/Nethermind.Arbitrum/Genesis/ArbitrumGenesisLoader.cs b/src/Nethermind.Arbitrum/Genesis/ArbitrumGenesisLoader.cs index a0dde41f..aa602d2e 100644 --- a/src/Nethermind.Arbitrum/Genesis/ArbitrumGenesisLoader.cs +++ b/src/Nethermind.Arbitrum/Genesis/ArbitrumGenesisLoader.cs @@ -5,10 +5,10 @@ using Nethermind.Core; using Nethermind.Core.Specs; using Nethermind.Crypto; +using Nethermind.Evm.State; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Specs.ChainSpecStyle; -using Nethermind.State; namespace Nethermind.Arbitrum.Genesis; diff --git a/src/Nethermind.Arbitrum/Genesis/ArbitrumLoadGenesisBlockStep.cs b/src/Nethermind.Arbitrum/Genesis/ArbitrumLoadGenesisBlockStep.cs index 91d774e6..d954883e 100644 --- a/src/Nethermind.Arbitrum/Genesis/ArbitrumLoadGenesisBlockStep.cs +++ b/src/Nethermind.Arbitrum/Genesis/ArbitrumLoadGenesisBlockStep.cs @@ -1,18 +1,12 @@ using Nethermind.Api; -using Nethermind.Core.Crypto; using Nethermind.Init.Steps; -using Nethermind.State; namespace Nethermind.Arbitrum.Genesis; public class ArbitrumLoadGenesisBlockStep(ArbitrumNethermindApi api) : LoadGenesisBlock(api) { - protected override Task Load(IMainProcessingContext mainProcessingContext) - { - return Task.CompletedTask; - } - - protected override void ValidateGenesisHash(Hash256? expectedGenesisHash, IWorldState worldState) + protected override void Load(IMainProcessingContext mainProcessingContext) { + //Genesis block processed in DigestInitMessage call - intentionally empty } } diff --git a/src/Nethermind.Arbitrum/Modules/ArbitrumEthModuleFactory.cs b/src/Nethermind.Arbitrum/Modules/ArbitrumEthModuleFactory.cs index 268e69af..0a851c83 100644 --- a/src/Nethermind.Arbitrum/Modules/ArbitrumEthModuleFactory.cs +++ b/src/Nethermind.Arbitrum/Modules/ArbitrumEthModuleFactory.cs @@ -1,10 +1,10 @@ // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System; using Nethermind.Arbitrum.Evm; using Nethermind.Blockchain; using Nethermind.Blockchain.Receipts; +using Nethermind.Config; using Nethermind.Core.Specs; using Nethermind.Evm; using Nethermind.Facade; @@ -19,6 +19,7 @@ using Nethermind.State; using Nethermind.TxPool; using Nethermind.Wallet; +using System; namespace Nethermind.Arbitrum.Modules; @@ -38,6 +39,7 @@ public class ArbitrumEthModuleFactory : ModuleFactoryBase private readonly IEthSyncingInfo _ethSyncingInfo; private readonly IFeeHistoryOracle _feeHistoryOracle; private readonly IProtocolsManager _protocolsManager; + private readonly IForkInfo _forkInfo; private readonly ulong? _secondsPerSlot; public ArbitrumEthModuleFactory( @@ -55,7 +57,8 @@ public ArbitrumEthModuleFactory( IEthSyncingInfo ethSyncingInfo, IFeeHistoryOracle feeHistoryOracle, IProtocolsManager protocolsManager, - ulong? secondsPerSlot) + IForkInfo forkInfo, + IBlocksConfig blocksConfig) { _txPool = txPool; _txSender = txSender; @@ -71,7 +74,8 @@ public ArbitrumEthModuleFactory( _ethSyncingInfo = ethSyncingInfo; _feeHistoryOracle = feeHistoryOracle; _protocolsManager = protocolsManager; - _secondsPerSlot = secondsPerSlot; + _forkInfo = forkInfo; + _secondsPerSlot = blocksConfig.SecondsPerSlot; } public override IEthRpcModule Create() @@ -91,6 +95,7 @@ public override IEthRpcModule Create() _ethSyncingInfo, _feeHistoryOracle, _protocolsManager, + _forkInfo, _secondsPerSlot); } } diff --git a/src/Nethermind.Arbitrum/Modules/ArbitrumEthRpcModule.cs b/src/Nethermind.Arbitrum/Modules/ArbitrumEthRpcModule.cs index d87eaf77..565f47d3 100644 --- a/src/Nethermind.Arbitrum/Modules/ArbitrumEthRpcModule.cs +++ b/src/Nethermind.Arbitrum/Modules/ArbitrumEthRpcModule.cs @@ -45,8 +45,9 @@ public ArbitrumEthRpcModule( IEthSyncingInfo ethSyncingInfo, IFeeHistoryOracle feeHistoryOracle, IProtocolsManager protocolsManager, + IForkInfo forkInfo, ulong? secondsPerSlot) - : base(rpcConfig, blockchainBridge, blockFinder, receiptFinder, stateReader, txPool, txSender, wallet, logManager, specProvider, gasPriceOracle, ethSyncingInfo, feeHistoryOracle, protocolsManager, secondsPerSlot) + : base(rpcConfig, blockchainBridge, blockFinder, receiptFinder, stateReader, txPool, txSender, wallet, logManager, specProvider, gasPriceOracle, ethSyncingInfo, feeHistoryOracle, protocolsManager, forkInfo, secondsPerSlot) { } diff --git a/src/Nethermind.Arbitrum/Modules/IArbitrumRpcModule.cs b/src/Nethermind.Arbitrum/Modules/IArbitrumRpcModule.cs index 881d2587..d92f255d 100644 --- a/src/Nethermind.Arbitrum/Modules/IArbitrumRpcModule.cs +++ b/src/Nethermind.Arbitrum/Modules/IArbitrumRpcModule.cs @@ -7,7 +7,7 @@ namespace Nethermind.Arbitrum.Modules { - [RpcModule(ModuleType.Arbitrum)] + [RpcModule("Arbitrum")] public interface IArbitrumRpcModule : IRpcModule { [JsonRpcMethod(IsSharable = false, IsImplemented = true)] diff --git a/src/Nethermind.Arbitrum/Precompiles/ArbSys.cs b/src/Nethermind.Arbitrum/Precompiles/ArbSys.cs index 8756553b..8a661838 100644 --- a/src/Nethermind.Arbitrum/Precompiles/ArbSys.cs +++ b/src/Nethermind.Arbitrum/Precompiles/ArbSys.cs @@ -4,6 +4,7 @@ using Nethermind.Arbitrum.Execution; using Nethermind.Arbitrum.Execution.Transactions; using Nethermind.Arbitrum.Precompiles.Events; +using Nethermind.Blockchain.Tracing.GethStyle.Custom.JavaScript; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Int256; @@ -314,5 +315,5 @@ or ArbitrumTxType.ArbitrumContract or ArbitrumTxType.ArbitrumRetry; private static bool IsTopLevel(ArbitrumPrecompileExecutionContext context) - => context.CallDepth < 2 || context.Origin == context.GrandCaller; + => context.CallDepth < 2 || context.Origin == context.GrandCaller?.ToHash(); } diff --git a/src/Nethermind.Arbitrum/Precompiles/ArbitrumCodeInfoRepository.cs b/src/Nethermind.Arbitrum/Precompiles/ArbitrumCodeInfoRepository.cs index 24c402ff..89bcba05 100644 --- a/src/Nethermind.Arbitrum/Precompiles/ArbitrumCodeInfoRepository.cs +++ b/src/Nethermind.Arbitrum/Precompiles/ArbitrumCodeInfoRepository.cs @@ -5,7 +5,8 @@ using Nethermind.Core.Specs; using Nethermind.Evm; using Nethermind.Evm.CodeAnalysis; -using Nethermind.State; +using Nethermind.Evm.Precompiles; +using Nethermind.Evm.State; namespace Nethermind.Arbitrum.Precompiles; @@ -27,6 +28,8 @@ private static Dictionary InitializePrecompiledContracts() }; } + public bool IsPrecompile(Address address, IReleaseSpec spec) => spec.IsPrecompile(address); + public ICodeInfo GetCachedCodeInfo(IWorldState worldState, Address codeSource, bool followDelegation, IReleaseSpec vmSpec, out Address? delegationAddress) { delegationAddress = null; diff --git a/src/Nethermind.Arbitrum/Precompiles/ArbitrumPrecompileExecutionContext.cs b/src/Nethermind.Arbitrum/Precompiles/ArbitrumPrecompileExecutionContext.cs index 9eb1a463..a113b461 100644 --- a/src/Nethermind.Arbitrum/Precompiles/ArbitrumPrecompileExecutionContext.cs +++ b/src/Nethermind.Arbitrum/Precompiles/ArbitrumPrecompileExecutionContext.cs @@ -5,8 +5,8 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Evm; +using Nethermind.Evm.State; using Nethermind.Int256; -using Nethermind.State; namespace Nethermind.Arbitrum.Precompiles; @@ -43,7 +43,7 @@ public record ArbitrumPrecompileExecutionContext( public Address? GrandCaller { get; init; } - public Address Origin { get; init; } + public ValueHash256 Origin { get; init; } public UInt256 Value { get; init; } @@ -74,7 +74,8 @@ public void Burn(ulong amount) public void BurnOut() { GasLeft = 0; - EvmPooledMemory.ThrowOutOfGasException(); + Metrics.EvmExceptions++; + throw new OutOfGasException(); } public ValueHash256 GetCodeHash(Address address) diff --git a/src/Nethermind.Arbitrum/Precompiles/PrecompileInfo.cs b/src/Nethermind.Arbitrum/Precompiles/PrecompileInfo.cs index 5b7119ca..f5944f64 100644 --- a/src/Nethermind.Arbitrum/Precompiles/PrecompileInfo.cs +++ b/src/Nethermind.Arbitrum/Precompiles/PrecompileInfo.cs @@ -5,7 +5,8 @@ namespace Nethermind.Arbitrum.Precompiles; public sealed class PrecompileInfo(IArbitrumPrecompile precompile) : ICodeInfo { - public ReadOnlyMemory MachineCode => Array.Empty(); + public ReadOnlyMemory Code => ReadOnlyMemory.Empty; + ReadOnlySpan ICodeInfo.CodeSpan => Code.Span; public IArbitrumPrecompile Precompile { get; } = precompile; public bool IsPrecompile => true; diff --git a/src/Nethermind.Arbitrum/Properties/chainspec/arbitrum-local.json b/src/Nethermind.Arbitrum/Properties/chainspec/arbitrum-local.json index b9f83c1c..b74e36d2 100644 --- a/src/Nethermind.Arbitrum/Properties/chainspec/arbitrum-local.json +++ b/src/Nethermind.Arbitrum/Properties/chainspec/arbitrum-local.json @@ -59,7 +59,9 @@ "eip6780TransitionTimestamp": "0x65B97D60", "eip2537TransitionTimestamp": "0x67C7FD60", "eip2935TransitionTimestamp": "0x67C7FD60", - "eip7702TransitionTimestamp": "0x67C7FD60" + "eip7702TransitionTimestamp": "0x67C7FD60", + "minHistoryRetentionEpochs": "0x0", + "eip7934MaxRlpBlockSize": "0x0" }, "genesis": { "seal": { diff --git a/src/Nethermind.Arbitrum/Tracing/ArbitrumGethLikeBlockTracer.cs b/src/Nethermind.Arbitrum/Tracing/ArbitrumGethLikeBlockTracer.cs index 9ea75461..673f92aa 100644 --- a/src/Nethermind.Arbitrum/Tracing/ArbitrumGethLikeBlockTracer.cs +++ b/src/Nethermind.Arbitrum/Tracing/ArbitrumGethLikeBlockTracer.cs @@ -1,13 +1,9 @@ // SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using Nethermind.Blockchain.Tracing; +using Nethermind.Blockchain.Tracing.GethStyle; using Nethermind.Core; -using Nethermind.Core.Crypto; -using Nethermind.Evm; -using Nethermind.Evm.Tracing; -using Nethermind.Evm.Tracing.GethStyle; -using Nethermind.Evm.TransactionProcessing; -using Nethermind.Int256; namespace Nethermind.Arbitrum.Tracing; diff --git a/src/Nethermind.Arbitrum/Tracing/ArbitrumGethLikeTxTracer.cs b/src/Nethermind.Arbitrum/Tracing/ArbitrumGethLikeTxTracer.cs index 1ee53b70..9df86d14 100644 --- a/src/Nethermind.Arbitrum/Tracing/ArbitrumGethLikeTxTracer.cs +++ b/src/Nethermind.Arbitrum/Tracing/ArbitrumGethLikeTxTracer.cs @@ -1,6 +1,6 @@ +using Nethermind.Blockchain.Tracing.GethStyle; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Evm.Tracing.GethStyle; using Nethermind.Int256; namespace Nethermind.Arbitrum.Tracing; diff --git a/src/Nethermind.Arbitrum/Tracing/ArbitrumNativePrestateTracer.cs b/src/Nethermind.Arbitrum/Tracing/ArbitrumNativePrestateTracer.cs index 017500fa..eb7b323e 100644 --- a/src/Nethermind.Arbitrum/Tracing/ArbitrumNativePrestateTracer.cs +++ b/src/Nethermind.Arbitrum/Tracing/ArbitrumNativePrestateTracer.cs @@ -1,10 +1,10 @@ using Nethermind.Arbitrum.Arbos; +using Nethermind.Blockchain.Tracing.GethStyle; +using Nethermind.Blockchain.Tracing.GethStyle.Custom.Native.Prestate; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Evm.Tracing.GethStyle; -using Nethermind.Evm.Tracing.GethStyle.Custom.Native.Prestate; +using Nethermind.Evm.State; using Nethermind.Int256; -using Nethermind.State; namespace Nethermind.Arbitrum.Tracing; diff --git a/src/Nethermind.Arbitrum/nuget.config b/src/Nethermind.Arbitrum/nuget.config index d3293ee4..ad7cb00f 100644 --- a/src/Nethermind.Arbitrum/nuget.config +++ b/src/Nethermind.Arbitrum/nuget.config @@ -4,17 +4,5 @@ - - - - - - - - - - - \ No newline at end of file + diff --git a/src/nuget.config b/src/nuget.config index d7993970..ad7cb00f 100644 --- a/src/nuget.config +++ b/src/nuget.config @@ -4,18 +4,5 @@ - - - - - - - - - -