Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 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
2 changes: 1 addition & 1 deletion src/Nethermind
Submodule Nethermind updated 253 files
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Nethermind.Arbitrum.Test.Precompiles;
using Nethermind.Blockchain.Tracing;
using Nethermind.Consensus.Processing;
using Nethermind.Consensus.Producers;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Test.Builders;
Expand Down Expand Up @@ -89,6 +90,9 @@ public void ProcessTransactions_SubmitRetryable_CreatesRetryTx()
IWorldState worldState = chain.WorldStateManager.GlobalWorldState;
using var dispose = worldState.BeginScope(chain.BlockTree.Head!.Header);

BlockToProduce blockToProduce = new BlockToProduce(newBlock.Header, newBlock.Transactions, [],
null);

var arbosState = ArbosState.OpenArbosState(worldState, new SystemBurner(),
LimboLogs.Instance.GetLogger("arbosState"));
newBlock.Header.BaseFeePerGas = arbosState.L2PricingState.BaseFeeWeiStorage.Get();
Expand All @@ -101,9 +105,9 @@ public void ProcessTransactions_SubmitRetryable_CreatesRetryTx()
};

var blockTracer = new BlockReceiptsTracer();
blockTracer.StartNewBlockTrace(newBlock);
blockTracer.StartNewBlockTrace(blockToProduce);

chain.BlockProcessor.ProcessOne(newBlock, ProcessingOptions.ProducingBlock, blockTracer, chain.SpecProvider.GenesisSpec);
chain.BlockProcessor.ProcessOne(blockToProduce, ProcessingOptions.ProducingBlock, blockTracer, chain.SpecProvider.GenesisSpec);

blockTracer.EndBlockTrace();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,18 @@ 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);
UInt256 gasPrice = UInt256.Zero;
using (chain.WorldStateManager.GlobalWorldState.BeginScope(chain.BlockTree.Head!.Header))
{
ArbosState arbosState = ArbosState.OpenArbosState(chain.WorldStateManager.GlobalWorldState,
new SystemBurner(), LimboNoErrorLogger.Instance);
gasPrice = arbosState.L2PricingState.BaseFeeWeiStorage.Get();
}

var ethereumEcdsa = new EthereumEcdsa(chain.SpecProvider.ChainId);
Transaction transaction = Build.A.Transaction
.WithGasLimit(GasCostOf.Transaction)
.WithGasPrice(arbosState.L2PricingState.BaseFeeWeiStorage.Get())
.WithGasPrice(gasPrice)
.WithNonce(0)
.WithValue(1.Ether())
.To(TestItem.AddressB)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void ChainSpecProvider_SeveralLifetimeScopes_OneSpecProviderPerScope()
chainSpec.EngineChainSpecParametersProvider.GetChainSpecParameters<ArbitrumChainSpecEngineParameters>();
engineParameters.InitialArbOSVersion = 10;

ArbitrumModule module = new(chainSpec);
ArbitrumModule module = new(chainSpec, new BlocksConfig());

