Skip to content

Commit

Permalink
Fix ecotone fee logic (#7009)
Browse files Browse the repository at this point in the history
Co-authored-by: Alexey Osipov <me@flcl.me>
  • Loading branch information
deffrian and flcl42 authored May 22, 2024
1 parent 485fd8a commit 7172ef9
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 22 deletions.
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
9 changes: 8 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,7 @@ public OPSpecHelper(OptimismParameters parameters)
_regolithTimestamp = parameters.RegolithTimestamp;
_bedrockBlockNumber = parameters.BedrockBlockNumber;
_canyonTimestamp = parameters.CanyonTimestamp;
_ecotoneTimestamp = parameters.EcotoneTimestamp;

L1FeeReceiver = parameters.L1FeeRecipient;
Create2DeployerCode = parameters.Create2DeployerCode;
Expand All @@ -37,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)
{
// 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);

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

0 comments on commit 7172ef9

Please sign in to comment.