Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor state and storage behind one interface #5659

Merged
merged 5 commits into from
May 12, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 9 additions & 16 deletions src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
IEthereumEcdsa ecdsa = new EthereumEcdsa(specProvider.ChainId, _logManager);

TrieStore trieStore = new(stateDb, _logManager);
IStateProvider stateProvider = new StateProvider(trieStore, codeDb, _logManager);
IWorldState stateProvider = new WorldState(trieStore, codeDb, _logManager);
MemDb blockInfoDb = new MemDb();
IBlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, _logManager);
ITransactionComparerProvider transactionComparerProvider = new TransactionComparerProvider(specProvider, blockTree);
Expand All @@ -141,7 +141,6 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
IHeaderValidator headerValidator = new HeaderValidator(blockTree, Sealer, specProvider, _logManager);
IUnclesValidator unclesValidator = new UnclesValidator(blockTree, headerValidator, _logManager);
IBlockValidator blockValidator = new BlockValidator(txValidator, headerValidator, unclesValidator, specProvider, _logManager);
IStorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, _logManager);
IVirtualMachine virtualMachine = new VirtualMachine(
blockhashProvider,
specProvider,
Expand All @@ -155,12 +154,10 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
new TransactionProcessor(
specProvider,
stateProvider,
storageProvider,
virtualMachine,
_logManager),
stateProvider),
stateProvider,
storageProvider,
receiptStorage,
NullWitnessCollector.Instance,
_logManager);
Expand All @@ -173,7 +170,7 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
_logManager,
BlockchainProcessor.Options.NoReceipts);

InitializeTestState(test, stateProvider, storageProvider, specProvider);
InitializeTestState(test, stateProvider, specProvider);

stopwatch?.Start();
List<(Block Block, string ExpectedException)> correctRlp = DecodeRlps(test, failOnInvalidRlp);
Expand Down Expand Up @@ -239,7 +236,7 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
await blockchainProcessor.StopAsync(true);
stopwatch?.Stop();

List<string> differences = RunAssertions(test, blockTree.RetrieveHeadBlock(), storageProvider, stateProvider);
List<string> differences = RunAssertions(test, blockTree.RetrieveHeadBlock(), stateProvider);

Assert.Zero(differences.Count, "differences");

Expand Down Expand Up @@ -309,36 +306,32 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
return correctRlp;
}

private void InitializeTestState(BlockchainTest test, IStateProvider stateProvider, IStorageProvider storageProvider, ISpecProvider specProvider)
private void InitializeTestState(BlockchainTest test, IWorldState stateProvider, ISpecProvider specProvider)
{
foreach (KeyValuePair<Address, AccountState> accountState in
((IEnumerable<KeyValuePair<Address, AccountState>>)test.Pre ?? Array.Empty<KeyValuePair<Address, AccountState>>()))
{
foreach (KeyValuePair<UInt256, byte[]> storageItem in accountState.Value.Storage)
{
storageProvider.Set(new StorageCell(accountState.Key, storageItem.Key), storageItem.Value);
stateProvider.Set(new StorageCell(accountState.Key, storageItem.Key), storageItem.Value);
}

stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance);
Keccak codeHash = stateProvider.UpdateCode(accountState.Value.Code);
stateProvider.UpdateCodeHash(accountState.Key, codeHash, specProvider.GenesisSpec);
stateProvider.InsertCode(accountState.Key, accountState.Value.Code, specProvider.GenesisSpec);
for (int i = 0; i < accountState.Value.Nonce; i++)
{
stateProvider.IncrementNonce(accountState.Key);
}
}

storageProvider.Commit();
stateProvider.Commit(specProvider.GenesisSpec);

storageProvider.CommitTrees(0);
stateProvider.CommitTree(0);

storageProvider.Reset();
stateProvider.Reset();
}