ContainerBuilder containerBuilder = new();
containerBuilder.AddModule(new TestNethermindModule(new ConfigProvider(), chainSpec));
Expand Down Expand Up @@ -84,7 +84,7 @@ public void ChainSpecProvider_WhenArbOSVersionChanges_ReturnsCorrectSpec()
{
ChainSpec chainSpec = FullChainSimulationChainSpecProvider.Create();

ArbitrumModule module = new(chainSpec);
ArbitrumModule module = new(chainSpec, new BlocksConfig());

ContainerBuilder containerBuilder = new();
//explicitly state we won't use TestSpecProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ protected virtual ArbitrumTestBlockchainBase Build(Action<ContainerBuilder>? con
JsonSerializer = new EthereumJsonSerializer();

IConfigProvider configProvider = new ConfigProvider(arbitrumConfig);
//it's a mess... but we need to ensure that both configs are in sync
Comment thread
damian-orzechowski marked this conversation as resolved.
configProvider.GetConfig<IBlocksConfig>().BuildBlocksOnMainState = true;
this.BlocksConfig.BuildBlocksOnMainState = true;

ContainerBuilder builder = ConfigureContainer(new ContainerBuilder(), configProvider);
configurer?.Invoke(builder);
Expand All @@ -163,22 +166,14 @@ protected virtual ArbitrumTestBlockchainBase Build(Action<ContainerBuilder>? con
TransactionComparerProvider transactionComparerProvider = new(Dependencies.SpecProvider, BlockFinder);

BlockProducer = CreateTestBlockProducer(Dependencies.Sealer, transactionComparerProvider);

BlockProducerRunner = new StandardBlockProducerRunner(BlockProductionTrigger, BlockTree, BlockProducer);
_ = new NonProcessingProducedBlockSuggester(BlockTree, BlockProducerRunner);
Comment thread
damian-orzechowski marked this conversation as resolved.
BlockProducerRunner.Start();

Suggester = new ProducedBlockSuggester(BlockTree, BlockProducerRunner);

RegisterTransactionDecoders();

Cts = AutoCancelTokenSource.ThatCancelAfter(TimeSpan.FromMilliseconds(TestTimout));
//TestUtil = new TestBlockchainUtil(
// BlockProducerRunner,
// BlockProductionTrigger,
// Timestamper,
// BlockTree,
// TxPool,
// 1
//);

Configuration testConfig = Container.Resolve<Configuration>();
IWorldState worldState = WorldStateManager.GlobalWorldState;
Expand Down Expand Up @@ -277,7 +272,7 @@ protected virtual ContainerBuilder ConfigureContainer(ContainerBuilder builder,
return builder
.AddModule(new PseudoNethermindModule(ChainSpec, configProvider, LimboLogs.Instance))
.AddModule(new TestEnvironmentModule(TestItem.PrivateKeyA, Random.Shared.Next().ToString()))
.AddModule(new ArbitrumModule(ChainSpec))
.AddModule(new ArbitrumModule(ChainSpec, configProvider.GetConfig<IBlocksConfig>()))
.AddSingleton<IDbFactory>(new MemDbFactory())
.AddSingleton<ISpecProvider>(FullChainSimulationSpecProvider.Instance)
.AddSingleton<Configuration>()
Expand All @@ -287,7 +282,6 @@ protected virtual ContainerBuilder ConfigureContainer(ContainerBuilder builder,
.AddDecorator<IRocksDbConfigFactory, ArbitrumDbConfigFactory>()
.AddSingleton<IWasmDb, WasmDb>()

.AddSingleton<IBlockProducerEnvFactory, ArbitrumBlockProducerEnvFactory>()
.AddSingleton<IBlockProducerTxSourceFactory, ArbitrumBlockProducerTxSourceFactory>()
.AddDecorator<ICodeInfoRepository, ArbitrumCodeInfoRepository>()

Expand Down
1 change: 0 additions & 1 deletion src/Nethermind.Arbitrum.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
<Project Path="Nethermind/src/Nethermind/Nethermind.Core.Test/Nethermind.Core.Test.csproj" />
<Project Path="Nethermind/src/Nethermind/Nethermind.JsonRpc.Test/Nethermind.JsonRpc.Test.csproj" />
<Project Path="Nethermind/src/Nethermind/Nethermind.Monitoring.Test/Nethermind.Monitoring.Test.csproj" />
<Project Path="Nethermind/src/Nethermind/Nethermind.Overseer.Test/Nethermind.Overseer.Test.csproj" />
<Project Path="Nethermind/src/Nethermind/Nethermind.Runner.Test/Nethermind.Runner.Test.csproj" />
<Project Path="Nethermind/src/Nethermind/Nethermind.Specs.Test/Nethermind.Specs.Test.csproj" />
<Project Path="Nethermind/src/Nethermind/Nethermind.Evm.Test/Nethermind.Evm.Test.csproj" />
Expand Down
12 changes: 8 additions & 4 deletions src/Nethermind.Arbitrum/ArbitrumPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

namespace Nethermind.Arbitrum;

public class ArbitrumPlugin(ChainSpec chainSpec) : IConsensusPlugin
public class ArbitrumPlugin(ChainSpec chainSpec, IBlocksConfig blocksConfig) : IConsensusPlugin
{
private ArbitrumNethermindApi _api = null!;
private IJsonRpcConfig _jsonRpcConfig = null!;
Expand All @@ -47,7 +47,7 @@ public class ArbitrumPlugin(ChainSpec chainSpec) : IConsensusPlugin
public string Description => "Nethermind Arbitrum client";
public string Author => "Nethermind";
public bool Enabled => chainSpec.SealEngineType == ArbitrumChainSpecEngineParameters.ArbitrumEngineName;
public IModule Module => new ArbitrumModule(chainSpec);
public IModule Module => new ArbitrumModule(chainSpec, blocksConfig);
public Type ApiType => typeof(ArbitrumNethermindApi);

public Task Init(INethermindApi api)
Expand Down Expand Up @@ -156,7 +156,7 @@ public class ArbitrumGasLimitCalculator : IGasLimitCalculator
public long GetGasLimit(BlockHeader parentHeader) => long.MaxValue;
}

public class ArbitrumModule(ChainSpec chainSpec) : Module
public class ArbitrumModule(ChainSpec chainSpec, IBlocksConfig blocksConfig) : Module
{
protected override void Load(ContainerBuilder builder)
{
Expand Down Expand Up @@ -194,7 +194,6 @@ protected override void Load(ContainerBuilder builder)
.AddScoped<BlockProcessor.IBlockProductionTransactionPicker, ISpecProvider, IBlocksConfig>((specProvider, blocksConfig) =>
new ArbitrumBlockProductionTransactionPicker(specProvider))

.AddSingleton<IBlockProducerEnvFactory, ArbitrumBlockProducerEnvFactory>()
.AddSingleton<IBlockProducerTxSourceFactory, ArbitrumBlockProducerTxSourceFactory>()
.AddDecorator<ICodeInfoRepository, ArbitrumCodeInfoRepository>()
.AddScoped<IArbosVersionProvider, ArbosStateVersionProvider>()
Expand All @@ -205,6 +204,11 @@ protected override void Load(ContainerBuilder builder)
// Rpcs
.AddSingleton<ArbitrumEthModuleFactory>()
.Bind<IRpcModuleFactory<IEthRpcModule>, ArbitrumEthModuleFactory>();

if (blocksConfig.BuildBlocksOnMainState)
builder.AddSingleton<IBlockProducerEnvFactory, ArbitrumGlobalWorldStateBlockProducerEnvFactory>();
else
builder.AddSingleton<IBlockProducerEnvFactory, ArbitrumBlockProducerEnvFactory>();
}

private class ArbitrumBlockValidationModule : Module, IBlockValidationModule
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Autofac;
using Nethermind.Arbitrum.Execution;
using Nethermind.Consensus.Processing;
using Nethermind.Consensus.Producers;
using Nethermind.Core;
Expand All @@ -23,3 +22,19 @@ protected override ContainerBuilder ConfigureBuilder(ContainerBuilder builder)
.AddScoped<IBlockProcessor.IBlockTransactionsExecutor, ArbitrumBlockProductionTransactionsExecutor>();
}
}

public class ArbitrumGlobalWorldStateBlockProducerEnvFactory : GlobalWorldStateBlockProducerEnvFactory
{
public ArbitrumGlobalWorldStateBlockProducerEnvFactory(
ILifetimeScope rootLifetime,
IWorldStateManager worldStateManager,
IBlockProducerTxSourceFactory txSourceFactory) : base(rootLifetime, worldStateManager, txSourceFactory)
{
}

protected override ContainerBuilder ConfigureBuilder(ContainerBuilder builder)
{
return base.ConfigureBuilder(builder)
.AddScoped<IBlockProcessor.IBlockTransactionsExecutor, ArbitrumBlockProductionTransactionsExecutor>();
}
}
4 changes: 2 additions & 2 deletions src/Nethermind.Arbitrum/Execution/ArbitrumBlockProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ public virtual TxReceipt[] ProcessTransactions(Block block, ProcessingOptions pr

//only pickup scheduled transactions when producing block - otherwise already included in block
IEnumerable<Transaction> scheduledTransactions = [];
if (processingOptions.ContainsFlag(ProcessingOptions.ProducingBlock))
if (blockToProduce is not null)
{
scheduledTransactions = receiptsTracer.TxReceipts.Count > 0
? GetScheduledTransactions(arbosState, receiptsTracer.LastReceipt, block.Header, specProvider.ChainId)
Expand Down Expand Up @@ -333,7 +333,7 @@ private TxAction ProcessTransaction(
}
else
{
if (processingOptions.ContainsFlag(ProcessingOptions.DoNotVerifyNonce) && currentTx.SenderAddress != Address.SystemUser)
if (processingOptions.ContainsFlag(ProcessingOptions.LoadNonceFromState) && currentTx.SenderAddress != Address.SystemUser)
{
currentTx.Nonce = stateProvider.GetNonce(currentTx.SenderAddress!);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Nethermind.Arbitrum/Execution/ArbitrumBlockProducer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Nethermind.Arbitrum.Execution.Transactions;
using Nethermind.Arbitrum.Precompiles.Abi;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Tracing;
using Nethermind.Config;
using Nethermind.Consensus;
using Nethermind.Consensus.Processing;
Expand All @@ -16,6 +17,7 @@
using Nethermind.Core.Specs;
using Nethermind.Crypto;
using Nethermind.Evm.State;
using Nethermind.Evm.Tracing;
using Nethermind.Logging;
using Nethermind.Merge.Plugin.BlockProduction;

Expand Down
65 changes: 4 additions & 61 deletions src/Nethermind.Arbitrum/Modules/ArbitrumRpcModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ public class ArbitrumRpcModule(
protected readonly ILogger Logger = logManager.GetClassLogger<ArbitrumRpcModule>();
private readonly ArbitrumSyncMonitor _syncMonitor = new(blockTree, specHelper, arbitrumConfig, logManager);

private readonly ConcurrentDictionary<Hash256, TaskCompletionSource<Block>> _newBestSuggestedBlockEvents = new();
private readonly ConcurrentDictionary<Hash256, TaskCompletionSource<BlockRemovedEventArgs>> _blockRemovedEvents = new();

public ResultWrapper<MessageResult> DigestInitMessage(DigestInitMessage message)
{
if (message.InitialL1BaseFee.IsZero)
Expand Down Expand Up @@ -216,76 +213,22 @@ protected async Task<ResultWrapper<MessageResult>> ProduceBlockWhileLockedAsync(
Number = blockNumber
};

void OnNewBestSuggestedBlock(object? sender, BlockEventArgs e)
{
if (e.Block.Hash is null)
return;

_newBestSuggestedBlockEvents
.GetOrAdd(e.Block.Hash, _ => new TaskCompletionSource<Block>())
.TrySetResult(e.Block);
}

void OnBlockRemoved(object? sender, BlockRemovedEventArgs e)
{
_blockRemovedEvents
.GetOrAdd(e.BlockHash, _ => new TaskCompletionSource<BlockRemovedEventArgs>())
.TrySetResult(e);
}

blockTree.NewBestSuggestedBlock += OnNewBestSuggestedBlock;
processingQueue.BlockRemoved += OnBlockRemoved;

try
{
Block? block = await trigger.BuildBlock(parentHeader: headBlockHeader, payloadAttributes: payload);
if (block?.Hash is null)
return ResultWrapper<MessageResult>.Fail("Failed to build block or block has no hash.", ErrorCodes.InternalError);

TaskCompletionSource<Block> newBestBlockTcs = _newBestSuggestedBlockEvents.GetOrAdd(block.Hash, _ => new TaskCompletionSource<Block>());
TaskCompletionSource<BlockRemovedEventArgs> blockRemovedTcs = _blockRemovedEvents.GetOrAdd(block.Hash, _ => new TaskCompletionSource<BlockRemovedEventArgs>());

using CancellationTokenSource processingTimeoutTokenSource = arbitrumConfig.BuildProcessingTimeoutTokenSource();
await Task.WhenAll(newBestBlockTcs.Task, blockRemovedTcs.Task)
.WaitAsync(processingTimeoutTokenSource.Token);

BlockRemovedEventArgs resultArgs = blockRemovedTcs.Task.Result;

if (resultArgs.ProcessingResult == ProcessingResult.Exception)
{
BlockchainException exception = new(
resultArgs.Exception?.Message ?? "Block processing threw an unspecified exception.",
resultArgs.Exception);

if (Logger.IsError)
Logger.Error($"Block processing failed for {block.Hash}", exception);

return ResultWrapper<MessageResult>.Fail(exception.Message, ErrorCodes.InternalError);
}

return resultArgs.ProcessingResult switch
return ResultWrapper<MessageResult>.Success(new MessageResult
{
ProcessingResult.Success => ResultWrapper<MessageResult>.Success(new MessageResult
{
BlockHash = block.Hash!,
SendRoot = GetSendRootFromBlock(block)
}),
ProcessingResult.ProcessingError => ResultWrapper<MessageResult>.Fail(resultArgs.Message ?? "Block processing failed.", ErrorCodes.InternalError),
_ => ResultWrapper<MessageResult>.Fail($"Block processing ended in an unhandled state: {resultArgs.ProcessingResult}", ErrorCodes.InternalError)
};
BlockHash = block.Hash!,
SendRoot = GetSendRootFromBlock(block)
});
}
catch (TimeoutException)
{
return ResultWrapper<MessageResult>.Fail("Timeout waiting for block processing result.", ErrorCodes.Timeout);
}
finally
{
blockTree.NewBestSuggestedBlock -= OnNewBestSuggestedBlock;
processingQueue.BlockRemoved -= OnBlockRemoved;

_newBestSuggestedBlockEvents.Clear();
_blockRemovedEvents.Clear();
}
}

private Hash256 GetSendRootFromBlock(Block block)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
"PruningBoundary": 192
},
"Blocks": {
"SecondsPerSlot": 2
"SecondsPerSlot": 2,
"BuildBlocksOnMainState": true
},
"Merge": {
"Enabled": true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
"MaxBufferedCommitCount": 2500
},
"Blocks": {
"PreWarmStateOnBlockProcessing": false
"PreWarmStateOnBlockProcessing": false,
"BuildBlocksOnMainState": true
},
"Metrics": {
"NodeName": "Nethermind Arbitrum Sepolia Archive"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
},
"Blocks": {
"SecondsPerSlot": 2,
"PreWarmStateOnBlockProcessing": false
"PreWarmStateOnBlockProcessing": false,
"BuildBlocksOnMainState": true
},
"Metrics": {
"NodeName": "Nethermind Arbitrum Sepolia"
Expand Down
Loading