@@ -19,7 +19,6 @@ package main
19
19
import (
20
20
"encoding/json"
21
21
"fmt"
22
- "math/big"
23
22
"os"
24
23
"runtime"
25
24
"strconv"
@@ -97,13 +96,15 @@ if already existing.`,
97
96
copydbCommand = cli.Command {
98
97
Action : utils .MigrateFlags (copyDb ),
99
98
Name : "copydb" ,
100
- Usage : "Copy from one chain DB into another using the downloader " ,
101
- ArgsUsage : "<filename >" ,
99
+ Usage : "Create a local chain from a target chaindata folder " ,
100
+ ArgsUsage : "<sourceChaindataDir >" ,
102
101
Flags : []cli.Flag {
103
102
utils .DataDirFlag ,
104
103
utils .CacheFlag ,
105
104
utils .SyncModeFlag ,
106
105
utils .FakePoWFlag ,
106
+ utils .TestnetFlag ,
107
+ utils .RinkebyFlag ,
107
108
},
108
109
Category : "BLOCKCHAIN COMMANDS" ,
109
110
Description : `
@@ -286,172 +287,44 @@ func exportChain(ctx *cli.Context) error {
286
287
return nil
287
288
}
288
289
289
- type localPeer struct {
290
- chainDb ethdb.Database
291
- hc * core.HeaderChain
292
- dl * downloader.Downloader
293
- }
294
-
295
- func (lp * localPeer ) Head () (common.Hash , * big.Int ) {
296
- header := lp .hc .CurrentHeader ()
297
- return header .Hash (), header .Number
298
- }
299
-
300
- func (lp * localPeer ) RequestHeadersByHash (hash common.Hash , amount int , skip int , reverse bool ) error {
301
- var (
302
- headers []* types.Header
303
- unknown bool
304
- )
305
-
306
- for ! unknown && len (headers ) < amount {
307
- origin := lp .hc .GetHeaderByHash (hash )
308
- if origin == nil {
309
- break
310
- }
311
-
312
- number := origin .Number .Uint64 ()
313
- headers = append (headers , origin )
314
- if reverse {
315
- for i := 0 ; i < int (skip )+ 1 ; i ++ {
316
- if header := lp .hc .GetHeader (hash , number ); header != nil {
317
- hash = header .ParentHash
318
- number --
319
- } else {
320
- unknown = true
321
- break
322
- }
323
- }
324
- } else {
325
- var (
326
- current = origin .Number .Uint64 ()
327
- next = current + uint64 (skip ) + 1
328
- )
329
- if header := lp .hc .GetHeaderByNumber (next ); header != nil {
330
- if lp .hc .GetBlockHashesFromHash (header .Hash (), uint64 (skip + 1 ))[skip ] == hash {
331
- hash = header .Hash ()
332
- } else {
333
- unknown = true
334
- }
335
- } else {
336
- unknown = true
337
- }
338
- }
339
- }
340
-
341
- lp .dl .DeliverHeaders ("local" , headers )
342
- return nil
343
- }
344
-
345
- func (lp * localPeer ) RequestHeadersByNumber (num uint64 , amount int , skip int , reverse bool ) error {
346
- var (
347
- headers []* types.Header
348
- unknown bool
349
- )
350
-
351
- for ! unknown && len (headers ) < amount {
352
- origin := lp .hc .GetHeaderByNumber (num )
353
- if origin == nil {
354
- break
355
- }
356
-
357
- if reverse {
358
- if num >= uint64 (skip + 1 ) {
359
- num -= uint64 (skip + 1 )
360
- } else {
361
- unknown = true
362
- }
363
- } else {
364
- num += uint64 (skip + 1 )
365
- }
366
- headers = append (headers , origin )
367
- }
368
-
369
- lp .dl .DeliverHeaders ("local" , headers )
370
- return nil
371
- }
372
-
373
- func (lp * localPeer ) RequestBodies (hashes []common.Hash ) error {
374
- var (
375
- transactions [][]* types.Transaction
376
- uncles [][]* types.Header
377
- )
378
-
379
- for _ , hash := range hashes {
380
- block := core .GetBlock (lp .chainDb , hash , lp .hc .GetBlockNumber (hash ))
381
- transactions = append (transactions , block .Transactions ())
382
- uncles = append (uncles , block .Uncles ())
383
- }
384
-
385
- lp .dl .DeliverBodies ("local" , transactions , uncles )
386
- return nil
387
- }
388
-
389
- func (lp * localPeer ) RequestReceipts (hashes []common.Hash ) error {
390
- var receipts [][]* types.Receipt
391
-
392
- for _ , hash := range hashes {
393
- receipts = append (receipts , core .GetBlockReceipts (lp .chainDb , hash , lp .hc .GetBlockNumber (hash )))
394
- }
395
-
396
- lp .dl .DeliverReceipts ("local" , receipts )
397
- return nil
398
- }
399
-
400
- func (lp * localPeer ) RequestNodeData (hashes []common.Hash ) error {
401
- var data [][]byte
402
-
403
- for _ , hash := range hashes {
404
- if entry , err := lp .chainDb .Get (hash .Bytes ()); err == nil {
405
- data = append (data , entry )
406
- }
407
- }
408
-
409
- lp .dl .DeliverNodeData ("local" , data )
410
- return nil
411
- }
412
-
413
290
func copyDb (ctx * cli.Context ) error {
291
+ // Ensure we have a source chain directory to copy
414
292
if len (ctx .Args ()) != 1 {
415
- utils .Fatalf ("This command requires an argument. " )
293
+ utils .Fatalf ("Source chaindata directory path argument missing " )
416
294
}
417
-
295
+ // Initialize a new chain for the running node to sync into
418
296
stack := makeFullNode (ctx )
419
297
chain , chainDb := utils .MakeChain (ctx , stack )
420
- start := time .Now ()
421
298
422
299
syncmode := * utils .GlobalTextMarshaler (ctx , utils .SyncModeFlag .Name ).(* downloader.SyncMode )
423
- mux := new (event.TypeMux )
424
- dl := downloader .New (syncmode , chainDb , mux , chain , nil , nil )
300
+ dl := downloader .New (syncmode , chainDb , new (event.TypeMux ), chain , nil , nil )
425
301
426
- var err error
427
- filename := ctx .Args ().First ()
428
- cache := ctx .GlobalInt (utils .CacheFlag .Name )
429
- handles := 256
430
- localdb , err := ethdb .NewLDBDatabase (filename , cache , handles )
302
+ // Create a source peer to satisfy downloader requests from
303
+ db , err := ethdb .NewLDBDatabase (ctx .Args ().First (), ctx .GlobalInt (utils .CacheFlag .Name ), 256 )
431
304
if err != nil {
432
305
return err
433
306
}
434
-
435
- hc , err := core .NewHeaderChain (localdb , chain .Config (), chain .Engine (), func () bool { return false })
307
+ hc , err := core .NewHeaderChain (db , chain .Config (), chain .Engine (), func () bool { return false })
436
308
if err != nil {
437
309
return err
438
310
}
439
-
440
- peer := & localPeer {localdb , hc , dl }
441
- if err := dl .RegisterPeer ("local" , 63 , peer ); err != nil {
311
+ peer := downloader .NewFakePeer ("local" , db , hc , dl )
312
+ if err = dl .RegisterPeer ("local" , 63 , peer ); err != nil {
442
313
return err
443
314
}
315
+ // Synchronise with the simulated peer
316
+ start := time .Now ()
444
317
445
318
currentHeader := hc .CurrentHeader ()
446
- if err : = dl .Synchronise ("local" , currentHeader .Hash (), hc .GetTd (currentHeader .Hash (), currentHeader .Number .Uint64 ()), syncmode ); err != nil {
319
+ if err = dl .Synchronise ("local" , currentHeader .Hash (), hc .GetTd (currentHeader .Hash (), currentHeader .Number .Uint64 ()), syncmode ); err != nil {
447
320
return err
448
321
}
449
322
for dl .Synchronising () {
450
323
time .Sleep (10 * time .Millisecond )
451
324
}
325
+ fmt .Printf ("Database copy done in %v\n " , time .Since (start ))
452
326
453
- fmt .Printf ("Database copy done in %v" , time .Since (start ))
454
-
327
+ // Compact the entire database to remove any sync overhead
455
328
start = time .Now ()
456
329
fmt .Println ("Compacting entire database..." )
457
330
if err = chainDb .(* ethdb.LDBDatabase ).LDB ().CompactRange (util.Range {}); err != nil {
0 commit comments