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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Nethermind.Core;
using Nethermind.Core.Test.Builders;
using Nethermind.Core.Test.Modules;
using Nethermind.Specs.Forks;
using NUnit.Framework;

namespace Nethermind.Blockchain.Test.Producers;
Expand All @@ -22,21 +23,21 @@ public class DevBlockProducerTests
public void Test()
{
using IContainer container = new ContainerBuilder()
.AddModule(new TestNethermindModule())
.AddModule(new TestNethermindModule(Cancun.Instance))
.AddSingleton<IBlockValidator>(Always.Valid)
.AddSingleton<IBlockProducerTxSourceFactory, EmptyTxSourceFactory>()
.AddScoped<IBlockProducerFactory, TestBlockProcessingModule.AutoBlockProducerFactory<DevBlockProducer>>()
.Build();

IBlockTree blockTree = container.Resolve<IBlockTree>();
AutoResetEvent autoResetEvent = new(false);
blockTree.NewHeadBlock += (_, _) => autoResetEvent.Set();

IManualBlockProductionTrigger trigger = container.Resolve<IManualBlockProductionTrigger>();

container.Resolve<IMainProcessingContext>().BlockchainProcessor.Start();
container.Resolve<IBlockProducerRunner>().Start();

AutoResetEvent autoResetEvent = new(false);

blockTree.NewHeadBlock += (_, _) => autoResetEvent.Set();
blockTree.SuggestBlock(Build.A.Block.Genesis.TestObject);

autoResetEvent.WaitOne(1000).Should().BeTrue("genesis");
Expand Down
4 changes: 1 addition & 3 deletions src/Nethermind/Nethermind.Blockchain/BlockTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -504,9 +504,7 @@ private AddBlockResult Suggest(Block? block, BlockHeader header, BlockTreeSugges
bool bestSuggestedImprovementSatisfied = BestSuggestedImprovementRequirementsSatisfied(header);
if (bestSuggestedImprovementSatisfied)
{
if (_logger.IsTrace)
_logger.Trace(
$"New best suggested block. PreviousBestSuggestedBlock {BestSuggestedBody}, BestSuggestedBlock TD {BestSuggestedBody?.TotalDifficulty}, Block TD {block?.TotalDifficulty}, Head: {Head}, Head: {Head?.TotalDifficulty}, Block {block?.ToString(Block.Format.FullHashAndNumber)}");
if (_logger.IsTrace) _logger.Trace($"New best suggested block. PreviousBestSuggestedBlock {BestSuggestedBody}, BestSuggestedBlock TD {BestSuggestedBody?.TotalDifficulty}, Block TD {block?.TotalDifficulty}, Head: {Head}, Head: {Head?.TotalDifficulty}, Block {block?.ToString(Block.Format.FullHashAndNumber)}");
BestSuggestedHeader = block.Header;

if (block.IsPostMerge)
Expand Down
28 changes: 14 additions & 14 deletions src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Threading;
using Nethermind.Config;
using Nethermind.Core;
Expand Down Expand Up @@ -31,19 +32,17 @@ public long Estimate(Transaction tx, BlockHeader header, EstimateGasTracer gasTr
{
err = null;

if (errorMargin < 0)
switch (errorMargin)
{
err = "Invalid error margin, cannot be negative.";
return 0;
}
else if (errorMargin >= MaxErrorMargin)
{
err = $"Invalid error margin, must be lower than {MaxErrorMargin}.";
return 0;
case < 0:
err = "Invalid error margin, cannot be negative.";
return 0;
case >= MaxErrorMargin:
err = $"Invalid error margin, must be lower than {MaxErrorMargin}.";
return 0;
}

IReleaseSpec releaseSpec =
specProvider.GetSpec(header.Number + 1, header.Timestamp + blocksConfig.SecondsPerSlot);
IReleaseSpec releaseSpec = specProvider.GetSpec(header.Number + 1, header.Timestamp + blocksConfig.SecondsPerSlot);

tx.SenderAddress ??= Address.Zero; // If sender is not specified, use zero address.

Expand All @@ -60,19 +59,20 @@ public long Estimate(Transaction tx, BlockHeader header, EstimateGasTracer gasTr
return additionalGas;
}

var lowerBound = IntrinsicGasCalculator.Calculate(tx, releaseSpec).MinimalGas;
long lowerBound = IntrinsicGasCalculator.Calculate(tx, releaseSpec).MinimalGas;

// Setting boundaries for binary search - determine lowest and highest gas can be used during the estimation:
long leftBound = (gasTracer.GasSpent != 0 && gasTracer.GasSpent >= lowerBound)
long leftBound = gasTracer.GasSpent != 0 && gasTracer.GasSpent >= lowerBound
? gasTracer.GasSpent - 1
: lowerBound - 1;
long rightBound = (tx.GasLimit != 0 && tx.GasLimit >= lowerBound)
long rightBound = tx.GasLimit != 0 && tx.GasLimit >= lowerBound
? tx.GasLimit
: header.GasLimit;
rightBound = Math.Min(rightBound, releaseSpec.GetTxGasLimitCap());

if (leftBound > rightBound)
{
err = "Cannot estimate gas, gas spent exceeded transaction and block gas limit";
err = "Cannot estimate gas, gas spent exceeded transaction and block gas limit or transaction gas limit cap";
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class BuildBlocksWhenRequested : IManualBlockProductionTrigger
BlockHeader? parentHeader = null,
CancellationToken? cancellationToken = null,
IBlockTracer? blockTracer = null,
PayloadAttributes payloadAttributes = null)
PayloadAttributes? payloadAttributes = null)
{
BlockProductionEventArgs args = new(parentHeader, cancellationToken, blockTracer, payloadAttributes);
TriggerBlockProduction?.Invoke(this, args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace Nethermind.Consensus.Producers
{
public interface IManualBlockProductionTrigger : IBlockProductionTrigger
{
// TODO: too many parameters
public Task<Block?> BuildBlock(
BlockHeader? parentHeader = null,
CancellationToken? cancellationToken = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ private GasLimitCapTxValidator() { }

public ValidationResult IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec)
{
long gasLimitCap = Eip7825Constants.GetTxGasLimitCap(releaseSpec);
long gasLimitCap = releaseSpec.GetTxGasLimitCap();
return transaction.GasLimit > gasLimitCap ?
TxErrorMessages.TxGasLimitCapExceeded(transaction.GasLimit, gasLimitCap) : ValidationResult.Success;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ namespace Nethermind.Core.Test.Modules;
/// <param name="configProvider"></param>
public class TestNethermindModule(IConfigProvider configProvider, ChainSpec chainSpec) : Module
{
public TestNethermindModule() : this(new ConfigProvider())
private readonly IReleaseSpec? _releaseSpec;

public TestNethermindModule(IReleaseSpec? releaseSpec = null) : this(new ConfigProvider())
{
_releaseSpec = releaseSpec;
}

public TestNethermindModule(params IConfig[] configs) : this(new ConfigProvider(configs))
Expand Down Expand Up @@ -53,6 +56,6 @@ protected override void Load(ContainerBuilder builder)
builder
.AddModule(new PseudoNethermindModule(chainSpec, configProvider, LimboLogs.Instance))
.AddModule(new TestEnvironmentModule(TestItem.PrivateKeyA, Random.Shared.Next().ToString()))
.AddSingleton<ISpecProvider>(_ => new TestSpecProvider(Cancun.Instance));
.AddSingleton<ISpecProvider>(_ => new TestSpecProvider(_releaseSpec ?? Osaka.Instance));
}
}
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Core/Eip7825Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ namespace Nethermind.Core;
public static class Eip7825Constants
{
public static readonly long DefaultTxGasLimitCap = 16_777_216;
public static long GetTxGasLimitCap(IReleaseSpec spec)
public static long GetTxGasLimitCap(this IReleaseSpec spec)
=> spec.IsEip7825Enabled ? DefaultTxGasLimitCap : long.MaxValue;
}
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ public void Estimate_DifferentAmountOfGasAndMargin_EstimationResultIsWithinMargi
{
using (Assert.EnterMultipleScope())
{
Assert.That(err, Is.EqualTo("Cannot estimate gas, gas spent exceeded transaction and block gas limit"));
Assert.That(err, Is.EqualTo("Cannot estimate gas, gas spent exceeded transaction and block gas limit or transaction gas limit cap"));
Assert.That(result, Is.EqualTo(0));
}
}
Expand Down Expand Up @@ -540,7 +540,7 @@ public void Should_return_zero_when_address_zero_exceeds_gas_limits()
long estimate = testEnvironment.estimator.Estimate(tx, block.Header, tracer, out string? err);

estimate.Should().Be(0, "Should return 0 when gas spent exceeds limits");
err.Should().Be("Cannot estimate gas, gas spent exceeded transaction and block gas limit",
err.Should().Be("Cannot estimate gas, gas spent exceeded transaction and block gas limit or transaction gas limit cap",
"Should provide gas limit exceeded error message");
}

Expand Down
16 changes: 14 additions & 2 deletions src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ public Task SetUp()
.AddSingleton<IReceiptFinder>(_receiptStorage)
.AddSingleton(_timestamper)
.AddSingleton(Substitute.For<ILogFinder>())
.AddSingleton<IMiningConfig>(new MiningConfig() { Enabled = false })
.AddScoped<ITransactionProcessor>(_transactionProcessor)
.AddSingleton<IMiningConfig>(new MiningConfig { Enabled = false })
.AddScoped(_transactionProcessor)
.Build();

_blockchainBridge = _container.Resolve<IBlockchainBridge>();
Expand Down Expand Up @@ -546,6 +546,18 @@ public void EstimateGas_tx_returns_GasLimitBelowIntrinsicGasError()
Assert.That(callOutput.Error, Is.EqualTo("gas limit below intrinsic gas"));
}

[Test]
public void EstimateGas_tx_returns_GasLimitOverCap()
{
BlockHeader header = Build.A.BlockHeader
.TestObject;
Transaction tx = new() { GasLimit = 30_000_000, Data = new byte[1_680_000] };

CallOutput callOutput = _blockchainBridge.EstimateGas(header, tx, 1);

Assert.That(callOutput.Error, Is.EqualTo("Cannot estimate gas, gas spent exceeded transaction and block gas limit or transaction gas limit cap"));
}

[Test]
public void Call_tx_returns_InsufficientMaxFeePerGasForSenderBalanceError()
{
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Facade/BlockchainBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ private TransactionResult CallAndRestore(
blockHeader.Number + 1,
blockHeader.GasLimit,
Math.Max(blockHeader.Timestamp + blocksConfig.SecondsPerSlot, timestamper.UnixTime.Seconds),
Array.Empty<byte>())
[])
: new(
blockHeader.ParentHash!,
blockHeader.UnclesHash!,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ public class MainProcessingContextTests
public async Task Test_TransactionProcessed_EventIsFired(CancellationToken cancelationToken)
{
await using IContainer ctx = new ContainerBuilder()
.AddModule(new TestNethermindModule())
.WithGenesisPostProcessor((block, state) =>
.AddModule(new TestNethermindModule(Cancun.Instance))
.WithGenesisPostProcessor((_, state) =>
{
state.AddToBalanceAndCreateIfNotExists(TestItem.AddressA, 10.Ether(), Osaka.Instance);
})
.Build();

var mainProcessingContext = ctx.Resolve<IMainProcessingContext>();
int totalTransactionProcessed = 0;
mainProcessingContext.TransactionProcessed += (sender, args) => totalTransactionProcessed++;
mainProcessingContext.TransactionProcessed += (_, _) => totalTransactionProcessed++;

await ctx.Resolve<PseudoNethermindRunner>().StartBlockProcessing(cancelationToken);
await ctx.Resolve<TestBlockchainUtil>().AddBlockAndWaitForHead(false, cancelationToken,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,7 @@ public class DisposableScopeOverridableEnv<T>(
T resolvedComponents
) : IOverridableEnv<T>
{
public Scope<T> BuildAndOverride(BlockHeader header)
{
IDisposable disposable = overridableEnv.BuildAndOverride(header, null);
return new Scope<T>(resolvedComponents, disposable);
}

public Scope<T> BuildAndOverride(BlockHeader header, Dictionary<Address, AccountOverride> stateOverride)
public Scope<T> BuildAndOverride(BlockHeader header, Dictionary<Address, AccountOverride>? stateOverride = null)
{
IDisposable disposable = overridableEnv.BuildAndOverride(header, stateOverride);
return new Scope<T>(resolvedComponents, disposable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Nethermind.State.OverridableEnv;
/// </summary>
public interface IOverridableEnv : IModule
{
IDisposable BuildAndOverride(BlockHeader? header, Dictionary<Address, AccountOverride>? stateOverride);
IDisposable BuildAndOverride(BlockHeader? header, Dictionary<Address, AccountOverride>? stateOverride = null);
}

/// <summary>
Expand All @@ -31,6 +31,5 @@ public interface IOverridableEnv : IModule
/// <typeparam name="T"></typeparam>
public interface IOverridableEnv<T>
{
Scope<T> BuildAndOverride(BlockHeader? header);
Scope<T> BuildAndOverride(BlockHeader? header, Dictionary<Address, AccountOverride>? stateOverride);
Scope<T> BuildAndOverride(BlockHeader? header, Dictionary<Address, AccountOverride>? stateOverride = null);
}