forked from erigontech/erigon
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathreset_blocks.go
134 lines (123 loc) · 3.71 KB
/
reset_blocks.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package migrations
import (
"context"
"encoding/binary"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/datadir"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/log/v3"
"github.com/ledgerwatch/erigon/cmd/hack/tool"
"github.com/ledgerwatch/erigon/core/rawdb"
"github.com/ledgerwatch/erigon/core/rawdb/rawdbreset"
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
"github.com/ledgerwatch/erigon/turbo/snapshotsync"
"github.com/ledgerwatch/erigon/turbo/snapshotsync/snap"
)
var resetBlocks4 = Migration{
Name: "reset_blocks_4",
Up: func(db kv.RwDB, dirs datadir.Dirs, progress []byte, BeforeCommit Callback) (err error) {
tx, err := db.BeginRw(context.Background())
if err != nil {
return err
}
defer tx.Rollback()
enabled, err := snap.Enabled(tx)
if err != nil {
return err
}
if !enabled {
if err := BeforeCommit(tx, nil, true); err != nil {
return err
}
return tx.Commit()
}
// Detect whether the correction is required
snaps := snapshotsync.NewRoSnapshots(ethconfig.Snapshot{
Enabled: true,
KeepBlocks: true,
Produce: false,
}, dirs.Snap)
snaps.ReopenFolder()
var lastFound bool
var lastBlockNum, lastBaseTxNum, lastAmount uint64
if err := snaps.Bodies.View(func(sns []*snapshotsync.BodySegment) error {
// Take the last snapshot
if len(sns) == 0 {
return nil
}
sn := sns[len(sns)-1]
sn.Iterate(func(blockNum uint64, baseTxNum uint64, txAmount uint64) error {
lastBlockNum = blockNum
lastBaseTxNum = baseTxNum
lastAmount = txAmount
lastFound = true
return nil
})
return nil
}); err != nil {
return err
}
if !lastFound {
if err := BeforeCommit(tx, nil, true); err != nil {
return err
}
return tx.Commit()
}
c, err := tx.Cursor(kv.BlockBody)
if err != nil {
return err
}
defer c.Close()
var fixNeeded bool
for k, _, err := c.First(); k != nil; k, _, err = c.Next() {
if err != nil {
return err
}
blockNumber := binary.BigEndian.Uint64(k[:8])
if blockNumber != lastBlockNum+1 {
continue
}
blockHash := libcommon.BytesToHash(k[8:])
var hash libcommon.Hash
if hash, err = rawdb.ReadCanonicalHash(tx, blockNumber); err != nil {
return err
}
// ReadBody is not returning baseTxId which is written into the DB record, but that value + 1
_, baseTxId, _ := rawdb.ReadBody(tx, blockHash, blockNumber)
if hash != blockHash {
continue
}
if lastBaseTxNum+lastAmount+1 != baseTxId {
log.Info("Fix required, last block in seg files", "height", lastBlockNum, "baseTxNum", lastBaseTxNum, "txAmount", lastAmount, "first txId in DB", baseTxId, "expected", lastBaseTxNum+lastAmount+1)
fixNeeded = true
}
}
if !fixNeeded {
log.Info("Fix is not required")
if err := BeforeCommit(tx, nil, true); err != nil {
return err
}
return tx.Commit()
}
headersProgress, _ := stages.GetStageProgress(tx, stages.Headers)
if headersProgress > 0 {
log.Warn("NOTE: this migration will remove recent blocks (and senders) to fix several recent bugs. Your node will re-download last ~400K blocks, should not take very long")
}
cc := tool.ChainConfig(tx)
if err := rawdbreset.ResetBlocks(tx, db, nil, nil, nil, dirs, *cc, nil); err != nil {
return err
}
if err := rawdbreset.ResetSenders(context.Background(), db, tx); err != nil {
return err
}
if err := rawdbreset.ResetTxLookup(tx); err != nil {
return err
}
// This migration is no-op, but it forces the migration mechanism to apply it and thus write the DB schema version info
if err := BeforeCommit(tx, nil, true); err != nil {
return err
}
return tx.Commit()
},
}