Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-4844-Pectra: Blob gas fee collection for Gnosis #6866

Merged
merged 26 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
276d214
burn blob gas fees, rename price to fee
Marchhill Mar 26, 2024
c65c172
add test that blob gas fee burned / collected
Marchhill Mar 26, 2024
6b437d3
compute blob gas once, check burned funds added to fee collector
Marchhill Mar 28, 2024
11fd256
change blob gas price names to be clearer
Marchhill Apr 2, 2024
1d167f4
timestamp enabled fork
Marchhill Apr 8, 2024
83d0153
load transition timestamp from chainspec config
Marchhill Apr 9, 2024
ee888bd
merge master
Marchhill Apr 15, 2024
824a5d1
Merge branch 'master' of github.com:NethermindEth/nethermind into fix…
Marchhill Apr 15, 2024
43656ca
use nameof Barnet
Marchhill Apr 15, 2024
1d291dc
merge master
Marchhill Sep 12, 2024
62f450c
move to prague fork
Marchhill Sep 12, 2024
36472af
add to all chainspec loaders and rename to EIP4844-Pectra
Marchhill Sep 12, 2024
8d58ca1
fix whitespace
Marchhill Sep 12, 2024
76f5d0d
prague specs in test
Marchhill Sep 12, 2024
8c5c77e
merge master
Marchhill Sep 26, 2024
28dd715
rename eip1559feecollector to feecollector
Marchhill Sep 26, 2024
fd2148d
Merge remote-tracking branch 'upstream/master' into fix/blob-fee-coll…
Marchhill Sep 26, 2024
b168a55
uint256 zero
Marchhill Sep 26, 2024
9c605fa
rename pectra to feecollector, refactor collection/burning
Marchhill Sep 26, 2024
919ec8d
separate gnosis prague instance
Marchhill Sep 26, 2024
0b114c3
use gnosisprague instance in test
Marchhill Sep 26, 2024
d31b965
separate gnosis forks
Marchhill Sep 26, 2024
75ffc3b
add gnosisforks folder
Marchhill Sep 26, 2024
cea59ea
Merge remote-tracking branch 'upstream/master' into fix/blob-fee-coll…
Marchhill Sep 26, 2024
7168da7
praguegnosis instance
Marchhill Sep 26, 2024
9a53e38
merge master
Marchhill Oct 1, 2024
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 @@ -106,10 +106,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.TryCalculateBlobGasFee(block.Header, transaction, out UInt256 blobGasFee) ||
senderBalance < (maxFee += blobGasFee)))
{
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}, BlobGasFee: {blobGasFee}");
return false;
}
}
Expand Down
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_gas_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.TryCalculateBlobGasFee(header, testCase.tx, out UInt256 blobGasFee);

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

[Test]
public void Blob_gas_price_may_overflow()
public void Blob_gas_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.TryCalculateBlobGasFee(header, tx, out UInt256 blobGasFee);

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

public static IEnumerable<(ulong parentExcessBlobGas, int parentBlobsCount, ulong expectedExcessBlobGas)> ExcessBlobGasTestCaseSource()
Expand Down
35 changes: 35 additions & 0 deletions src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Nethermind.Specs.Test;
using Nethermind.State;
using Nethermind.Trie.Pruning;
using Nethermind.Int256;
using NUnit.Framework;

namespace Nethermind.Evm.Test;
Expand Down Expand Up @@ -106,6 +107,40 @@ public void Check_paid_fees_multiple_transactions(bool withFeeCollector)
tracer.BurntFees.Should().Be(84000);
}

