Skip to content

Commit

Permalink
Merge pull request bnb-chain#95 from ethereum-optimism/aj/l1-overhead
Browse files Browse the repository at this point in the history
core/types: Include overhead in the L1GasUsed for receipts.
  • Loading branch information
protolambda authored May 26, 2023
2 parents 3fa9e81 + 4a8d967 commit bfdfd9b
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 1 deletion.
3 changes: 2 additions & 1 deletion core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,8 @@ func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, nu
if !txs[i].IsDepositTx() {
gas := txs[i].RollupDataGas().DataGas(time, config)
rs[i].L1GasPrice = l1Basefee
rs[i].L1GasUsed = new(big.Int).SetUint64(gas)
// GasUsed reported in receipt should include the overhead
rs[i].L1GasUsed = new(big.Int).Add(new(big.Int).SetUint64(gas), overhead)
rs[i].L1Fee = L1Cost(gas, l1Basefee, overhead, scalar)
rs[i].FeeScalar = feeScalar
}
Expand Down
109 changes: 109 additions & 0 deletions core/types/receipt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,115 @@ func TestDeriveFields(t *testing.T) {
}
}

func TestDeriveOptimismTxReceipt(t *testing.T) {
to4 := common.HexToAddress("0x4")
// Create a few transactions to have receipts for
txs := Transactions{
NewTx(&DepositTx{
To: nil, // contract creation
Value: big.NewInt(6),
Gas: 50,
// System config with L1Scalar=2_000_000 (becomes 2 after division), L1Overhead=2500, L1BaseFee=5000
Data: common.Hex2Bytes("015d8eb900000000000000000000000000000000000000000000000026b39534042076f70000000000000000000000000000000000000000000000007e33b7c4995967580000000000000000000000000000000000000000000000000000000000001388547dea8ff339566349ed0ef6384876655d1b9b955e36ac165c6b8ab69b9af5cd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123400000000000000000000000000000000000000000000000000000000000009c400000000000000000000000000000000000000000000000000000000001e8480"),
}),
NewTx(&DynamicFeeTx{
To: &to4,
Nonce: 4,
Value: big.NewInt(4),
Gas: 4,
GasTipCap: big.NewInt(44),
GasFeeCap: big.NewInt(1045),
Data: []byte{0, 1, 255, 0},
}),
}
depNonce := uint64(7)
blockNumber := big.NewInt(1)
blockHash := common.BytesToHash([]byte{0x03, 0x14})

// Create the corresponding receipts
receipts := Receipts{
&Receipt{
Type: DepositTxType,
PostState: common.Hash{5}.Bytes(),
CumulativeGasUsed: 50 + 15,
Logs: []*Log{
{
Address: common.BytesToAddress([]byte{0x33}),
// derived fields:
BlockNumber: blockNumber.Uint64(),
TxHash: txs[0].Hash(),
TxIndex: 0,
BlockHash: blockHash,
Index: 0,
},
{
Address: common.BytesToAddress([]byte{0x03, 0x33}),
// derived fields:
BlockNumber: blockNumber.Uint64(),
TxHash: txs[0].Hash(),
TxIndex: 0,
BlockHash: blockHash,
Index: 1,
},
},
TxHash: txs[0].Hash(),
ContractAddress: common.HexToAddress("0x3bb898b4bbe24f68a4e9be46cfe72d1787fd74f4"),
GasUsed: 65,
EffectiveGasPrice: big.NewInt(0),
BlockHash: blockHash,
BlockNumber: blockNumber,
TransactionIndex: 0,
DepositNonce: &depNonce,
},
&Receipt{
Type: DynamicFeeTxType,
PostState: common.Hash{4}.Bytes(),
CumulativeGasUsed: 10,
Logs: []*Log{},
// derived fields:
TxHash: txs[1].Hash(),
GasUsed: 18446744073709551561,
EffectiveGasPrice: big.NewInt(1044),
BlockHash: blockHash,
BlockNumber: blockNumber,
TransactionIndex: 1,
L1GasPrice: big.NewInt(5000),
L1GasUsed: big.NewInt(3976),
L1Fee: big.NewInt(39760000),
FeeScalar: big.NewFloat(2),
},
}

// Re-derive receipts.
basefee := big.NewInt(1000)
derivedReceipts := clearComputedFieldsOnReceipts(receipts)
err := Receipts(derivedReceipts).DeriveFields(params.OptimismTestConfig, blockHash, blockNumber.Uint64(), 0, basefee, txs)
if err != nil {
t.Fatalf("DeriveFields(...) = %v, want <nil>", err)
}

// Check diff of receipts against derivedReceipts.
r1, err := json.MarshalIndent(receipts, "", " ")
if err != nil {
t.Fatal("error marshaling input receipts:", err)
}
r2, err := json.MarshalIndent(derivedReceipts, "", " ")
if err != nil {
t.Fatal("error marshaling derived receipts:", err)
}
d := diff.Diff(string(r1), string(r2))
if d != "" {
t.Fatal("receipts differ:", d)
}

// Check that we preserved the invariant: l1Fee = l1GasPrice * l1GasUsed * l1FeeScalar
// but with more difficult int math...
l2Rcpt := derivedReceipts[1]
l1GasCost := new(big.Int).Mul(l2Rcpt.L1GasPrice, l2Rcpt.L1GasUsed)
l1Fee := new(big.Float).Mul(new(big.Float).SetInt(l1GasCost), l2Rcpt.FeeScalar)
require.Equal(t, new(big.Float).SetInt(l2Rcpt.L1Fee), l1Fee)
}

// TestTypedReceiptEncodingDecoding reproduces a flaw that existed in the receipt
// rlp decoder, which failed due to a shadowing error.
func TestTypedReceiptEncodingDecoding(t *testing.T) {
Expand Down

0 comments on commit bfdfd9b

Please sign in to comment.