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

Add fields to OP rpc; fix Ecotone gas issue; update pivots #7180

Merged
merged 4 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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: 0 additions & 1 deletion src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Nethermind.Core.Crypto;
using Nethermind.Core.Specs;
using Nethermind.Int256;
using Nethermind.JsonRpc.Data;
using Nethermind.Serialization.Json;
using Nethermind.Serialization.Rlp;
using System.Text.Json.Serialization;
Expand Down
7 changes: 0 additions & 7 deletions src/Nethermind/Nethermind.Facade/Eth/TransactionForRpc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Nethermind.Core.Eip2930;
using Nethermind.Core.Extensions;
using Nethermind.Int256;
using Nethermind.JsonRpc.Data;

namespace Nethermind.Facade.Eth;

Expand All @@ -24,12 +23,6 @@ public TransactionForRpc(Transaction transaction) : this(null, null, null, trans

public TransactionForRpc(Hash256? blockHash, long? blockNumber, int? txIndex, Transaction transaction, UInt256? baseFee = null)
{
if (transaction.Type == TxType.DepositTx)
{
SourceHash = transaction.SourceHash;
Mint = transaction.Mint;
IsSystemTx = transaction.IsOPSystemTransaction;
}
Hash = transaction.Hash;
Nonce = transaction.Nonce;
BlockHash = blockHash;
Expand Down
8 changes: 4 additions & 4 deletions src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ public ResultWrapper<BlockForRpc> eth_getBlockByNumber(BlockParameter blockParam
return GetBlock(blockParameter, returnFullTransactionObjects);
}

private ResultWrapper<BlockForRpc> GetBlock(BlockParameter blockParameter, bool returnFullTransactionObjects)
protected virtual ResultWrapper<BlockForRpc?> GetBlock(BlockParameter blockParameter, bool returnFullTransactionObjects)
{
SearchResult<Block> searchResult = _blockFinder.SearchForBlock(blockParameter, true);
if (searchResult.IsError)
Expand All @@ -362,7 +362,7 @@ private ResultWrapper<BlockForRpc> GetBlock(BlockParameter blockParameter, bool
_blockchainBridge.RecoverTxSenders(block);
}

return ResultWrapper<BlockForRpc>.Success(block is null
return ResultWrapper<BlockForRpc?>.Success(block is null
? null
: new BlockForRpc(block, returnFullTransactionObjects, _specProvider));
}
Expand Down Expand Up @@ -680,7 +680,7 @@ public ResultWrapper<ulong> eth_chainId()
}
}

private void RecoverTxSenderIfNeeded(Transaction transaction)
protected void RecoverTxSenderIfNeeded(Transaction transaction)
{
transaction.SenderAddress ??= _blockchainBridge.RecoverTxSender(transaction);
}
Expand Down Expand Up @@ -713,7 +713,7 @@ private static IEnumerable<FilterLog> GetLogs(IEnumerable<FilterLog> logs, Cance
: null);
}

private static ResultWrapper<TResult> GetFailureResult<TResult, TSearch>(SearchResult<TSearch> searchResult, bool isTemporary) where TSearch : class =>
protected static ResultWrapper<TResult> GetFailureResult<TResult, TSearch>(SearchResult<TSearch> searchResult, bool isTemporary) where TSearch : class =>
ResultWrapper<TResult>.Fail(searchResult, isTemporary && searchResult.ErrorCode == ErrorCodes.ResourceNotFound);

