Skip to content
Merged
Show file tree
Hide file tree
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
5 changes: 0 additions & 5 deletions src/Nethermind/Nethermind.Api/BasicApiExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,5 @@ public static T Config<T>(this IBasicApi api) where T : IConfig
{
return api.ConfigProvider.GetConfig<T>();
}

public static T Db<T>(this IBasicApi api, string dbName) where T : class, IDb
{
return api.DbProvider!.GetDb<T>(dbName);
}
}
}
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Api/IApiWithStores.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Nethermind.Api
{
public interface IApiWithStores : IBasicApi
{
IBlobTxStorage? BlobTxStorage { get; set; }
IBlobTxStorage BlobTxStorage { get; }
IBlockTree? BlockTree { get; set; }
IBloomStorage? BloomStorage { get; set; }
IChainLevelInfoRepository? ChainLevelInfoRepository { get; set; }
Expand Down
3 changes: 1 addition & 2 deletions src/Nethermind/Nethermind.Api/IBasicApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ public interface IBasicApi
[SkipServiceCollection]
IConfigProvider ConfigProvider { get; }
ICryptoRandom CryptoRandom { get; }
IDbProvider? DbProvider { get; set; }
IDbFactory? DbFactory { get; set; }
IDbProvider DbProvider { get; }
IEthereumEcdsa EthereumEcdsa { get; }
[SkipServiceCollection]
IJsonSerializer EthereumJsonSerializer { get; }
Expand Down
6 changes: 2 additions & 4 deletions src/Nethermind/Nethermind.Api/NethermindApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Collections.Generic;
using System.IO.Abstractions;
using Autofac;
using Nethermind.Abi;
using Nethermind.Api.Extensions;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Blocks;
Expand Down Expand Up @@ -71,7 +70,7 @@ public IBlockchainBridge CreateBlockchainBridge()
return Context.Resolve<IBlockchainBridgeFactory>().CreateBlockchainBridge();
}

public IBlobTxStorage? BlobTxStorage { get; set; }
public IBlobTxStorage BlobTxStorage => Context.Resolve<IBlobTxStorage>();
public CompositeBlockPreprocessorStep BlockPreprocessor { get; } = new();
public IBlockProcessingQueue? BlockProcessingQueue { get; set; }
public IBlockProducer? BlockProducer { get; set; }
Expand All @@ -82,8 +81,7 @@ public IBlockchainBridge CreateBlockchainBridge()
public IChainLevelInfoRepository? ChainLevelInfoRepository { get; set; }
public IConfigProvider ConfigProvider => _dependencies.ConfigProvider;
public ICryptoRandom CryptoRandom => Context.Resolve<ICryptoRandom>();
public IDbProvider? DbProvider { get; set; }
public IDbFactory? DbFactory { get; set; }
public IDbProvider DbProvider => Context.Resolve<IDbProvider>();
public ISigner? EngineSigner { get; set; }
public ISignerStore? EngineSignerStore { get; set; }
public IEnode? Enode { get; set; }
Expand Down
1 change: 0 additions & 1 deletion src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public void Init_when_not_AuRa_doesnt_trow()
Substitute.For<IProcessExitSource>(),
testNethermindContainer);
AuRaNethermindApi api = new AuRaNethermindApi(apiDependencies);
api.DbProvider = TestMemDbProvider.Init();
Action init = () => auRaPlugin.Init(api);
init.Should().NotThrow();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Threading.Tasks;
using Autofac;
using FluentAssertions;
using Nethermind.Api;
using Nethermind.Blockchain.FullPruning;
using Nethermind.Config;
using Nethermind.Core;
Expand Down Expand Up @@ -75,16 +76,14 @@ protected override async Task<TestBlockchain> Build(Action<ContainerBuilder>? co
return chain;
}

