diff --git a/core/blockchain.go b/core/blockchain.go index c194ebc6bc..84652aa042 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1010,41 +1010,9 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. // // After insertion is done, all accumulated events will be fired. func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { - if bc.chainConfig != nil && bc.chainConfig.Posv != nil { - epoch := bc.chainConfig.Posv.Epoch - gap := bc.chainConfig.Posv.Gap - length := len(chain) - start := int(chain[0].NumberU64() % epoch) - end := int(epoch - gap - uint64(start)) - if (end < 0) { - end = end + int(epoch) - } - start = 0 - for { - if end >= length { - end = length - 1 - } - inserts := make([]*types.Block, end-start+1) - copy(inserts, chain[start:end+1]) - if len(inserts) > 0 { - n, events, logs, err := bc.insertChain(inserts) - bc.PostChainEvents(events, logs) - if err != nil { - return n, err - } - } - start = end + 1 - end = end + int(epoch) - if (start >= length) { - break - } - } - return 0, nil - } else { - n, events, logs, err := bc.insertChain(chain) - bc.PostChainEvents(events, logs) - return n, err - } + n, events, logs, err := bc.insertChain(chain) + bc.PostChainEvents(events, logs) + return n, err } // insertChain will execute the actual chain insertion and event aggregation. The @@ -1224,14 +1192,14 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty stats.processed++ stats.usedGas += usedGas stats.report(chain, i, bc.stateCache.TrieDB().Size()) - if bc.chainConfig.Posv != nil { + if i == len(chain)-1 && bc.chainConfig.Posv != nil { // epoch block if (chain[i].NumberU64() % bc.chainConfig.Posv.Epoch) == 0 { CheckpointCh <- 1 } // prepare set of masternodes for the next epoch if (chain[i].NumberU64() % bc.chainConfig.Posv.Epoch) == (bc.chainConfig.Posv.Epoch - bc.chainConfig.Posv.Gap) { - bc.UpdateM1() + M1Ch <- 1 } } } diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 90bbba65a5..89a274c0de 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -25,7 +25,7 @@ import ( "sync/atomic" "time" - ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" @@ -172,6 +172,8 @@ type LightChain interface { // BlockChain encapsulates functions required to sync a (full or fast) blockchain. type BlockChain interface { + Config() *params.ChainConfig + UpdateM1() LightChain // HasBlock verifies a block's presence in the local chain. @@ -1322,11 +1324,38 @@ func (d *Downloader) processFullSyncContent() error { if len(results) == 0 { return nil } - if d.chainInsertHook != nil { - d.chainInsertHook(results) + epoch := d.blockchain.Config().Posv.Epoch + gap := d.blockchain.Config().Posv.Gap + length := len(results) + start := int(results[0].Header.Number.Uint64() % epoch) + end := int(epoch - gap - uint64(start)) + if (end < 0) { + end = end + int(epoch) } - if err := d.importBlockResults(results); err != nil { - return err + start = 0 + for { + if end >= length { + end = length - 1 + } + inserts := make([]*fetchResult, end-start+1) + copy(inserts, results[start:end+1]) + if len(inserts) > 0 { + if d.chainInsertHook != nil { + d.chainInsertHook(inserts) + } + if err := d.importBlockResults(inserts); err != nil { + return err + } + // prepare set of masternodes for the next epoch + if (inserts[len(inserts)-1].Header.Number.Uint64() % epoch) == (epoch - gap) { + d.blockchain.UpdateM1() + } + } + start = end + 1 + end = end + int(epoch) + if (start >= length) { + break + } } } } @@ -1355,6 +1384,7 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error { log.Debug("Downloaded item processing failed", "number", results[index].Header.Number, "hash", results[index].Header.Hash(), "err", err) return errInvalidChain } + return nil } diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 56ce1aebd6..35dcdbc782 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -456,6 +456,10 @@ func (dl *downloadTester) dropPeer(id string) { dl.downloader.UnregisterPeer(id) } +// Config retrieves the blockchain's chain configuration. +func (dl *downloadTester) Config() *params.ChainConfig { return dl.downloader.blockchain.Config() } +func (dl *downloadTester) UpdateM1() { dl.downloader.blockchain.UpdateM1() } + type downloadTesterPeer struct { dl *downloadTester id string