Skip to content

Commit ecd09f3

Browse files
authored
Merge pull request #212 from CortexFoundation/ucwong
freeze and compress block from active leveldb
2 parents ae403b6 + 66b2e73 commit ecd09f3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+6909
-1700
lines changed

accounts/abi/bind/auth.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
"github.com/CortexFoundation/CortexTheseus/common"
2727
"github.com/CortexFoundation/CortexTheseus/core/types"
2828
"github.com/CortexFoundation/CortexTheseus/crypto"
29-
"github.com/ethereum/go-ethereum/accounts"
29+
"github.com/ethereum/CortexTheseus/accounts"
3030
)
3131

3232
// NewTransactor is a utility method to easily create a transaction signer from

cmd/cortex/chaincmd.go

Lines changed: 100 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ package main
1818

1919
import (
2020
"encoding/json"
21+
"path/filepath"
2122
"fmt"
2223
"os"
2324
"runtime"
2425
"strconv"
2526
"sync/atomic"
2627
"time"
2728

28-
"github.com/CortexFoundation/CortexTheseus/cmd/utils"
29+
"github.com/CortexFoundation/CortexTheseus/core/rawdb"
2930
"github.com/CortexFoundation/CortexTheseus/common"
31+
"github.com/CortexFoundation/CortexTheseus/cmd/utils"
3032
"github.com/CortexFoundation/CortexTheseus/console"
3133
"github.com/CortexFoundation/CortexTheseus/core"
3234
"github.com/CortexFoundation/CortexTheseus/core/state"
@@ -36,7 +38,7 @@ import (
3638
"github.com/CortexFoundation/CortexTheseus/event"
3739
"github.com/CortexFoundation/CortexTheseus/log"
3840
"github.com/CortexFoundation/CortexTheseus/trie"
39-
"github.com/syndtr/goleveldb/leveldb/util"
41+
//"github.com/syndtr/goleveldb/leveldb/util"
4042
"gopkg.in/urfave/cli.v1"
4143
)
4244

@@ -169,6 +171,19 @@ Remove blockchain and state databases`,
169171
The arguments are interpreted as block numbers or hashes.
170172
Use "cortex dump 0" to dump the genesis block.`,
171173
}
174+
inspectCommand = cli.Command{
175+
Action: utils.MigrateFlags(inspect),
176+
Name: "inspect",
177+
Usage: "Inspect the storage size for each type of data in the database",
178+
ArgsUsage: " ",
179+
Flags: []cli.Flag{
180+
utils.DataDirFlag,
181+
utils.AncientFlag,
182+
utils.CacheFlag,
183+
utils.SyncModeFlag,
184+
},
185+
Category: "BLOCKCHAIN COMMANDS",
186+
}
172187
)
173188

