Skip to content

Commit

Permalink
refactor MaxBlobGas, TargetBlobGas calculation (#8088)
Browse files Browse the repository at this point in the history
yerke26 authored Jan 21, 2025
1 parent 16e9e0d commit fe89802
Showing 11 changed files with 41 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -123,7 +123,7 @@ private void SelectBlobTransactions(IEnumerable<Transaction> blobTransactions, B
UInt256 blobGasCounter = 0;
UInt256 feePerBlobGas = UInt256.Zero;

var maxBlobGasPerBlock = spec.MaxBlobCount * Eip4844Constants.GasPerBlob;
var maxBlobGasPerBlock = spec.GetMaxBlobGas();
foreach (Transaction blobTx in blobTransactions)
{
if (blobGasCounter >= maxBlobGasPerBlock)
Original file line number Diff line number Diff line change
@@ -337,9 +337,9 @@ protected virtual bool ValidateEip4844Fields(Block block, IReleaseSpec spec, out

ulong blobGasUsed = BlobGasCalculator.CalculateBlobGas(blobsInBlock);

if (blobGasUsed > spec.MaxBlobCount * Eip4844Constants.GasPerBlob)
if (blobGasUsed > spec.GetMaxBlobGas())
{
error = string.Format(BlockErrorMessages.BlobGasUsedAboveBlockLimit, spec.MaxBlobCount * Eip4844Constants.GasPerBlob, blobsInBlock, blobGasUsed);
error = string.Format(BlockErrorMessages.BlobGasUsedAboveBlockLimit, spec.GetMaxBlobGas(), blobsInBlock, blobGasUsed);
if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} {error}.");
return false;
}
Original file line number Diff line number Diff line change
@@ -199,7 +199,7 @@ private ValidationResult ValidateBlobFields(Transaction transaction, IReleaseSpe
{
int blobCount = transaction.BlobVersionedHashes!.Length;
ulong totalDataGas = BlobGasCalculator.CalculateBlobGas(blobCount);
var maxBlobGasPerTxn = spec.MaxBlobCount * Eip4844Constants.GasPerBlob;
var maxBlobGasPerTxn = spec.GetMaxBlobGas();
return totalDataGas > maxBlobGasPerTxn ? string.Format(TxErrorMessages.BlobTxGasLimitExceeded, maxBlobGasPerTxn)
: blobCount < Eip4844Constants.MinBlobsPerTransaction ? TxErrorMessages.BlobTxMissingBlobs
: ValidateBlobVersionedHashes();
10 changes: 5 additions & 5 deletions src/Nethermind/Nethermind.Evm.Test/BlobGasCalculatorTests.cs
Original file line number Diff line number Diff line change
@@ -91,13 +91,13 @@ private static IEnumerable<TestCaseData> GenerateTestCases()
yield return (0, (int)spec.TargetBlobCount, 0);
yield return (100000, (int)spec.TargetBlobCount, 100000);
yield return (0, (int)spec.TargetBlobCount + 1, Eip4844Constants.GasPerBlob * 1);
yield return (spec.TargetBlobCount * Eip4844Constants.GasPerBlob, 1, Eip4844Constants.GasPerBlob * 1);
yield return (spec.TargetBlobCount * Eip4844Constants.GasPerBlob, 0, 0);
yield return (spec.TargetBlobCount * Eip4844Constants.GasPerBlob, 2, Eip4844Constants.GasPerBlob * 2);
yield return (spec.MaxBlobCount * Eip4844Constants.GasPerBlob, 1, (spec.MaxBlobCount + 1 - spec.TargetBlobCount) * Eip4844Constants.GasPerBlob);
yield return (spec.GetTargetBlobGas(), 1, Eip4844Constants.GasPerBlob * 1);
yield return (spec.GetTargetBlobGas(), 0, 0);
yield return (spec.GetTargetBlobGas(), 2, Eip4844Constants.GasPerBlob * 2);
yield return (spec.GetMaxBlobGas(), 1, (spec.MaxBlobCount + 1 - spec.TargetBlobCount) * Eip4844Constants.GasPerBlob);
yield return (1, (int)spec.TargetBlobCount, 1);
yield return (
spec.MaxBlobCount * Eip4844Constants.GasPerBlob,
spec.GetMaxBlobGas(),
(int)spec.MaxBlobCount,
(spec.MaxBlobCount * 2 - spec.TargetBlobCount) * Eip4844Constants.GasPerBlob
);
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ public static IEnumerable<TestCaseData> BalanceIsAffectedByBlobGasTestCaseSource
yield return new TestCaseData(1.Ether(), (int)Cancun.Instance.MaxBlobCount, 1ul, 0ul, 0ul)
{
TestName = "Blob gas consumed for max blobs",
ExpectedResult = (UInt256)(GasCostOf.Transaction + Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob),
ExpectedResult = (UInt256)(GasCostOf.Transaction + Cancun.Instance.GetMaxBlobGas()),
};
yield return new TestCaseData(1.Ether(), 1, 10ul, 0ul, 0ul)
{
4 changes: 2 additions & 2 deletions src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs
Original file line number Diff line number Diff line change
@@ -102,8 +102,8 @@ static bool FakeExponentialOverflow(UInt256 factor, UInt256 num, UInt256 denomin

ulong excessBlobGas = parentBlockHeader.ExcessBlobGas ?? 0;
excessBlobGas += parentBlockHeader.BlobGasUsed ?? 0;
return excessBlobGas < releaseSpec.TargetBlobCount * Eip4844Constants.GasPerBlob
return excessBlobGas < releaseSpec.GetTargetBlobGas()
? 0
: (excessBlobGas - releaseSpec.TargetBlobCount * Eip4844Constants.GasPerBlob);
: excessBlobGas - releaseSpec.GetTargetBlobGas();
}
}
7 changes: 7 additions & 0 deletions src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using Nethermind.Core;
using Nethermind.Core.Specs;

namespace Nethermind.Evm
@@ -83,5 +84,11 @@ public static long GetExpByteCost(this IReleaseSpec spec) =>
spec.UseExpDDosProtection
? GasCostOf.ExpByteEip160
: GasCostOf.ExpByte;

public static ulong GetMaxBlobGas(this IReleaseSpec spec) =>
spec.MaxBlobCount * Eip4844Constants.GasPerBlob;

public static ulong GetTargetBlobGas(this IReleaseSpec spec) =>
spec.TargetBlobCount * Eip4844Constants.GasPerBlob;
}
}
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
using Nethermind.Core.Crypto;
using Nethermind.Core.Specs;
using Nethermind.Core.Test.Builders;
using Nethermind.Evm;
using Nethermind.Int256;
using Nethermind.JsonRpc.Modules.Eth;
using Nethermind.JsonRpc.Modules.Eth.FeeHistory;
@@ -88,15 +89,15 @@ public static IEnumerable<TestCaseData> FeeHistoryBlobTestCases
new ulong?[] { 1,
2,
0,
Cancun.Instance.TargetBlobCount * Eip4844Constants.GasPerBlob,
Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob,
Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob * 4 },
Cancun.Instance.GetTargetBlobGas(),
Cancun.Instance.GetMaxBlobGas(),
Cancun.Instance.GetMaxBlobGas() * 4 },
new ulong?[] { 0,
Eip4844Constants.GasPerBlob * 2,
Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob,
Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob,
Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob,
Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob })
Cancun.Instance.GetMaxBlobGas(),
Cancun.Instance.GetMaxBlobGas(),
Cancun.Instance.GetMaxBlobGas(),
Cancun.Instance.GetMaxBlobGas() })
{
TestName = "Different values",
ExpectedResult = (
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
using Nethermind.Core.Extensions;
using Nethermind.Core.Specs;
using Nethermind.Core.Test.Builders;
using Nethermind.Evm;
using Nethermind.Int256;
using Nethermind.JsonRpc.Modules.Eth.GasPrice;
using Nethermind.Logging;
@@ -72,21 +73,21 @@ public async Task Eth_gasPrice_BlocksAvailableLessThanBlocksToCheckWith1559Tx_Sh
private static Block[] GetThreeTestBlocks(bool eip1559Enabled = true)
{
Block firstBlock = Build.A.Block.WithNumber(0).WithParentHash(Keccak.Zero)
.WithExcessBlobGas(eip1559Enabled ? Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob * 4 : null)
.WithExcessBlobGas(eip1559Enabled ? Cancun.Instance.GetMaxBlobGas() * 4 : null)
.WithTransactions(
Build.A.Transaction.WithGasPrice(1).SignedAndResolved(TestItem.PrivateKeyA).WithNonce(0).TestObject,
Build.A.Transaction.WithGasPrice(2).SignedAndResolved(TestItem.PrivateKeyB).WithNonce(0).TestObject
).TestObject;

Block secondBlock = Build.A.Block.WithNumber(1).WithParentHash(firstBlock.Hash!)
.WithExcessBlobGas(eip1559Enabled ? Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob * 8 : null)
.WithExcessBlobGas(eip1559Enabled ? Cancun.Instance.GetMaxBlobGas() * 8 : null)
.WithTransactions(
Build.A.Transaction.WithGasPrice(3).SignedAndResolved(TestItem.PrivateKeyC).WithNonce(0).TestObject,
Build.A.Transaction.WithGasPrice(4).SignedAndResolved(TestItem.PrivateKeyD).WithNonce(0).TestObject
).TestObject;

Block thirdBlock = Build.A.Block.WithNumber(2).WithParentHash(secondBlock.Hash!)
.WithExcessBlobGas(eip1559Enabled ? Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob * 12 : null)
.WithExcessBlobGas(eip1559Enabled ? Cancun.Instance.GetMaxBlobGas() * 12 : null)
.WithTransactions(
Build.A.Transaction.WithGasPrice(5).SignedAndResolved(TestItem.PrivateKeyA).WithNonce(1).TestObject,
Build.A.Transaction.WithGasPrice(6).SignedAndResolved(TestItem.PrivateKeyB).WithNonce(1).TestObject
@@ -142,22 +143,22 @@ public static IEnumerable<TestCaseData> GetBlobBaseFeeTestCases
TestName = $"Low {nameof(BlockHeader.ExcessBlobGas)}",
ExpectedResult = Success(Eip4844Constants.MinBlobGasPrice)
};
yield return new TestCaseData(Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob * 4)
yield return new TestCaseData(Cancun.Instance.GetMaxBlobGas() * 4)
{
TestName = "Initial price spike",
ExpectedResult = Success(2)
};
yield return new TestCaseData(Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob * 42)
yield return new TestCaseData(Cancun.Instance.GetMaxBlobGas() * 42)
{
TestName = "Price spike",
ExpectedResult = Success(19806)
};
yield return new TestCaseData(Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob * 419)
yield return new TestCaseData(Cancun.Instance.GetMaxBlobGas() * 419)
{
TestName = $"Price spike higher than {nameof(UInt64)} value",
ExpectedResult = Success(UInt256.Parse("0x54486950184d094e079641e7e0d6dd85a81c"))
};
yield return new TestCaseData(Cancun.Instance.MaxBlobCount * Eip4844Constants.GasPerBlob * 3000)
yield return new TestCaseData(Cancun.Instance.GetMaxBlobGas() * 3000)
{
TestName = $"Overflow for huge {nameof(BlockHeader.ExcessBlobGas)} value",
ExpectedResult = Fail()
Original file line number Diff line number Diff line change
@@ -113,7 +113,7 @@ BlockFeeHistorySearchInfo BlockFeeHistorySearchInfoFromBlock(Block b)
out UInt256 feePerBlobGas);

double blobGasUsedRatio = 0;
var maxBlobGasPerBlob = _specProvider.GetSpec(b.Header).MaxBlobCount * Eip4844Constants.GasPerBlob;
var maxBlobGasPerBlob = _specProvider.GetSpec(b.Header).GetMaxBlobGas();
if (maxBlobGasPerBlob != 0)
{
blobGasUsedRatio = (b.BlobGasUsed ?? 0) / (double)maxBlobGasPerBlob;
Original file line number Diff line number Diff line change
@@ -12,12 +12,11 @@
using Nethermind.Core;
using Nethermind.Core.Extensions;
using Nethermind.Core.Specs;
using Nethermind.Evm;
using Nethermind.Int256;
using Nethermind.Logging;
using Nethermind.Serialization.Json;
using Nethermind.Specs.ChainSpecStyle;
using Nethermind.Specs.Forks;
using Nethermind.Specs.GnosisForks;
using NSubstitute;
using NUnit.Framework;

@@ -197,9 +196,9 @@ private static void VerifyCancunSpecificsForMainnetAndHoleskyAndSepolia(IRelease
Assert.Multiple(() =>
{
Assert.That(spec.BlobBaseFeeUpdateFraction, Is.EqualTo((UInt256)3338477));
Assert.That(spec.MaxBlobCount * Eip4844Constants.GasPerBlob, Is.EqualTo(786432));
Assert.That(spec.GetMaxBlobGas(), Is.EqualTo(786432));
Assert.That(Eip4844Constants.MinBlobGasPrice, Is.EqualTo(1.GWei()));
Assert.That(spec.TargetBlobCount * Eip4844Constants.GasPerBlob, Is.EqualTo(393216));
Assert.That(spec.GetTargetBlobGas(), Is.EqualTo(393216));
});
}

@@ -301,9 +300,9 @@ private static void VerifyGnosisCancunSpecifics(IReleaseSpec spec)
Assert.Multiple(() =>
{
Assert.That(spec.BlobBaseFeeUpdateFraction, Is.EqualTo((UInt256)1112826));
Assert.That(spec.MaxBlobCount * Eip4844Constants.GasPerBlob, Is.EqualTo(262144));
Assert.That(spec.GetMaxBlobGas(), Is.EqualTo(262144));
Assert.That(Eip4844Constants.MinBlobGasPrice, Is.EqualTo(1.GWei()));
Assert.That(spec.TargetBlobCount * Eip4844Constants.GasPerBlob, Is.EqualTo(131072));
Assert.That(spec.GetTargetBlobGas(), Is.EqualTo(131072));
});
}

0 comments on commit fe89802

Please sign in to comment.