Skip to content

Commit

Permalink
Refactor/state cleanup (#6260)
Browse files Browse the repository at this point in the history
* Separate statedb initialization from blockchain initialization

* Minor cleanup

* World state factory

* Don't take db provider or trie store

* Use state reader instead of trie store for full state finder

* Unify and use property

* Boundary watcher

* Dont need this anymore

* Minor comment

* Reducing change

* Missed a setter

* Some tests

* Fix build

* Fix build

* Addressing comment

* Minor comment adjustment

* Fix startup block tree fixer missed
  • Loading branch information
asdacap committed Dec 8, 2023
1 parent 9bb51a0 commit 0e0e35e
Show file tree
Hide file tree
Showing 67 changed files with 669 additions and 464 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,8 @@ public TestAccountAbstractionRpcBlockchain(UInt256? initialBaseFeePerGas)
SpecProvider.UpdateMergeTransitionInfo(1, 0);

BlockProducerEnvFactory blockProducerEnvFactory = new BlockProducerEnvFactory(
DbProvider,
WorldStateManager,
BlockTree,
ReadOnlyTrieStore,
SpecProvider,
BlockValidator,
NoBlockRewards.Instance,
Expand Down Expand Up @@ -212,7 +211,7 @@ protected override BlockProcessor CreateBlockProcessor()
UserOperationSimulator[entryPoint] = new(
UserOperationTxBuilder[entryPoint],
ReadOnlyState,
new ReadOnlyTxProcessingEnvFactory(DbProvider, ReadOnlyTrieStore, BlockTree, SpecProvider, LogManager),
new ReadOnlyTxProcessingEnvFactory(WorldStateManager, BlockTree, SpecProvider, LogManager),
EntryPointContractAbi,
entryPoint!,
WhitelistedPayamsters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ private UserOperationSimulator UserOperationSimulator(Address entryPoint)
var (getFromApi, _) = _nethermindApi!.ForProducer;

ReadOnlyTxProcessingEnvFactory readOnlyTxProcessingEnvFactory = new(
getFromApi.DbProvider,
getFromApi.ReadOnlyTrieStore,
getFromApi.WorldStateManager!,
getFromApi.BlockTree,
getFromApi.SpecProvider,
getFromApi.LogManager);
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 @@ -43,7 +43,6 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory
IUnclesValidator? UnclesValidator { get; set; }
IHeaderValidator? HeaderValidator { get; set; }
IManualBlockProductionTrigger ManualBlockProductionTrigger { get; }
IReadOnlyTrieStore? ReadOnlyTrieStore { get; set; }
IRewardCalculatorSource? RewardCalculatorSource { get; set; }
/// <summary>
/// PoS switcher for The Merge
Expand All @@ -59,9 +58,9 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory
/// DO NOT USE OUTSIDE OF PROCESSING BLOCK CONTEXT!
/// </remarks>
IWorldState? WorldState { get; set; }
IKeyValueStoreWithBatching? MainStateDbWithCache { get; set; }
IReadOnlyStateProvider? ChainHeadStateProvider { get; set; }
IStateReader? StateReader { get; set; }
IWorldStateManager? WorldStateManager { get; set; }
ITransactionProcessor? TransactionProcessor { get; set; }
ITrieStore? TrieStore { get; set; }
ITxSender? TxSender { get; set; }
Expand Down
8 changes: 2 additions & 6 deletions src/Nethermind/Nethermind.Api/NethermindApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,13 @@ public NethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSeriali
DisposeStack.Push(CryptoRandom);
}

private IReadOnlyDbProvider? _readOnlyDbProvider;

public IBlockchainBridge CreateBlockchainBridge()
{
ReadOnlyBlockTree readOnlyTree = BlockTree!.AsReadOnly();
LazyInitializer.EnsureInitialized(ref _readOnlyDbProvider, () => new ReadOnlyDbProvider(DbProvider, false));

// TODO: reuse the same trie cache here
ReadOnlyTxProcessingEnv readOnlyTxProcessingEnv = new(
_readOnlyDbProvider,
ReadOnlyTrieStore,
WorldStateManager!,
readOnlyTree,
SpecProvider,
LogManager);
Expand Down Expand Up @@ -191,13 +187,13 @@ public ISealEngine SealEngine
public ISyncServer? SyncServer { get; set; }
public IWorldState? WorldState { get; set; }
public IReadOnlyStateProvider? ChainHeadStateProvider { get; set; }
public IWorldStateManager? WorldStateManager { get; set; }
public IStateReader? StateReader { get; set; }
public IStaticNodesManager? StaticNodesManager { get; set; }
public ITimestamper Timestamper { get; } = Core.Timestamper.Default;
public ITimerFactory TimerFactory { get; } = Core.Timers.TimerFactory.Default;
public ITransactionProcessor? TransactionProcessor { get; set; }
public ITrieStore? TrieStore { get; set; }
public IReadOnlyTrieStore? ReadOnlyTrieStore { get; set; }
public ITxSender? TxSender { get; set; }
public INonceManager? NonceManager { get; set; }
public ITxPool? TxPool { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ protected override BlockProcessor CreateBlockProcessor()
KeyValuePair<long, Address> blockGasLimitContractTransition = ChainSpec.AuRa.BlockGasLimitContractTransitions.First();
BlockGasLimitContract gasLimitContract = new(AbiEncoder.Instance, blockGasLimitContractTransition.Value, blockGasLimitContractTransition.Key,
new ReadOnlyTxProcessingEnv(
DbProvider,
new TrieStore(DbProvider.StateDb, LimboLogs.Instance).AsReadOnly(),
WorldStateManager,
BlockTree, SpecProvider, LimboLogs.Instance));

GasLimitOverrideCache = new AuRaContractGasLimitOverride.Cache();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ protected override TxPoolTxSource CreateTxPoolTxSource()
TxPoolTxSource txPoolTxSource = base.CreateTxPoolTxSource();

TxPriorityContract = new TxPriorityContract(AbiEncoder.Instance, TestItem.AddressA,
new ReadOnlyTxProcessingEnv(DbProvider, TrieStore.AsReadOnly(), BlockTree, SpecProvider, LimboLogs.Instance));
new ReadOnlyTxProcessingEnv(WorldStateManager, BlockTree, SpecProvider, LimboLogs.Instance));

Priorities = new DictionaryContractDataStore<TxPriorityContract.Destination>(
new TxPriorityContract.DestinationSortedListContractDataStoreCollection(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,8 @@ protected override BlockProcessor CreateBlockProcessor()
{
AbiEncoder abiEncoder = AbiEncoder.Instance;
ReadOnlyTransactionProcessorSource = new ReadOnlyTxProcessingEnv(
DbProvider,
new TrieStore(DbProvider.StateDb, LimboLogs.Instance).AsReadOnly(),
BlockTree, SpecProvider,
WorldStateManager,
BlockTree, SpecProvider,
LimboLogs.Instance);
RegisterContract = new RegisterContract(abiEncoder, ChainSpec.Parameters.Registrar, ReadOnlyTransactionProcessorSource);
CertifierContract = new CertifierContract(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,14 +276,13 @@ protected override BlockProcessor CreateBlockProcessor()

IReadOnlyTrieStore trieStore = new TrieStore(DbProvider.StateDb, LimboLogs.Instance).AsReadOnly();
IReadOnlyTxProcessorSource txProcessorSource = new ReadOnlyTxProcessingEnv(
DbProvider,
trieStore,
WorldStateManager,
BlockTree,
SpecProvider,
LimboLogs.Instance);

VersionedTransactionPermissionContract transactionPermissionContract = new(AbiEncoder.Instance, _contractAddress, 1,
new ReadOnlyTxProcessingEnv(DbProvider, trieStore, BlockTree, SpecProvider, LimboLogs.Instance), TransactionPermissionContractVersions, LimboLogs.Instance, SpecProvider);
new ReadOnlyTxProcessingEnv(WorldStateManager, BlockTree, SpecProvider, LimboLogs.Instance), TransactionPermissionContractVersions, LimboLogs.Instance, SpecProvider);

TxPermissionFilterCache = new PermissionBasedTxFilter.Cache();
PermissionBasedTxFilter = new PermissionBasedTxFilter(transactionPermissionContract, TxPermissionFilterCache, LimboLogs.Instance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
using Nethermind.State.Repositories;
using Nethermind.Db.Blooms;
using Nethermind.JsonRpc.Test.Modules;
using Nethermind.State;
using NSubstitute;
using NUnit.Framework;

namespace Nethermind.Blockchain.Test.Visitors
Expand Down Expand Up @@ -72,7 +74,7 @@ public async Task Deletes_everything_after_the_missing_level()
.WithDatabaseFrom(builder)
.TestObject;

StartupBlockTreeFixer fixer = new(new SyncConfig(), tree, new MemDb(), LimboNoErrorLogger.Instance);
StartupBlockTreeFixer fixer = new(new SyncConfig(), tree, Substitute.For<IStateReader>(), LimboNoErrorLogger.Instance);
await tree.Accept(fixer, CancellationToken.None);

Assert.Null(blockInfosDb.Get(3), "level 3");
Expand Down Expand Up @@ -110,7 +112,7 @@ public async Task Suggesting_blocks_works_correctly_after_processor_restart(int
testRpc.BlockchainProcessor = newBlockchainProcessor;

// fixing after restart
StartupBlockTreeFixer fixer = new(new SyncConfig(), tree, testRpc.DbProvider.StateDb, LimboNoErrorLogger.Instance, 5);
StartupBlockTreeFixer fixer = new(new SyncConfig(), tree, testRpc.StateReader, LimboNoErrorLogger.Instance, 5);
await tree.Accept(fixer, CancellationToken.None);

// waiting for N new heads
Expand Down Expand Up @@ -144,8 +146,7 @@ public async Task Fixer_should_not_suggest_block_without_state(int suggestedBloc
testRpc.BlockchainProcessor = newBlockchainProcessor;

// we create a new empty db for stateDb so we shouldn't suggest new blocks
MemDb stateDb = new();
IBlockTreeVisitor fixer = new StartupBlockTreeFixer(new SyncConfig(), tree, stateDb, LimboNoErrorLogger.Instance, 5);
IBlockTreeVisitor fixer = new StartupBlockTreeFixer(new SyncConfig(), tree, Substitute.For<IStateReader>(), LimboNoErrorLogger.Instance, 5);
BlockVisitOutcome result = await fixer.VisitBlock(tree.Head!, CancellationToken.None);

Assert.That(result, Is.EqualTo(BlockVisitOutcome.None));
Expand All @@ -166,7 +167,7 @@ public async Task Fixer_should_not_suggest_block_with_null_block()
newBlockchainProcessor.Start();
testRpc.BlockchainProcessor = newBlockchainProcessor;

IBlockTreeVisitor fixer = new StartupBlockTreeFixer(new SyncConfig(), tree, testRpc.DbProvider.StateDb, LimboNoErrorLogger.Instance, 5);
IBlockTreeVisitor fixer = new StartupBlockTreeFixer(new SyncConfig(), tree, testRpc.StateReader, LimboNoErrorLogger.Instance, 5);
BlockVisitOutcome result = await fixer.VisitBlock(null!, CancellationToken.None);

Assert.That(result, Is.EqualTo(BlockVisitOutcome.None));
Expand Down Expand Up @@ -213,7 +214,7 @@ public async Task When_head_block_is_followed_by_a_block_bodies_gap_it_should_de

tree.UpdateMainChain(block2);

StartupBlockTreeFixer fixer = new(new SyncConfig(), tree, new MemDb(), LimboNoErrorLogger.Instance);
StartupBlockTreeFixer fixer = new(new SyncConfig(), tree, Substitute.For<IStateReader>(), LimboNoErrorLogger.Instance);
await tree.Accept(fixer, CancellationToken.None);

Assert.Null(blockInfosDb.Get(3), "level 3");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@
using System;
using Nethermind.Blockchain.Find;
using Nethermind.Logging;
using Nethermind.State;
using Nethermind.Trie.Pruning;

namespace Nethermind.Blockchain
{
/// <summary>
/// Watches state persistence in <see cref="ITrieStore"/> with <see cref="ITrieStore.ReorgBoundaryReached"/> and saves it in <see cref="IBlockFinder.BestPersistedState"/>.
/// Watches state persistence in <see cref="IWorldStateManager"/> with <see cref="IWorldStateManager.ReorgBoundaryReached"/> and saves it in <see cref="IBlockFinder.BestPersistedState"/>.
/// </summary>
public class TrieStoreBoundaryWatcher : IDisposable
{
private readonly ITrieStore _trieStore;
private readonly IWorldStateManager _trieStore;
private readonly IBlockTree _blockTree;
private readonly ILogger _logger;

public TrieStoreBoundaryWatcher(ITrieStore trieStore, IBlockTree blockTree, ILogManager logManager)
public TrieStoreBoundaryWatcher(IWorldStateManager trieStore, IBlockTree blockTree, ILogManager logManager)
{
_trieStore = trieStore;
_blockTree = blockTree;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
using Nethermind.Core.Crypto;
using Nethermind.Db;
using Nethermind.Logging;
using Nethermind.State;

namespace Nethermind.Blockchain.Visitors
{
public class StartupBlockTreeFixer : IBlockTreeVisitor
{
public const int DefaultBatchSize = 4000;
private readonly IBlockTree _blockTree;
private readonly IDb _stateDb;
private readonly IStateReader _stateReader;
private readonly ILogger _logger;
private long _startNumber;
private long _blocksToLoad;
Expand All @@ -42,12 +43,12 @@ public class StartupBlockTreeFixer : IBlockTreeVisitor
public StartupBlockTreeFixer(
ISyncConfig syncConfig,
IBlockTree blockTree,
IDb stateDb,
IStateReader stateReader,
ILogger logger,
long batchSize = DefaultBatchSize)
{
_blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
_stateDb = stateDb;
_stateReader = stateReader;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));

_batchSize = batchSize;
Expand Down Expand Up @@ -242,7 +243,7 @@ private bool CanSuggestBlocks(Block block)
{
BlockHeader? parentHeader = _blockTree.FindParentHeader(block.Header, BlockTreeLookupOptions.TotalDifficultyNotNeeded);
if (parentHeader is null || parentHeader.StateRoot is null ||
_stateDb.Get(parentHeader.StateRoot) is null)
!_stateReader.HasStateForRoot(parentHeader.StateRoot))
return false;
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using Nethermind.Evm.TransactionProcessing;
using Nethermind.Init.Steps;
using Nethermind.Logging;
using Nethermind.State;
using Nethermind.TxPool;
using Nethermind.TxPool.Comparison;

Expand Down Expand Up @@ -53,7 +54,6 @@ protected override BlockProcessor CreateBlockProcessor()
if (_api.RewardCalculatorSource is null) throw new StepDependencyException(nameof(_api.RewardCalculatorSource));
if (_api.TransactionProcessor is null) throw new StepDependencyException(nameof(_api.TransactionProcessor));
if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider));
if (_api.WorldState is null) throw new StepDependencyException(nameof(_api.WorldState));
if (_api.TxPool is null) throw new StepDependencyException(nameof(_api.TxPool));
if (_api.ReceiptStorage is null) throw new StepDependencyException(nameof(_api.ReceiptStorage));
if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree));
Expand Down Expand Up @@ -87,12 +87,14 @@ protected override BlockProcessor CreateBlockProcessor()

protected virtual BlockProcessor NewBlockProcessor(AuRaNethermindApi api, ITxFilter txFilter, ContractRewriter contractRewriter)
{
IWorldState worldState = _api.WorldState!;

return new AuRaBlockProcessor(
_api.SpecProvider,
_api.BlockValidator,
_api.RewardCalculatorSource.Get(_api.TransactionProcessor),
new BlockProcessor.BlockValidationTransactionsExecutor(_api.TransactionProcessor, _api.WorldState),
_api.WorldState,
new BlockProcessor.BlockValidationTransactionsExecutor(_api.TransactionProcessor, worldState),
worldState,
_api.ReceiptStorage,
_api.LogManager,
_api.BlockTree,
Expand All @@ -104,7 +106,7 @@ protected virtual BlockProcessor NewBlockProcessor(AuRaNethermindApi api, ITxFil
}

protected ReadOnlyTxProcessingEnv CreateReadOnlyTransactionProcessorSource() =>
new ReadOnlyTxProcessingEnv(_api.DbProvider, _api.ReadOnlyTrieStore, _api.BlockTree, _api.SpecProvider, _api.LogManager);
new ReadOnlyTxProcessingEnv(_api.WorldStateManager!, _api.BlockTree, _api.SpecProvider, _api.LogManager);

protected override IHealthHintService CreateHealthHintService() =>
new AuraHealthHintService(_auRaStepCalculator, _api.ValidatorStore);
Expand All @@ -129,8 +131,10 @@ private IAuRaValidator CreateAuRaValidator(IBlockProcessor processor, IReadOnlyT
_api.LogManager,
chainSpecAuRa.TwoThirdsMajorityTransition);

IWorldState worldState = _api.WorldState!;

IAuRaValidator validator = new AuRaValidatorFactory(_api.AbiEncoder,
_api.WorldState,
worldState,
_api.TransactionProcessor,
_api.BlockTree,
readOnlyTxProcessorSource,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Nethermind.Init.Steps;
using Nethermind.Int256;
using Nethermind.Specs.Forks;
using Nethermind.State;

namespace Nethermind.Consensus.AuRa.InitializationSteps
{
Expand All @@ -18,23 +19,21 @@ public LoadGenesisBlockAuRa(AuRaNethermindApi api) : base(api)
_api = api;
}

protected override void Load()
protected override void Load(IWorldState worldState)
{
CreateSystemAccounts();
base.Load();
CreateSystemAccounts(worldState);
base.Load(worldState);
}

private void CreateSystemAccounts()
private void CreateSystemAccounts(IWorldState worldState)
{
if (_api.ChainSpec is null) throw new StepDependencyException(nameof(_api.ChainSpec));

bool hasConstructorAllocation = _api.ChainSpec.Allocations.Values.Any(a => a.Constructor is not null);
if (hasConstructorAllocation)
{
if (_api.WorldState is null) throw new StepDependencyException(nameof(_api.WorldState));

_api.WorldState.CreateAccount(Address.Zero, UInt256.Zero);
_api.WorldState.Commit(Homestead.Instance);
worldState.CreateAccount(Address.Zero, UInt256.Zero);
worldState.Commit(Homestead.Instance);
}
}
}
Expand Down

0 comments on commit 0e0e35e

Please sign in to comment.