protected override ContainerBuilder ConfigureContainer(ContainerBuilder builder, IConfigProvider configProvider)
{
IDbProvider dbProvider = new DbProvider();
RocksDbFactory rocksDbFactory = new(new DbConfig(), LimboLogs.Instance, TempDirectory.Path);
StandardDbInitializer standardDbInitializer = new(dbProvider, rocksDbFactory, new FileSystem());
standardDbInitializer.InitStandardDbs(true);

return base.ConfigureContainer(builder, configProvider)
.AddSingleton<IDbProvider>(dbProvider);
}
protected override ContainerBuilder ConfigureContainer(ContainerBuilder builder, IConfigProvider configProvider) =>
// Reenable rocksdb
base.ConfigureContainer(builder, configProvider)
.AddSingleton<IDbFactory, RocksDbFactory>()
.Intercept<IInitConfig>((initConfig) =>
{
initConfig.BaseDbPath = TempDirectory.Path;
});

public override void Dispose()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,16 @@
// SPDX-License-Identifier: LGPL-3.0-only

using System.Threading;
using Autofac;
using FluentAssertions;
using Nethermind.Blockchain.BeaconBlockRoot;
using Nethermind.Blockchain.Blocks;
using Nethermind.Blockchain.Receipts;
using Nethermind.Config;
using Nethermind.Api;
using Nethermind.Consensus;
using Nethermind.Consensus.ExecutionRequests;
using Nethermind.Consensus.Processing;
using Nethermind.Consensus.Producers;
using Nethermind.Consensus.Rewards;
using Nethermind.Consensus.Transactions;
using Nethermind.Consensus.Validators;
using Nethermind.Consensus.Withdrawals;
using Nethermind.Core;
using Nethermind.Core.Specs;
using Nethermind.Core.Test;
using Nethermind.Core.Test.Builders;
using Nethermind.Db;
using Nethermind.Evm;
using Nethermind.Evm.TransactionProcessing;
using Nethermind.Logging;
using Nethermind.Specs;
using Nethermind.Evm.State;
using Nethermind.State;
using Nethermind.Core.Test.Modules;
using NUnit.Framework;

namespace Nethermind.Blockchain.Test.Producers;
Expand All @@ -35,70 +21,18 @@ public class DevBlockProducerTests
[Test, MaxTime(Timeout.MaxTestTime)]
public void Test()
{
ISpecProvider specProvider = MainnetSpecProvider.Instance;
DbProvider dbProvider = new();
dbProvider.RegisterDb(DbNames.BlockInfos, new MemDb());
dbProvider.RegisterDb(DbNames.Blocks, new MemDb());
dbProvider.RegisterDb(DbNames.Headers, new MemDb());
dbProvider.RegisterDb(DbNames.State, new MemDb());
dbProvider.RegisterDb(DbNames.Code, new MemDb());
dbProvider.RegisterDb(DbNames.Metadata, new MemDb());
using IContainer container = new ContainerBuilder()
.AddModule(new TestNethermindModule())
.AddSingleton<IBlockValidator>(Always.Valid)
.AddSingleton<IBlockProducerTxSourceFactory, EmptyTxSourceFactory>()
.AddScoped<IBlockProducerFactory, TestBlockProcessingModule.AutoBlockProducerFactory<DevBlockProducer>>()
.Build();

BlockTree blockTree = Build.A.BlockTree()
.WithoutSettingHead
.TestObject;
IBlockTree blockTree = container.Resolve<IBlockTree>();
IManualBlockProductionTrigger trigger = container.Resolve<IManualBlockProductionTrigger>();

IWorldStateManager worldStateManager = TestWorldStateFactory.CreateForTest(dbProvider, LimboLogs.Instance);
IWorldState stateProvider = worldStateManager.GlobalWorldState;
IStateReader stateReader = worldStateManager.GlobalStateReader;
BlockhashProvider blockhashProvider = new(blockTree, specProvider, stateProvider, LimboLogs.Instance);
EthereumCodeInfoRepository codeInfoRepository = new();
VirtualMachine virtualMachine = new(
blockhashProvider,
specProvider,
LimboLogs.Instance);
TransactionProcessor txProcessor = new(
specProvider,
stateProvider,
virtualMachine,
codeInfoRepository,
LimboLogs.Instance);
BlockProcessor blockProcessor = new BlockProcessor(
specProvider,
Always.Valid,
NoBlockRewards.Instance,
new BlockProcessor.BlockValidationTransactionsExecutor(new ExecuteTransactionProcessorAdapter(txProcessor), stateProvider),
stateProvider,
NullReceiptStorage.Instance,
new BeaconBlockRootHandler(txProcessor, stateProvider),
new BlockhashStore(specProvider, stateProvider),
LimboLogs.Instance,
new WithdrawalProcessor(stateProvider, LimboLogs.Instance),
new ExecutionRequestsProcessor(txProcessor));
BlockchainProcessor blockchainProcessor = new(
blockTree,
blockProcessor,
NullRecoveryStep.Instance,
stateReader,
LimboLogs.Instance,
BlockchainProcessor.Options.Default);
BuildBlocksWhenRequested trigger = new();
ManualTimestamper timestamper = new ManualTimestamper();
DevBlockProducer devBlockProducer = new(
EmptyTxSource.Instance,
blockchainProcessor,
stateProvider,
blockTree,
timestamper,
specProvider,
new BlocksConfig(),
LimboLogs.Instance);

StandardBlockProducerRunner blockProducerRunner = new StandardBlockProducerRunner(trigger, blockTree, devBlockProducer);

blockchainProcessor.Start();
blockProducerRunner.Start();
ProducedBlockSuggester _ = new ProducedBlockSuggester(blockTree, blockProducerRunner);
container.Resolve<IMainProcessingContext>().BlockchainProcessor.Start();
container.Resolve<IBlockProducerRunner>().Start();

AutoResetEvent autoResetEvent = new(false);

Expand All @@ -111,4 +45,12 @@ public void Test()
autoResetEvent.WaitOne(1000).Should().BeTrue("1");
blockTree.Head!.Number.Should().Be(1);
}

