@ -28,9 +28,7 @@ import (
"github.com/ethereum/go-ethereum/console/prompt"
"github.com/ethereum/go-ethereum/console/prompt"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb/leveldb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/syndtr/goleveldb/leveldb/opt"
"gopkg.in/urfave/cli.v1"
"gopkg.in/urfave/cli.v1"
)
)
@ -65,43 +63,98 @@ Remove blockchain and state databases`,
Action : utils . MigrateFlags ( inspect ) ,
Action : utils . MigrateFlags ( inspect ) ,
Name : "inspect" ,
Name : "inspect" ,
ArgsUsage : "<prefix> <start>" ,
ArgsUsage : "<prefix> <start>" ,
Flags : [ ] cli . Flag {
utils . DataDirFlag ,
utils . SyncModeFlag ,
utils . MainnetFlag ,
utils . RopstenFlag ,
utils . RinkebyFlag ,
utils . GoerliFlag ,
utils . YoloV3Flag ,
} ,
Usage : "Inspect the storage size for each type of data in the database" ,
Usage : "Inspect the storage size for each type of data in the database" ,
Description : ` This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data. ` ,
Description : ` This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data. ` ,
}
}
dbStatCmd = cli . Command {
dbStatCmd = cli . Command {
Action : dbStats ,
Action : utils . MigrateFlags ( dbStats ) ,
Name : "stats" ,
Name : "stats" ,
Usage : "Print leveldb statistics" ,
Usage : "Print leveldb statistics" ,
Flags : [ ] cli . Flag {
utils . DataDirFlag ,
utils . SyncModeFlag ,
utils . MainnetFlag ,
utils . RopstenFlag ,
utils . RinkebyFlag ,
utils . GoerliFlag ,
utils . YoloV3Flag ,
} ,
}
}
dbCompactCmd = cli . Command {
dbCompactCmd = cli . Command {
Action : dbCompact ,
Action : utils . MigrateFlags ( dbCompact ) ,
Name : "compact" ,
Name : "compact" ,
Usage : "Compact leveldb database. WARNING: May take a very long time" ,
Usage : "Compact leveldb database. WARNING: May take a very long time" ,
Flags : [ ] cli . Flag {
utils . DataDirFlag ,
utils . SyncModeFlag ,
utils . MainnetFlag ,
utils . RopstenFlag ,
utils . RinkebyFlag ,
utils . GoerliFlag ,
utils . YoloV3Flag ,
utils . CacheFlag ,
utils . CacheDatabaseFlag ,
} ,
Description : ` This command performs a database compaction .
Description : ` This command performs a database compaction .
WARNING : This operation may take a very long time to finish , and may cause database
WARNING : This operation may take a very long time to finish , and may cause database
corruption if it is aborted during execution ' ! ` ,
corruption if it is aborted during execution ' ! ` ,
}
}
dbGetCmd = cli . Command {
dbGetCmd = cli . Command {
Action : dbGet ,
Action : utils . MigrateFlags ( dbGet ) ,
Name : "get" ,
Name : "get" ,
Usage : "Show the value of a database key" ,
Usage : "Show the value of a database key" ,
ArgsUsage : "<hex-encoded key>" ,
ArgsUsage : "<hex-encoded key>" ,
Flags : [ ] cli . Flag {
utils . DataDirFlag ,
utils . SyncModeFlag ,
utils . MainnetFlag ,
utils . RopstenFlag ,
utils . RinkebyFlag ,
utils . GoerliFlag ,
utils . YoloV3Flag ,
} ,
Description : "This command looks up the specified database key from the database." ,
Description : "This command looks up the specified database key from the database." ,
}
}
dbDeleteCmd = cli . Command {
dbDeleteCmd = cli . Command {
Action : dbDelete ,
Action : utils . MigrateFlags ( dbDelete ) ,
Name : "delete" ,
Name : "delete" ,
Usage : "Delete a database key (WARNING: may corrupt your database)" ,
Usage : "Delete a database key (WARNING: may corrupt your database)" ,
ArgsUsage : "<hex-encoded key>" ,
ArgsUsage : "<hex-encoded key>" ,
Flags : [ ] cli . Flag {
utils . DataDirFlag ,
utils . SyncModeFlag ,
utils . MainnetFlag ,
utils . RopstenFlag ,
utils . RinkebyFlag ,
utils . GoerliFlag ,
utils . YoloV3Flag ,
} ,
Description : ` This command deletes the specified database key from the database .
Description : ` This command deletes the specified database key from the database .
WARNING : This is a low - level operation which may cause database corruption ! ` ,
WARNING : This is a low - level operation which may cause database corruption ! ` ,
}
}
dbPutCmd = cli . Command {
dbPutCmd = cli . Command {
Action : dbPut ,
Action : utils . MigrateFlags ( dbPut ) ,
Name : "put" ,
Name : "put" ,
Usage : "Set the value of a database key (WARNING: may corrupt your database)" ,
Usage : "Set the value of a database key (WARNING: may corrupt your database)" ,
ArgsUsage : "<hex-encoded key> <hex-encoded value>" ,
ArgsUsage : "<hex-encoded key> <hex-encoded value>" ,
Flags : [ ] cli . Flag {
utils . DataDirFlag ,
utils . SyncModeFlag ,
utils . MainnetFlag ,
utils . RopstenFlag ,
utils . RinkebyFlag ,
utils . GoerliFlag ,
utils . YoloV3Flag ,
} ,
Description : ` This command sets a given database key to the given value .
Description : ` This command sets a given database key to the given value .
WARNING : This is a low - level operation which may cause database corruption ! ` ,
WARNING : This is a low - level operation which may cause database corruption ! ` ,
}
}
@ -192,10 +245,10 @@ func inspect(ctx *cli.Context) error {
stack , _ := makeConfigNode ( ctx )
stack , _ := makeConfigNode ( ctx )
defer stack . Close ( )
defer stack . Close ( )
_ , chainD b := utils . MakeChain ( ctx , stack , true )
d b := utils . MakeChainDatabase ( ctx , stack , true )
defer chainD b. Close ( )
defer d b. Close ( )
return rawdb . InspectDatabase ( chainD b, prefix , start )
return rawdb . InspectDatabase ( d b, prefix , start )
}
}
func showLeveldbStats ( db ethdb . Stater ) {
func showLeveldbStats ( db ethdb . Stater ) {
@ -214,48 +267,32 @@ func showLeveldbStats(db ethdb.Stater) {
func dbStats ( ctx * cli . Context ) error {
func dbStats ( ctx * cli . Context ) error {
stack , _ := makeConfigNode ( ctx )
stack , _ := makeConfigNode ( ctx )
defer stack . Close ( )
defer stack . Close ( )
path := stack . ResolvePath ( "chaindata" )
db , err := leveldb . NewCustom ( path , "" , func ( options * opt . Options ) {
db := utils . MakeChainDatabase ( ctx , stack , true )
options . ReadOnly = true
defer db . Close ( )
} )
if err != nil {
return err
}
showLeveldbStats ( db )
showLeveldbStats ( db )
err = db . Close ( )
if err != nil {
log . Info ( "Close err" , "error" , err )
}
return nil
return nil
}
}
func dbCompact ( ctx * cli . Context ) error {
func dbCompact ( ctx * cli . Context ) error {
stack , _ := makeConfigNode ( ctx )
stack , _ := makeConfigNode ( ctx )
defer stack . Close ( )
defer stack . Close ( )
path := stack . ResolvePath ( "chaindata" )
cache := ctx . GlobalInt ( utils . CacheFlag . Name ) * ctx . GlobalInt ( utils . CacheDatabaseFlag . Name ) / 100
db := utils . MakeChainDatabase ( ctx , stack , false )
db , err := leveldb . NewCustom ( path , "" , func ( options * opt . Options ) {
defer db . Close ( )
options . OpenFilesCacheCapacity = utils . MakeDatabaseHandles ( )
options . BlockCacheCapacity = cache / 2 * opt . MiB
log . Info ( "Stats before compaction" )
options . WriteBuffer = cache / 4 * opt . MiB // Two of these are used internally
} )
if err != nil {
return err
}
showLeveldbStats ( db )
showLeveldbStats ( db )
log . Info ( "Triggering compaction" )
log . Info ( "Triggering compaction" )
err = db . Compact ( nil , nil )
if err := db . Compact ( nil , nil ) ; err != nil {
if err != nil {
log . Info ( "Compact err" , "error" , err )
log . Info ( "Compact err" , "error" , err )
return err
}
}
log . Info ( "Stats after compaction" )
showLeveldbStats ( db )
showLeveldbStats ( db )
log . Info ( "Closing db" )
return nil
err = db . Close ( )
if err != nil {
log . Info ( "Close err" , "error" , err )
}
log . Info ( "Exiting" )
return err
}
}
// dbGet shows the value of a given database key
// dbGet shows the value of a given database key
@ -265,14 +302,10 @@ func dbGet(ctx *cli.Context) error {
}
}
stack , _ := makeConfigNode ( ctx )
stack , _ := makeConfigNode ( ctx )
defer stack . Close ( )
defer stack . Close ( )
path := stack . ResolvePath ( "chaindata" )
db , err := leveldb . NewCustom ( path , "" , func ( options * opt . Options ) {
db := utils . MakeChainDatabase ( ctx , stack , true )
options . ReadOnly = true
} )
if err != nil {
return err
}
defer db . Close ( )
defer db . Close ( )
key , err := hexutil . Decode ( ctx . Args ( ) . Get ( 0 ) )
key , err := hexutil . Decode ( ctx . Args ( ) . Get ( 0 ) )
if err != nil {
if err != nil {
log . Info ( "Could not decode the key" , "error" , err )
log . Info ( "Could not decode the key" , "error" , err )
@ -283,7 +316,7 @@ func dbGet(ctx *cli.Context) error {
log . Info ( "Get operation failed" , "error" , err )
log . Info ( "Get operation failed" , "error" , err )
return err
return err
}
}
fmt . Printf ( "key %#x:\n\t %#x\n" , key , data )
fmt . Printf ( "key %#x: %#x\n" , key , data )
return nil
return nil
}
}
@ -294,13 +327,19 @@ func dbDelete(ctx *cli.Context) error {
}
}
stack , _ := makeConfigNode ( ctx )
stack , _ := makeConfigNode ( ctx )
defer stack . Close ( )
defer stack . Close ( )
db := utils . MakeChainDatabase ( ctx , stack )
db := utils . MakeChainDatabase ( ctx , stack , false )
defer db . Close ( )
defer db . Close ( )
key , err := hexutil . Decode ( ctx . Args ( ) . Get ( 0 ) )
key , err := hexutil . Decode ( ctx . Args ( ) . Get ( 0 ) )
if err != nil {
if err != nil {
log . Info ( "Could not decode the key" , "error" , err )
log . Info ( "Could not decode the key" , "error" , err )
return err
return err
}
}
data , err := db . Get ( key )
if err == nil {
fmt . Printf ( "Previous value: %#x\n" , data )
}
if err = db . Delete ( key ) ; err != nil {
if err = db . Delete ( key ) ; err != nil {
log . Info ( "Delete operation returned an error" , "error" , err )
log . Info ( "Delete operation returned an error" , "error" , err )
return err
return err
@ -315,8 +354,10 @@ func dbPut(ctx *cli.Context) error {
}
}
stack , _ := makeConfigNode ( ctx )
stack , _ := makeConfigNode ( ctx )
defer stack . Close ( )
defer stack . Close ( )
db := utils . MakeChainDatabase ( ctx , stack )
db := utils . MakeChainDatabase ( ctx , stack , false )
defer db . Close ( )
defer db . Close ( )
var (
var (
key [ ] byte
key [ ] byte
value [ ] byte
value [ ] byte
@ -335,7 +376,7 @@ func dbPut(ctx *cli.Context) error {
}
}
data , err = db . Get ( key )
data , err = db . Get ( key )
if err == nil {
if err == nil {
fmt . Printf ( "Previous value:\n %#x\n" , data )
fmt . Printf ( "Previous value: %#x\n" , data )
}
}
return db . Put ( key , value )
return db . Put ( key , value )
}
}