Skip to content

Commit 0467a6c

Browse files
committed
Merge pull request #1889 from karalabe/fast-sync-rebase
eth/63 fast synchronization algorithm
2 parents dba15d9 + 5b0ee8e commit 0467a6c

Some content is hidden

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

53 files changed

+5022
-1777
lines changed

cmd/geth/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
304304
utils.DataDirFlag,
305305
utils.BlockchainVersionFlag,
306306
utils.OlympicFlag,
307-
utils.EthVersionFlag,
307+
utils.FastSyncFlag,
308308
utils.CacheFlag,
309309
utils.JSpathFlag,
310310
utils.ListenPortFlag,
@@ -360,7 +360,6 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
360360
utils.SetupLogger(ctx)
361361
utils.SetupNetwork(ctx)
362362
utils.SetupVM(ctx)
363-
utils.SetupEth(ctx)
364363
if ctx.GlobalBool(utils.PProfEanbledFlag.Name) {
365364
utils.StartPProf(ctx)
366365
}

cmd/utils/flags.go

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,9 @@ var (
148148
Name: "olympic",
149149
Usage: "Use olympic style protocol",
150150
}
151-
EthVersionFlag = cli.IntFlag{
152-
Name: "eth",
153-
Value: 62,
154-
Usage: "Highest eth protocol to advertise (temporary, dev option)",
151+
FastSyncFlag = cli.BoolFlag{
152+
Name: "fast",
153+
Usage: "Enables fast syncing through state downloads",
155154
}
156155

157156
// miner settings
@@ -425,12 +424,13 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
425424
if err != nil {
426425
glog.V(logger.Error).Infoln("WARNING: No etherbase set and no accounts found as default")
427426
}
428-
427+
// Assemble the entire eth configuration and return
429428
cfg := &eth.Config{
430429
Name: common.MakeName(clientID, version),
431430
DataDir: MustDataDir(ctx),
432431
GenesisNonce: ctx.GlobalInt(GenesisNonceFlag.Name),
433432
GenesisFile: ctx.GlobalString(GenesisFileFlag.Name),
433+
FastSync: ctx.GlobalBool(FastSyncFlag.Name),
434434
BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name),
435435
DatabaseCache: ctx.GlobalInt(CacheFlag.Name),
436436
SkipBcVersionCheck: false,
@@ -499,7 +499,6 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
499499

500500
glog.V(logger.Info).Infoln("dev mode enabled")
501501
}
502-
503502
return cfg
504503
}
505504

@@ -532,18 +531,6 @@ func SetupVM(ctx *cli.Context) {
532531
vm.SetJITCacheSize(ctx.GlobalInt(VMJitCacheFlag.Name))
533532
}
534533

535-
// SetupEth configures the eth packages global settings
536-
func SetupEth(ctx *cli.Context) {
537-
version := ctx.GlobalInt(EthVersionFlag.Name)
538-
for len(eth.ProtocolVersions) > 0 && eth.ProtocolVersions[0] > uint(version) {
539-
eth.ProtocolVersions = eth.ProtocolVersions[1:]
540-
eth.ProtocolLengths = eth.ProtocolLengths[1:]
541-
}
542-
if len(eth.ProtocolVersions) == 0 {
543-
Fatalf("No valid eth protocols remaining")
544-
}
545-
}
546-
547534
// MakeChain creates a chain manager from set command line flags.
548535
func MakeChain(ctx *cli.Context) (chain *core.BlockChain, chainDb ethdb.Database) {
549536
datadir := MustDataDir(ctx)

core/bench_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
163163
// Generate a chain of b.N blocks using the supplied block
164164
// generator function.
165165
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{benchRootAddr, benchRootFunds})
166-
chain := GenerateChain(genesis, db, b.N, gen)
166+
chain, _ := GenerateChain(genesis, db, b.N, gen)
167167

168168
// Time the insertion of the new chain.
169169
// State and blocks are stored in the same DB.

core/block_processor.go

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ func (self *BlockProcessor) ApplyTransaction(gp *GasPool, statedb *state.StateDB
128128
}
129129

130130
logs := statedb.GetLogs(tx.Hash())
131-
receipt.SetLogs(logs)
131+
receipt.Logs = logs
132132
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
133133