private class EmptyTxSourceFactory : IBlockProducerTxSourceFactory
{
public ITxSource Create()
{
return EmptyTxSource.Instance;
}
}
}
1 change: 1 addition & 0 deletions src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Nethermind.Core.Specs;
using Nethermind.Core.Test;
using Nethermind.Core.Test.Builders;
using Nethermind.Core.Test.Db;
using Nethermind.Crypto;
using Nethermind.Db;
using Nethermind.Evm;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Autofac;
using FluentAssertions;
using NUnit.Framework;

namespace Nethermind.Core.Test.Container;

public class KeyedMapperRegistrationSourceTests
{
[Test]
public void TestCanMap()
{
using IContainer cont = new ContainerBuilder()
.AddKeyedSingleton<ClassA>("Key", new ClassA("Property1"))
.AddKeyedAdapter<ClassB, ClassA>((a) => new ClassB(a.Property))
.Build();

cont.ResolveKeyed<ClassB>("Key").Property.Should().Be("Property1");
}

private record ClassA(string Property);
private record ClassB(string Property);
}
44 changes: 44 additions & 0 deletions src/Nethermind/Nethermind.Core.Test/Db/TestMemDbProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only


using System;
using System.Threading.Tasks;
using Autofac;
using Nethermind.Api;
using Nethermind.Blockchain.Receipts;
using Nethermind.Blockchain.Synchronization;
using Nethermind.Db;
using Nethermind.Init.Modules;