[TestCase(false)]
[TestCase(true)]
public void Check_paid_fees_with_blob(bool withFeeCollector)
Marchhill marked this conversation as resolved.
Show resolved Hide resolved
{
UInt256 initialBalance = 0;
if (withFeeCollector)
{
_spec.Eip1559FeeCollector = TestItem.AddressC;
initialBalance = _stateProvider.GetBalance(TestItem.AddressC);
}

BlockHeader header = Build.A.BlockHeader.WithExcessBlobGas(0).TestObject;

Transaction tx = Build.A.Transaction
.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithType(TxType.Blob)
.WithBlobVersionedHashes(1).WithMaxFeePerBlobGas(1).TestObject;

Block block = Build.A.Block.WithNumber(0).WithBaseFeePerGas(1)
.WithBeneficiary(TestItem.AddressB).WithTransactions(tx).WithGasLimit(21000).WithHeader(header).TestObject;

FeesTracer tracer = new();
ExecuteAndTrace(block, tracer);

tracer.Fees.Should().Be(0);

block.GasUsed.Should().Be(21000);
tracer.BurntFees.Should().Be(131072);

if (withFeeCollector)
{
UInt256 currentBalance = _stateProvider.GetBalance(TestItem.AddressC);
(currentBalance - initialBalance).Should().Be(131072);
}
}

[Test]
public void Check_paid_fees_with_byte_code()
Expand Down
6 changes: 3 additions & 3 deletions src/Nethermind/Nethermind.Evm/BlobGasCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ public static ulong CalculateBlobGas(Transaction[] transactions)
return CalculateBlobGas(blobCount);
}

public static bool TryCalculateBlobGasPrice(BlockHeader header, Transaction transaction, out UInt256 blobGasPrice)
public static bool TryCalculateBlobGasFee(BlockHeader header, Transaction transaction, out UInt256 blobGasFee)
Marchhill marked this conversation as resolved.
Show resolved Hide resolved
{
if (!TryCalculateBlobGasPricePerUnit(header.ExcessBlobGas.Value, out UInt256 blobGasPricePerUnit))
{
blobGasPrice = UInt256.MaxValue;
blobGasFee = UInt256.MaxValue;
return false;
}
return !UInt256.MultiplyOverflow(CalculateBlobGas(transaction), blobGasPricePerUnit, out blobGasPrice);
return !UInt256.MultiplyOverflow(CalculateBlobGas(transaction), blobGasPricePerUnit, out blobGasFee);
}