private static ResultWrapper<TResult> GetFailureResult<TResult>(ResourceNotFoundException exception, bool isTemporary) =>
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Optimism.Test/GasCostTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class GasCostTests
{
[TestCaseSource(nameof(FjordL1CostCalculationTestCases))]
public UInt256 Fjord_l1cost_should_match(UInt256 fastLzSize, UInt256 l1BaseFee, UInt256 blobBaseFee, UInt256 l1BaseFeeScalar, UInt256 l1BlobBaseFeeScalar) =>
OPL1CostHelper.ComputeL1CostFjord(fastLzSize, l1BaseFee, blobBaseFee, l1BaseFeeScalar, l1BlobBaseFeeScalar);
OPL1CostHelper.ComputeL1CostFjord(fastLzSize, l1BaseFee, blobBaseFee, l1BaseFeeScalar, l1BlobBaseFeeScalar, out _);

public static IEnumerable FjordL1CostCalculationTestCases
{
Expand Down
27 changes: 16 additions & 11 deletions src/Nethermind/Nethermind.Optimism/L1BlockGasInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,31 @@

namespace Nethermind.Optimism;

public readonly struct L1TxGasInfo(UInt256? l1Fee, UInt256? l1GasPrice, UInt256? l1GasUsed, string? l1FeeScalar)
public readonly struct L1TxGasInfo(UInt256? l1Fee, UInt256? l1GasPrice, UInt256? l1GasUsed, string? l1FeeScalar, UInt256? l1BaseFeeScalar = null, UInt256? l1BlobBaseFee = null, UInt256? l1BlobBaseFeeScalar = null)
{
public UInt256? L1Fee { get; } = l1Fee;
public UInt256? L1GasPrice { get; } = l1GasPrice;
public UInt256? L1GasUsed { get; } = l1GasUsed;
public string? L1FeeScalar { get; } = l1FeeScalar;

public UInt256? L1BaseFeeScalar { get; } = l1BaseFeeScalar;
public UInt256? L1BlobBaseFee { get; } = l1BlobBaseFee;
public UInt256? L1BlobBaseFeeScalar { get; } = l1BlobBaseFeeScalar;
}

public readonly struct L1BlockGasInfo
{
private readonly UInt256? _l1GasPrice;
private readonly UInt256 _l1BlobBaseFee;
private readonly UInt256 _l1BaseFeeScalar;
private readonly UInt256 _l1BlobBaseFeeScalar;
private readonly UInt256? _l1BlobBaseFee;
private readonly UInt256? _l1BaseFeeScalar;
private readonly UInt256? _l1BlobBaseFeeScalar;
private readonly UInt256 _l1BaseFee;
private readonly UInt256 _overhead;
private readonly UInt256 _feeScalar;
private readonly string? _feeScalarDecimal;
private readonly bool _isFjord;
private readonly bool _isEcotone;
private readonly bool _isRegolith;
private readonly bool _isPostRegolith;

private static readonly byte[] BedrockL1AttributesSelector = [0x01, 0x5d, 0x8e, 0xb9];
private readonly IOptimismSpecHelper _specHelper;
Expand All @@ -48,6 +52,7 @@ public L1BlockGasInfo(Block block, IOptimismSpecHelper specHelper)
Memory<byte> data = depositTx.Data.Value;

_isFjord = _specHelper.IsFjord(block.Header);
_isPostRegolith = _specHelper.IsRegolith(block.Header);

if (_isFjord || (_isEcotone = (_specHelper.IsEcotone(block.Header) && !data[0..4].Span.SequenceEqual(BedrockL1AttributesSelector))))
{
Expand All @@ -63,7 +68,6 @@ public L1BlockGasInfo(Block block, IOptimismSpecHelper specHelper)
}
else
{
_isRegolith = true;
if (data.Length < 4 + 32 * 8)
{
return;
Expand All @@ -88,20 +92,21 @@ public readonly L1TxGasInfo GetTxGasInfo(Transaction tx)
if (_isFjord)
{
UInt256 fastLzSize = OPL1CostHelper.ComputeFlzCompressLen(tx);
l1Fee = OPL1CostHelper.ComputeL1CostFjord(fastLzSize, _l1GasPrice.Value, _l1BlobBaseFee, _l1BaseFeeScalar, _l1BlobBaseFeeScalar);
l1Fee = OPL1CostHelper.ComputeL1CostFjord(fastLzSize, _l1GasPrice.Value, _l1BlobBaseFee!.Value, _l1BaseFeeScalar!.Value, _l1BlobBaseFeeScalar!.Value, out UInt256 estimatedSize);
l1GasUsed = OPL1CostHelper.ComputeGasUsedFjord(estimatedSize);
}
else if (_isEcotone)
{
l1GasUsed = OPL1CostHelper.ComputeDataGas(tx, _isRegolith);
l1Fee = OPL1CostHelper.ComputeL1CostEcotone(l1GasUsed.Value, _l1GasPrice.Value, _l1BlobBaseFee, _l1BaseFeeScalar, _l1BlobBaseFeeScalar);
l1GasUsed = OPL1CostHelper.ComputeDataGas(tx, _isPostRegolith);
l1Fee = OPL1CostHelper.ComputeL1CostEcotone(l1GasUsed.Value, _l1GasPrice.Value, _l1BlobBaseFee!.Value, _l1BaseFeeScalar!.Value, _l1BlobBaseFeeScalar!.Value);
}
else
{
l1GasUsed = OPL1CostHelper.ComputeDataGas(tx, _isRegolith) + _overhead;
l1GasUsed = OPL1CostHelper.ComputeDataGas(tx, _isPostRegolith) + _overhead;
l1Fee = OPL1CostHelper.ComputeL1CostPreEcotone(l1GasUsed.Value, _l1BaseFee, _feeScalar);
}
}

return new L1TxGasInfo(l1Fee, _l1GasPrice, l1GasUsed, _feeScalarDecimal);
return new L1TxGasInfo(l1Fee, _l1GasPrice, l1GasUsed, _feeScalarDecimal, _l1BaseFeeScalar, _l1BlobBaseFee, _l1BlobBaseFeeScalar);
}
}
8 changes: 5 additions & 3 deletions src/Nethermind/Nethermind.Optimism/OPL1CostHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public UInt256 ComputeL1Cost(Transaction tx, BlockHeader header, IWorldState wor

uint fastLzSize = ComputeFlzCompressLen(tx);

return ComputeL1CostFjord(fastLzSize, l1BaseFee, blobBaseFee, l1BaseFeeScalar, l1BlobBaseFeeScalar);
return ComputeL1CostFjord(fastLzSize, l1BaseFee, blobBaseFee, l1BaseFeeScalar, l1BlobBaseFeeScalar, out _);
}

UInt256 dataGas = ComputeDataGas(tx, _opSpecHelper.IsRegolith(header));
Expand Down Expand Up @@ -112,7 +112,7 @@ public static UInt256 ComputeDataGas(Transaction tx, bool isRegolith)
// l1FeeScaled = baseFeeScalar * l1BaseFee * 16 + blobFeeScalar * l1BlobBaseFee
// estimatedSize = max(minTransactionSize, intercept + fastlzCoef * fastlzSize)
// l1Cost = estimatedSize * l1FeeScaled / 1e12
public static UInt256 ComputeL1CostFjord(UInt256 fastLzSize, UInt256 l1BaseFee, UInt256 blobBaseFee, UInt256 l1BaseFeeScalar, UInt256 l1BlobBaseFeeScalar)
public static UInt256 ComputeL1CostFjord(UInt256 fastLzSize, UInt256 l1BaseFee, UInt256 blobBaseFee, UInt256 l1BaseFeeScalar, UInt256 l1BlobBaseFeeScalar, out UInt256 estimatedSize)
{
UInt256 l1FeeScaled = l1BaseFeeScalar * l1BaseFee * PrecisionMultiplier + l1BlobBaseFeeScalar * blobBaseFee;
UInt256 fastLzCost = L1CostFastlzCoef * fastLzSize;
Expand All @@ -126,7 +126,7 @@ public static UInt256 ComputeL1CostFjord(UInt256 fastLzSize, UInt256 l1BaseFee,
fastLzCost -= L1CostInterceptNeg;
}

var estimatedSize = UInt256.Max(MinTransactionSizeScaled, fastLzCost);
estimatedSize = UInt256.Max(MinTransactionSizeScaled, fastLzCost);
return estimatedSize * l1FeeScaled / FjordDivisor;
}

Expand Down Expand Up @@ -242,4 +242,6 @@ uint setNextHash(uint ip, ref Span<uint> ht)
}
return FlzCompressLen(encoded);
}