174189
// initGenesis will initialise the given JSON format genesis file and writes it as
@@ -192,7 +207,7 @@ func initGenesis(ctx *cli.Context) error {
192207
// Open an initialise both full and light databases
193208
stack := makeFullNode(ctx)
194209
for _, name := range []string{"chaindata"} {
195-
chaindb, err := stack.OpenDatabase(name, 0, 0)
210+
chaindb, err := stack.OpenDatabase(name, 0, 0, "")
196211
if err != nil {
197212
utils.Fatalf("Failed to open database: %v", err)
198213
}
@@ -246,15 +261,17 @@ func importChain(ctx *cli.Context) error {
246261
fmt.Printf("Import done in %v.\n\n", time.Since(start))
247262

248263
// Output pre-compaction stats mostly to see the import trashing
249-
db := chainDb.(*ctxcdb.LDBDatabase)
264+
db := chainDb.(ctxcdb.Database)
250265

251-
stats, err := db.LDB().GetProperty("leveldb.stats")
266+
//stats, err := db.LDB().GetProperty("leveldb.stats")
267+
stats, err := db.Stat("leveldb.stats")
252268
if err != nil {
253269
utils.Fatalf("Failed to read database stats: %v", err)
254270
}
255271
fmt.Println(stats)
256272

257-
ioStats, err := db.LDB().GetProperty("leveldb.iostats")
273+
//ioStats, err := db.LDB().GetProperty("leveldb.iostats")
274+
ioStats, err := db.Stat("leveldb.iostats")
258275
if err != nil {
259276
utils.Fatalf("Failed to read database iostats: %v", err)
260277
}
@@ -279,18 +296,18 @@ func importChain(ctx *cli.Context) error {
279296
// Compact the entire database to more accurately measure disk io and print the stats
280297
start = time.Now()
281298
fmt.Println("Compacting entire database...")
282-
if err = db.LDB().CompactRange(util.Range{}); err != nil {
283-
utils.Fatalf("Compaction failed: %v", err)
284-
}
299+
if err = db.Compact(nil, nil); err != nil {
300+
utils.Fatalf("Compaction failed: %v", err)
301+
}
285302
fmt.Printf("Compaction done in %v.\n\n", time.Since(start))
286303

287-
stats, err = db.LDB().GetProperty("leveldb.stats")
304+
stats, err = db.Stat("leveldb.stats")
288305
if err != nil {
289306
utils.Fatalf("Failed to read database stats: %v", err)
290307
}
291308
fmt.Println(stats)
292309

293-
ioStats, err = db.LDB().GetProperty("leveldb.iostats")
310+
ioStats, err = db.Stat("leveldb.iostats")
294311
if err != nil {
295312
utils.Fatalf("Failed to read database iostats: %v", err)
296313
}
@@ -337,7 +354,7 @@ func importPreimages(ctx *cli.Context) error {
337354
utils.Fatalf("This command requires an argument.")
338355
}
339356
stack := makeFullNode(ctx)
340-
diskdb := utils.MakeChainDatabase(ctx, stack).(*ctxcdb.LDBDatabase)
357+
diskdb := utils.MakeChainDatabase(ctx, stack).(ctxcdb.Database)
341358

342359
start := time.Now()
343360
if err := utils.ImportPreimages(diskdb, ctx.Args().First()); err != nil {
@@ -353,7 +370,7 @@ func exportPreimages(ctx *cli.Context) error {
353370
utils.Fatalf("This command requires an argument.")
354371
}
355372
stack := makeFullNode(ctx)
356-
diskdb := utils.MakeChainDatabase(ctx, stack).(*ctxcdb.LDBDatabase)
373+
diskdb := utils.MakeChainDatabase(ctx, stack).(ctxcdb.Database)
357374

358375
start := time.Now()
359376
if err := utils.ExportPreimages(diskdb, ctx.Args().First()); err != nil {
@@ -365,9 +382,13 @@ func exportPreimages(ctx *cli.Context) error {
365382

366383
func copyDb(ctx *cli.Context) error {
367384
// Ensure we have a source chain directory to copy
368-
if len(ctx.Args()) != 1 {
385+
if len(ctx.Args()) < 1 {
369386
utils.Fatalf("Source chaindata directory path argument missing")
370387
}
388+
389+
if len(ctx.Args()) < 2 {
390+
utils.Fatalf("Source ancient chain directory path argument missing")
391+
}
371392
// Initialize a new chain for the running node to sync into
372393
stack := makeFullNode(ctx)
373394
chain, chainDb := utils.MakeChain(ctx, stack)
@@ -376,7 +397,8 @@ func copyDb(ctx *cli.Context) error {
376397
dl := downloader.New(syncmode, 0, chainDb, new(event.TypeMux), chain, nil)
377398

378399
// Create a source peer to satisfy downloader requests from
379-
db, err := ctxcdb.NewLDBDatabase(ctx.Args().First(), ctx.GlobalInt(utils.CacheFlag.Name), 256)
400+
//db, err := ctxcdb.NewLevelDatabase(ctx.Args().First(), ctx.GlobalInt(utils.CacheFlag.Name), 256)
401+
db, err := rawdb.NewLevelDBDatabaseWithFreezer(ctx.Args().First(), ctx.GlobalInt(utils.CacheFlag.Name)/2, 256, ctx.Args().Get(1), "")
380402
if err != nil {
381403
return err
382404
}
@@ -403,41 +425,65 @@ func copyDb(ctx *cli.Context) error {
403425
// Compact the entire database to remove any sync overhead
404426
start = time.Now()
405427
fmt.Println("Compacting entire database...")
406-
if err = chainDb.(*ctxcdb.LDBDatabase).LDB().CompactRange(util.Range{}); err != nil {
407-
utils.Fatalf("Compaction failed: %v", err)
408-
}
428+
if err = db.Compact(nil, nil); err != nil {
429+
utils.Fatalf("Compaction failed: %v", err)
430+
}
409431
fmt.Printf("Compaction done in %v.\n\n", time.Since(start))
410432

411433
return nil
412434
}
413435

414436
func removeDB(ctx *cli.Context) error {
415-
stack, _ := makeConfigNode(ctx)
416-
417-
for _, name := range []string{"chaindata"} {
418-
// Ensure the database exists in the first place
419-
logger := log.New("database", name)
437+
stack, config := makeConfigNode(ctx)
438+
439+
// Remove the full node state database
440+
path := stack.ResolvePath("chaindata")
441+
if common.FileExist(path) {
442+
confirmAndRemoveDB(path, "full node state database")
443+
} else {
444+
log.Info("Full node state database missing", "path", path)
445+
}
446+
// Remove the full node ancient database
447+
path = config.Cortex.DatabaseFreezer
448+
switch {
449+
case path == "":
450+
path = filepath.Join(stack.ResolvePath("chaindata"), "ancient")
451+
case !filepath.IsAbs(path):
452+
path = config.Node.ResolvePath(path)
453+
}
454+
if common.FileExist(path) {
455+
confirmAndRemoveDB(path, "full node ancient database")
456+
} else {
457+
log.Info("Full node ancient database missing", "path", path)
458+
}
459+
return nil
460+
}
420461

421-
dbdir := stack.ResolvePath(name)
422-
if !common.FileExist(dbdir) {
423-
logger.Info("Database doesn't exist, skipping", "path", dbdir)
424-
continue
425-
}
426-
// Confirm removal and execute
427-
fmt.Println(dbdir)
428-
confirm, err := console.Stdin.PromptConfirm("Remove this database?")
429-
switch {
430-
case err != nil:
431-
utils.Fatalf("%v", err)
432-
case !confirm:
433-
logger.Warn("Database deletion aborted")
434-
default:
435-
start := time.Now()
436-
os.RemoveAll(dbdir)
437-
logger.Info("Database successfully deleted", "elapsed", common.PrettyDuration(time.Since(start)))
438-
}
439-
}
440-
return nil
462+
// confirmAndRemoveDB prompts the user for a last confirmation and removes the
463+
// folder if accepted.
464+
func confirmAndRemoveDB(database string, kind string) {
465+
confirm, err := console.Stdin.PromptConfirm(fmt.Sprintf("Remove %s (%s)?", kind, database))
466+
switch {
467+
case err != nil:
468+
utils.Fatalf("%v", err)
469+
case !confirm:
470+
log.Info("Database deletion skipped", "path", database)
471+
default:
472+
start := time.Now()
473+
filepath.Walk(database, func(path string, info os.FileInfo, err error) error {
474+
// If we're at the top level folder, recurse into
475+
if path == database {
476+
return nil
477+
}
478+
// Delete all the files, but not subfolders
479+
if !info.IsDir() {
480+
os.Remove(path)
481+
return nil
482+
}
483+
return filepath.SkipDir
484+
})
485+
log.Info("Database successfully deleted", "path", database, "elapsed", common.PrettyDuration(time.Since(start)))
486+
}
441487
}
442488

443489
func dump(ctx *cli.Context) error {
@@ -466,6 +512,17 @@ func dump(ctx *cli.Context) error {
466512
return nil
467513
}
468514

515+
func inspect(ctx *cli.Context) error {
516+
node, _ := makeConfigNode(ctx)
517+
defer node.Close()
518+
519+
_, chainDb := utils.MakeChain(ctx, node)
520+
defer chainDb.Close()
521+
522+
return rawdb.InspectDatabase(chainDb)
523+
}
524+
525+
469526
// hashish returns true for strings that look like hashes.
470527
func hashish(x string) bool {
471528
_, err := strconv.Atoi(x)

cmd/utils/cmd.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func ExportAppendChain(blockchain *core.BlockChain, fn string, first uint64, las
238238
}
239239

240240
// ImportPreimages imports a batch of exported hash preimages into the database.
241-
func ImportPreimages(db *ctxcdb.LDBDatabase, fn string) error {
241+
func ImportPreimages(db ctxcdb.Database, fn string) error {
242242
log.Info("Importing preimages", "file", fn)
243243

244244
// Open the file handle and potentially unwrap the gzip stream
@@ -285,7 +285,7 @@ func ImportPreimages(db *ctxcdb.LDBDatabase, fn string) error {
285285

286286
// ExportPreimages exports all known hash preimages into the specified file,
287287
// truncating any data already present in the file.
288-
func ExportPreimages(db *ctxcdb.LDBDatabase, fn string) error {
288+
func ExportPreimages(db ctxcdb.Database, fn string) error {
289289
log.Info("Exporting preimages", "file", fn)
290290

291291
// Open the file handle and potentially wrap with a gzip stream
@@ -302,6 +302,7 @@ func ExportPreimages(db *ctxcdb.LDBDatabase, fn string) error {
302302
}
303303
// Iterate over the preimages and export them
304304
it := db.NewIteratorWithPrefix([]byte("secure-key-"))
305+
defer it.Release()
305306
for it.Next() {
306307
if err := rlp.Encode(writer, it.Value()); err != nil {
307308
return err

cmd/utils/flags.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ var (
125125
Name: "keystore",
126126
Usage: "Directory for the keystore (default = inside the datadir)",
127127
}
128+
AncientFlag = DirectoryFlag{
129+
Name: "datadir.ancient",
130+
Usage: "Data directory for ancient chain segments (default = inside chaindata)",
131+
}
128132
// NoUSBFlag = cli.BoolFlag{
129133
// Name: "nousb",
130134
// Usage: "Disables monitoring for and managing USB hardware wallets",
@@ -1062,6 +1066,9 @@ func SetCortexConfig(ctx *cli.Context, stack *node.Node, cfg *ctxc.Config) {
10621066
cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
10631067
}
10641068
cfg.DatabaseHandles = makeDatabaseHandles()
1069+
if ctx.GlobalIsSet(AncientFlag.Name) {
1070+
cfg.DatabaseFreezer = ctx.GlobalString(AncientFlag.Name)
1071+
}
10651072

10661073
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
10671074
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
@@ -1296,7 +1303,8 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ctxcdb.Database {
12961303
handles = makeDatabaseHandles()
12971304
)
12981305
name := "chaindata"
1299-
chainDb, err := stack.OpenDatabase(name, cache, handles)
1306+
//chainDb, err := stack.OpenDatabase(name, cache, handles)
1307+
chainDb, err := stack.OpenDatabaseWithFreezer(name, cache, handles, ctx.GlobalString(AncientFlag.Name), "")
13001308
if err != nil {
13011309
Fatalf("Could not open database: %v", err)
13021310
}

common/prque/prque.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
1+
// CookieJar - A contestant's algorithm toolbox
2+
// Copyright (c) 2013 Peter Szilagyi. All rights reserved.
3+
//
4+
// CookieJar is dual licensed: use of this source code is governed by a BSD
5+
// license that can be found in the LICENSE file. Alternatively, the CookieJar
6+
// toolbox may be used in accordance with the terms and conditions contained
7+
// in a signed written agreement between you and the author(s).
8+
19
// This is a duplicated and slightly modified version of "gopkg.in/karalabe/cookiejar.v2/collections/prque".
210

11+
// Package prque implements a priority queue data structure supporting arbitrary
12+
// value types and int64 priorities.
13+
//
14+
// If you would like to use a min-priority queue, simply negate the priorities.
15+
//
16+
// Internally the queue is based on the standard heap package working on a
17+
// sortable version of the block based stack.
318
package prque
419

520
import (
@@ -11,8 +26,8 @@ type Prque struct {
1126
cont *sstack
1227
}
1328

14-
// Creates a new priority queue.
15-
func New(setIndex setIndexCallback) *Prque {
29+
// New creates a new priority queue.
30+
func New(setIndex SetIndexCallback) *Prque {
1631
return &Prque{newSstack(setIndex)}
1732
}
1833

@@ -21,6 +36,12 @@ func (p *Prque) Push(data interface{}, priority int64) {
2136
heap.Push(p.cont, &item{data, priority})
2237
}
2338

39+
// Peek returns the value with the greates priority but does not pop it off.
40+
func (p *Prque) Peek() (interface{}, int64) {
41+
item := p.cont.blocks[0][0]
42+
return item.value, item.priority
43+
}
44+
2445
// Pops the value with the greates priority off the stack and returns it.
2546
// Currently no shrinking is done.
2647
func (p *Prque) Pop() (interface{}, int64) {

0 commit comments

Comments
 (0)