diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index d5f3a9aa8..d150d09d8 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -619,6 +619,10 @@ type storedReceiptRLP struct { CumulativeGasUsed uint64 Logs []*types.LogForStorage L1Fee *big.Int + FeeTokenID *uint16 + FeeRate *big.Int + TokenScale *big.Int + FeeLimit *big.Int } // ReceiptLogs is a barebone version of ReceiptForStorage which only keeps diff --git a/core/types/receipt.go b/core/types/receipt.go index e044c0281..964c2f3b8 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -119,6 +119,29 @@ type storedReceiptRLP struct { FeeLimit *big.Int } +// v7StoredReceiptRLP is the storage encoding of a receipt used in database version 7. +// This version was introduced when AltFee feature was added (2024-11). +// It includes L1Fee and all AltFee fields (FeeTokenID, FeeRate, TokenScale, FeeLimit). +type v7StoredReceiptRLP struct { + PostStateOrStatus []byte + CumulativeGasUsed uint64 + Logs []*LogForStorage + L1Fee *big.Int + FeeTokenID *uint16 + FeeRate *big.Int + TokenScale *big.Int + FeeLimit *big.Int +} + +// v6StoredReceiptRLP is the storage encoding of a receipt used in database version 6. +// It includes L1Fee but not the altFee fields. +type v6StoredReceiptRLP struct { + PostStateOrStatus []byte + CumulativeGasUsed uint64 + Logs []*LogForStorage + L1Fee *big.Int +} + // v5StoredReceiptRLP is the storage encoding of a receipt used in database version 5. type v5StoredReceiptRLP struct { PostStateOrStatus []byte @@ -340,6 +363,12 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { if err := decodeStoredReceiptRLP(r, blob); err == nil { return nil } + if err := decodeV7StoredReceiptRLP(r, blob); err == nil { + return nil + } + if err := decodeV6StoredReceiptRLP(r, blob); err == nil { + return nil + } if err := decodeV3StoredReceiptRLP(r, blob); err == nil { return nil } @@ -372,6 +401,48 @@ func decodeStoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { return nil } +func decodeV7StoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { + var stored v7StoredReceiptRLP + if err := rlp.DecodeBytes(blob, &stored); err != nil { + return err + } + if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { + return err + } + r.CumulativeGasUsed = stored.CumulativeGasUsed + r.Logs = make([]*Log, len(stored.Logs)) + for i, log := range stored.Logs { + r.Logs[i] = (*Log)(log) + } + r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) + r.L1Fee = stored.L1Fee + r.FeeTokenID = stored.FeeTokenID + r.FeeRate = stored.FeeRate + r.TokenScale = stored.TokenScale + r.FeeLimit = stored.FeeLimit + + return nil +} + +func decodeV6StoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { + var stored v6StoredReceiptRLP + if err := rlp.DecodeBytes(blob, &stored); err != nil { + return err + } + if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { + return err + } + r.CumulativeGasUsed = stored.CumulativeGasUsed + r.Logs = make([]*Log, len(stored.Logs)) + for i, log := range stored.Logs { + r.Logs[i] = (*Log)(log) + } + r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) + r.L1Fee = stored.L1Fee + + return nil +} + func decodeV5StoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { var stored v5StoredReceiptRLP if err := rlp.DecodeBytes(blob, &stored); err != nil { diff --git a/core/types/receipt_test.go b/core/types/receipt_test.go index d20e9dc01..0939f429d 100644 --- a/core/types/receipt_test.go +++ b/core/types/receipt_test.go @@ -117,6 +117,14 @@ func TestLegacyReceiptDecoding(t *testing.T) { "StoredReceiptRLP", encodeAsStoredReceiptRLP, }, + { + "V7StoredReceiptRLP", + encodeAsV7StoredReceiptRLP, + }, + { + "V6StoredReceiptRLP", + encodeAsV6StoredReceiptRLP, + }, { "V5StoredReceiptRLP", encodeAsV5StoredReceiptRLP, @@ -204,6 +212,36 @@ func encodeAsStoredReceiptRLP(want *Receipt) ([]byte, error) { return rlp.EncodeToBytes(stored) } +func encodeAsV7StoredReceiptRLP(want *Receipt) ([]byte, error) { + stored := &v7StoredReceiptRLP{ + PostStateOrStatus: want.statusEncoding(), + CumulativeGasUsed: want.CumulativeGasUsed, + Logs: make([]*LogForStorage, len(want.Logs)), + L1Fee: want.L1Fee, + FeeTokenID: want.FeeTokenID, + FeeRate: want.FeeRate, + TokenScale: want.TokenScale, + FeeLimit: want.FeeLimit, + } + for i, log := range want.Logs { + stored.Logs[i] = (*LogForStorage)(log) + } + return rlp.EncodeToBytes(stored) +} + +func encodeAsV6StoredReceiptRLP(want *Receipt) ([]byte, error) { + stored := &v6StoredReceiptRLP{ + PostStateOrStatus: want.statusEncoding(), + CumulativeGasUsed: want.CumulativeGasUsed, + Logs: make([]*LogForStorage, len(want.Logs)), + L1Fee: want.L1Fee, + } + for i, log := range want.Logs { + stored.Logs[i] = (*LogForStorage)(log) + } + return rlp.EncodeToBytes(stored) +} + func encodeAsV5StoredReceiptRLP(want *Receipt) ([]byte, error) { stored := &v5StoredReceiptRLP{ PostStateOrStatus: want.statusEncoding(), diff --git a/core/types/token_fee.go b/core/types/token_fee.go index 6c4ff59e2..c219ea44d 100644 --- a/core/types/token_fee.go +++ b/core/types/token_fee.go @@ -48,10 +48,10 @@ func (dca *SuperAccount) SetAltAmount(id uint16, amount *big.Int) { // EthToAlt altAmount = ethAmount / (tokenRate / tokenScale) = ethAmount * tokenScale / tokenRate func EthToAlt(ethAmount, rate, tokenScale *big.Int) *big.Int { if rate == nil || rate.Sign() <= 0 { - panic("invalid token scale") + panic("invalid token rate") } if tokenScale == nil || tokenScale.Sign() <= 0 { - panic("invalid token rate") + panic("invalid token scale") } altAmount := new(big.Int) remainder := new(big.Int) @@ -65,10 +65,10 @@ func EthToAlt(ethAmount, rate, tokenScale *big.Int) *big.Int { // AltToEth ethAmount = altAmount * (tokenRate / tokenScale) func AltToEth(erc20Amount, rate, tokenScale *big.Int) *big.Int { if rate == nil || rate.Sign() <= 0 { - panic("invalid token scale") + panic("invalid token rate") } if tokenScale == nil || tokenScale.Sign() <= 0 { - panic("invalid token rate") + panic("invalid token scale") } ethAmount := new(big.Int) remainder := new(big.Int) diff --git a/rollup/fees/rate.go b/rollup/fees/rate.go index c84393b21..12e6aae4e 100644 --- a/rollup/fees/rate.go +++ b/rollup/fees/rate.go @@ -38,6 +38,9 @@ func TokenRate(state StateDB, tokenID uint16) (*big.Int, *big.Int, error) { log.Error("Failed to get token scale", "tokenID", tokenID, "error", err) return nil, nil, err } + if scale == nil || scale.Sign() == 0 { + log.Error("Invalid token scale", "tokenID", tokenID, "tokenAddr", info.TokenAddress.Hex()) + } return rate, scale, err }