diff --git a/core/rawdb/accessors_chain_op_test.go b/core/rawdb/accessors_chain_op_test.go new file mode 100644 index 0000000000..23884a8444 --- /dev/null +++ b/core/rawdb/accessors_chain_op_test.go @@ -0,0 +1,74 @@ +package rawdb + +import ( + "fmt" + "math" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/stretchr/testify/require" +) + +func TestParseLegacyReceiptRLP(t *testing.T) { + // Create a gasUsed value greater than a uint64 can represent + gasUsed := big.NewInt(0) + gasUsed = gasUsed.SetUint64(math.MaxUint64) + gasUsed = gasUsed.Add(gasUsed, big.NewInt(math.MaxInt64)) + sanityCheck := (&big.Int{}).SetUint64(gasUsed.Uint64()) + require.NotEqual(t, gasUsed, sanityCheck) + receipt := types.LegacyOptimismStoredReceiptRLP{ + CumulativeGasUsed: 1, + Logs: []*types.LogForStorage{ + {Address: common.BytesToAddress([]byte{0x11})}, + {Address: common.BytesToAddress([]byte{0x01, 0x11})}, + }, + L1GasUsed: gasUsed, + L1GasPrice: gasUsed, + L1Fee: gasUsed, + FeeScalar: "6", + } + + data, err := rlp.EncodeToBytes(receipt) + require.NoError(t, err) + var result types.ReceiptForStorage + err = rlp.DecodeBytes(data, &result) + require.NoError(t, err) + require.Equal(t, receipt.L1GasUsed, result.L1GasUsed) + require.Equal(t, receipt.L1GasPrice, result.L1GasPrice) + require.Equal(t, receipt.L1Fee, result.L1Fee) + feeScalarFloat, ok := new(big.Float).SetString(receipt.FeeScalar) + require.True(t, ok) + require.Equal(t, feeScalarFloat, result.FeeScalar) +} + +func TestDecodeRawLegacyReceipt(t *testing.T) { + // On op-mainnet: + // cast rpc debug_dbAncient -w '["receipts",n]' for n=1..10 + rawDBReceiptHexes := []string{ + "0xf901a2f9019f018303183df90197f89b948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff863a00109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271a00000000000000000000000000000000000000000000000000000000000014218a000000000000000000000000070b17c0fe982ab4a7ac17a4c25485643151a1f2da000000000000000000000000000000000000000000000000000000000618d8837f89c948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68ca000000000000000000000000000000000000000000000000000000000d0e3ebf0a00000000000000000000000000000000000000000000000000000000000014218a000000000000000000000000070b17c0fe982ab4a7ac17a4c25485643151a1f2d80f85a948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234fa000000000000000000000000000000000000000000000007edc6ca0bb6834800080", + "0xf90104f90101018301c60df8faf89c948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68ca000000000000000000000000000000000000000000000000000000000d0ea0e40a00000000000000000000000000000000000000000000000000000000000014218a0000000000000000000000000e5e7492282fd1e3bfac337a0beccd29b15b7b24080f85a948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234fa000000000000000000000000000000000000000000000007eda7867e0c7d4800080", + "0xf90104f90101018301c60df8faf89c948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68ca000000000000000000000000000000000000000000000000000000000d101e54ba00000000000000000000000000000000000000000000000000000000000014218a0000000000000000000000000fa011d8d6c26f13abe2cefed38226e401b2b8a9980f85a948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234fa000000000000000000000000000000000000000000000007ed8842f062774800080", + "0xf862f86001827434f85af85894420000000000000000000000000000000000000fe1a0351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c44a000000000000000000000000000000000000000000000000000000029a05f69e1", + "0xf90104f90101018301c60df8faf89c948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68ca000000000000000000000000000000000000000000000000000000000d0cb89c0a00000000000000000000000000000000000000000000000000000000000014218a0000000000000000000000000ae00f7474dcc5a0e9f4d7a65dfb938c275f75db680f85a948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234fa000000000000000000000000000000000000000000000007ed68ff62b8714800080", + "0xf901a2f9019f018302b524f90197f89c948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68ca000000000000000000000000000000000000000000000000000000000d1052e1ca00000000000000000000000000000000000000000000000000000000000014218a00000000000000000000000002539ffc9ded82926a5aaee065e800c7d1de0245480f89b948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff863a00559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5fa000000000000000000000000000000000000000000000000000000000d0ea0e40a00000000000000000000000000000000000000000000000000000000000014218a000000000000000000000000000000000000000000000000000000000618d8837f85a948ce8c13d816fe6daf12d6fd9e4952e1fc88850aff842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234fa000000000000000000000000000000000000000000000007ed49bbd50e6b4800080", + "0xf901a2f9019f018303183df90197f89b9425e1c58040f27ecf20bbd4ca83a09290326896b3f863a00109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271a0000000000000000000000000000000000000000000000000000000000000c026a0000000000000000000000000689d0367b9d654aae886982894896f3a826840eda000000000000000000000000000000000000000000000000000000000618d8837f89c9425e1c58040f27ecf20bbd4ca83a09290326896b3f884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68ca00000000000000000000000000000000000000000000000000000006e77d5ea1ca0000000000000000000000000000000000000000000000000000000000000c026a0000000000000000000000000689d0367b9d654aae886982894896f3a826840ed80f85a9425e1c58040f27ecf20bbd4ca83a09290326896b3f842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234fa000000000000000000000000000000000000000000000005b3c134de04354800080", + "0xf90104f90101018301c60df8faf89c9425e1c58040f27ecf20bbd4ca83a09290326896b3f884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68ca00000000000000000000000000000000000000000000000000000006ec9dbc284a0000000000000000000000000000000000000000000000000000000000000c026a000000000000000000000000070b17c0fe982ab4a7ac17a4c25485643151a1f2d80f85a9425e1c58040f27ecf20bbd4ca83a09290326896b3f842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234fa000000000000000000000000000000000000000000000005b3a1f1505a2f4800080", + "0xf90104f90101018301c60df8faf89c9425e1c58040f27ecf20bbd4ca83a09290326896b3f884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68ca00000000000000000000000000000000000000000000000000000006e89bf95dea0000000000000000000000000000000000000000000000000000000000000c026a0000000000000000000000000e5e7492282fd1e3bfac337a0beccd29b15b7b24080f85a9425e1c58040f27ecf20bbd4ca83a09290326896b3f842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234fa000000000000000000000000000000000000000000000005b382adc2b0294800080", + "0xf90104f90101018301c60df8faf89c9425e1c58040f27ecf20bbd4ca83a09290326896b3f884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68ca00000000000000000000000000000000000000000000000000000006ea50c77c9a0000000000000000000000000000000000000000000000000000000000000c026a00000000000000000000000002539ffc9ded82926a5aaee065e800c7d1de0245480f85a9425e1c58040f27ecf20bbd4ca83a09290326896b3f842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234fa000000000000000000000000000000000000000000000005b3636a3506234800080", + } + + for i, rawDBReceiptHex := range rawDBReceiptHexes { + t.Run(fmt.Sprintf("OPM block %d", i), func(t *testing.T) { + rawDBReceiptBytes, err := hexutil.Decode(rawDBReceiptHex) + require.NoError(t, err) + + sr := make([]*types.ReceiptForStorage, 0) + err = rlp.DecodeBytes(rawDBReceiptBytes, &sr) + require.NoError(t, err) + }) + } +} diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 94ba0f883f..eacf3027a9 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -32,7 +32,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "github.com/stretchr/testify/require" "golang.org/x/crypto/sha3" ) @@ -818,37 +817,39 @@ func TestReadLogs(t *testing.T) { } } -func TestParseLegacyReceiptRLP(t *testing.T) { - // Create a gasUsed value greater than a uint64 can represent - gasUsed := big.NewInt(0) - gasUsed = gasUsed.SetUint64(math.MaxUint64) - gasUsed = gasUsed.Add(gasUsed, big.NewInt(math.MaxInt64)) - sanityCheck := (&big.Int{}).SetUint64(gasUsed.Uint64()) - require.NotEqual(t, gasUsed, sanityCheck) - receipt := types.LegacyOptimismStoredReceiptRLP{ - CumulativeGasUsed: 1, - Logs: []*types.LogForStorage{ - {Address: common.BytesToAddress([]byte{0x11})}, - {Address: common.BytesToAddress([]byte{0x01, 0x11})}, - }, - L1GasUsed: gasUsed, - L1GasPrice: gasUsed, - L1Fee: gasUsed, - FeeScalar: "6", - } - - data, err := rlp.EncodeToBytes(receipt) - require.NoError(t, err) +<<<<<<< Conflict 1 of 1 +%%%%%%% Changes from base to side #1 + func TestParseLegacyReceiptRLP(t *testing.T) { + // Create a gasUsed value greater than a uint64 can represent + gasUsed := big.NewInt(0) + gasUsed = gasUsed.SetUint64(math.MaxUint64) + gasUsed = gasUsed.Add(gasUsed, big.NewInt(math.MaxInt64)) + sanityCheck := (&big.Int{}).SetUint64(gasUsed.Uint64()) + require.NotEqual(t, gasUsed, sanityCheck) + receipt := types.LegacyOptimismStoredReceiptRLP{ + CumulativeGasUsed: 1, + Logs: []*types.LogForStorage{ + {Address: common.BytesToAddress([]byte{0x11})}, + {Address: common.BytesToAddress([]byte{0x01, 0x11})}, + }, + L1GasUsed: gasUsed, + L1GasPrice: gasUsed, + L1Fee: gasUsed, + FeeScalar: "6", + } + + data, err := rlp.EncodeToBytes(receipt) + require.NoError(t, err) var result types.ReceiptForStorage - err = rlp.DecodeBytes(data, &result) - require.NoError(t, err) - require.Equal(t, receipt.L1GasUsed, result.L1GasUsed) - require.Equal(t, receipt.L1GasPrice, result.L1GasPrice) - require.Equal(t, receipt.L1Fee, result.L1Fee) + err = rlp.DecodeBytes(data, &result) + require.NoError(t, err) + require.Equal(t, receipt.L1GasUsed, result.L1GasUsed) + require.Equal(t, receipt.L1GasPrice, result.L1GasPrice) + require.Equal(t, receipt.L1Fee, result.L1Fee) feeScalarFloat, ok := new(big.Float).SetString(receipt.FeeScalar) require.True(t, ok) require.Equal(t, feeScalarFloat, result.FeeScalar) -} + } func TestDeriveLogFields(t *testing.T) { // Create a few transactions to have receipts for diff --git a/core/types/receipt.go b/core/types/receipt.go index e385df2d3b..07b928f518 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -169,10 +169,15 @@ type LegacyOptimismStoredReceiptRLP struct { PostStateOrStatus []byte CumulativeGasUsed uint64 Logs []*LogForStorage - L1GasUsed *big.Int - L1GasPrice *big.Int - L1Fee *big.Int - FeeScalar string + + // Remaining fields are declared to allow the receipt RLP to be parsed without errors. + // However, they must not be used as they may not be populated correctly due to multiple receipt formats + // being combined into a single list of optional fields which can be mistaken for each other. + // DepositNonce (*uint64) from Regolith deposit tx receipts will be parsed into L1GasUsed + L1GasUsed *big.Int `rlp:"optional"` // OVM Legacy + L1GasPrice *big.Int `rlp:"optional"` // OVM Legacy + L1Fee *big.Int `rlp:"optional"` // OVM Legacy + FeeScalar string `rlp:"optional"` // OVM Legacy } // LogForStorage is a wrapper around a Log that handles