internal static UInt256 ComputeGasUsedFjord(UInt256 estimatedSize) => estimatedSize * GasCostOf.TxDataNonZeroEip2028 / BasicDivisor;
}
24 changes: 24 additions & 0 deletions src/Nethermind/Nethermind.Optimism/Rpc/IOptimismEthRpcModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
using Nethermind.Core.Crypto;
using Nethermind.JsonRpc;
using Nethermind.Blockchain.Find;
using Nethermind.Int256;
using System.Threading.Tasks;
using Nethermind.Facade.Eth;

namespace Nethermind.Optimism.Rpc;

Expand All @@ -23,4 +26,25 @@ public interface IOptimismEthRpcModule : IEthRpcModule
IsSharable = true,
ExampleResponse = "{\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"transactionIndex\":\"0x7\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"cumulativeGasUsed\":\"0x62c9d\",\"gasUsed\":\"0xe384\",\"effectiveGasPrice\":\"0x12a05f200\",\"from\":\"0x0afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"to\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"contractAddress\":null,\"logs\":[{\"removed\":false,\"logIndex\":\"0x0\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x2ac3c1d3e24b45c6c310534bc2dd84b5ed576335\",\"data\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x00000000000000000000000019e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\"]},{\"removed\":false,\"logIndex\":\"0x1\",\"transactionIndex\":\"0x7\",\"transactionHash\":\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\",\"blockHash\":\"0x42def051b21038905cd2a2bc28d460a94df2249466847f0e1bcb4be4eb21891a\",\"blockNumber\":\"0x4e3f39\",\"address\":\"0x19e8c84d4943e58b035626b064cfc76ee13ee6cb\",\"data\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007735940000000000000000000000000000000000000000000000000000000000000000000\",\"topics\":[\"0x950494fc3642fae5221b6c32e0e45765c95ebb382a04a71b160db0843e74c99f\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\",\"0x00000000000000000000000028078300a459a9e136f872285654cdc74463041e\",\"0x0000000000000000000000000afe0a94415e8974052e7e6cfab19ee1c2ef4f69\"]}],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000020000000000000800000000000000000000400000000000000000000000000000000000000002000000000000000000000000008000000000000000000000000000000000000000000000002002000000000000000000000000000000000000000000812000000000000000000000000000001000000000000000000000008000400008000000000000000000000000000000000000000000000000000000000800000000000000000000002000000000000000000000000000000000000100000000000000000002000000000000000000000000010000000000000000000000400000000020000\",\"status\":\"0x1\",\"type\":\"0x0\"}")]
new ResultWrapper<OptimismReceiptForRpc?> eth_getTransactionReceipt([JsonRpcParameter(ExampleValue = "[\"0x80757153e93d1b475e203406727b62a501187f63e23b8fa999279e219ee3be71\"]")] Hash256 txHashData);

