|
|
|
@ -115,7 +115,7 @@ type Downloader struct { |
|
|
|
|
syncStatsLock sync.RWMutex // Lock protecting the sync stats fields
|
|
|
|
|
|
|
|
|
|
lightchain LightChain |
|
|
|
|
chain BlockChain |
|
|
|
|
blockchain BlockChain |
|
|
|
|
|
|
|
|
|
// Callbacks
|
|
|
|
|
dropPeer peerDropFn // Drops a peer for misbehaving
|
|
|
|
@ -212,7 +212,7 @@ func New(mode SyncMode, stateDb ethdb.Database, mux *event.TypeMux, chain BlockC |
|
|
|
|
peers: newPeerSet(), |
|
|
|
|
rttEstimate: uint64(rttMaxEstimate), |
|
|
|
|
rttConfidence: uint64(1000000), |
|
|
|
|
chain: chain, |
|
|
|
|
blockchain: chain, |
|
|
|
|
lightchain: lightchain, |
|
|
|
|
dropPeer: dropPeer, |
|
|
|
|
headerCh: make(chan dataPack, 1), |
|
|
|
@ -246,9 +246,9 @@ func (d *Downloader) Progress() ethereum.SyncProgress { |
|
|
|
|
current := uint64(0) |
|
|
|
|
switch d.mode { |
|
|
|
|
case FullSync: |
|
|
|
|
current = d.chain.CurrentBlock().NumberU64() |
|
|
|
|
current = d.blockchain.CurrentBlock().NumberU64() |
|
|
|
|
case FastSync: |
|
|
|
|
current = d.chain.CurrentFastBlock().NumberU64() |
|
|
|
|
current = d.blockchain.CurrentFastBlock().NumberU64() |
|
|
|
|
case LightSync: |
|
|
|
|
current = d.lightchain.CurrentHeader().Number.Uint64() |
|
|
|
|
} |
|
|
|
@ -281,6 +281,11 @@ func (d *Downloader) RegisterPeer(id string, version int, peer Peer) error { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// RegisterLightPeer injects a light client peer
|
|
|
|
|
func (d *Downloader) RegisterLightPeer(id string, version int, peer LightPeer) error { |
|
|
|
|
return d.RegisterPeer(id, version, &lightPeerWrapper{peer}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// UnregisterPeer remove a peer from the known list, preventing any action from
|
|
|
|
|
// the specified peer. An effort is also made to return any pending fetches into
|
|
|
|
|
// the queue.
|
|
|
|
@ -597,9 +602,9 @@ func (d *Downloader) findAncestor(p *peerConnection, height uint64) (uint64, err |
|
|
|
|
|
|
|
|
|
p.log.Debug("Looking for common ancestor", "local", ceil, "remote", height) |
|
|
|
|
if d.mode == FullSync { |
|
|
|
|
ceil = d.chain.CurrentBlock().NumberU64() |
|
|
|
|
ceil = d.blockchain.CurrentBlock().NumberU64() |
|
|
|
|
} else if d.mode == FastSync { |
|
|
|
|
ceil = d.chain.CurrentFastBlock().NumberU64() |
|
|
|
|
ceil = d.blockchain.CurrentFastBlock().NumberU64() |
|
|
|
|
} |
|
|
|
|
if ceil >= MaxForkAncestry { |
|
|
|
|
floor = int64(ceil - MaxForkAncestry) |
|
|
|
@ -659,7 +664,7 @@ func (d *Downloader) findAncestor(p *peerConnection, height uint64) (uint64, err |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
// Otherwise check if we already know the header or not
|
|
|
|
|
if (d.mode == FullSync && d.chain.HasBlockAndState(headers[i].Hash())) || (d.mode != FullSync && d.lightchain.HasHeader(headers[i].Hash())) { |
|
|
|
|
if (d.mode == FullSync && d.blockchain.HasBlockAndState(headers[i].Hash())) || (d.mode != FullSync && d.lightchain.HasHeader(headers[i].Hash())) { |
|
|
|
|
number, hash = headers[i].Number.Uint64(), headers[i].Hash() |
|
|
|
|
|
|
|
|
|
// If every header is known, even future ones, the peer straight out lied about its head
|
|
|
|
@ -724,7 +729,7 @@ func (d *Downloader) findAncestor(p *peerConnection, height uint64) (uint64, err |
|
|
|
|
arrived = true |
|
|
|
|
|
|
|
|
|
// Modify the search interval based on the response
|
|
|
|
|
if (d.mode == FullSync && !d.chain.HasBlockAndState(headers[0].Hash())) || (d.mode != FullSync && !d.lightchain.HasHeader(headers[0].Hash())) { |
|
|
|
|
if (d.mode == FullSync && !d.blockchain.HasBlockAndState(headers[0].Hash())) || (d.mode != FullSync && !d.lightchain.HasHeader(headers[0].Hash())) { |
|
|
|
|
end = check |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
@ -1147,14 +1152,14 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error { |
|
|
|
|
} |
|
|
|
|
lastHeader, lastFastBlock, lastBlock := d.lightchain.CurrentHeader().Number, common.Big0, common.Big0 |
|
|
|
|
if d.mode != LightSync { |
|
|
|
|
lastFastBlock = d.chain.CurrentFastBlock().Number() |
|
|
|
|
lastBlock = d.chain.CurrentBlock().Number() |
|
|
|
|
lastFastBlock = d.blockchain.CurrentFastBlock().Number() |
|
|
|
|
lastBlock = d.blockchain.CurrentBlock().Number() |
|
|
|
|
} |
|
|
|
|
d.lightchain.Rollback(hashes) |
|
|
|
|
curFastBlock, curBlock := common.Big0, common.Big0 |
|
|
|
|
if d.mode != LightSync { |
|
|
|
|
curFastBlock = d.chain.CurrentFastBlock().Number() |
|
|
|
|
curBlock = d.chain.CurrentBlock().Number() |
|
|
|
|
curFastBlock = d.blockchain.CurrentFastBlock().Number() |
|
|
|
|
curBlock = d.blockchain.CurrentBlock().Number() |
|
|
|
|
} |
|
|
|
|
log.Warn("Rolled back headers", "count", len(hashes), |
|
|
|
|
"header", fmt.Sprintf("%d->%d", lastHeader, d.lightchain.CurrentHeader().Number), |
|
|
|
@ -1207,7 +1212,7 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error { |
|
|
|
|
// L: Request new headers up from 11 (R's TD was higher, it must have something)
|
|
|
|
|
// R: Nothing to give
|
|
|
|
|
if d.mode != LightSync { |
|
|
|
|
if !gotHeaders && td.Cmp(d.chain.GetTdByHash(d.chain.CurrentBlock().Hash())) > 0 { |
|
|
|
|
if !gotHeaders && td.Cmp(d.blockchain.GetTdByHash(d.blockchain.CurrentBlock().Hash())) > 0 { |
|
|
|
|
return errStallingPeer |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -1345,7 +1350,7 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error { |
|
|
|
|
for i, result := range results[:items] { |
|
|
|
|
blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles) |
|
|
|
|
} |
|
|
|
|
if index, err := d.chain.InsertChain(blocks); err != nil { |
|
|
|
|
if index, err := d.blockchain.InsertChain(blocks); err != nil { |
|
|
|
|
log.Debug("Downloaded item processing failed", "number", results[index].Header.Number, "hash", results[index].Header.Hash(), "err", err) |
|
|
|
|
return errInvalidChain |
|
|
|
|
} |
|
|
|
@ -1434,7 +1439,7 @@ func (d *Downloader) commitFastSyncData(results []*fetchResult, stateSync *state |
|
|
|
|
blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles) |
|
|
|
|
receipts[i] = result.Receipts |
|
|
|
|
} |
|
|
|
|
if index, err := d.chain.InsertReceiptChain(blocks, receipts); err != nil { |
|
|
|
|
if index, err := d.blockchain.InsertReceiptChain(blocks, receipts); err != nil { |
|
|
|
|
log.Debug("Downloaded item processing failed", "number", results[index].Header.Number, "hash", results[index].Header.Hash(), "err", err) |
|
|
|
|
return errInvalidChain |
|
|
|
|
} |
|
|
|
@ -1452,10 +1457,10 @@ func (d *Downloader) commitPivotBlock(result *fetchResult) error { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
log.Debug("Committing fast sync pivot as new head", "number", b.Number(), "hash", b.Hash()) |
|
|
|
|
if _, err := d.chain.InsertReceiptChain([]*types.Block{b}, []types.Receipts{result.Receipts}); err != nil { |
|
|
|
|
if _, err := d.blockchain.InsertReceiptChain([]*types.Block{b}, []types.Receipts{result.Receipts}); err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
return d.chain.FastSyncCommitHead(b.Hash()) |
|
|
|
|
return d.blockchain.FastSyncCommitHead(b.Hash()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// DeliverHeaders injects a new batch of block headers received from a remote
|
|
|
|
|