mirror of
https://github.com/status-im/op-geth.git
synced 2025-02-15 00:08:00 +00:00
core/types: add legacy receipt deserialization (#28)
Receipts in `l2geth` are stored with L1 fee data to prevent
the need of having an archive node for historical L1 fee data.
91a80d2872/l2geth/core/types/receipt.go (L247)
This ports the deserialization of the legacy `l2geth` style
serialization to `op-geth`. This is required for nodes that upgrade
using the db migration tool.
This commit is contained in:
parent
28c13bd98d
commit
ca8bbd6cf5
@ -108,6 +108,72 @@ type storedReceiptRLP struct {
|
||||
Logs []*Log
|
||||
}
|
||||
|
||||
// LegacyOptimismStoredReceiptRLP is the pre bedrock storage encoding of a
|
||||
// receipt. It will only exist in the database if it was migrated using the
|
||||
// migration tool. Nodes that sync using snap-sync will not have any of these
|
||||
// entries.
|
||||
type LegacyOptimismStoredReceiptRLP struct {
|
||||
PostStateOrStatus []byte
|
||||
CumulativeGasUsed uint64
|
||||
Logs []*LogForStorage
|
||||
L1GasUsed *big.Int
|
||||
L1GasPrice *big.Int
|
||||
L1Fee *big.Int
|
||||
FeeScalar string
|
||||
}
|
||||
|
||||
// LogForStorage is a wrapper around a Log that handles
|
||||
// backward compatibility with prior storage formats.
|
||||
type LogForStorage Log
|
||||
|
||||
// EncodeRLP implements rlp.Encoder.
|
||||
func (l *LogForStorage) EncodeRLP(w io.Writer) error {
|
||||
rl := rlpLog{Address: l.Address, Topics: l.Topics, Data: l.Data}
|
||||
return rlp.Encode(w, &rl)
|
||||
}
|
||||
|
||||
type legacyRlpStorageLog struct {
|
||||
Address common.Address
|
||||
Topics []common.Hash
|
||||
Data []byte
|
||||
BlockNumber uint64
|
||||
TxHash common.Hash
|
||||
TxIndex uint
|
||||
BlockHash common.Hash
|
||||
Index uint
|
||||
}
|
||||
|
||||
// DecodeRLP implements rlp.Decoder.
|
||||
//
|
||||
// Note some redundant fields(e.g. block number, tx hash etc) will be assembled later.
|
||||
func (l *LogForStorage) DecodeRLP(s *rlp.Stream) error {
|
||||
blob, err := s.Raw()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var dec rlpLog
|
||||
err = rlp.DecodeBytes(blob, &dec)
|
||||
if err == nil {
|
||||
*l = LogForStorage{
|
||||
Address: dec.Address,
|
||||
Topics: dec.Topics,
|
||||
Data: dec.Data,
|
||||
}
|
||||
} else {
|
||||
// Try to decode log with previous definition.
|
||||
var dec legacyRlpStorageLog
|
||||
err = rlp.DecodeBytes(blob, &dec)
|
||||
if err == nil {
|
||||
*l = LogForStorage{
|
||||
Address: dec.Address,
|
||||
Topics: dec.Topics,
|
||||
Data: dec.Data,
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// NewReceipt creates a barebone transaction receipt, copying the init fields.
|
||||
// Deprecated: create receipts using a struct literal instead.
|
||||
func NewReceipt(root []byte, failed bool, cumulativeGasUsed uint64) *Receipt {
|
||||
@ -283,8 +349,51 @@ func (r *ReceiptForStorage) EncodeRLP(_w io.Writer) error {
|
||||
// DecodeRLP implements rlp.Decoder, and loads both consensus and implementation
|
||||
// fields of a receipt from an RLP stream.
|
||||
func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error {
|
||||
// Retrieve the entire receipt blob as we need to try multiple decoders
|
||||
blob, err := s.Raw()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// First try to decode the latest receipt database format, try the pre-bedrock Optimism legacy format otherwise.
|
||||
if err := decodeStoredReceiptRLP(r, blob); err == nil {
|
||||
return nil
|
||||
}
|
||||
return decodeLegacyOptimismReceiptRLP(r, blob)
|
||||
}
|
||||
|
||||
func decodeLegacyOptimismReceiptRLP(r *ReceiptForStorage, blob []byte) error {
|
||||
var stored LegacyOptimismStoredReceiptRLP
|
||||
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)})
|
||||
// UsingOVM
|
||||
scalar := new(big.Float)
|
||||
if stored.FeeScalar != "" {
|
||||
var ok bool
|
||||
scalar, ok = scalar.SetString(stored.FeeScalar)
|
||||
if !ok {
|
||||
return errors.New("cannot parse fee scalar")
|
||||
}
|
||||
}
|
||||
r.L1GasUsed = stored.L1GasUsed
|
||||
r.L1GasPrice = stored.L1GasPrice
|
||||
r.L1Fee = stored.L1Fee
|
||||
r.FeeScalar = scalar
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeStoredReceiptRLP(r *ReceiptForStorage, blob []byte) error {
|
||||
var stored storedReceiptRLP
|
||||
if err := s.Decode(&stored); err != nil {
|
||||
if err := rlp.DecodeBytes(blob, &stored); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user