@@ -16,10 +16,22 @@ import (
16
16
blsCommon "github.com/ethereum/go-ethereum/crypto/bls/common"
17
17
"github.com/ethereum/go-ethereum/ethdb"
18
18
"github.com/ethereum/go-ethereum/internal/ethapi"
19
+ "github.com/ethereum/go-ethereum/log"
19
20
"github.com/ethereum/go-ethereum/params"
20
21
lru "github.com/hashicorp/golang-lru"
21
22
)
22
23
24
+ const (
25
+ blocksPerEpoch = 200
26
+ epochsPerPeriod = 144
27
+ )
28
+
29
+ var (
30
+ latestSnapshotsKeep = blocksPerEpoch * epochsPerPeriod * 5 // 5 days
31
+ snapshotsToBePruned = epochsPerPeriod * 2 // 2 days
32
+ pruningPeriod = blocksPerEpoch * epochsPerPeriod * 1 // every 1 day
33
+ )
34
+
23
35
// Snapshot is the state of the authorization validators at a given point in time.
24
36
type Snapshot struct {
25
37
// private fields are not json.Marshalled
@@ -112,6 +124,42 @@ func loadSnapshot(
112
124
return snap , nil
113
125
}
114
126
127
+ // snapshot pruning
128
+ // delete the nSnapshotsPrune oldest snapshots, keep the latestSnapshotsKeep snapshots
129
+ func (s * Snapshot ) pruneSnapshot (db ethdb.Database , nSnapshotPrune int , chain consensus.ChainHeaderReader ) error {
130
+ log .Info ("Pruning snapshots at block" , "block" , s .Number , "nSnapshotPrune" , nSnapshotPrune )
131
+ // Get block number to start pruning
132
+ curBlockNumber := s .Number
133
+ curBlockNumber -= curBlockNumber % uint64 (blocksPerEpoch ) // start of the current epoch
134
+ curBlockNumber -= uint64 (latestSnapshotsKeep ) // start of the oldest epoch to keep
135
+
136
+ // delete nSnapshotPrune snapshots starting from curBlockNumber to the older ones
137
+ batch := db .NewBatch ()
138
+ for nSnapshotPrune > 0 {
139
+ nSnapshotPrune --
140
+ header := chain .GetHeaderByNumber (curBlockNumber )
141
+ if header == nil {
142
+ // no more snapshots to prune
143
+ break
144
+ }
145
+ curHash := header .Hash ()
146
+ if err := batch .Delete (append (rawdb .ConsortiumSnapshotPrefix , curHash [:]... )); err != nil {
147
+ return err
148
+ }
149
+ curBlockNumber -= uint64 (blocksPerEpoch )
150
+ }
151
+ log .Info ("Pruned snapshots done" )
152
+ return batch .Write ()
153
+ }
154
+
155
+ // periodically prune the snapshots at the start of each pruningPeriod
156
+ func (s * Snapshot ) pruneSnapshotPeriodically (db ethdb.Database , chain consensus.ChainHeaderReader ) error {
157
+ if s .Number % uint64 (pruningPeriod ) == 0 {
158
+ return s .pruneSnapshot (db , snapshotsToBePruned , chain )
159
+ }
160
+ return nil
161
+ }
162
+
115
163
// store inserts the snapshot into the database.
116
164
func (s * Snapshot ) store (db ethdb.Database ) error {
117
165
blob , err := json .Marshal (s )
0 commit comments