Skip to content

Commit

Permalink
Avoid redundant copy; split into methods; add constants
Browse files Browse the repository at this point in the history
  • Loading branch information
flcl42 committed May 21, 2024
1 parent 704d932 commit 9e3b387
Showing 1 changed file with 28 additions and 21 deletions.
49 changes: 28 additions & 21 deletions src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,44 +35,51 @@ public OPL1CostHelper(IOPConfigHelper opConfigHelper, Address l1BlockAddr)
_baseFeeScalarSlot = new StorageCell(l1BlockAddr, new UInt256(3));
}

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

public UInt256 ComputeL1Cost(Transaction tx, BlockHeader header, IWorldState worldState)
{
if (tx.IsDeposit())
return UInt256.Zero;

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


if (_opConfigHelper.IsEcotone(header))
UInt256 ComputeL1CostEcotone(IWorldState worldState, UInt256 dataGas)
{
// Ecotone formula: (dataGas) * (16*l1BaseFee*l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar) / 16e6
// 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);
Span<byte> scalarDataAligned = stackalloc byte[32];
scalarData.CopyTo(scalarDataAligned[(32 - scalarData.Length)..]);

const int offset = 32 - 12 - 4;
UInt256 l1BaseFeeScalar = new(scalarDataAligned[offset..(offset + 4)], true);
UInt256 l1BlobBaseFeeScalar = new(scalarDataAligned[(offset + 4)..(offset + 8)], true);
const int baseFeeFieldsStart = 16;

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

return (UInt256)dataGas * (16 * l1BaseFee * l1BaseFeeScalar + blobBaseFee * l1BlobBaseFeeScalar) /
16_000_000;
return dataGas * (precisionMultiplier * l1BaseFee * l1BaseFeeScalar + blobBaseFee * l1BlobBaseFeeScalar) / precisionDevider;
}
else

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 ((UInt256)dataGas + overhead) * l1BaseFee * scalar / 1_000_000;
return (dataGas + overhead) * l1BaseFee * scalar / basicDevider;
}

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

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

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 @@ -81,6 +88,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);
}
}

0 comments on commit 9e3b387

Please sign in to comment.