Skip to content

Commit

Permalink
EIP-4844-Pectra: Blob gas fee collection for Gnosis (#6866)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marchhill authored Oct 1, 2024
1 parent f825abd commit dcc9ef1
Show file tree
Hide file tree
Showing 43 changed files with 201 additions and 111 deletions.
2 changes: 1 addition & 1 deletion src/Nethermind/Chains/base-mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"eip2930Transition": "0x0",
"eip1559Transition": "0x0",
"eip1559FeeCollectorTransition": "0x0",
"eip1559FeeCollector": "0x4200000000000000000000000000000000000019",
"feeCollector": "0x4200000000000000000000000000000000000019",
"eip1559ElasticityMultiplier": "0x6",
"eip1559BaseFeeMaxChangeDenominator": "0x32",
"eip3198Transition": "0x0",
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Chains/base-sepolia.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"eip2930Transition": "0x0",
"eip1559Transition": "0x0",
"eip1559FeeCollectorTransition": "0x0",
"eip1559FeeCollector": "0x4200000000000000000000000000000000000019",
"feeCollector": "0x4200000000000000000000000000000000000019",
"eip1559ElasticityMultiplier": "0xa",
"eip1559BaseFeeMaxChangeDenominator": "0x32",
"eip3198Transition": "0x0",
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Chains/chiado.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"eip6780TransitionTimestamp": "0x65ba8e4c",
"eip1559BaseFeeMaxChangeDenominator": "0x8",
"eip1559ElasticityMultiplier": "0x2",
"eip1559FeeCollector": "0x1559000000000000000000000000000000000000",
"feeCollector": "0x1559000000000000000000000000000000000000",
"eip1559FeeCollectorTransition": 0,
"eip4844BlobGasPriceUpdateFraction": "0x10fafa",
"eip4844MaxBlobGasPerBlock": "0x40000",
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Chains/gnosis.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"eip1559BaseFeeMaxChangeDenominator": "0x8",
"eip1559ElasticityMultiplier": "0x2",
"eip1559BaseFeeInitialValue": "0x3b9aca00",
"eip1559FeeCollector": "0x6BBe78ee9e474842Dbd4AB4987b3CeFE88426A92",
"feeCollector": "0x6BBe78ee9e474842Dbd4AB4987b3CeFE88426A92",
"eip1559FeeCollectorTransition": 19040000,
"eip4844BlobGasPriceUpdateFraction": "0x10fafa",
"eip4844MaxBlobGasPerBlock": "0x40000",
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Chains/op-mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"eip2930Transition": "0x3C45B0",
"eip1559Transition": "0x645C277",
"eip1559FeeCollectorTransition": "0x645C277",
"eip1559FeeCollector": "0x4200000000000000000000000000000000000019",
"feeCollector": "0x4200000000000000000000000000000000000019",
"eip1559ElasticityMultiplier": "0x6",
"eip1559BaseFeeMaxChangeDenominator": "0x32",
"eip3198Transition": "0x645C277",
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Chains/op-sepolia.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"eip2930Transition": "0x0",
"eip1559Transition": "0x0",
"eip1559FeeCollectorTransition": "0x0",
"eip1559FeeCollector": "0x4200000000000000000000000000000000000019",
"feeCollector": "0x4200000000000000000000000000000000000019",
"eip1559ElasticityMultiplier": "0x6",
"eip1559BaseFeeMaxChangeDenominator": "0x32",
"eip3198Transition": "0x0",
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Chains/poacore.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"eip1559BaseFeeInitialValue": "0x3b9aca00",
"eip1559BaseFeeMinValue": "0x2540be400",
"eip1559BaseFeeMinValueTransition": 24199500,
"eip1559FeeCollector": "0x517F3AcfF3aFC2fb45e574718bca6F919b798e10",
"feeCollector": "0x517F3AcfF3aFC2fb45e574718bca6F919b798e10",
"eip1559FeeCollectorTransition": 24090200
},
"genesis": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private async Task<ScenarioBuilder> CreateTestBlockchainAsync(long gasLimit)
{
IsEip1559Enabled = _eip1559Enabled,
Eip1559TransitionBlock = _eip1559TransitionBlock,
Eip1559FeeCollector = _eip1559FeeCollector,
FeeCollector = _feeCollector,
IsEip155Enabled = true
});
BlockBuilder blockBuilder = Build.A.Block.Genesis.WithGasLimit(gasLimit);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ public static partial class BaseFeeTestScenario
{
public partial class ScenarioBuilder
{
private Address _eip1559FeeCollector = null!;
private Address _feeCollector = null!;

public ScenarioBuilder WithEip1559FeeCollector(Address address)
public ScenarioBuilder WithFeeCollector(Address address)
{
_eip1559FeeCollector = address;
_feeCollector = address;
return this;
}

Expand All @@ -33,9 +33,9 @@ public ScenarioBuilder AssertNewBlockFeeCollected(UInt256 expectedFeeCollected,
private async Task<ScenarioBuilder> AssertNewBlockFeeCollectedAsync(UInt256 expectedFeeCollected, params Transaction[] transactions)
{
await ExecuteAntecedentIfNeeded();
UInt256 balanceBefore = _testRpcBlockchain.State.GetBalance(_eip1559FeeCollector);
UInt256 balanceBefore = _testRpcBlockchain.State.GetBalance(_feeCollector);
await _testRpcBlockchain.AddBlock(transactions);
UInt256 balanceAfter = _testRpcBlockchain.State.GetBalance(_eip1559FeeCollector);
UInt256 balanceAfter = _testRpcBlockchain.State.GetBalance(_feeCollector);
Assert.That(balanceAfter - balanceBefore, Is.EqualTo(expectedFeeCollected));

return this;
Expand All @@ -49,7 +49,7 @@ public async Task FeeCollector_should_collect_burned_fees_when_eip1559_and_fee_c
long gasTarget = 3000000;
BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis()
.WithEip1559TransitionBlock(6)
.WithEip1559FeeCollector(TestItem.AddressE)
.WithFeeCollector(TestItem.AddressE)
.CreateTestBlockchain(gasTarget)
.DeployContract()
.BlocksBeforeTransitionShouldHaveZeroBaseFee()
Expand All @@ -65,7 +65,7 @@ public async Task FeeCollector_should_not_collect_burned_fees_when_eip1559_is_no
{
long gasTarget = 3000000;
BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis()
.WithEip1559FeeCollector(TestItem.AddressE)
.WithFeeCollector(TestItem.AddressE)
.CreateTestBlockchain(gasTarget)
.DeployContract()
.BlocksBeforeTransitionShouldHaveZeroBaseFee()
Expand All @@ -82,7 +82,7 @@ public async Task FeeCollector_should_not_collect_burned_fees_when_transaction_i
long gasTarget = 3000000;
BaseFeeTestScenario.ScenarioBuilder scenario = BaseFeeTestScenario.GoesLikeThis()
.WithEip1559TransitionBlock(6)
.WithEip1559FeeCollector(TestItem.AddressE)
.WithFeeCollector(TestItem.AddressE)
.CreateTestBlockchain(gasTarget)
.DeployContract()
.BlocksBeforeTransitionShouldHaveZeroBaseFee()
Expand Down
8 changes: 4 additions & 4 deletions src/Nethermind/Nethermind.Blockchain/ChainHeadInfoProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public ChainHeadInfoProvider(IChainHeadSpecProvider specProvider, IBlockTree blo

public UInt256 CurrentBaseFee { get; private set; }

public UInt256 CurrentPricePerBlobGas { get; internal set; }
public UInt256 CurrentFeePerBlobGas { get; internal set; }

public event EventHandler<BlockReplacementEventArgs>? HeadChanged;

Expand All @@ -55,9 +55,9 @@ private void OnHeadChanged(object? sender, BlockReplacementEventArgs e)
HeadNumber = e.Block.Number;
BlockGasLimit = e.Block!.GasLimit;
CurrentBaseFee = e.Block.Header.BaseFeePerGas;
CurrentPricePerBlobGas =
BlobGasCalculator.TryCalculateBlobGasPricePerUnit(e.Block.Header, out UInt256 currentPricePerBlobGas)
? currentPricePerBlobGas
CurrentFeePerBlobGas =
BlobGasCalculator.TryCalculateFeePerBlobGas(e.Block.Header, out UInt256 currentFeePerBlobGas)
? currentFeePerBlobGas
: UInt256.Zero;
HeadChanged?.Invoke(sender, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ private static bool HasEnoughFounds(Transaction transaction, in UInt256 senderBa
}

if (transaction.SupportsBlobs && (
!BlobGasCalculator.TryCalculateBlobGasPrice(block.Header, transaction, out UInt256 blobGasPrice) ||
senderBalance < (maxFee += blobGasPrice)))
!BlobGasCalculator.TryCalculateBlobBaseFee(block.Header, transaction, out UInt256 blobBaseFee) ||
senderBalance < (maxFee += blobBaseFee)))
{
e.Set(TxAction.Skip, $"{maxFee} is higher than sender balance ({senderBalance}), MaxFeePerGas: ({transaction.MaxFeePerGas}), GasLimit {transaction.GasLimit}, BlobGasPrice: {blobGasPrice}");
e.Set(TxAction.Skip, $"{maxFee} is higher than sender balance ({senderBalance}), MaxFeePerGas: ({transaction.MaxFeePerGas}), GasLimit {transaction.GasLimit}, BlobBaseFee: {blobBaseFee}");
return false;
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private void SelectBlobTransactions(IEnumerable<Transaction> blobTransactions, B
int checkedBlobTransactions = 0;
int selectedBlobTransactions = 0;
UInt256 blobGasCounter = 0;
UInt256 blobGasPrice = UInt256.Zero;
UInt256 feePerBlobGas = UInt256.Zero;

foreach (Transaction blobTx in blobTransactions)
{
Expand All @@ -143,13 +143,13 @@ private void SelectBlobTransactions(IEnumerable<Transaction> blobTransactions, B
continue;
}

if (blobGasPrice.IsZero && !TryUpdateBlobGasPrice(blobTx, parent, spec, out blobGasPrice))
if (feePerBlobGas.IsZero && !TryUpdateFeePerBlobGas(blobTx, parent, spec, out feePerBlobGas))
{
if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, failed to get full version of this blob tx from TxPool.");
continue;
}

if (blobGasPrice > blobTx.MaxFeePerBlobGas)
if (feePerBlobGas > blobTx.MaxFeePerBlobGas)
{
if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, data gas fee is too low.");
continue;
Expand Down Expand Up @@ -186,20 +186,20 @@ private bool TryGetFullBlobTx(Transaction blobTx, [NotNullWhen(true)] out Transa
return blobTx.Hash is not null && _transactionPool.TryGetPendingBlobTransaction(blobTx.Hash, out fullBlobTx);
}

private bool TryUpdateBlobGasPrice(Transaction lightBlobTx, BlockHeader parent, IReleaseSpec spec, out UInt256 blobGasPrice)
private bool TryUpdateFeePerBlobGas(Transaction lightBlobTx, BlockHeader parent, IReleaseSpec spec, out UInt256 feePerBlobGas)
{
ulong? excessDataGas = BlobGasCalculator.CalculateExcessBlobGas(parent, spec);
if (excessDataGas is null)
{
if (_logger.IsTrace) _logger.Trace($"Declining {lightBlobTx.ToShortString()}, the specification is not configured to handle shard blob transactions.");
blobGasPrice = UInt256.Zero;
feePerBlobGas = UInt256.Zero;
return false;
}

if (!BlobGasCalculator.TryCalculateBlobGasPricePerUnit(excessDataGas.Value, out blobGasPrice))
if (!BlobGasCalculator.TryCalculateFeePerBlobGas(excessDataGas.Value, out feePerBlobGas))
{
if (_logger.IsTrace) _logger.Trace($"Declining {lightBlobTx.ToShortString()}, failed to calculate data gas price.");
blobGasPrice = UInt256.Zero;
feePerBlobGas = UInt256.Zero;
return false;
}

Expand Down
10 changes: 5 additions & 5 deletions src/Nethermind/Nethermind.Consensus/Validators/BlockValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ private bool ValidateEip4844Fields(Block block, IReleaseSpec spec, out string? e
}

int blobsInBlock = 0;
UInt256 blobGasPrice = UInt256.Zero;
UInt256 feePerBlobGas = UInt256.Zero;
Transaction[] transactions = block.Transactions;

for (int txIndex = 0; txIndex < transactions.Length; txIndex++)
Expand All @@ -383,20 +383,20 @@ private bool ValidateEip4844Fields(Block block, IReleaseSpec spec, out string? e
continue;
}

if (blobGasPrice.IsZero)
if (feePerBlobGas.IsZero)
{
if (!BlobGasCalculator.TryCalculateBlobGasPricePerUnit(block.Header, out blobGasPrice))
if (!BlobGasCalculator.TryCalculateFeePerBlobGas(block.Header, out feePerBlobGas))
{
error = BlockErrorMessages.BlobGasPriceOverflow;
if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} {error}.");
return false;
}
}

if (transaction.MaxFeePerBlobGas < blobGasPrice)
if (transaction.MaxFeePerBlobGas < feePerBlobGas)
{
error = BlockErrorMessages.InsufficientMaxFeePerBlobGas;
if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} Transaction at index {txIndex} has insufficient {nameof(transaction.MaxFeePerBlobGas)} to cover current blob gas fee: {transaction.MaxFeePerBlobGas} < {blobGasPrice}.");
if (_logger.IsDebug) _logger.Debug($"{Invalid(block)} Transaction at index {txIndex} has insufficient {nameof(transaction.MaxFeePerBlobGas)} to cover current blob gas fee: {transaction.MaxFeePerBlobGas} < {feePerBlobGas}.");
return false;
}

Expand Down
3 changes: 2 additions & 1 deletion src/Nethermind/Nethermind.Core/Specs/IEip1559Spec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public interface IEip1559Spec
/// </summary>
bool IsEip1559Enabled { get; }
public long Eip1559TransitionBlock { get; }
public Address? Eip1559FeeCollector => null;
// Collects for both EIP-1559 and EIP-4844-Pectra
public Address? FeeCollector => null;
public UInt256? Eip1559BaseFeeMinValue => null;
public UInt256 ForkBaseFee { get; }
public UInt256 BaseFeeMaxChangeDenominator { get; }
Expand Down
6 changes: 6 additions & 0 deletions src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,12 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec
/// </summary>
bool IsEip6780Enabled { get; }

/// <summary>
/// Blob base fee collection for Gnosis
/// </summary>
bool IsEip4844FeeCollectorEnabled { get; }

/// <summary>
/// Secp256r1 precompile
/// </summary>
bool IsRip7212Enabled { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,5 @@ public class ReleaseSpecDecorator(IReleaseSpec spec) : IReleaseSpec
public virtual ulong WithdrawalTimestamp => spec.WithdrawalTimestamp;
public virtual ulong Eip4844TransitionTimestamp => spec.Eip4844TransitionTimestamp;
public virtual bool IsEip158IgnoredAccount(Address address) => spec.IsEip158IgnoredAccount(address);
public bool IsEip4844FeeCollectorEnabled => spec.IsEip4844FeeCollectorEnabled;
}
12 changes: 6 additions & 6 deletions src/Nethermind/Nethermind.Evm.Test/BlobGasCalculatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,27 @@ void Test(IReleaseSpec spec, bool areBlobsEnabled)
}

[TestCaseSource(nameof(BlobGasCostTestCaseSource))]
public void Blob_gas_price_is_calculated_properly(
public void Blob_base_fee_is_calculated_properly(
(Transaction tx, ulong excessBlobGas, UInt256 expectedCost) testCase)
{
BlockHeader header = Build.A.BlockHeader.WithExcessBlobGas(testCase.excessBlobGas).TestObject;

bool success = BlobGasCalculator.TryCalculateBlobGasPrice(header, testCase.tx, out UInt256 blobGasPrice);
bool success = BlobGasCalculator.TryCalculateBlobBaseFee(header, testCase.tx, out UInt256 blobBaseFee);

Assert.That(success, Is.True);
Assert.That(blobGasPrice, Is.EqualTo(testCase.expectedCost));
Assert.That(blobBaseFee, Is.EqualTo(testCase.expectedCost));
}

[Test]
public void Blob_gas_price_may_overflow()
public void Blob_base_fee_may_overflow()
{
var tx = Build.A.Transaction.WithType(TxType.Blob).WithBlobVersionedHashes(1000).TestObject;
BlockHeader header = Build.A.BlockHeader.WithExcessBlobGas(ulong.MaxValue).TestObject;

bool success = BlobGasCalculator.TryCalculateBlobGasPrice(header, tx, out UInt256 blobGasPrice);
bool success = BlobGasCalculator.TryCalculateBlobBaseFee(header, tx, out UInt256 blobBaseFee);

Assert.That(success, Is.False);
Assert.That(blobGasPrice, Is.EqualTo(UInt256.MaxValue));
Assert.That(blobBaseFee, Is.EqualTo(UInt256.MaxValue));
}

public static IEnumerable<(ulong parentExcessBlobGas, int parentBlobsCount, ulong expectedExcessBlobGas)> ExcessBlobGasTestCaseSource()
Expand Down
4 changes: 2 additions & 2 deletions src/Nethermind/Nethermind.Evm.Test/Eip7516BlobBaseFeeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ public void Blob_Base_fee_opcode_should_return_expected_results(bool eip7516Enab
TestAllTracerWithOutput tracer = CreateTracer();
_processor.Execute(transaction, block.Header, tracer);

_ = BlobGasCalculator.TryCalculateBlobGasPricePerUnit(excessBlobGas, out UInt256 expectedGasPrice);
_ = BlobGasCalculator.TryCalculateFeePerBlobGas(excessBlobGas, out UInt256 expectedFeePerBlobGas);
if (eip7516Enabled)
{
AssertStorage((UInt256)0, expectedGasPrice);
AssertStorage((UInt256)0, expectedFeePerBlobGas);
}
else
{
Expand Down
Loading

0 comments on commit dcc9ef1

Please sign in to comment.