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(verkle): world state for transition #7689

Draft
wants to merge 1 commit into
base: verkle/mainnet
Choose a base branch
from
Draft
Changes from all 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
136 changes: 125 additions & 11 deletions src/Nethermind/Nethermind.State/WorldState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,17 @@ public class WorldState : IWorldState
internal readonly PersistentStorageProvider _persistentStorageProvider;
private readonly TransientStorageProvider _transientStorageProvider;
private readonly ITrieStore _trieStore;
public StateType StateType => StateType.Merkle;
private long _currentBlockNumber;
private IReleaseSpec _currentSpec;
private bool _isInitialized;
public StateType StateType
Copy link
Author

@marcuspang marcuspang Oct 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these changes be higher up in the abstraction? Like world state manager

{
get
{
return _currentBlockNumber >= VerkleTransitionBlock ? StateType.Verkle : StateType.Merkle;
}
}

public Hash256 StateRoot
{
get => _stateProvider.StateRoot;
Expand All @@ -39,7 +49,12 @@ public Hash256 StateRoot
}
}

public WorldState(ITrieStore? trieStore, IKeyValueStore? codeDb, ILogManager? logManager)
// TODO: Should this be in release spec?
private const long VerkleTransitionBlock = 24_000_000;

// TODO: store verkle state tree in WorldState or store ref to VerkleWorldState?
public WorldState(ITrieStore trieStore, IKeyValueStore? codeDb, ILogManager? logManager)
: this(trieStore, codeDb, logManager, null, null)
{
_trieStore = trieStore;
_stateProvider = new StateProvider(trieStore.GetTrieStore(null), codeDb, logManager);
Expand All @@ -54,165 +69,260 @@ internal WorldState(ITrieStore? trieStore, IKeyValueStore? codeDb, ILogManager?
_transientStorageProvider = new TransientStorageProvider(logManager);
}

public void InitializeForBlock(long blockNumber, IReleaseSpec spec)
{
_currentBlockNumber = blockNumber;
_currentSpec = spec;
_isInitialized = true;
}

private void EnsureInitialized()
{
if (!_isInitialized)
{
throw new InvalidOperationException("WorldState must be initialized with InitializeForBlock before use");
}
}

public Account GetAccount(Address address)
{
EnsureInitialized();
return _stateProvider.GetAccount(address);
}

bool IAccountStateProvider.TryGetAccount(Address address, out AccountStruct account)
{
EnsureInitialized();
account = _stateProvider.GetAccount(address).ToStruct();
return !account.IsTotallyEmpty;
}

public bool IsContract(Address address)
{
EnsureInitialized();
return _stateProvider.IsContract(address);
}

public byte[] GetOriginal(in StorageCell storageCell)
{
EnsureInitialized();
return _persistentStorageProvider.GetOriginal(storageCell);
}
public ReadOnlySpan<byte> Get(in StorageCell storageCell)
{
EnsureInitialized();
return _persistentStorageProvider.Get(storageCell);
}
public void Set(in StorageCell storageCell, byte[] newValue)
{
EnsureInitialized();
_persistentStorageProvider.Set(storageCell, newValue);
}
public ReadOnlySpan<byte> GetTransientState(in StorageCell storageCell)
{
EnsureInitialized();
return _transientStorageProvider.Get(storageCell);
}
public void SetTransientState(in StorageCell storageCell, byte[] newValue)
{
EnsureInitialized();
_transientStorageProvider.Set(storageCell, newValue);
}
public void Reset()
{
EnsureInitialized();
_stateProvider.Reset();
_persistentStorageProvider.Reset();
_transientStorageProvider.Reset();
}

public void ClearStorage(Address address)
{
EnsureInitialized();
_persistentStorageProvider.ClearStorage(address);
_transientStorageProvider.ClearStorage(address);
}
public void RecalculateStateRoot()
{
EnsureInitialized();
_stateProvider.RecalculateStateRoot();
}
public void DeleteAccount(Address address)
{
EnsureInitialized();
_stateProvider.DeleteAccount(address);
}
public void CreateAccount(Address address, in UInt256 balance, in UInt256 nonce = default)
{
EnsureInitialized();
_stateProvider.CreateAccount(address, balance, nonce);
}

public void InsertCode(Address address, Hash256 codeHash, ReadOnlyMemory<byte> code, IReleaseSpec spec, bool isGenesis = false)
{
EnsureInitialized();
_stateProvider.InsertCode(address, codeHash, code, spec, isGenesis);
}

public void InsertCode(Address address, Hash256 codeHash, ReadOnlyMemory<byte> code, bool isGenesis = false)
{
EnsureInitialized();
_stateProvider.InsertCode(address, codeHash, code, _currentSpec, isGenesis);
}

public void AddToBalance(Address address, in UInt256 balanceChange, IReleaseSpec spec)
{
EnsureInitialized();
_stateProvider.AddToBalance(address, balanceChange, spec);
}
public void AddToBalance(Address address, in UInt256 balanceChange)
{
EnsureInitialized();
_stateProvider.AddToBalance(address, balanceChange, _currentSpec);
}
public void AddToBalanceAndCreateIfNotExists(Address address, in UInt256 balanceChange, IReleaseSpec spec)
{
EnsureInitialized();
_stateProvider.AddToBalanceAndCreateIfNotExists(address, balanceChange, spec);
}
public void AddToBalanceAndCreateIfNotExists(Address address, in UInt256 balanceChange)
{
EnsureInitialized();
_stateProvider.AddToBalanceAndCreateIfNotExists(address, balanceChange, _currentSpec);
}
public void SubtractFromBalance(Address address, in UInt256 balanceChange, IReleaseSpec spec)
{
EnsureInitialized();
_stateProvider.SubtractFromBalance(address, balanceChange, spec);
}
public void SubtractFromBalance(Address address, in UInt256 balanceChange)
{
EnsureInitialized();
_stateProvider.SubtractFromBalance(address, balanceChange, _currentSpec);
}
public void UpdateStorageRoot(Address address, Hash256 storageRoot)
{
EnsureInitialized();
_stateProvider.UpdateStorageRoot(address, storageRoot);
}
public void IncrementNonce(Address address)
{
EnsureInitialized();
_stateProvider.IncrementNonce(address);
}
public void DecrementNonce(Address address)
{
EnsureInitialized();
_stateProvider.DecrementNonce(address);
}

public void CommitTree(long blockNumber)
{
EnsureInitialized();
_persistentStorageProvider.CommitTrees(blockNumber);
_stateProvider.CommitTree(blockNumber);
_persistentStorageProvider.StateRoot = _stateProvider.StateRoot;
}

public void TouchCode(in ValueHash256 codeHash)
{
EnsureInitialized();
_stateProvider.TouchCode(codeHash);
}

public UInt256 GetNonce(Address address) => _stateProvider.GetNonce(address);
public UInt256 GetNonce(Address address)
{
EnsureInitialized();
return _stateProvider.GetNonce(address);
}

public UInt256 GetBalance(Address address) => _stateProvider.GetBalance(address);
public UInt256 GetBalance(Address address)
{
EnsureInitialized();
return _stateProvider.GetBalance(address);
}

public ValueHash256 GetStorageRoot(Address address) => _stateProvider.GetStorageRoot(address);
public ValueHash256 GetStorageRoot(Address address)
{
EnsureInitialized();
return _stateProvider.GetStorageRoot(address);
}

public byte[] GetCode(Address address) => _stateProvider.GetCode(address);
public byte[] GetCode(Address address)
{
EnsureInitialized();
return _stateProvider.GetCode(address);
}

public byte[] GetCode(Hash256 codeHash) => _stateProvider.GetCode(codeHash);
public byte[] GetCode(Hash256 codeHash)
{
EnsureInitialized();
return _stateProvider.GetCode(codeHash);
}

public byte[] GetCode(ValueHash256 codeHash) => _stateProvider.GetCode(codeHash);
public byte[] GetCode(ValueHash256 codeHash)
{
EnsureInitialized();
return _stateProvider.GetCode(codeHash);
}

public Hash256 GetCodeHash(Address address) => _stateProvider.GetCodeHash(address);
public Hash256 GetCodeHash(Address address)
{
EnsureInitialized();
return _stateProvider.GetCodeHash(address);
}

ValueHash256 IAccountStateProvider.GetCodeHash(Address address)
{
EnsureInitialized();
return _stateProvider.GetCodeHash(address);
}

public void Accept(ITreeVisitor visitor, Hash256 stateRoot, VisitingOptions? visitingOptions = null)
{
EnsureInitialized();
_stateProvider.Accept(visitor, stateRoot, visitingOptions);
}
public bool AccountExists(Address address)
{
EnsureInitialized();
return _stateProvider.AccountExists(address);
}
public bool IsDeadAccount(Address address)
{
EnsureInitialized();
return _stateProvider.IsDeadAccount(address);
}
public bool IsEmptyAccount(Address address)
{
EnsureInitialized();
return _stateProvider.IsEmptyAccount(address);
}

public bool HasStateForRoot(Hash256 stateRoot)
{
EnsureInitialized();
return _trieStore.HasRoot(stateRoot);
}

public void Commit(IReleaseSpec releaseSpec, bool isGenesis = false)
{
_persistentStorageProvider.Commit();
_transientStorageProvider.Commit();
EnsureInitialized();
_persistentStorageProvider.Commit(commitStorageRoots);
_transientStorageProvider.Commit(commitStorageRoots);
_stateProvider.Commit(releaseSpec, isGenesis);
}
public void Commit(IReleaseSpec releaseSpec, IWorldStateTracer tracer, bool isGenesis = false)
{
EnsureInitialized();
_persistentStorageProvider.Commit(tracer);
_transientStorageProvider.Commit(tracer);
_stateProvider.Commit(releaseSpec, tracer, isGenesis);
}

public Snapshot TakeSnapshot(bool newTransactionStart = false)
{
EnsureInitialized();
int persistentSnapshot = _persistentStorageProvider.TakeSnapshot(newTransactionStart);
int transientSnapshot = _transientStorageProvider.TakeSnapshot(newTransactionStart);
Snapshot.Storage storageSnapshot = new Snapshot.Storage(persistentSnapshot, transientSnapshot);
Expand All @@ -222,23 +332,27 @@ public Snapshot TakeSnapshot(bool newTransactionStart = false)

public void Restore(Snapshot snapshot)
{
EnsureInitialized();
_persistentStorageProvider.Restore(snapshot.StorageSnapshot.PersistentStorageSnapshot);
_transientStorageProvider.Restore(snapshot.StorageSnapshot.TransientStorageSnapshot);
_stateProvider.Restore(snapshot.StateSnapshot);
}

internal void Restore(int state, int persistantStorage, int transientStorage)
{
EnsureInitialized();
Restore(new Snapshot(state, new Snapshot.Storage(persistantStorage, transientStorage)));
}

internal void SetNonce(Address address, in UInt256 nonce)
{
EnsureInitialized();
_stateProvider.SetNonce(address, nonce);
}

public void CreateAccountIfNotExists(Address address, in UInt256 balance, in UInt256 nonce = default)
{
EnsureInitialized();
_stateProvider.CreateAccountIfNotExists(address, balance, nonce);
}

Expand Down