[JsonRpcMethod(IsImplemented = true,
Description = "Retrieves a transaction by hash",
IsSharable = true,
ExampleResponse = "{\"hash\":\"0xabca23910646013d608ec671de099447ab60b2b7159ad8319c3c088e8d9ea0fa\",\"nonce\":\"0x1a\",\"blockHash\":\"0xcb6756f69e0469acd5e5bb77966be580786ec2c11de85c9ddfd75257010e34f8\",\"blockNumber\":\"0x4dfbc7\",\"transactionIndex\":\"0xb\",\"from\":\"0xe1e7ab1c643dbe5b24739fdf2a5c7c193b54dd99\",\"to\":\"0x0b10e304088b2ba2b2acfd2f72573faad31a13a5\",\"value\":\"0x0\",\"gasPrice\":\"0x2540be400\",\"gas\":\"0xb4a4\",\"data\":\"0x095ea7b300000000000000000000000092c1576845703089cf6c0788379ed81f75f45dd500000000000000000000000000000000000000000000000000000002540be400\",\"input\":\"0x095ea7b300000000000000000000000092c1576845703089cf6c0788379ed81f75f45dd500000000000000000000000000000000000000000000000000000002540be400\",\"type\":\"0x0\",\"v\":\"0x2d\",\"s\":\"0x496d72d435ead8a8a9a865b14d6a102c1a9f848681d050dbbf11c522c612235\",\"r\":\"0xc8350e831203fecc8bff41f5cf858ac1d121e4b4d9e59c1137cc9440516ca9fd\"}")]
new Task<ResultWrapper<OptimismTransactionForRpc?>> eth_getTransactionByHash(
[JsonRpcParameter(ExampleValue = "\"0xabca23910646013d608ec671de099447ab60b2b7159ad8319c3c088e8d9ea0fa\"")] Hash256 transactionHash);