134134
glog.V(logger.Debug).Infoln(receipt)
@@ -212,14 +212,16 @@ func (sm *BlockProcessor) Process(block *types.Block) (logs vm.Logs, receipts ty
212212
defer sm.mutex.Unlock()
213213

214214
if sm.bc.HasBlock(block.Hash()) {
215-
return nil, nil, &KnownBlockError{block.Number(), block.Hash()}
215+
if _, err := state.New(block.Root(), sm.chainDb); err == nil {
216+
return nil, nil, &KnownBlockError{block.Number(), block.Hash()}
217+
}
216218
}
217-
218-
if !sm.bc.HasBlock(block.ParentHash()) {
219-
return nil, nil, ParentError(block.ParentHash())
219+
if parent := sm.bc.GetBlock(block.ParentHash()); parent != nil {
220+
if _, err := state.New(parent.Root(), sm.chainDb); err == nil {
221+
return sm.processWithParent(block, parent)
222+
}
220223
}
221-
parent := sm.bc.GetBlock(block.ParentHash())
222-
return sm.processWithParent(block, parent)
224+
return nil, nil, ParentError(block.ParentHash())
223225
}
224226

225227
func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs vm.Logs, receipts types.Receipts, err error) {
@@ -381,18 +383,40 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs vm.Logs, err error)
381383
receipts := GetBlockReceipts(sm.chainDb, block.Hash())
382384
// coalesce logs
383385
for _, receipt := range receipts {
384-
logs = append(logs, receipt.Logs()...)
386+
logs = append(logs, receipt.Logs...)
385387
}
386388
return logs, nil
387389
}
388390

391+
// ValidateHeader verifies the validity of a header, relying on the database and
392+
// POW behind the block processor.
393+
func (sm *BlockProcessor) ValidateHeader(header *types.Header, checkPow, uncle bool) error {
394+
// Short circuit if the header's already known or its parent missing
395+
if sm.bc.HasHeader(header.Hash()) {
396+
return nil
397+
}
398+
if parent := sm.bc.GetHeader(header.ParentHash); parent == nil {
399+
return ParentError(header.ParentHash)
400+
} else {
401+
return ValidateHeader(sm.Pow, header, parent, checkPow, uncle)
402+
}
403+
}
404+
405+
// ValidateHeaderWithParent verifies the validity of a header, relying on the database and
406+
// POW behind the block processor.
407+
func (sm *BlockProcessor) ValidateHeaderWithParent(header, parent *types.Header, checkPow, uncle bool) error {
408+
if sm.bc.HasHeader(header.Hash()) {
409+
return nil
410+
}
411+
return ValidateHeader(sm.Pow, header, parent, checkPow, uncle)
412+
}
413+
389414
// See YP section 4.3.4. "Block Header Validity"
390415
// Validates a header. Returns an error if the header is invalid.
391416
func ValidateHeader(pow pow.PoW, header *types.Header, parent *types.Header, checkPow, uncle bool) error {
392417
if big.NewInt(int64(len(header.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
393418
return fmt.Errorf("Header extra data too long (%d)", len(header.Extra))
394419
}
395-
396420
if uncle {
397421
if header.Time.Cmp(common.MaxBig) == 1 {
398422
return BlockTSTooBigErr
@@ -429,7 +453,7 @@ func ValidateHeader(pow pow.PoW, header *types.Header, parent *types.Header, che
429453
if checkPow {
430454
// Verify the nonce of the header. Return an error if it's not valid
431455
if !pow.Verify(types.NewBlockWithHeader(header)) {
432-
return ValidationError("Header's nonce is invalid (= %x)", header.Nonce)
456+
return &BlockNonceErr{Hash: header.Hash(), Number: header.Number, Nonce: header.Nonce.Uint64()}
433457
}
434458
}
435459
return nil

core/block_processor_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,16 @@ func TestPutReceipt(t *testing.T) {
7070
hash[0] = 2
7171

7272
receipt := new(types.Receipt)
73-
receipt.SetLogs(vm.Logs{&vm.Log{
74-
Address: addr,
75-
Topics: []common.Hash{hash},
76-
Data: []byte("hi"),
77-
Number: 42,
78-
TxHash: hash,
79-
TxIndex: 0,
80-
BlockHash: hash,
81-
Index: 0,
82-
}})
73+
receipt.Logs = vm.Logs{&vm.Log{
74+
Address: addr,
75+
Topics: []common.Hash{hash},
76+
Data: []byte("hi"),
77+
BlockNumber: 42,
78+
TxHash: hash,
79+
TxIndex: 0,
80+
BlockHash: hash,
81+
Index: 0,
82+
}}
8383

8484
PutReceipts(db, types.Receipts{receipt})
8585
receipt = GetReceipt(db, common.Hash{})

0 commit comments

Comments
 (0)