Skip to content

Commit 10347c6

Browse files
authored
core: drop legacy receipt types (#26225)
This PR drops the legacy receipt types, the freezer-migrate command and the startup check. The previous attempt #22852 at this failed because there were users who still had legacy receipts in their db, so it had to be reverted #23247. Since then we added a command to migrate legacy dbs #24028. As of the last hardforks all users either must have done the migration, or used the --ignore-legacy-receipts flag which will stop working now.
1 parent e24d600 commit 10347c6

File tree

9 files changed

+8
-476
lines changed

9 files changed

+8
-476
lines changed

cmd/geth/config.go

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
"github.com/ethereum/go-ethereum/accounts/scwallet"
3232
"github.com/ethereum/go-ethereum/accounts/usbwallet"
3333
"github.com/ethereum/go-ethereum/cmd/utils"
34-
"github.com/ethereum/go-ethereum/core/rawdb"
3534
"github.com/ethereum/go-ethereum/eth/ethconfig"
3635
"github.com/ethereum/go-ethereum/internal/ethapi"
3736
"github.com/ethereum/go-ethereum/internal/flags"
@@ -166,26 +165,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
166165
cfg.Eth.OverrideTerminalTotalDifficultyPassed = &override
167166
}
168167

169-
backend, eth := utils.RegisterEthService(stack, &cfg.Eth)
170-
171-
// Warn users to migrate if they have a legacy freezer format.
172-
if eth != nil && !ctx.IsSet(utils.IgnoreLegacyReceiptsFlag.Name) {
173-
firstIdx := uint64(0)
174-
// Hack to speed up check for mainnet because we know
175-
// the first non-empty block.
176-
ghash := rawdb.ReadCanonicalHash(eth.ChainDb(), 0)
177-
if cfg.Eth.NetworkId == 1 && ghash == params.MainnetGenesisHash {
178-
firstIdx = 46147
179-
}
180-
isLegacy, firstLegacy, err := dbHasLegacyReceipts(eth.ChainDb(), firstIdx)
181-
if err != nil {
182-
log.Error("Failed to check db for legacy receipts", "err", err)
183-
} else if isLegacy {
184-
stack.Close()
185-
log.Error("Database has receipts with a legacy format", "firstLegacy", firstLegacy)
186-
utils.Fatalf("Aborting. Please run `geth db freezer-migrate`.")
187-
}
188-
}
168+
backend, _ := utils.RegisterEthService(stack, &cfg.Eth)
189169

190170
// Configure log filter RPC API.
191171
filterSystem := utils.RegisterFilterAPI(stack, backend, &cfg.Eth)

cmd/geth/dbcmd.go

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import (
3333
"github.com/ethereum/go-ethereum/console/prompt"
3434
"github.com/ethereum/go-ethereum/core/rawdb"
3535
"github.com/ethereum/go-ethereum/core/state/snapshot"
36-
"github.com/ethereum/go-ethereum/core/types"
3736
"github.com/ethereum/go-ethereum/crypto"
3837
"github.com/ethereum/go-ethereum/ethdb"
3938
"github.com/ethereum/go-ethereum/internal/flags"
@@ -69,7 +68,6 @@ Remove blockchain and state databases`,
6968
dbImportCmd,
7069
dbExportCmd,
7170
dbMetadataCmd,
72-
dbMigrateFreezerCmd,
7371
dbCheckStateContentCmd,
7472
},
7573
}
@@ -195,17 +193,6 @@ WARNING: This is a low-level operation which may cause database corruption!`,
195193
}, utils.NetworkFlags, utils.DatabasePathFlags),
196194
Description: "Shows metadata about the chain status.",
197195
}
198-
dbMigrateFreezerCmd = &cli.Command{
199-
Action: freezerMigrate,
200-
Name: "freezer-migrate",
201-
Usage: "Migrate legacy parts of the freezer. (WARNING: may take a long time)",
202-
ArgsUsage: "",
203-
Flags: flags.Merge([]cli.Flag{
204-
utils.SyncModeFlag,
205-
}, utils.NetworkFlags, utils.DatabasePathFlags),
206-
Description: `The freezer-migrate command checks your database for receipts in a legacy format and updates those.
207-
WARNING: please back-up the receipt files in your ancients before running this command.`,
208-
}
209196
)
210197