private List<string> RunAssertions(BlockchainTest test, Block headBlock, IStorageProvider storageProvider, IStateProvider stateProvider)
private List<string> RunAssertions(BlockchainTest test, Block headBlock, IWorldState stateProvider)
{
if (test.PostStateRoot != null)
{
Expand Down Expand Up @@ -407,7 +400,7 @@ private List<string> RunAssertions(BlockchainTest test, Block headBlock, IStorag

foreach (KeyValuePair<UInt256, byte[]> clearedStorage in clearedStorages)
{
byte[] value = !stateProvider.AccountExists(acountAddress) ? Bytes.Empty : storageProvider.Get(new StorageCell(acountAddress, clearedStorage.Key));
byte[] value = !stateProvider.AccountExists(acountAddress) ? Bytes.Empty : stateProvider.Get(new StorageCell(acountAddress, clearedStorage.Key));
if (!value.IsZero())
{
differences.Add($"{acountAddress} storage[{clearedStorage.Key}] exp: 0x00, actual: {value.ToHexString(true)}");
Expand All @@ -416,7 +409,7 @@ private List<string> RunAssertions(BlockchainTest test, Block headBlock, IStorag

foreach (KeyValuePair<UInt256, byte[]> storageItem in accountState.Storage)
{
byte[] value = !stateProvider.AccountExists(acountAddress) ? Bytes.Empty : storageProvider.Get(new StorageCell(acountAddress, storageItem.Key)) ?? new byte[0];
byte[] value = !stateProvider.AccountExists(acountAddress) ? Bytes.Empty : stateProvider.Get(new StorageCell(acountAddress, storageItem.Key)) ?? new byte[0];
if (!Bytes.AreEqual(storageItem.Value, value))
{
differences.Add($"{acountAddress} storage[{storageItem.Key}] exp: {storageItem.Value.ToHexString(true)}, actual: {value.ToHexString(true)}");
Expand Down
21 changes: 6 additions & 15 deletions src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer)
}

TrieStore trieStore = new(stateDb, _logManager);
StateProvider stateProvider = new(trieStore, codeDb, _logManager);
WorldState stateProvider = new(trieStore, codeDb, _logManager);
IBlockhashProvider blockhashProvider = new TestBlockhashProvider();
IStorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, _logManager);
IVirtualMachine virtualMachine = new VirtualMachine(
blockhashProvider,
specProvider,
Expand All @@ -76,11 +75,10 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer)
TransactionProcessor transactionProcessor = new(
specProvider,
stateProvider,
storageProvider,
virtualMachine,
_logManager);

InitializeTestState(test, stateProvider, storageProvider, specProvider);
InitializeTestState(test, stateProvider, specProvider);

BlockHeader header = new(test.PreviousHash, Keccak.OfAnEmptySequenceRlp, test.CurrentCoinbase,
test.CurrentDifficulty, test.CurrentNumber, test.CurrentGasLimit, test.CurrentTimestamp, Array.Empty<byte>());
Expand Down Expand Up @@ -121,34 +119,27 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer)
return testResult;
}

private static void InitializeTestState(GeneralStateTest test, StateProvider stateProvider,
IStorageProvider storageProvider, ISpecProvider specProvider)
private static void InitializeTestState(GeneralStateTest test, WorldState stateProvider, ISpecProvider specProvider)
{
foreach (KeyValuePair<Address, AccountState> accountState in test.Pre)
{
foreach (KeyValuePair<UInt256, byte[]> storageItem in accountState.Value.Storage)
{
storageProvider.Set(new StorageCell(accountState.Key, storageItem.Key),
stateProvider.Set(new StorageCell(accountState.Key, storageItem.Key),
storageItem.Value.WithoutLeadingZeros().ToArray());
}

stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance);
Keccak codeHash = stateProvider.UpdateCode(accountState.Value.Code);
stateProvider.UpdateCodeHash(accountState.Key, codeHash, specProvider.GenesisSpec);
stateProvider.InsertCode(accountState.Key, accountState.Value.Code, specProvider.GenesisSpec);
stateProvider.SetNonce(accountState.Key, accountState.Value.Nonce);
}

storageProvider.Commit();
stateProvider.Commit(specProvider.GenesisSpec);

storageProvider.CommitTrees(0);
stateProvider.CommitTree(0);

storageProvider.Reset();
stateProvider.Reset();
}

private List<string> RunAssertions(GeneralStateTest test, IStateProvider stateProvider)
private List<string> RunAssertions(GeneralStateTest test, IWorldState stateProvider)
{
List<string> differences = new();
if (test.PostHash != stateProvider.StateRoot)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class AccountAbstractionPeerManagerTests
private IBlockTree _blockTree = Substitute.For<IBlockTree>();
private ILogger _logger = Substitute.For<ILogger>();
private ILogFinder _logFinder = Substitute.For<ILogFinder>();
private IStateProvider _stateProvider = Substitute.For<IStateProvider>();
private IWorldState _stateProvider = Substitute.For<IWorldState>();
private ISpecProvider _specProvider = Substitute.For<ISpecProvider>();
private readonly ISigner _signer = Substitute.For<ISigner>();
private readonly string[] _entryPointContractAddress = { "0x8595dd9e0438640b5e1254f9df579ac12a86865f", "0x96cc609c8f5458fb8a7da4d94b678e38ebf3d04e" };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ protected override BlockProcessor CreateBlockProcessor()
NoBlockRewards.Instance,
new BlockProcessor.BlockValidationTransactionsExecutor(TxProcessor, State),
State,
Storage,
ReceiptStorage,
NullWitnessCollector.Instance,
LogManager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,7 @@ public async Task Should_execute_well_formed_op_successfully_if_codehash_not_cha
chain.SendUserOperation(entryPointAddress[0], op);
if (changeCodeHash)
{
Keccak codeHash = chain.State.UpdateCode(Bytes.Concat(chain.State.GetCode(walletAddress[0]!), 0x00));
chain.State.UpdateCodeHash(walletAddress[0]!, codeHash, chain.SpecProvider.GenesisSpec);
chain.State.InsertCode(walletAddress[0]!, Bytes.Concat(chain.State.GetCode(walletAddress[0]!), 0x00), chain.SpecProvider.GenesisSpec);
chain.State.Commit(chain.SpecProvider.GenesisSpec);
chain.State.RecalculateStateRoot();
chain.State.CommitTree(chain.BlockTree.Head!.Number);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class UserOperationPoolTests
private IBlockTree _blockTree = Substitute.For<IBlockTree>();
private IReceiptFinder _receiptFinder = Substitute.For<IReceiptFinder>();
private ILogFinder _logFinder = Substitute.For<ILogFinder>();
private IStateProvider _stateProvider = Substitute.For<IStateProvider>();
private IWorldState _stateProvider = Substitute.For<IWorldState>();
private ISpecProvider _specProvider = Substitute.For<ISpecProvider>();
private readonly ISigner _signer = Substitute.For<ISigner>();
private readonly Keccak _userOperationEventTopic = new("0x33fd4d1f25a5461bea901784a6571de6debc16cd0831932c22c6969cd73ba994");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ public void Should_fail_if_banned_opcode_is_used_when_call_depth_is_more_than_on
.Done;

TestState.CreateAccount(TestItem.AddressC, 1.Ether());
Keccak deployedCodeHash = TestState.UpdateCode(deployedCode);
TestState.UpdateCodeHash(TestItem.AddressC, deployedCodeHash, Spec);
TestState.InsertCode(TestItem.AddressC, deployedCode, Spec);

byte[] code = Prepare.EvmCode
.Call(TestItem.AddressC, 50000)
Expand Down Expand Up @@ -95,16 +94,14 @@ public void Should_allow_external_storage_access_only_with_whitelisted_paymaster
.Done;

TestState.CreateAccount(externalContractAddress, 1.Ether());
Keccak externalContractDeployedCodeHash = TestState.UpdateCode(externalContractCalledByPaymasterCode);
TestState.UpdateCodeHash(externalContractAddress, externalContractDeployedCodeHash, Spec);
TestState.InsertCode(externalContractAddress, externalContractCalledByPaymasterCode, Spec);

byte[] paymasterCode = Prepare.EvmCode
.Call(externalContractAddress, 70000)
.Done;

TestState.CreateAccount(paymasterContractAddress, 1.Ether());
Keccak paymasterDeployedCodeHash = TestState.UpdateCode(paymasterCode);
TestState.UpdateCodeHash(paymasterContractAddress, paymasterDeployedCodeHash, Spec);
TestState.InsertCode(paymasterContractAddress, paymasterCode, Spec);

byte[] code = Prepare.EvmCode
.Op(paymasterValidation ? Instruction.NUMBER : Instruction.BASEFEE) // switch to paymaster validation with NUMBER
Expand Down Expand Up @@ -137,16 +134,14 @@ public void Should_make_sure_external_contract_extcodehashes_stays_same_after_si
.Done;

TestState.CreateAccount(externalContractAddress, 1.Ether());
Keccak externalContractDeployedCodeHash = TestState.UpdateCode(externalContractCalledByPaymasterCode);
TestState.UpdateCodeHash(externalContractAddress, externalContractDeployedCodeHash, Spec);
TestState.InsertCode(externalContractAddress, externalContractCalledByPaymasterCode, Spec);

byte[] paymasterCode = Prepare.EvmCode
.Call(externalContractAddress, 70000)
.Done;

TestState.CreateAccount(paymasterContractAddress, 1.Ether());
Keccak paymasterDeployedCodeHash = TestState.UpdateCode(paymasterCode);
TestState.UpdateCodeHash(paymasterContractAddress, paymasterDeployedCodeHash, Spec);
TestState.InsertCode(paymasterContractAddress, paymasterCode, Spec);

byte[] code = Prepare.EvmCode
.Op(paymasterValidation ? Instruction.NUMBER : Instruction.BASEFEE) // switch to paymaster validation with NUMBER
Expand Down Expand Up @@ -181,8 +176,7 @@ public void Should_not_allow_inner_call_to_run_out_of_gas(long gasLimit, bool sh
.Done;

TestState.CreateAccount(externalContractAddress, 1.Ether());
Keccak externalContractDeployedCodeHash = TestState.UpdateCode(externalContractCalledByPaymasterCode);
TestState.UpdateCodeHash(externalContractAddress, externalContractDeployedCodeHash, Spec);
TestState.InsertCode(externalContractAddress, externalContractCalledByPaymasterCode, Spec);

byte[] paymasterCode = Prepare.EvmCode
.Call(externalContractAddress, gasLimit)
Expand All @@ -194,8 +188,7 @@ public void Should_not_allow_inner_call_to_run_out_of_gas(long gasLimit, bool sh
.Done;

TestState.CreateAccount(paymasterContractAddress, 1.Ether());
Keccak paymasterDeployedCodeHash = TestState.UpdateCode(paymasterCode);
TestState.UpdateCodeHash(paymasterContractAddress, paymasterDeployedCodeHash, Spec);
TestState.InsertCode(paymasterContractAddress, paymasterCode, Spec);

byte[] code = Prepare.EvmCode
.Call(paymasterContractAddress, 100000)
Expand Down Expand Up @@ -232,8 +225,7 @@ public void Should_allow_gas_only_if_followed_by_call(Instruction instruction, b
.Done;

TestState.CreateAccount(TestItem.AddressC, 1.Ether());
Keccak deployedCodeHash = TestState.UpdateCode(deployedCode);
TestState.UpdateCodeHash(TestItem.AddressC, deployedCodeHash, Spec);
TestState.InsertCode(TestItem.AddressC, deployedCode, Spec);

byte[] code = Prepare.EvmCode
.Call(TestItem.AddressC, 70000)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,24 @@ namespace Nethermind.AccountAbstraction.Executor
{
public class AABlockProducerTransactionsExecutor : BlockProcessor.BlockProductionTransactionsExecutor
{
private readonly IStateProvider _stateProvider;
private readonly IStorageProvider _storageProvider;
private readonly IWorldState _stateProvider;
private readonly ISigner _signer;
private readonly Address[] _entryPointAddresses;

public AABlockProducerTransactionsExecutor(
ITransactionProcessor transactionProcessor,
IStateProvider stateProvider,
IStorageProvider storageProvider,
IWorldState stateProvider,
ISpecProvider specProvider,
ILogManager logManager,
ISigner signer,
Address[] entryPointAddresses)
: base(
transactionProcessor,
stateProvider,
storageProvider,
specProvider,
logManager)
{
_stateProvider = stateProvider;
_storageProvider = storageProvider;
_signer = signer;
_entryPointAddresses = entryPointAddresses;
}
Expand Down Expand Up @@ -69,7 +65,6 @@ public override TxReceipt[] ProcessTransactions(
}

_stateProvider.Commit(spec, receiptsTracer);
_storageProvider.Commit(receiptsTracer);

SetTransactions(block, transactionsInBlock);
return receiptsTracer.TxReceipts.ToArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public IBlockProcessor.IBlockTransactionsExecutor Create(ReadOnlyTxProcessingEnv
=> new AABlockProducerTransactionsExecutor(
readOnlyTxProcessingEnv.TransactionProcessor,
readOnlyTxProcessingEnv.StateProvider,
readOnlyTxProcessingEnv.StorageProvider,
_specProvider,
_logManager,
_signer,
Expand Down
3 changes: 1 addition & 2 deletions src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,10 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory
/// <remarks>
/// DO NOT USE OUTSIDE OF PROCESSING BLOCK CONTEXT!
/// </remarks>
IStateProvider? StateProvider { get; set; }
IWorldState? WorldState { get; set; }
IKeyValueStoreWithBatching? MainStateDbWithCache { get; set; }
IReadOnlyStateProvider? ChainHeadStateProvider { get; set; }
IStateReader? StateReader { get; set; }
IStorageProvider? StorageProvider { get; set; }
ITransactionProcessor? TransactionProcessor { get; set; }
ITrieStore? TrieStore { get; set; }
ITxSender? TxSender { get; set; }
Expand Down
Loading