63
63
emptyCode = crypto .Keccak256 (nil )
64
64
)
65
65
66
+ // Config includes all the configurations for pruning.
67
+ type Config struct {
68
+ Datadir string // The directory of the state database
69
+ Cachedir string // The directory of state clean cache
70
+ BloomSize uint64 // The Megabytes of memory allocated to bloom-filter
71
+ }
72
+
66
73
// Pruner is an offline tool to prune the stale state with the
67
74
// help of the snapshot. The workflow of pruner is very simple:
68
75
//
@@ -75,40 +82,44 @@ var (
75
82
// periodically in order to release the disk usage and improve the
76
83
// disk read performance to some extent.
77
84
type Pruner struct {
78
- db ethdb.Database
79
- stateBloom * stateBloom
80
- datadir string
81
- trieCachePath string
82
- headHeader * types.Header
83
- snaptree * snapshot.Tree
85
+ config Config
86
+ chainHeader * types.Header
87
+ db ethdb.Database
88
+ stateBloom * stateBloom
89
+ snaptree * snapshot.Tree
84
90
}
85
91
86
92
// NewPruner creates the pruner instance.
87
- func NewPruner (db ethdb.Database , datadir , trieCachePath string , bloomSize uint64 ) (* Pruner , error ) {
93
+ func NewPruner (db ethdb.Database , config Config ) (* Pruner , error ) {
88
94
headBlock := rawdb .ReadHeadBlock (db )
89
95
if headBlock == nil {
90
96
return nil , errors .New ("Failed to load head block" )
91
97
}
92
- snaptree , err := snapshot .New (db , trie .NewDatabase (db ), 256 , headBlock .Root (), false , false , false )
98
+ snapconfig := snapshot.Config {
99
+ CacheSize : 256 ,
100
+ Recovery : false ,
101
+ NoBuild : true ,
102
+ AsyncBuild : false ,
103
+ }
104
+ snaptree , err := snapshot .New (snapconfig , db , trie .NewDatabase (db ), headBlock .Root ())
93
105
if err != nil {
94
106
return nil , err // The relevant snapshot(s) might not exist
95
107
}
96
108
// Sanitize the bloom filter size if it's too small.
97
- if bloomSize < 256 {
98
- log .Warn ("Sanitizing bloomfilter size" , "provided(MB)" , bloomSize , "updated(MB)" , 256 )
99
- bloomSize = 256
109
+ if config . BloomSize < 256 {
110
+ log .Warn ("Sanitizing bloomfilter size" , "provided(MB)" , config . BloomSize , "updated(MB)" , 256 )
111
+ config . BloomSize = 256
100
112
}
101
- stateBloom , err := newStateBloomWithSize (bloomSize )
113
+ stateBloom , err := newStateBloomWithSize (config . BloomSize )
102
114
if err != nil {
103
115
return nil , err
104
116
}
105
117
return & Pruner {
106
- db : db ,
107
- stateBloom : stateBloom ,
108
- datadir : datadir ,
109
- trieCachePath : trieCachePath ,
110
- headHeader : headBlock .Header (),
111
- snaptree : snaptree ,
118
+ config : config ,
119
+ chainHeader : headBlock .Header (),
120
+ db : db ,
121
+ stateBloom : stateBloom ,
122
+ snaptree : snaptree ,
112
123
}, nil
113
124
}
114
125
@@ -236,12 +247,12 @@ func (p *Pruner) Prune(root common.Hash) error {
236
247
// reuse it for pruning instead of generating a new one. It's
237
248
// mandatory because a part of state may already be deleted,
238
249
// the recovery procedure is necessary.
239
- _ , stateBloomRoot , err := findBloomFilter (p .datadir )
250
+ _ , stateBloomRoot , err := findBloomFilter (p .config . Datadir )
240
251
if err != nil {
241
252
return err
242
253
}
243
254
if stateBloomRoot != (common.Hash {}) {
244
- return RecoverPruning (p .datadir , p .db , p .trieCachePath )
255
+ return RecoverPruning (p .config . Datadir , p .db , p .config . Cachedir )
245
256
}
246
257
// If the target state root is not specified, use the HEAD-127 as the
247
258
// target. The reason for picking it is:
@@ -252,7 +263,7 @@ func (p *Pruner) Prune(root common.Hash) error {
252
263
// Retrieve all snapshot layers from the current HEAD.
253
264
// In theory there are 128 difflayers + 1 disk layer present,
254
265
// so 128 diff layers are expected to be returned.
255
- layers = p .snaptree .Snapshots (p .headHeader .Root , 128 , true )
266
+ layers = p .snaptree .Snapshots (p .chainHeader .Root , 128 , true )
256
267
if len (layers ) != 128 {
257
268
// Reject if the accumulated diff layers are less than 128. It
258
269
// means in most of normal cases, there is no associated state
@@ -294,7 +305,7 @@ func (p *Pruner) Prune(root common.Hash) error {
294
305
}
295
306
} else {
296
307
if len (layers ) > 0 {
297
- log .Info ("Selecting bottom-most difflayer as the pruning target" , "root" , root , "height" , p .headHeader .Number .Uint64 ()- 127 )
308
+ log .Info ("Selecting bottom-most difflayer as the pruning target" , "root" , root , "height" , p .chainHeader .Number .Uint64 ()- 127 )
298
309
} else {
299
310
log .Info ("Selecting user-specified state as the pruning target" , "root" , root )
300
311
}
@@ -303,7 +314,7 @@ func (p *Pruner) Prune(root common.Hash) error {
303
314
// It's necessary otherwise in the next restart we will hit the
304
315
// deleted state root in the "clean cache" so that the incomplete
305
316
// state is picked for usage.
306
- deleteCleanTrieCache (p .trieCachePath )
317
+ deleteCleanTrieCache (p .config . Cachedir )
307
318
308
319
// All the state roots of the middle layer should be forcibly pruned,
309
320
// otherwise the dangling state will be left.
@@ -325,7 +336,7 @@ func (p *Pruner) Prune(root common.Hash) error {
325
336
if err := extractGenesis (p .db , p .stateBloom ); err != nil {
326
337
return err
327
338
}
328
- filterName := bloomFilterName (p .datadir , root )
339
+ filterName := bloomFilterName (p .config . Datadir , root )
329
340
330
341
log .Info ("Writing state bloom to disk" , "name" , filterName )
331
342
if err := p .stateBloom .Commit (filterName , filterName + stateBloomFileTempSuffix ); err != nil {
@@ -362,7 +373,13 @@ func RecoverPruning(datadir string, db ethdb.Database, trieCachePath string) err
362
373
// - The state HEAD is rewound already because of multiple incomplete `prune-state`
363
374
// In this case, even the state HEAD is not exactly matched with snapshot, it
364
375
// still feasible to recover the pruning correctly.
365
- snaptree , err := snapshot .New (db , trie .NewDatabase (db ), 256 , headBlock .Root (), false , false , true )
376
+ snapconfig := snapshot.Config {
377
+ CacheSize : 256 ,
378
+ Recovery : true ,
379
+ NoBuild : true ,
380
+ AsyncBuild : false ,
381
+ }
382
+ snaptree , err := snapshot .New (snapconfig , db , trie .NewDatabase (db ), headBlock .Root ())
366
383
if err != nil {
367
384
return err // The relevant snapshot(s) might not exist
368
385
}
0 commit comments