public static bool TryCalculateBlobGasPricePerUnit(BlockHeader header, out UInt256 blobGasPricePerUnit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ protected virtual TransactionResult Execute(Transaction tx, in BlockExecutionCon
bool deleteCallerAccount = RecoverSenderIfNeeded(tx, spec, opts, effectiveGasPrice);

if (!(result = ValidateSender(tx, header, spec, tracer, opts))) return result;
if (!(result = BuyGas(tx, header, spec, tracer, opts, effectiveGasPrice, out UInt256 premiumPerGas, out UInt256 senderReservedGasPayment))) return result;
if (!(result = BuyGas(tx, header, spec, tracer, opts, effectiveGasPrice, out UInt256 premiumPerGas, out UInt256 senderReservedGasPayment, out UInt256 blobGasFee))) return result;
if (!(result = IncrementNonce(tx, header, spec, tracer, opts))) return result;

if (commit) WorldState.Commit(spec, tracer.IsTracingState ? tracer : NullTxTracer.Instance);
Expand All @@ -131,7 +131,7 @@ protected virtual TransactionResult Execute(Transaction tx, in BlockExecutionCon

long gasAvailable = tx.GasLimit - intrinsicGas;
ExecuteEvmCall(tx, header, spec, tracer, opts, gasAvailable, env, out TransactionSubstate? substate, out long spentGas, out byte statusCode);
PayFees(tx, header, spec, tracer, substate, spentGas, premiumPerGas, statusCode);
PayFees(tx, header, spec, tracer, substate, spentGas, premiumPerGas, blobGasFee, statusCode);

// Finalize
if (restore)
Expand Down Expand Up @@ -319,10 +319,11 @@ protected virtual TransactionResult ValidateSender(Transaction tx, BlockHeader h
}

protected virtual TransactionResult BuyGas(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts,
in UInt256 effectiveGasPrice, out UInt256 premiumPerGas, out UInt256 senderReservedGasPayment)
in UInt256 effectiveGasPrice, out UInt256 premiumPerGas, out UInt256 senderReservedGasPayment, out UInt256 blobGasFee)
{
premiumPerGas = UInt256.Zero;
senderReservedGasPayment = UInt256.Zero;
blobGasFee = UInt256.Zero;
bool validate = !opts.HasFlag(ExecutionOptions.NoValidation);

if (!tx.IsSystem() && validate)
Expand Down Expand Up @@ -363,7 +364,7 @@ protected virtual TransactionResult BuyGas(Transaction tx, BlockHeader header, I
overflows = UInt256.MultiplyOverflow((UInt256)tx.GasLimit, effectiveGasPrice, out senderReservedGasPayment);
if (!overflows && tx.SupportsBlobs)
{
overflows = !BlobGasCalculator.TryCalculateBlobGasPrice(header, tx, out UInt256 blobGasFee);
overflows = !BlobGasCalculator.TryCalculateBlobGasFee(header, tx, out blobGasFee);
if (!overflows)
{
overflows = UInt256.AddOverflow(senderReservedGasPayment, blobGasFee, out senderReservedGasPayment);
Expand Down Expand Up @@ -552,7 +553,7 @@ protected void ExecuteEvmCall(
header.GasUsed += spentGas;
}

protected virtual void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, in TransactionSubstate substate, in long spentGas, in UInt256 premiumPerGas, in byte statusCode)
protected virtual void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, in TransactionSubstate substate, in long spentGas, in UInt256 premiumPerGas, in UInt256 blobGasFee, in byte statusCode)
{
if (!tx.IsSystem())
{
Expand All @@ -562,6 +563,11 @@ protected virtual void PayFees(Transaction tx, BlockHeader header, IReleaseSpec
UInt256 fees = (UInt256)spentGas * premiumPerGas;
UInt256 burntFees = !tx.IsFree() ? (UInt256)spentGas * header.BaseFeePerGas : 0;

if (tx.SupportsBlobs)
{
burntFees += blobGasFee;
LukaszRozmej marked this conversation as resolved.
Show resolved Hide resolved
}

WorldState.AddToBalanceAndCreateIfNotExists(header.GasBeneficiary, fees, spec);

if (spec.IsEip1559Enabled && spec.Eip1559FeeCollector is not null && !burntFees.IsZero)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,11 @@ protected override TransactionResult ValidateStatic(Transaction tx, BlockHeader
}

protected override TransactionResult BuyGas(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts,
in UInt256 effectiveGasPrice, out UInt256 premiumPerGas, out UInt256 senderReservedGasPayment)
in UInt256 effectiveGasPrice, out UInt256 premiumPerGas, out UInt256 senderReservedGasPayment, out UInt256 blobGasFee)
{
premiumPerGas = UInt256.Zero;
senderReservedGasPayment = UInt256.Zero;
blobGasFee = UInt256.Zero;

bool validate = !opts.HasFlag(ExecutionOptions.NoValidation);

Expand Down Expand Up @@ -145,12 +146,12 @@ protected override TransactionResult ValidateSender(Transaction tx, BlockHeader
tx.IsDeposit() ? TransactionResult.Ok : base.ValidateSender(tx, header, spec, tracer, opts);

protected override void PayFees(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer,
in TransactionSubstate substate, in long spentGas, in UInt256 premiumPerGas, in byte statusCode)
in TransactionSubstate substate, in long spentGas, in UInt256 premiumPerGas, in UInt256 blobGasFee, in byte statusCode)
{
if (!tx.IsDeposit())
{
// Skip coinbase payments for deposit tx in Regolith
base.PayFees(tx, header, spec, tracer, substate, spentGas, premiumPerGas, statusCode);
base.PayFees(tx, header, spec, tracer, substate, spentGas, premiumPerGas, blobGasFee, statusCode);

if (_opConfigHelper.IsBedrock(header))
{
Expand Down