namespace Nethermind.Core.Test.Db
{
public class TestMemDbProvider
{
public static Task<IDbProvider> InitAsync()
{
return Task.FromResult(Init());
}

public static IDbProvider Init()
{
return new ContainerBuilder()
.AddModule(new DbModule(new InitConfig() { DiagnosticMode = DiagnosticMode.MemDb }, new ReceiptConfig(), new SyncConfig()))
.AddSingleton<IDbProvider, ContainerOwningDbProvider>()
.Build()
.Resolve<IDbProvider>();
}
}

/// <summary>
/// Like <see cref="DbProvider"/>, but also dispose lifetime scope. Useful for existing test to make sure
/// container is disposed properly.
/// </summary>
public class ContainerOwningDbProvider(ILifetimeScope ctx) : DbProvider(ctx), IDisposable
{
public override void Dispose()
{
ctx.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ protected override void Load(ContainerBuilder builder)
initConfig.BackgroundTaskMaxNumber,
logManager))
.AddSingleton<IFileSystem>(new FileSystem())
.AddSingleton<IDbProvider>(new DbProvider())
.AddSingleton<IProcessExitSource>(new ProcessExitSource(default))
.AddSingleton<IJsonSerializer, EthereumJsonSerializer>()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private MainBlockProcessingContext ConfigureMainBlockProcessingContext(ILifetime
return innerScope.Resolve<MainBlockProcessingContext>();
}

private class AutoBlockProducerFactory<T>(ILifetimeScope rootLifetime, IBlockProducerEnvFactory producerEnvFactory) : IBlockProducerFactory where T : IBlockProducer
public class AutoBlockProducerFactory<T>(ILifetimeScope rootLifetime, IBlockProducerEnvFactory producerEnvFactory) : IBlockProducerFactory where T : IBlockProducer
{
public IBlockProducer InitBlockProducer()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ protected override void Load(ContainerBuilder builder)
builder
.AddSingleton<ILogManager>(new TestLogManager(LogLevel.Error)) // Limbologs actually have IsTrace set to true, so actually slow.
.AddSingleton<IDbFactory>((_) => new MemDbFactory())
.AddSingleton<IDbProvider>(TestMemDbProvider.Init())
// These two dont use db provider
.AddKeyedSingleton<IFullDb>(DbNames.PeersDb, (_) => new MemDb())
.AddKeyedSingleton<IFullDb>(DbNames.DiscoveryNodes, (_) => new MemDb())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Consensus.Validators;
using Nethermind.Core.Test.Db;
using Nethermind.Db;
using Nethermind.Logging;
using Nethermind.Evm.State;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Collections.Generic;
using System.Linq;
using Autofac;
using Autofac.Core;
using Autofac.Core.Activators.Delegate;
using Autofac.Core.Lifetime;
using Autofac.Core.Registration;

namespace Nethermind.Core.Container;

/// <summary>
/// Utility that map between two type that act on keyed service.
/// </summary>
/// <param name="mapper"></param>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTo"></typeparam>
public class KeyedMapperRegistrationSource<TFrom, TTo>(Func<TFrom, TTo> mapper) : IRegistrationSource where TFrom : notnull
{
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<ServiceRegistration>> registrationAccessor)
{
if (service is not KeyedService keyedService || keyedService.ServiceType != typeof(TTo))
{
// Not a keyed service
return Enumerable.Empty<IComponentRegistration>();
}

ComponentRegistration registration = new ComponentRegistration(
Guid.NewGuid(),
new DelegateActivator(keyedService.ServiceType, (c, p) =>
{
TFrom from = c.ResolveKeyed<TFrom>(keyedService.ServiceKey);
return mapper(from)!;
}),
new RootScopeLifetime(),
InstanceSharing.Shared,
InstanceOwnership.OwnedByLifetimeScope,
new[] { service },
new Dictionary<string, object?>());

return [registration];
}

public bool IsAdapterForIndividualComponents => true;
}
5 changes: 5 additions & 0 deletions src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,11 @@ public static IRegistrationBuilder<T, TAct, TStyle> Fixed<T, TAct, TStyle>(this
reg.RegistrationData.Options |= RegistrationOptions.Fixed;
return reg;
}

public static ContainerBuilder AddKeyedAdapter<TTo, TFrom>(this ContainerBuilder builder, Func<TFrom, TTo> mapper) where TFrom : notnull
{
return builder.AddSource(new KeyedMapperRegistrationSource<TFrom, TTo>(mapper));
}
}

/// <summary>
Expand Down
Loading