@@ -80,8 +80,6 @@ type Database struct {
8080 oldest common.Hash // Oldest tracked node, flush-list head
8181 newest common.Hash // Newest tracked node, flush-list tail
8282
83- preimages map [common.Hash ][]byte // Preimages of nodes from the secure trie
84-
8583 gctime time.Duration // Time spent on garbage collection since last commit
8684 gcnodes uint64 // Nodes garbage collected since last commit
8785 gcsize common.StorageSize // Data storage garbage collected since last commit
@@ -90,9 +88,9 @@ type Database struct {
9088 flushnodes uint64 // Nodes flushed since last commit
9189 flushsize common.StorageSize // Data storage flushed since last commit
9290
93- dirtiesSize common.StorageSize // Storage size of the dirty node cache (exc. metadata)
94- childrenSize common.StorageSize // Storage size of the external children tracking
95- preimagesSize common. StorageSize // Storage size of the preimages cache
91+ dirtiesSize common.StorageSize // Storage size of the dirty node cache (exc. metadata)
92+ childrenSize common.StorageSize // Storage size of the external children tracking
93+ preimages * preimageStore // The store for caching preimages
9694
9795 lock sync.RWMutex
9896}
@@ -305,16 +303,18 @@ func NewDatabaseWithConfig(diskdb ethdb.KeyValueStore, config *Config) *Database
305303 cleans = fastcache .LoadFromFileOrNew (config .Journal , config .Cache * 1024 * 1024 )
306304 }
307305 }
306+ var preimage * preimageStore
307+ if config != nil && config .Preimages {
308+ preimage = newPreimageStore (diskdb )
309+ }
308310 db := & Database {
309311 diskdb : diskdb ,
310312 cleans : cleans ,
311313 dirties : map [common.Hash ]* cachedNode {{}: {
312314 children : make (map [common.Hash ]uint16 ),
313315 }},
314316 rawDirties : make (KvMap ),
315- }
316- if config == nil || config .Preimages { // TODO(karalabe): Flip to default off in the future
317- db .preimages = make (map [common.Hash ][]byte )
317+ preimages : preimage ,
318318 }
319319 return db
320320}
@@ -357,24 +357,6 @@ func (db *Database) insert(hash common.Hash, size int, node node) {
357357 db .dirtiesSize += common .StorageSize (common .HashLength + entry .size )
358358}
359359
360- // insertPreimage writes a new trie node pre-image to the memory database if it's
361- // yet unknown. The method will NOT make a copy of the slice,
362- // only use if the preimage will NOT be changed later on.
363- //
364- // Note, this method assumes that the database's lock is held!
365- func (db * Database ) insertPreimage (hash common.Hash , preimage []byte ) {
366- // Short circuit if preimage collection is disabled
367- if db .preimages == nil {
368- return
369- }
370- // Track the preimage if a yet unknown one
371- if _ , ok := db .preimages [hash ]; ok {
372- return
373- }
374- db .preimages [hash ] = preimage
375- db .preimagesSize += common .StorageSize (common .HashLength + len (preimage ))
376- }
377-
378360// node retrieves a cached trie node from memory, or returns nil if none can be
379361// found in the memory cache.
380362func (db * Database ) node (hash common.Hash ) node {
@@ -451,24 +433,6 @@ func (db *Database) Node(hash common.Hash) ([]byte, error) {
451433 return nil , errors .New ("not found" )
452434}
453435
454- // preimage retrieves a cached trie node pre-image from memory. If it cannot be
455- // found cached, the method queries the persistent database for the content.
456- func (db * Database ) preimage (hash common.Hash ) []byte {
457- // Short circuit if preimage collection is disabled
458- if db .preimages == nil {
459- return nil
460- }
461- // Retrieve the node from cache if available
462- db .lock .RLock ()
463- preimage := db .preimages [hash ]
464- db .lock .RUnlock ()
465-
466- if preimage != nil {
467- return preimage
468- }
469- return rawdb .ReadPreimage (db .diskdb , hash )
470- }
471-
472436// Nodes retrieves the hashes of all the nodes cached within the memory database.
473437// This method is extremely expensive and should only be used to validate internal
474438// states in test code.
@@ -613,19 +577,8 @@ func (db *Database) Cap(limit common.StorageSize) error {
613577
614578 // If the preimage cache got large enough, push to disk. If it's still small
615579 // leave for later to deduplicate writes.
616- flushPreimages := db .preimagesSize > 4 * 1024 * 1024
617- if flushPreimages {
618- if db .preimages == nil {
619- log .Error ("Attempted to write preimages whilst disabled" )
620- } else {
621- rawdb .WritePreimages (batch , db .preimages )
622- if batch .ValueSize () > ethdb .IdealBatchSize {
623- if err := batch .Write (); err != nil {
624- return err
625- }
626- batch .Reset ()
627- }
628- }
580+ if db .preimages != nil {
581+ db .preimages .commit (false )
629582 }
630583 // Keep committing nodes from the flush-list until we're below allowance
631584 oldest := db .oldest
@@ -660,13 +613,6 @@ func (db *Database) Cap(limit common.StorageSize) error {
660613 db .lock .Lock ()
661614 defer db .lock .Unlock ()
662615
663- if flushPreimages {
664- if db .preimages == nil {
665- log .Error ("Attempted to reset preimage cache whilst disabled" )
666- } else {
667- db .preimages , db .preimagesSize = make (map [common.Hash ][]byte ), 0
668- }
669- }
670616 for db .oldest != oldest {
671617 node := db .dirties [db .oldest ]
672618 delete (db .dirties , db .oldest )
@@ -727,13 +673,7 @@ func (db *Database) Commit(node common.Hash, report bool, callback func(common.H
727673
728674 // Move all of the accumulated preimages into a write batch
729675 if db .preimages != nil {
730- rawdb .WritePreimages (batch , db .preimages )
731- // Since we're going to replay trie node writes into the clean cache, flush out
732- // any batched pre-images before continuing.
733- if err := batch .Write (); err != nil {
734- return err
735- }
736- batch .Reset ()
676+ db .preimages .commit (true )
737677 }
738678 // Move the trie itself into the batch, flushing if enough data is accumulated
739679 nodes , storage := len (db .dirties ), db .dirtiesSize
@@ -756,9 +696,6 @@ func (db *Database) Commit(node common.Hash, report bool, callback func(common.H
756696 batch .Reset ()
757697
758698 // Reset the storage counters and bumped metrics
759- if db .preimages != nil {
760- db .preimages , db .preimagesSize = make (map [common.Hash ][]byte ), 0
761- }
762699 memcacheCommitTimeTimer .Update (time .Since (start ))
763700 memcacheCommitSizeMeter .Mark (int64 (storage - db .dirtiesSize ))
764701 memcacheCommitNodesMeter .Mark (int64 (nodes - len (db .dirties )))
@@ -870,7 +807,11 @@ func (db *Database) Size() (common.StorageSize, common.StorageSize) {
870807 // counted.
871808 var metadataSize = common .StorageSize ((len (db .dirties ) - 1 ) * cachedNodeSize )
872809 var metarootRefs = common .StorageSize (len (db .dirties [common.Hash {}].children ) * (common .HashLength + 2 ))
873- return db .dirtiesSize + db .childrenSize + metadataSize - metarootRefs , db .preimagesSize
810+ var preimageSize common.StorageSize
811+ if db .preimages != nil {
812+ preimageSize = db .preimages .size ()
813+ }
814+ return db .dirtiesSize + db .childrenSize + metadataSize - metarootRefs , preimageSize
874815}
875816
876817// saveCache saves clean state cache to given directory path
0 commit comments