Skip to content

Commit 3f6bf40

Browse files
authored
all: dump trie journal into file (#546)
* all: load/dump trie disklayer into file Signed-off-by: jsvisa <delweng@gmail.com> * cmd: set cache.trie.journal=trie-disklayer.rlp as default Signed-off-by: jsvisa <delweng@gmail.com> * journal: directly write into file Signed-off-by: jsvisa <delweng@gmail.com> --------- Signed-off-by: jsvisa <delweng@gmail.com>
1 parent e37179e commit 3f6bf40

File tree

7 files changed

+55
-7
lines changed

7 files changed

+55
-7
lines changed

cmd/utils/flags.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,6 +1674,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
16741674
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheSnapshotFlag.Name) {
16751675
cfg.SnapshotCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheSnapshotFlag.Name) / 100
16761676
}
1677+
if journal := ctx.String(CacheTrieJournalFlag.Name); journal != "" {
1678+
cfg.TrieJournal = stack.ResolvePath(journal)
1679+
}
16771680
if ctx.IsSet(CacheLogSizeFlag.Name) {
16781681
cfg.FilterLogCacheSize = ctx.Int(CacheLogSizeFlag.Name)
16791682
}
@@ -2179,6 +2182,9 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
21792182
StateScheme: scheme,
21802183
StateHistory: ctx.Uint64(StateHistoryFlag.Name),
21812184
}
2185+
if journal := ctx.String(CacheTrieJournalFlag.Name); journal != "" {
2186+
cache.TrieJournal = stack.ResolvePath(journal)
2187+
}
21822188
if cache.TrieDirtyDisabled && !cache.Preimages {
21832189
cache.Preimages = true
21842190
log.Info("Enabling recording of key preimages since archive mode is used")

cmd/utils/flags_legacy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ var (
6363
CacheTrieJournalFlag = &cli.StringFlag{
6464
Name: "cache.trie.journal",
6565
Usage: "Disk journal directory for trie cache to survive node restarts",
66+
Value: "trie-disklayer.rlp",
6667
Category: flags.DeprecatedCategory,
6768
}
6869
CacheTrieRejournalFlag = &cli.DurationFlag{

core/blockchain.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ type CacheConfig struct {
166166
Preimages bool // Whether to store preimage of trie key to the disk
167167
StateHistory uint64 // Number of blocks from head whose state histories are reserved.
168168
StateScheme string // Scheme used to store ethereum states and merkle tree nodes on top
169+
TrieJournal string // Path used to store the trie pathdb journal
169170

170171
SnapshotNoBuild bool // Whether the background generation is allowed
171172
SnapshotWait bool // Wait for snapshot construction on startup. TODO(karalabe): This is a dirty hack for testing, nuke it
@@ -196,6 +197,7 @@ func (c *CacheConfig) triedbConfig(isVerkle bool) *triedb.Config {
196197
// for flushing both trie data and state data to disk. The config name
197198
// should be updated to eliminate the confusion.
198199
WriteBufferSize: c.TrieDirtyLimit * 1024 * 1024,
200+
Journal: c.TrieJournal,
199201
}
200202
}
201203
return config

eth/backend.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
205205
StateHistory: config.StateHistory,
206206
StateScheme: scheme,
207207
ChainHistoryMode: config.HistoryMode,
208+
TrieJournal: config.TrieJournal,
208209
}
209210
)
210211
if config.VMTrace != "" {

eth/ethconfig/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ type Config struct {
126126
TrieTimeout time.Duration
127127
SnapshotCache int
128128
Preimages bool
129+
TrieJournal string
129130

130131
// This is the number of blocks for which logs will be cached in the filter system.
131132
FilterLogCacheSize int

triedb/pathdb/database.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ type Config struct {
120120
WriteBufferSize int // Maximum memory allowance (in bytes) for write buffer
121121
ReadOnly bool // Flag whether the database is opened in read only mode
122122
SnapshotNoBuild bool // Flag Whether the background generation is allowed
123+
Journal string
123124
}
124125

125126
// sanitize checks the provided user configurations and changes anything that's

triedb/pathdb/journal.go

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"errors"
2222
"fmt"
2323
"io"
24+
"os"
2425
"time"
2526

2627
"github.com/ethereum/go-ethereum/common"
@@ -51,11 +52,24 @@ const journalVersion uint64 = 3
5152

5253
// loadJournal tries to parse the layer journal from the disk.
5354
func (db *Database) loadJournal(diskRoot common.Hash) (layer, error) {
54-
journal := rawdb.ReadTrieJournal(db.diskdb)
55-
if len(journal) == 0 {
56-
return nil, errMissJournal
55+
var reader io.Reader
56+
if db.config.Journal != "" && common.FileExist(db.config.Journal) {
57+
log.Info("Load pathdb disklayer journal", "path", db.config.Journal)
58+
// If a journal file is specified, read it from there
59+
f, err := os.OpenFile(db.config.Journal, os.O_RDONLY, 0644)
60+
if err != nil {
61+
return nil, fmt.Errorf("failed to read journal file %s: %w", db.config.Journal, err)
62+
}
63+
defer f.Close()
64+
reader = f
65+
} else {
66+
journal := rawdb.ReadTrieJournal(db.diskdb)
67+
if len(journal) == 0 {
68+
return nil, errMissJournal
69+
}
70+
reader = bytes.NewReader(journal)
5771
}
58-
r := rlp.NewStream(bytes.NewReader(journal), 0)
72+
r := rlp.NewStream(reader, 0)
5973

6074
// Firstly, resolve the first element as the journal version
6175
version, err := r.Uint64()
@@ -315,8 +329,21 @@ func (db *Database) Journal(root common.Hash) error {
315329
if db.readOnly {
316330
return errDatabaseReadOnly
317331
}
332+
333+
var journal io.Writer
334+
// Store the journal into the database and return
335+
if db.config.Journal != "" {
336+
file, err := os.OpenFile(db.config.Journal, os.O_WRONLY|os.O_CREATE, 0644)
337+
if err != nil {
338+
return fmt.Errorf("failed to open journal file %s: %w", db.config.Journal, err)
339+
}
340+
defer file.Close()
341+
journal = file
342+
} else {
343+
journal = new(bytes.Buffer)
344+
}
345+
318346
// Firstly write out the metadata of journal
319-
journal := new(bytes.Buffer)
320347
if err := rlp.Encode(journal, journalVersion); err != nil {
321348
return err
322349
}
@@ -333,11 +360,20 @@ func (db *Database) Journal(root common.Hash) error {
333360
if err := l.journal(journal); err != nil {
334361
return err
335362
}
363+
336364
// Store the journal into the database and return
337-
rawdb.WriteTrieJournal(db.diskdb, journal.Bytes())
365+
var size int
366+
if db.config.Journal == "" {
367+
data := journal.(*bytes.Buffer)
368+
size = data.Len()
369+
rawdb.WriteTrieJournal(db.diskdb, data.Bytes())
370+
} else {
371+
stat, _ := journal.(*os.File).Stat()
372+
size = int(stat.Size())
373+
}
338374

339375
// Set the db in read only mode to reject all following mutations
340376
db.readOnly = true
341-
log.Info("Persisted dirty state to disk", "size", common.StorageSize(journal.Len()), "elapsed", common.PrettyDuration(time.Since(start)))
377+
log.Info("Persisted dirty state to disk", "size", common.StorageSize(size), "elapsed", common.PrettyDuration(time.Since(start)))
342378
return nil
343379
}

0 commit comments

Comments
 (0)