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

Fix ecotone fee logic #7009

Merged
merged 8 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 7 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
1 change: 1 addition & 0 deletions src/Nethermind/Chains/base-mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"params": {
"regolithTimestamp": "0x0",
"bedrockBlockNumber": "0x0",
"ecotoneTimestamp": "0x65F23E01",
"l1FeeRecipient": "0x420000000000000000000000000000000000001A",
"l1BlockAddress": "0x4200000000000000000000000000000000000015"
}
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Chains/base-sepolia.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"regolithTimestamp": "0x0",
"bedrockBlockNumber": "0x0",
"canyonTimestamp": "0x6553a790",
"ecotoneTimestamp": "0x65D62C10",
"l1FeeRecipient": "0x420000000000000000000000000000000000001A",
"l1BlockAddress": "0x4200000000000000000000000000000000000015",
"canyonBaseFeeChangeDenominator": "250",
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Chains/op-mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"params": {
"regolithTimestamp": "0x0",
"bedrockBlockNumber": "0x645C277",
"ecotoneTimestamp": "0x65F23E01",
"l1FeeRecipient": "0x420000000000000000000000000000000000001A",
"l1BlockAddress": "0x4200000000000000000000000000000000000015"
}
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Chains/op-sepolia.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"regolithTimestamp": "0x0",
"bedrockBlockNumber": "0x0",
"canyonTimestamp": "0x6553a790",
"ecotoneTimestamp": "0x65D62C10",
"l1FeeRecipient": "0x420000000000000000000000000000000000001A",
"l1BlockAddress": "0x4200000000000000000000000000000000000015",
"canyonBaseFeeChangeDenominator": "250",
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Nethermind.Optimism/IOPConfigHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public interface IOPConfigHelper
bool IsBedrock(BlockHeader header);
bool IsRegolith(BlockHeader header);
bool IsCanyon(BlockHeader header);
bool IsEcotone(BlockHeader header);
Address? Create2DeployerAddress { get; }
byte[]? Create2DeployerCode { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
Expand Down
10 changes: 9 additions & 1 deletion src/Nethermind/Nethermind.Optimism/OPConfigHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class OPSpecHelper : IOPConfigHelper
private readonly ulong _regolithTimestamp;
private readonly long _bedrockBlockNumber;
private readonly ulong? _canyonTimestamp;
private readonly ulong? _ecotoneTimestamp;

public Address L1FeeReceiver { get; init; }

Expand All @@ -19,6 +20,8 @@ public OPSpecHelper(OptimismParameters parameters)
_regolithTimestamp = parameters.RegolithTimestamp;
_bedrockBlockNumber = parameters.BedrockBlockNumber;
_canyonTimestamp = parameters.CanyonTimestamp;
_ecotoneTimestamp = parameters.EcotoneTimestamp;

L1FeeReceiver = parameters.L1FeeRecipient;
Create2DeployerCode = parameters.Create2DeployerCode;
Create2DeployerAddress = parameters.Create2DeployerAddress;
Expand All @@ -36,7 +39,12 @@ public bool IsBedrock(BlockHeader header)

public bool IsCanyon(BlockHeader header)
{
return header.Timestamp >= (_canyonTimestamp ?? long.MaxValue);
return header.Timestamp >= _canyonTimestamp;
}

public bool IsEcotone(BlockHeader header)
{
return header.Timestamp >= _ecotoneTimestamp;
}

public Address? Create2DeployerAddress { get; }
Expand Down
71 changes: 50 additions & 21 deletions src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Linq;
using System.Runtime.CompilerServices;
using Nethermind.Core;
using Nethermind.Evm;
using Nethermind.Int256;
Expand All @@ -11,40 +12,68 @@

namespace Nethermind.Optimism;

public class OPL1CostHelper : IL1CostHelper
public class OPL1CostHelper(IOPConfigHelper opConfigHelper, Address l1BlockAddr) : IL1CostHelper
{
private readonly IOPConfigHelper _opConfigHelper;
private readonly IOPConfigHelper _opConfigHelper = opConfigHelper;

private readonly StorageCell _l1BaseFeeSlot;
private readonly StorageCell _overheadSlot;
private readonly StorageCell _scalarSlot;
private readonly StorageCell _l1BaseFeeSlot = new(l1BlockAddr, new UInt256(1));
private readonly StorageCell _overheadSlot = new(l1BlockAddr, new UInt256(5));
private readonly StorageCell _scalarSlot = new(l1BlockAddr, new UInt256(6));

public OPL1CostHelper(IOPConfigHelper opConfigHelper, Address l1BlockAddr)
{
_opConfigHelper = opConfigHelper;
private static readonly UInt256 basicDevider = 1_000_000;

_l1BaseFeeSlot = new StorageCell(l1BlockAddr, new UInt256(1));
_overheadSlot = new StorageCell(l1BlockAddr, new UInt256(5));
_scalarSlot = new StorageCell(l1BlockAddr, new UInt256(6));
}
// Ecotone
private readonly StorageCell _blobBaseFeeSlot = new(l1BlockAddr, new UInt256(7));
private readonly StorageCell _baseFeeScalarSlot = new(l1BlockAddr, new UInt256(3));

private static readonly UInt256 precisionMultiplier = 16;
private static readonly UInt256 precisionDevider = precisionMultiplier * basicDevider;

[SkipLocalsInit]
public UInt256 ComputeL1Cost(Transaction tx, BlockHeader header, IWorldState worldState)
{
[SkipLocalsInit]
UInt256 ComputeL1CostEcotone(IWorldState worldState, UInt256 dataGas)
{
flcl42 marked this conversation as resolved.
Show resolved Hide resolved
// Ecotone formula: (dataGas) * (16 * l1BaseFee * l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar) / 16e6
UInt256 l1BaseFee = new(worldState.Get(_l1BaseFeeSlot), true);
UInt256 blobBaseFee = new(worldState.Get(_blobBaseFeeSlot), true);

ReadOnlySpan<byte> scalarData = worldState.Get(_baseFeeScalarSlot);

const int baseFeeFieldsStart = 16;
const int fieldSize = sizeof(uint);

int l1BaseFeeScalarStart = scalarData.Length > baseFeeFieldsStart ? scalarData.Length - baseFeeFieldsStart : 0;
int l1BaseFeeScalarEnd = l1BaseFeeScalarStart + (scalarData.Length >= baseFeeFieldsStart ? fieldSize : fieldSize - baseFeeFieldsStart + scalarData.Length);
UInt256 l1BaseFeeScalar = new(scalarData[l1BaseFeeScalarStart..l1BaseFeeScalarEnd], true);
UInt256 l1BlobBaseFeeScalar = new(scalarData[l1BaseFeeScalarEnd..(l1BaseFeeScalarEnd + fieldSize)], true);

return dataGas * (precisionMultiplier * l1BaseFee * l1BaseFeeScalar + blobBaseFee * l1BlobBaseFeeScalar) / precisionDevider;
}

[SkipLocalsInit]
UInt256 ComputeL1CostPreEcotone(IWorldState worldState, UInt256 dataGas)
{
// Pre-Ecotone formula: (dataGas + overhead) * l1BaseFee * scalar / 1e6
UInt256 l1BaseFee = new(worldState.Get(_l1BaseFeeSlot), true);
UInt256 overhead = new(worldState.Get(_overheadSlot), true);
UInt256 scalar = new(worldState.Get(_scalarSlot), true);
flcl42 marked this conversation as resolved.
Show resolved Hide resolved

return (dataGas + overhead) * l1BaseFee * scalar / basicDevider;
}

if (tx.IsDeposit())
return UInt256.Zero;

long dataGas = ComputeDataGas(tx, header);
if (dataGas == 0)
UInt256 dataGas = ComputeDataGas(tx, header);
if (dataGas.IsZero)
return UInt256.Zero;

UInt256 l1BaseFee = new(worldState.Get(_l1BaseFeeSlot), true);
UInt256 overhead = new(worldState.Get(_overheadSlot), true);
UInt256 scalar = new(worldState.Get(_scalarSlot), true);

return ((UInt256)dataGas + overhead) * l1BaseFee * scalar / 1_000_000;
return _opConfigHelper.IsEcotone(header) ? ComputeL1CostEcotone(worldState, dataGas) : ComputeL1CostPreEcotone(worldState, dataGas);
}

private long ComputeDataGas(Transaction tx, BlockHeader header)
private UInt256 ComputeDataGas(Transaction tx, BlockHeader header)
{
byte[] encoded = Rlp.Encode(tx, RlpBehaviors.SkipTypedWrapping).Bytes;

Expand All @@ -53,6 +82,6 @@ private long ComputeDataGas(Transaction tx, BlockHeader header)
// Add pre-EIP-3529 overhead
nonZeroCount += _opConfigHelper.IsRegolith(header) ? 0 : OptimismConstants.PreRegolithNonZeroCountOverhead;

return zeroCount * GasCostOf.TxDataZero + nonZeroCount * GasCostOf.TxDataNonZeroEip2028;
return (ulong)(zeroCount * GasCostOf.TxDataZero + nonZeroCount * GasCostOf.TxDataNonZeroEip2028);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ static AuRaParameters.Validator LoadValidator(ChainSpecJson.AuRaValidatorJson va
RegolithTimestamp = chainSpecJson.Engine.Optimism.RegolithTimestamp,
BedrockBlockNumber = chainSpecJson.Engine.Optimism.BedrockBlockNumber,
CanyonTimestamp = chainSpecJson.Engine.Optimism.CanyonTimestamp,
EcotoneTimestamp = chainSpecJson.Engine.Optimism.EcotoneTimestamp,
L1FeeRecipient = chainSpecJson.Engine.Optimism.L1FeeRecipient,
L1BlockAddress = chainSpecJson.Engine.Optimism.L1BlockAddress,
CanyonBaseFeeChangeDenominator = chainSpecJson.Engine.Optimism.CanyonBaseFeeChangeDenominator,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ internal class OptimismEngineJson
public ulong RegolithTimestamp => Params.RegolithTimestamp;
public long BedrockBlockNumber => Params.BedrockBlockNumber;
public ulong? CanyonTimestamp => Params.CanyonTimestamp;
public ulong? EcotoneTimestamp => Params.EcotoneTimestamp;
public Address L1FeeRecipient => Params.L1FeeRecipient;
public Address L1BlockAddress => Params.L1BlockAddress;
public UInt256 CanyonBaseFeeChangeDenominator => Params.CanyonBaseFeeChangeDenominator;
Expand All @@ -186,6 +187,7 @@ internal class OptimismEngineParamsJson
public ulong RegolithTimestamp { get; set; }
public long BedrockBlockNumber { get; set; }
public ulong? CanyonTimestamp { get; set; }
public ulong? EcotoneTimestamp { get; set; }
public Address L1FeeRecipient { get; set; }
public Address L1BlockAddress { get; set; }
public UInt256 CanyonBaseFeeChangeDenominator { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class OptimismParameters

public ulong? CanyonTimestamp { get; set; }

public ulong? EcotoneTimestamp { get; set; }

public Address L1FeeRecipient { get; set; }

public Address L1BlockAddress { get; set; }
Expand Down