core/state/snapshot: write snapshot generator in batch (#22163)

* core/state/snapshot: write snapshot generator in batch

* core: refactor the tests

* core: update tests

* core: update tests
This commit is contained in:
gary rong 2021-01-18 21:39:43 +08:00 committed by GitHub
parent 10555d4684
commit 5e9f5ca5d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 653 additions and 417 deletions

File diff suppressed because it is too large Load Diff

View File

@ -101,18 +101,26 @@ func generateSnapshot(diskdb ethdb.KeyValueStore, triedb *trie.Database, cache i
wiper = wipeSnapshot(diskdb, true) wiper = wipeSnapshot(diskdb, true)
} }
// Create a new disk layer with an initialized state marker at zero // Create a new disk layer with an initialized state marker at zero
rawdb.WriteSnapshotRoot(diskdb, root) var (
stats = &generatorStats{wiping: wiper, start: time.Now()}
batch = diskdb.NewBatch()
genMarker = []byte{} // Initialized but empty!
)
rawdb.WriteSnapshotRoot(batch, root)
journalProgress(batch, genMarker, stats)
if err := batch.Write(); err != nil {
log.Crit("Failed to write initialized state marker", "error", err)
}
base := &diskLayer{ base := &diskLayer{
diskdb: diskdb, diskdb: diskdb,
triedb: triedb, triedb: triedb,
root: root, root: root,
cache: fastcache.New(cache * 1024 * 1024), cache: fastcache.New(cache * 1024 * 1024),
genMarker: []byte{}, // Initialized but empty! genMarker: genMarker,
genPending: make(chan struct{}), genPending: make(chan struct{}),
genAbort: make(chan chan *generatorStats), genAbort: make(chan chan *generatorStats),
} }
go base.generate(&generatorStats{wiping: wiper, start: time.Now()}) go base.generate(stats)
log.Debug("Start snapshot generation", "root", root) log.Debug("Start snapshot generation", "root", root)
return base return base
} }
@ -137,10 +145,12 @@ func journalProgress(db ethdb.KeyValueWriter, marker []byte, stats *generatorSta
panic(err) // Cannot happen, here to catch dev errors panic(err) // Cannot happen, here to catch dev errors
} }
var logstr string var logstr string
switch len(marker) { switch {
case 0: case marker == nil:
logstr = "done" logstr = "done"
case common.HashLength: case bytes.Equal(marker, []byte{}):
logstr = "empty"
case len(marker) == common.HashLength:
logstr = fmt.Sprintf("%#x", marker) logstr = fmt.Sprintf("%#x", marker)
default: default:
logstr = fmt.Sprintf("%#x:%#x", marker[:common.HashLength], marker[common.HashLength:]) logstr = fmt.Sprintf("%#x:%#x", marker[:common.HashLength], marker[common.HashLength:])
@ -307,13 +317,12 @@ func (dl *diskLayer) generate(stats *generatorStats) {
abort <- stats abort <- stats
return return
} }
// Snapshot fully generated, set the marker to nil // Snapshot fully generated, set the marker to nil.
if batch.ValueSize() > 0 { // Note even there is nothing to commit, persist the
// Ensure the generator entry is in sync with the data // generator anyway to mark the snapshot is complete.
journalProgress(batch, nil, stats) journalProgress(batch, nil, stats)
batch.Write()
batch.Write()
}
log.Info("Generated state snapshot", "accounts", stats.accounts, "slots", stats.slots, log.Info("Generated state snapshot", "accounts", stats.accounts, "slots", stats.slots,
"storage", stats.storage, "elapsed", common.PrettyDuration(time.Since(stats.start))) "storage", stats.storage, "elapsed", common.PrettyDuration(time.Since(stats.start)))

View File

@ -441,6 +441,6 @@ func (dl *diffLayer) LegacyJournal(buffer *bytes.Buffer) (common.Hash, error) {
if err := rlp.Encode(buffer, storage); err != nil { if err := rlp.Encode(buffer, storage); err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
log.Debug("Legacy journalled disk layer", "root", dl.root, "parent", dl.parent.Root()) log.Debug("Legacy journalled diff layer", "root", dl.root, "parent", dl.parent.Root())
return base, nil return base, nil
} }