211198
func removeDB(ctx *cli.Context) error {
@@ -756,92 +743,3 @@ func showMetaData(ctx *cli.Context) error {
756743
table.Render()
757744
return nil
758745
}
759-
760-
func freezerMigrate(ctx *cli.Context) error {
761-
stack, _ := makeConfigNode(ctx)
762-
defer stack.Close()
763-
764-
db := utils.MakeChainDatabase(ctx, stack, false)
765-
defer db.Close()
766-
767-
// Check first block for legacy receipt format
768-
numAncients, err := db.Ancients()
769-
if err != nil {
770-
return err
771-
}
772-
if numAncients < 1 {
773-
log.Info("No receipts in freezer to migrate")
774-
return nil
775-
}
776-
777-
isFirstLegacy, firstIdx, err := dbHasLegacyReceipts(db, 0)
778-
if err != nil {
779-
return err
780-
}
781-
if !isFirstLegacy {
782-
log.Info("No legacy receipts to migrate")
783-
return nil
784-
}
785-
786-
log.Info("Starting migration", "ancients", numAncients, "firstLegacy", firstIdx)
787-
start := time.Now()
788-
if err := db.MigrateTable("receipts", types.ConvertLegacyStoredReceipts); err != nil {
789-
return err
790-
}
791-
if err := db.Close(); err != nil {
792-
return err
793-
}
794-
log.Info("Migration finished", "duration", time.Since(start))
795-
796-
return nil
797-
}
798-
799-
// dbHasLegacyReceipts checks freezer entries for legacy receipts. It stops at the first
800-
// non-empty receipt and checks its format. The index of this first non-empty element is
801-
// the second return parameter.
802-
func dbHasLegacyReceipts(db ethdb.Database, firstIdx uint64) (bool, uint64, error) {
803-
// Check first block for legacy receipt format
804-
numAncients, err := db.Ancients()
805-
if err != nil {
806-
return false, 0, err
807-
}
808-
if numAncients < 1 {
809-
return false, 0, nil
810-
}
811-
if firstIdx >= numAncients {
812-
return false, firstIdx, nil
813-
}
814-
var (
815-
legacy bool
816-
blob []byte
817-
emptyRLPList = []byte{192}
818-
)
819-
// Find first block with non-empty receipt, only if
820-
// the index is not already provided.
821-
if firstIdx == 0 {
822-
for i := uint64(0); i < numAncients; i++ {
823-
blob, err = db.Ancient("receipts", i)
824-
if err != nil {
825-
return false, 0, err
826-
}
827-
if len(blob) == 0 {
828-
continue
829-
}
830-
if !bytes.Equal(blob, emptyRLPList) {
831-
firstIdx = i
832-
break
833-
}
834-
}
835-
}
836-
first, err := db.Ancient("receipts", firstIdx)
837-
if err != nil {
838-
return false, 0, err
839-
}
840-
// We looped over all receipts and they were all empty
841-
if bytes.Equal(first, emptyRLPList) {
842-
return false, 0, nil
843-
}
844-
// Is first non-empty receipt legacy?
845-
legacy, err = types.IsLegacyStoredReceipts(first)
846-
return legacy, firstIdx, err
847-
}

cmd/geth/main.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ var (
149149
utils.GpoMaxGasPriceFlag,
150150
utils.GpoIgnoreGasPriceFlag,
151151
utils.MinerNotifyFullFlag,
152-
utils.IgnoreLegacyReceiptsFlag,
153152
configFileFlag,
154153
}, utils.NetworkFlags, utils.DatabasePathFlags)
155154

cmd/utils/flags.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -669,11 +669,6 @@ var (
669669
}
670670

671671
// MISC settings
672-
IgnoreLegacyReceiptsFlag = &cli.BoolFlag{
673-
Name: "ignore-legacy-receipts",
674-
Usage: "Geth will start up even if there are legacy receipts in freezer",
675-
Category: flags.MiscCategory,
676-
}
677672
SyncTargetFlag = &cli.PathFlag{
678673
Name: "synctarget",
679674
Usage: `File for containing the hex-encoded block-rlp as sync target(dev feature)`,

core/rawdb/accessors_chain.go

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -669,10 +669,11 @@ func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
669669

670670
// storedReceiptRLP is the storage encoding of a receipt.
671671
// Re-definition in core/types/receipt.go.
672+
// TODO: Re-use the existing definition.
672673
type storedReceiptRLP struct {
673674
PostStateOrStatus []byte
674675
CumulativeGasUsed uint64
675-
Logs []*types.LogForStorage
676+
Logs []*types.Log
676677
}
677678

678679
// ReceiptLogs is a barebone version of ReceiptForStorage which only keeps
@@ -688,10 +689,7 @@ func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error {
688689
if err := s.Decode(&stored); err != nil {
689690
return err
690691
}
691-
r.Logs = make([]*types.Log, len(stored.Logs))
692-
for i, log := range stored.Logs {
693-
r.Logs[i] = (*types.Log)(log)
694-
}
692+
r.Logs = stored.Logs
695693
return nil
696694
}
697695

@@ -727,11 +725,6 @@ func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64, config *params.C
727725
}
728726
receipts := []*receiptLogs{}
729727
if err := rlp.DecodeBytes(data, &receipts); err != nil {
730-
// Receipts might be in the legacy format, try decoding that.
731-
// TODO: to be removed after users migrated
732-
if logs := readLegacyLogs(db, hash, number, config); logs != nil {
733-
return logs
734-
}
735728
log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
736729
return nil
737730
}
@@ -752,21 +745,6 @@ func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64, config *params.C
752745
return logs
753746
}
754747

