Skip to content

Commit 0c70b83

Browse files
authored
all: add read-only option to database (#22407)
* all: add read-only option to database * all: fixes tests * cmd/geth: migrate flags * cmd/geth: fix the compact * cmd/geth: fix the format * cmd/geth: fix log * cmd: add chain-readonly * core: add readonly notion to freezer * core/rawdb: add log * core/rawdb: fix freezer close * cmd: fix * cmd, core: construct db * core: update tests
1 parent aab3560 commit 0c70b83

26 files changed

+265
-190
lines changed

cmd/geth/chaincmd.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/ethereum/go-ethereum/cmd/utils"
2929
"github.com/ethereum/go-ethereum/common"
3030
"github.com/ethereum/go-ethereum/core"
31+
"github.com/ethereum/go-ethereum/core/rawdb"
3132
"github.com/ethereum/go-ethereum/core/state"
3233
"github.com/ethereum/go-ethereum/core/types"
3334
"github.com/ethereum/go-ethereum/log"
@@ -191,7 +192,7 @@ func initGenesis(ctx *cli.Context) error {
191192
defer stack.Close()
192193

193194
for _, name := range []string{"chaindata", "lightchaindata"} {
194-
chaindb, err := stack.OpenDatabase(name, 0, 0, "")
195+
chaindb, err := stack.OpenDatabase(name, 0, 0, "", false)
195196
if err != nil {
196197
utils.Fatalf("Failed to open database: %v", err)
197198
}
@@ -229,7 +230,7 @@ func importChain(ctx *cli.Context) error {
229230
stack, _ := makeConfigNode(ctx)
230231
defer stack.Close()
231232

232-
chain, db := utils.MakeChain(ctx, stack, false)
233+
chain, db := utils.MakeChain(ctx, stack)
233234
defer db.Close()
234235

235236
// Start periodically gathering memory profiles
@@ -304,7 +305,7 @@ func exportChain(ctx *cli.Context) error {
304305
stack, _ := makeConfigNode(ctx)
305306
defer stack.Close()
306307

307-
chain, _ := utils.MakeChain(ctx, stack, true)
308+
chain, _ := utils.MakeChain(ctx, stack)
308309
start := time.Now()
309310

310311
var err error
@@ -340,7 +341,7 @@ func importPreimages(ctx *cli.Context) error {
340341
stack, _ := makeConfigNode(ctx)
341342
defer stack.Close()
342343

343-
db := utils.MakeChainDatabase(ctx, stack)
344+
db := utils.MakeChainDatabase(ctx, stack, false)
344345
start := time.Now()
345346

346347
if err := utils.ImportPreimages(db, ctx.Args().First()); err != nil {
@@ -359,7 +360,7 @@ func exportPreimages(ctx *cli.Context) error {
359360
stack, _ := makeConfigNode(ctx)
360361
defer stack.Close()
361362

362-
db := utils.MakeChainDatabase(ctx, stack)
363+
db := utils.MakeChainDatabase(ctx, stack, true)
363364
start := time.Now()
364365

365366
if err := utils.ExportPreimages(db, ctx.Args().First()); err != nil {
@@ -373,21 +374,27 @@ func dump(ctx *cli.Context) error {
373374
stack, _ := makeConfigNode(ctx)
374375
defer stack.Close()
375376

376-
chain, chainDb := utils.MakeChain(ctx, stack, true)
377-
defer chainDb.Close()
377+
db := utils.MakeChainDatabase(ctx, stack, true)
378378
for _, arg := range ctx.Args() {
379-
var block *types.Block
379+
var header *types.Header
380380
if hashish(arg) {
381-
block = chain.GetBlockByHash(common.HexToHash(arg))
381+
hash := common.HexToHash(arg)
382+
number := rawdb.ReadHeaderNumber(db, hash)
383+
if number != nil {
384+
header = rawdb.ReadHeader(db, hash, *number)
385+
}
382386
} else {
383-
num, _ := strconv.Atoi(arg)
384-
block = chain.GetBlockByNumber(uint64(num))
387+
number, _ := strconv.Atoi(arg)
388+
hash := rawdb.ReadCanonicalHash(db, uint64(number))
389+
if hash != (common.Hash{}) {
390+
header = rawdb.ReadHeader(db, hash, uint64(number))
391+
}
385392
}
386-
if block == nil {
393+
if header == nil {
387394
fmt.Println("{}")
388395
utils.Fatalf("block not found")
389396
} else {
390-
state, err := state.New(block.Root(), state.NewDatabase(chainDb), nil)
397+
state, err := state.New(header.Root, state.NewDatabase(db), nil)
391398
if err != nil {
392399
utils.Fatalf("could not create new state: %v", err)
393400
}

cmd/geth/dao_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBloc
123123
}
124124
// Retrieve the DAO config flag from the database
125125
path := filepath.Join(datadir, "geth", "chaindata")
126-
db, err := rawdb.NewLevelDBDatabase(path, 0, 0, "")
126+
db, err := rawdb.NewLevelDBDatabase(path, 0, 0, "", false)
127127
if err != nil {
128128
t.Fatalf("test %d: failed to open test database: %v", test, err)
129129
}

cmd/geth/dbcmd.go

Lines changed: 96 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ import (
2828
"github.com/ethereum/go-ethereum/console/prompt"
2929
"github.com/ethereum/go-ethereum/core/rawdb"
3030
"github.com/ethereum/go-ethereum/ethdb"
31-
"github.com/ethereum/go-ethereum/ethdb/leveldb"
3231
"github.com/ethereum/go-ethereum/log"
33-
"github.com/syndtr/goleveldb/leveldb/opt"
3432
"gopkg.in/urfave/cli.v1"
3533
)
3634

@@ -65,43 +63,98 @@ Remove blockchain and state databases`,
6563
Action: utils.MigrateFlags(inspect),
6664
Name: "inspect",
6765
ArgsUsage: "<prefix> <start>",
68-
66+
Flags: []cli.Flag{
67+
utils.DataDirFlag,
68+
utils.SyncModeFlag,
69+
utils.MainnetFlag,
70+
utils.RopstenFlag,
71+
utils.RinkebyFlag,
72+
utils.GoerliFlag,
73+
utils.YoloV3Flag,
74+
},
6975
Usage: "Inspect the storage size for each type of data in the database",
7076
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.`,
7177
}
7278
dbStatCmd = cli.Command{
73-
Action: dbStats,
79+
Action: utils.MigrateFlags(dbStats),
7480
Name: "stats",
7581
Usage: "Print leveldb statistics",
82+
Flags: []cli.Flag{
83+
utils.DataDirFlag,
84+
utils.SyncModeFlag,
85+
utils.MainnetFlag,
86+
utils.RopstenFlag,
87+
utils.RinkebyFlag,
88+
utils.GoerliFlag,
89+
utils.YoloV3Flag,
90+
},
7691
}
7792
dbCompactCmd = cli.Command{
78-
Action: dbCompact,
93+
Action: utils.MigrateFlags(dbCompact),
7994
Name: "compact",
8095
Usage: "Compact leveldb database. WARNING: May take a very long time",
96+
Flags: []cli.Flag{
97+
utils.DataDirFlag,
98+
utils.SyncModeFlag,
99+
utils.MainnetFlag,
100+
utils.RopstenFlag,
101+
utils.RinkebyFlag,
102+
utils.GoerliFlag,
103+
utils.YoloV3Flag,
104+
utils.CacheFlag,
105+
utils.CacheDatabaseFlag,
106+
},
81107
Description: `This command performs a database compaction.
82108
WARNING: This operation may take a very long time to finish, and may cause database
83109
corruption if it is aborted during execution'!`,
84110
}
85111
dbGetCmd = cli.Command{
86-
Action: dbGet,
87-
Name: "get",
88-
Usage: "Show the value of a database key",
89-
ArgsUsage: "<hex-encoded key>",
112+
Action: utils.MigrateFlags(dbGet),
113+
Name: "get",
114+
Usage: "Show the value of a database key",
115+
ArgsUsage: "<hex-encoded key>",
116+
Flags: []cli.Flag{
117+
utils.DataDirFlag,
118+
utils.SyncModeFlag,
119+
utils.MainnetFlag,
120+
utils.RopstenFlag,
121+
utils.RinkebyFlag,
122+
utils.GoerliFlag,
123+
utils.YoloV3Flag,
124+
},
90125
Description: "This command looks up the specified database key from the database.",
91126
}
92127
dbDeleteCmd = cli.Command{
93-
Action: dbDelete,
128+
Action: utils.MigrateFlags(dbDelete),
94129
Name: "delete",
95130
Usage: "Delete a database key (WARNING: may corrupt your database)",
96131
ArgsUsage: "<hex-encoded key>",
132+
Flags: []cli.Flag{
133+
utils.DataDirFlag,
134+
utils.SyncModeFlag,
135+
utils.MainnetFlag,
136+
utils.RopstenFlag,
137+
utils.RinkebyFlag,
138+
utils.GoerliFlag,
139+
utils.YoloV3Flag,
140+
},
97141
Description: `This command deletes the specified database key from the database.
98142
WARNING: This is a low-level operation which may cause database corruption!`,
99143
}
100144
dbPutCmd = cli.Command{
101-
Action: dbPut,
145+
Action: utils.MigrateFlags(dbPut),
102146
Name: "put",
103147
Usage: "Set the value of a database key (WARNING: may corrupt your database)",
104148
ArgsUsage: "<hex-encoded key> <hex-encoded value>",
149+
Flags: []cli.Flag{
150+
utils.DataDirFlag,
151+
utils.SyncModeFlag,
152+
utils.MainnetFlag,
153+
utils.RopstenFlag,
154+
utils.RinkebyFlag,
155+
utils.GoerliFlag,
156+
utils.YoloV3Flag,
157+
},
105158
Description: `This command sets a given database key to the given value.
106159
WARNING: This is a low-level operation which may cause database corruption!`,
107160
}
@@ -192,10 +245,10 @@ func inspect(ctx *cli.Context) error {
192245
stack, _ := makeConfigNode(ctx)
193246
defer stack.Close()
194247

195-
_, chainDb := utils.MakeChain(ctx, stack, true)
196-
defer chainDb.Close()
248+
db := utils.MakeChainDatabase(ctx, stack, true)
249+
defer db.Close()
197250

198-
return rawdb.InspectDatabase(chainDb, prefix, start)
251+
return rawdb.InspectDatabase(db, prefix, start)
199252
}
200253

201254
func showLeveldbStats(db ethdb.Stater) {
@@ -214,48 +267,32 @@ func showLeveldbStats(db ethdb.Stater) {
214267
func dbStats(ctx *cli.Context) error {
215268
stack, _ := makeConfigNode(ctx)
216269
defer stack.Close()
217-
path := stack.ResolvePath("chaindata")
218-
db, err := leveldb.NewCustom(path, "", func(options *opt.Options) {
219-
options.ReadOnly = true
220-
})
221-
if err != nil {
222-
return err
223-
}
270+
271+
db := utils.MakeChainDatabase(ctx, stack, true)
272+
defer db.Close()
273+
224274
showLeveldbStats(db)
225-
err = db.Close()
226-
if err != nil {
227-
log.Info("Close err", "error", err)
228-
}
229275
return nil
230276
}
231277

232278
func dbCompact(ctx *cli.Context) error {
233279
stack, _ := makeConfigNode(ctx)
234280
defer stack.Close()
235-
path := stack.ResolvePath("chaindata")
236-
cache := ctx.GlobalInt(utils.CacheFlag.Name) * ctx.GlobalInt(utils.CacheDatabaseFlag.Name) / 100
237-
db, err := leveldb.NewCustom(path, "", func(options *opt.Options) {
238-
options.OpenFilesCacheCapacity = utils.MakeDatabaseHandles()
239-
options.BlockCacheCapacity = cache / 2 * opt.MiB
240-
options.WriteBuffer = cache / 4 * opt.MiB // Two of these are used internally
241-
})
242-
if err != nil {
243-
return err
244-
}
281+
282+
db := utils.MakeChainDatabase(ctx, stack, false)
283+
defer db.Close()
284+
285+
log.Info("Stats before compaction")
245286
showLeveldbStats(db)
287+
246288
log.Info("Triggering compaction")
247-
err = db.Compact(nil, nil)
248-
if err != nil {
289+
if err := db.Compact(nil, nil); err != nil {
249290
log.Info("Compact err", "error", err)
291+
return err
250292
}
293+
log.Info("Stats after compaction")
251294
showLeveldbStats(db)
252-
log.Info("Closing db")
253-
err = db.Close()
254-
if err != nil {
255-
log.Info("Close err", "error", err)
256-
}
257-
log.Info("Exiting")
258-
return err
295+
return nil
259296
}
260297

261298
// dbGet shows the value of a given database key
@@ -265,14 +302,10 @@ func dbGet(ctx *cli.Context) error {
265302
}
266303
stack, _ := makeConfigNode(ctx)
267304
defer stack.Close()
268-
path := stack.ResolvePath("chaindata")
269-
db, err := leveldb.NewCustom(path, "", func(options *opt.Options) {
270-
options.ReadOnly = true
271-
})
272-
if err != nil {
273-
return err
274-
}
305+
306+
db := utils.MakeChainDatabase(ctx, stack, true)
275307
defer db.Close()
308+
276309
key, err := hexutil.Decode(ctx.Args().Get(0))
277310
if err != nil {
278311
log.Info("Could not decode the key", "error", err)
@@ -283,7 +316,7 @@ func dbGet(ctx *cli.Context) error {
283316
log.Info("Get operation failed", "error", err)
284317
return err
285318
}
286-
fmt.Printf("key %#x:\n\t%#x\n", key, data)
319+
fmt.Printf("key %#x: %#x\n", key, data)
287320
return nil
288321
}
289322

@@ -294,13 +327,19 @@ func dbDelete(ctx *cli.Context) error {
294327
}
295328
stack, _ := makeConfigNode(ctx)
296329
defer stack.Close()
297-
db := utils.MakeChainDatabase(ctx, stack)
330+
331+
db := utils.MakeChainDatabase(ctx, stack, false)
298332
defer db.Close()
333+
299334
key, err := hexutil.Decode(ctx.Args().Get(0))
300335
if err != nil {
301336
log.Info("Could not decode the key", "error", err)
302337
return err
303338
}
339+
data, err := db.Get(key)
340+
if err == nil {
341+
fmt.Printf("Previous value: %#x\n", data)
342+
}
304343
if err = db.Delete(key); err != nil {
305344
log.Info("Delete operation returned an error", "error", err)
306345
return err
@@ -315,8 +354,10 @@ func dbPut(ctx *cli.Context) error {
315354
}
316355
stack, _ := makeConfigNode(ctx)
317356
defer stack.Close()
318-
db := utils.MakeChainDatabase(ctx, stack)
357+
358+
db := utils.MakeChainDatabase(ctx, stack, false)
319359
defer db.Close()
360+
320361
var (
321362
key []byte
322363
value []byte
@@ -335,7 +376,7 @@ func dbPut(ctx *cli.Context) error {
335376
}
336377
data, err = db.Get(key)
337378
if err == nil {
338-
fmt.Printf("Previous value:\n%#x\n", data)
379+
fmt.Printf("Previous value: %#x\n", data)
339380
}
340381
return db.Put(key, value)
341382
}

0 commit comments

Comments
 (0)