core, eth/downloader: expose the bad hashes, check in downloader
This commit is contained in:
@ -7,7 +7,10 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"gopkg.in/fatih/set.v0"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
@ -75,6 +78,7 @@ type Downloader struct {
|
||||
queue *queue // Scheduler for selecting the hashes to download
|
||||
peers *peerSet // Set of active peers from which download can proceed
|
||||
checks map[common.Hash]*crossCheck // Pending cross checks to verify a hash chain
|
||||
banned *set.SetNonTS // Set of hashes we've received and banned
|
||||
|
||||
// Callbacks
|
||||
hasBlock hashCheckFn
|
||||
@ -100,6 +104,7 @@ type Block struct {
|
||||
}
|
||||
|
||||
func New(mux *event.TypeMux, hasBlock hashCheckFn, getBlock getBlockFn) *Downloader {
|
||||
// Create the base downloader
|
||||
downloader := &Downloader{
|
||||
mux: mux,
|
||||
queue: newQueue(),
|
||||
@ -110,6 +115,11 @@ func New(mux *event.TypeMux, hasBlock hashCheckFn, getBlock getBlockFn) *Downloa
|
||||
hashCh: make(chan hashPack, 1),
|
||||
blockCh: make(chan blockPack, 1),
|
||||
}
|
||||
// Inject all the known bad hashes
|
||||
downloader.banned = set.NewNonTS()
|
||||
for hash, _ := range core.BadHashes {
|
||||
downloader.banned.Add(hash)
|
||||
}
|
||||
return downloader
|
||||
}
|
||||
|
||||
@ -280,6 +290,12 @@ func (d *Downloader) fetchHashes(p *peer, h common.Hash) error {
|
||||
glog.V(logger.Debug).Infof("Peer (%s) responded with empty hash set\n", active.id)
|
||||
return errEmptyHashSet
|
||||
}
|
||||
for _, hash := range hashPack.hashes {
|
||||
if d.banned.Has(hash) {
|
||||
glog.V(logger.Debug).Infof("Peer (%s) sent a known invalid chain\n", active.id)
|
||||
return ErrInvalidChain
|
||||
}
|
||||
}
|
||||
// Determine if we're done fetching hashes (queue up all pending), and continue if not done
|
||||
done, index := false, 0
|
||||
for index, head = range hashPack.hashes {
|
||||
|
@ -70,6 +70,7 @@ func (pm *ProtocolManager) processBlocks() error {
|
||||
// Try to inset the blocks, drop the originating peer if there's an error
|
||||
index, err := pm.chainman.InsertChain(raw)
|
||||
if err != nil {
|
||||
glog.V(logger.Debug).Infoln("Downloaded block import failed:", err)
|
||||
pm.removePeer(blocks[index].OriginPeer)
|
||||
pm.downloader.Cancel()
|
||||
return err
|
||||
@ -84,12 +85,10 @@ func (pm *ProtocolManager) processBlocks() error {
|
||||
func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||
// Short circuit if no peers are available
|
||||
if peer == nil {
|
||||
glog.V(logger.Debug).Infoln("Synchronisation canceled: no peers available")
|
||||
return
|
||||
}
|
||||
// Make sure the peer's TD is higher than our own. If not drop.
|
||||
if peer.td.Cmp(pm.chainman.Td()) <= 0 {
|
||||
glog.V(logger.Debug).Infoln("Synchronisation canceled: peer's total difficulty is too small")
|
||||
return
|
||||
}
|
||||
// FIXME if we have the hash in our chain and the TD of the peer is
|
||||
|
Reference in New Issue
Block a user