755-
// readLegacyLogs is a temporary workaround for when trying to read logs
756-
// from a block which has its receipt stored in the legacy format. It'll
757-
// be removed after users have migrated their freezer databases.
758-
func readLegacyLogs(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) [][]*types.Log {
759-
receipts := ReadReceipts(db, hash, number, config)
760-
if receipts == nil {
761-
return nil
762-
}
763-
logs := make([][]*types.Log, len(receipts))
764-
for i, receipt := range receipts {
765-
logs[i] = receipt.Logs
766-
}
767-
return logs
768-
}
769-
770748
// ReadBlock retrieves an entire block corresponding to the hash, assembling it
771749
// back from the stored header and body. If either the header or body could not
772750
// be retrieved nil is returned.

core/types/legacy.go

Lines changed: 0 additions & 53 deletions
This file was deleted.

core/types/log.go

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,13 @@ type logMarshaling struct {
6464

6565
//go:generate go run ../../rlp/rlpgen -type rlpLog -out gen_log_rlp.go
6666

67+
// rlpLog is used to RLP-encode both the consensus and storage formats.
6768
type rlpLog struct {
6869
Address common.Address
6970
Topics []common.Hash
7071
Data []byte
7172
}
7273

73-
// legacyRlpStorageLog is the previous storage encoding of a log including some redundant fields.
74-
type legacyRlpStorageLog struct {
75-
Address common.Address
76-
Topics []common.Hash
77-
Data []byte
78-
BlockNumber uint64
79-
TxHash common.Hash
80-
TxIndex uint
81-
BlockHash common.Hash
82-
Index uint
83-
}
84-
8574
// EncodeRLP implements rlp.Encoder.
8675
func (l *Log) EncodeRLP(w io.Writer) error {
8776
rl := rlpLog{Address: l.Address, Topics: l.Topics, Data: l.Data}
@@ -97,44 +86,3 @@ func (l *Log) DecodeRLP(s *rlp.Stream) error {
9786
}
9887
return err
9988
}
100-
101-
// LogForStorage is a wrapper around a Log that handles
102-
// backward compatibility with prior storage formats.
103-
type LogForStorage Log
104-
105-
// EncodeRLP implements rlp.Encoder.
106-
func (l *LogForStorage) EncodeRLP(w io.Writer) error {
107-
rl := rlpLog{Address: l.Address, Topics: l.Topics, Data: l.Data}
108-
return rlp.Encode(w, &rl)
109-
}
110-
111-
// DecodeRLP implements rlp.Decoder.
112-
//
113-
// Note some redundant fields(e.g. block number, tx hash etc) will be assembled later.
114-
func (l *LogForStorage) DecodeRLP(s *rlp.Stream) error {
115-
blob, err := s.Raw()
116-
if err != nil {
117-
return err
118-
}
119-
var dec rlpLog
120-
err = rlp.DecodeBytes(blob, &dec)
121-
if err == nil {
122-
*l = LogForStorage{
123-
Address: dec.Address,
124-
Topics: dec.Topics,
125-
Data: dec.Data,
126-
}
127-
} else {
128-
// Try to decode log with previous definition.
129-
var dec legacyRlpStorageLog
130-
err = rlp.DecodeBytes(blob, &dec)
131-
if err == nil {
132-
*l = LogForStorage{
133-
Address: dec.Address,
134-
Topics: dec.Topics,
135-
Data: dec.Data,
136-
}
137-
}
138-
}
139-
return err
140-
}

0 commit comments

Comments
 (0)