|
@@ -112,20 +112,20 @@ type Downloader struct {
|
|
|
syncStatsLock sync.RWMutex // Lock protecting the sync stats fields
|
|
syncStatsLock sync.RWMutex // Lock protecting the sync stats fields
|
|
|
|
|
|
|
|
// Callbacks
|
|
// Callbacks
|
|
|
- hasHeader headerCheckFn // Checks if a header is present in the chain
|
|
|
|
|
- hasBlock blockCheckFn // Checks if a block is present in the chain
|
|
|
|
|
- getHeader headerRetrievalFn // Retrieves a header from the chain
|
|
|
|
|
- getBlock blockRetrievalFn // Retrieves a block from the chain
|
|
|
|
|
- headHeader headHeaderRetrievalFn // Retrieves the head header from the chain
|
|
|
|
|
- headBlock headBlockRetrievalFn // Retrieves the head block from the chain
|
|
|
|
|
- headFastBlock headFastBlockRetrievalFn // Retrieves the head fast-sync block from the chain
|
|
|
|
|
- commitHeadBlock headBlockCommitterFn // Commits a manually assembled block as the chain head
|
|
|
|
|
- getTd tdRetrievalFn // Retrieves the TD of a block from the chain
|
|
|
|
|
- insertHeaders headerChainInsertFn // Injects a batch of headers into the chain
|
|
|
|
|
- insertBlocks blockChainInsertFn // Injects a batch of blocks into the chain
|
|
|
|
|
- insertReceipts receiptChainInsertFn // Injects a batch of blocks and their receipts into the chain
|
|
|
|
|
- rollback chainRollbackFn // Removes a batch of recently added chain links
|
|
|
|
|
- dropPeer peerDropFn // Drops a peer for misbehaving
|
|
|
|
|
|
|
+ hasHeader headerCheckFn // Checks if a header is present in the chain
|
|
|
|
|
+ hasBlockAndState blockAndStateCheckFn // Checks if a block and associated state is present in the chain
|
|
|
|
|
+ getHeader headerRetrievalFn // Retrieves a header from the chain
|
|
|
|
|
+ getBlock blockRetrievalFn // Retrieves a block from the chain
|
|
|
|
|
+ headHeader headHeaderRetrievalFn // Retrieves the head header from the chain
|
|
|
|
|
+ headBlock headBlockRetrievalFn // Retrieves the head block from the chain
|
|
|
|
|
+ headFastBlock headFastBlockRetrievalFn // Retrieves the head fast-sync block from the chain
|
|
|
|
|
+ commitHeadBlock headBlockCommitterFn // Commits a manually assembled block as the chain head
|
|
|
|
|
+ getTd tdRetrievalFn // Retrieves the TD of a block from the chain
|
|
|
|
|
+ insertHeaders headerChainInsertFn // Injects a batch of headers into the chain
|
|
|
|
|
+ insertBlocks blockChainInsertFn // Injects a batch of blocks into the chain
|
|
|
|
|
+ insertReceipts receiptChainInsertFn // Injects a batch of blocks and their receipts into the chain
|
|
|
|
|
+ rollback chainRollbackFn // Removes a batch of recently added chain links
|
|
|
|
|
+ dropPeer peerDropFn // Drops a peer for misbehaving
|
|
|
|
|
|
|
|
// Status
|
|
// Status
|
|
|
synchroniseMock func(id string, hash common.Hash) error // Replacement for synchronise during testing
|
|
synchroniseMock func(id string, hash common.Hash) error // Replacement for synchronise during testing
|
|
@@ -156,41 +156,41 @@ type Downloader struct {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// New creates a new downloader to fetch hashes and blocks from remote peers.
|
|
// New creates a new downloader to fetch hashes and blocks from remote peers.
|
|
|
-func New(stateDb ethdb.Database, mux *event.TypeMux, hasHeader headerCheckFn, hasBlock blockCheckFn, getHeader headerRetrievalFn,
|
|
|
|
|
- getBlock blockRetrievalFn, headHeader headHeaderRetrievalFn, headBlock headBlockRetrievalFn, headFastBlock headFastBlockRetrievalFn,
|
|
|
|
|
- commitHeadBlock headBlockCommitterFn, getTd tdRetrievalFn, insertHeaders headerChainInsertFn, insertBlocks blockChainInsertFn,
|
|
|
|
|
- insertReceipts receiptChainInsertFn, rollback chainRollbackFn, dropPeer peerDropFn) *Downloader {
|
|
|
|
|
|
|
+func New(stateDb ethdb.Database, mux *event.TypeMux, hasHeader headerCheckFn, hasBlockAndState blockAndStateCheckFn,
|
|
|
|
|
+ getHeader headerRetrievalFn, getBlock blockRetrievalFn, headHeader headHeaderRetrievalFn, headBlock headBlockRetrievalFn,
|
|
|
|
|
+ headFastBlock headFastBlockRetrievalFn, commitHeadBlock headBlockCommitterFn, getTd tdRetrievalFn, insertHeaders headerChainInsertFn,
|
|
|
|
|
+ insertBlocks blockChainInsertFn, insertReceipts receiptChainInsertFn, rollback chainRollbackFn, dropPeer peerDropFn) *Downloader {
|
|
|
|
|
|
|
|
return &Downloader{
|
|
return &Downloader{
|
|
|
- mode: FullSync,
|
|
|
|
|
- mux: mux,
|
|
|
|
|
- queue: newQueue(stateDb),
|
|
|
|
|
- peers: newPeerSet(),
|
|
|
|
|
- hasHeader: hasHeader,
|
|
|
|
|
- hasBlock: hasBlock,
|
|
|
|
|
- getHeader: getHeader,
|
|
|
|
|
- getBlock: getBlock,
|
|
|
|
|
- headHeader: headHeader,
|
|
|
|
|
- headBlock: headBlock,
|
|
|
|
|
- headFastBlock: headFastBlock,
|
|
|
|
|
- commitHeadBlock: commitHeadBlock,
|
|
|
|
|
- getTd: getTd,
|
|
|
|
|
- insertHeaders: insertHeaders,
|
|
|
|
|
- insertBlocks: insertBlocks,
|
|
|
|
|
- insertReceipts: insertReceipts,
|
|
|
|
|
- rollback: rollback,
|
|
|
|
|
- dropPeer: dropPeer,
|
|
|
|
|
- newPeerCh: make(chan *peer, 1),
|
|
|
|
|
- hashCh: make(chan dataPack, 1),
|
|
|
|
|
- blockCh: make(chan dataPack, 1),
|
|
|
|
|
- headerCh: make(chan dataPack, 1),
|
|
|
|
|
- bodyCh: make(chan dataPack, 1),
|
|
|
|
|
- receiptCh: make(chan dataPack, 1),
|
|
|
|
|
- stateCh: make(chan dataPack, 1),
|
|
|
|
|
- blockWakeCh: make(chan bool, 1),
|
|
|
|
|
- bodyWakeCh: make(chan bool, 1),
|
|
|
|
|
- receiptWakeCh: make(chan bool, 1),
|
|
|
|
|
- stateWakeCh: make(chan bool, 1),
|
|
|
|
|
|
|
+ mode: FullSync,
|
|
|
|
|
+ mux: mux,
|
|
|
|
|
+ queue: newQueue(stateDb),
|
|
|
|
|
+ peers: newPeerSet(),
|
|
|
|
|
+ hasHeader: hasHeader,
|
|
|
|
|
+ hasBlockAndState: hasBlockAndState,
|
|
|
|
|
+ getHeader: getHeader,
|
|
|
|
|
+ getBlock: getBlock,
|
|
|
|
|
+ headHeader: headHeader,
|
|
|
|
|
+ headBlock: headBlock,
|
|
|
|
|
+ headFastBlock: headFastBlock,
|
|
|
|
|
+ commitHeadBlock: commitHeadBlock,
|
|
|
|
|
+ getTd: getTd,
|
|
|
|
|
+ insertHeaders: insertHeaders,
|
|
|
|
|
+ insertBlocks: insertBlocks,
|
|
|
|
|
+ insertReceipts: insertReceipts,
|
|
|
|
|
+ rollback: rollback,
|
|
|
|
|
+ dropPeer: dropPeer,
|
|
|
|
|
+ newPeerCh: make(chan *peer, 1),
|
|
|
|
|
+ hashCh: make(chan dataPack, 1),
|
|
|
|
|
+ blockCh: make(chan dataPack, 1),
|
|
|
|
|
+ headerCh: make(chan dataPack, 1),
|
|
|
|
|
+ bodyCh: make(chan dataPack, 1),
|
|
|
|
|
+ receiptCh: make(chan dataPack, 1),
|
|
|
|
|
+ stateCh: make(chan dataPack, 1),
|
|
|
|
|
+ blockWakeCh: make(chan bool, 1),
|
|
|
|
|
+ bodyWakeCh: make(chan bool, 1),
|
|
|
|
|
+ receiptWakeCh: make(chan bool, 1),
|
|
|
|
|
+ stateWakeCh: make(chan bool, 1),
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -564,7 +564,7 @@ func (d *Downloader) findAncestor61(p *peer) (uint64, error) {
|
|
|
// Check if a common ancestor was found
|
|
// Check if a common ancestor was found
|
|
|
finished = true
|
|
finished = true
|
|
|
for i := len(hashes) - 1; i >= 0; i-- {
|
|
for i := len(hashes) - 1; i >= 0; i-- {
|
|
|
- if d.hasBlock(hashes[i]) {
|
|
|
|
|
|
|
+ if d.hasBlockAndState(hashes[i]) {
|
|
|
number, hash = uint64(from)+uint64(i), hashes[i]
|
|
number, hash = uint64(from)+uint64(i), hashes[i]
|
|
|
break
|
|
break
|
|
|
}
|
|
}
|
|
@@ -620,11 +620,11 @@ func (d *Downloader) findAncestor61(p *peer) (uint64, error) {
|
|
|
arrived = true
|
|
arrived = true
|
|
|
|
|
|
|
|
// Modify the search interval based on the response
|
|
// Modify the search interval based on the response
|
|
|
- block := d.getBlock(hashes[0])
|
|
|
|
|
- if block == nil {
|
|
|
|
|
|
|
+ if !d.hasBlockAndState(hashes[0]) {
|
|
|
end = check
|
|
end = check
|
|
|
break
|
|
break
|
|
|
}
|
|
}
|
|
|
|
|
+ block := d.getBlock(hashes[0]) // this doesn't check state, hence the above explicit check
|
|
|
if block.NumberU64() != check {
|
|
if block.NumberU64() != check {
|
|
|
glog.V(logger.Debug).Infof("%v: non requested hash #%d [%x…], instead of #%d", p, block.NumberU64(), block.Hash().Bytes()[:4], check)
|
|
glog.V(logger.Debug).Infof("%v: non requested hash #%d [%x…], instead of #%d", p, block.NumberU64(), block.Hash().Bytes()[:4], check)
|
|
|
return 0, errBadPeer
|
|
return 0, errBadPeer
|
|
@@ -989,7 +989,7 @@ func (d *Downloader) findAncestor(p *peer) (uint64, error) {
|
|
|
// Check if a common ancestor was found
|
|
// Check if a common ancestor was found
|
|
|
finished = true
|
|
finished = true
|
|
|
for i := len(headers) - 1; i >= 0; i-- {
|
|
for i := len(headers) - 1; i >= 0; i-- {
|
|
|
- if (d.mode != LightSync && d.hasBlock(headers[i].Hash())) || (d.mode == LightSync && d.hasHeader(headers[i].Hash())) {
|
|
|
|
|
|
|
+ if (d.mode != LightSync && d.hasBlockAndState(headers[i].Hash())) || (d.mode == LightSync && d.hasHeader(headers[i].Hash())) {
|
|
|
number, hash = headers[i].Number.Uint64(), headers[i].Hash()
|
|
number, hash = headers[i].Number.Uint64(), headers[i].Hash()
|
|
|
break
|
|
break
|
|
|
}
|
|
}
|
|
@@ -1045,7 +1045,7 @@ func (d *Downloader) findAncestor(p *peer) (uint64, error) {
|
|
|
arrived = true
|
|
arrived = true
|
|
|
|
|
|
|
|
// Modify the search interval based on the response
|
|
// Modify the search interval based on the response
|
|
|
- if (d.mode == FullSync && !d.hasBlock(headers[0].Hash())) || (d.mode != FullSync && !d.hasHeader(headers[0].Hash())) {
|
|
|
|
|
|
|
+ if (d.mode == FullSync && !d.hasBlockAndState(headers[0].Hash())) || (d.mode != FullSync && !d.hasHeader(headers[0].Hash())) {
|
|
|
end = check
|
|
end = check
|
|
|
break
|
|
break
|
|
|
}
|
|
}
|