[JsonRpcMethod(IsImplemented = true,
Description = "Retrieves a transaction by block hash and index",
IsSharable = true,
ExampleResponse = "{\"hash\":\"0xb87ec4c8cb36a06f49cdd93c2e9f63e0b7db9af07a605c8bcf1fbe705162344e\",\"nonce\":\"0x5d\",\"blockHash\":\"0xfe47fb3539ccce9d19a032473effdd6ce19e3c921bbae2746152ccf82ceef48e\",\"blockNumber\":\"0x4dfc90\",\"transactionIndex\":\"0x2\",\"from\":\"0xaa9a0f962e433755c843175488fe088fccf8526f\",\"to\":\"0x074b24cef703f17fe123fa1b82081055775b7004\",\"value\":\"0x0\",\"gasPrice\":\"0x2540be401\",\"gas\":\"0x130ab\",\"data\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"input\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"type\":\"0x0\",\"v\":\"0x2e\",\"s\":\"0x696f6db060a6dd30435a7f592506ba3213f81cf4704e211a1a45a99f8984189a\",\"r\":\"0x7e07076186e38b68cb7e4f68a04258a5744c5a2ad1a7153456ee662a07902954\"}")]
new ResultWrapper<OptimismTransactionForRpc?> eth_getTransactionByBlockHashAndIndex(
[JsonRpcParameter(ExampleValue = "[\"0xfe47fb3539ccce9d19a032473effdd6ce19e3c921bbae2746152ccf82ceef48e\",\"0x2\"]")] Hash256 blockHash, UInt256 positionIndex);

[JsonRpcMethod(IsImplemented = true,
Description = "Retrieves a transaction by block number and index",
IsSharable = true,
ExampleResponse = "{\"hash\":\"0xfd320a4949990929f64b52041c58a74c8ce13289b3d6853bd8073b0580aa031a\",\"nonce\":\"0x5b\",\"blockHash\":\"0xd779e1a5ce8f34544d66d219bb3e5331a7b280fae89a36d7d52813a23e1ca1e3\",\"blockNumber\":\"0x4dfdd8\",\"transactionIndex\":\"0x8\",\"from\":\"0xadb540569e2db497bd973c141b0b63be98461e40\",\"to\":\"0x074b24cef703f17fe123fa1b82081055775b7004\",\"value\":\"0x0\",\"gasPrice\":\"0x12a05f200\",\"gas\":\"0x927c0\",\"data\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"input\":\"0x428dc451000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005d3c0f4ca5ee99f8e8f59ff9a5fab04f6a7e007f0000000000000000000000009d233a907e065855d2a9c7d4b552ea27fb2e5a36000000000000000000000000cbe56b00d173a26a5978ce90db2e33622fd95a28\",\"type\":\"0x0\",\"v\":\"0x2e\",\"s\":\"0x37b90a929884787df717c87258f0434e2f115ce2fbb4bfc230322112fa9d5bbc\",\"r\":\"0x5222eff9e16b5c3e9e8901d9c45fc8e0f9cf774e8a56546a504025ef67ceefec\"}")]
new ResultWrapper<OptimismTransactionForRpc?> eth_getTransactionByBlockNumberAndIndex(
[JsonRpcParameter(ExampleValue = "[\"5111256\",\"0x8\"]")] BlockParameter blockParameter, UInt256 positionIndex);
}
Loading