Skip to content

Commit

Permalink
core, eth/downloader: expose the bad hashes, check in downloader
Browse files Browse the repository at this point in the history
  • Loading branch information
karalabe committed May 28, 2015
1 parent 27e0d2a commit 29b0480
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 12 deletions.
7 changes: 4 additions & 3 deletions core/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package core

import "github.com/ethereum/go-ethereum/common"

var badHashes = []common.Hash{
common.HexToHash("f269c503aed286caaa0d114d6a5320e70abbc2febe37953207e76a2873f2ba79"),
common.HexToHash("38f5bbbffd74804820ffa4bab0cd540e9de229725afb98c1a7e57936f4a714bc"),
// Set of manually tracked bad hashes (usually hard forks)
var BadHashes = map[common.Hash]bool{
common.HexToHash("f269c503aed286caaa0d114d6a5320e70abbc2febe37953207e76a2873f2ba79"): true,
common.HexToHash("38f5bbbffd74804820ffa4bab0cd540e9de229725afb98c1a7e57936f4a714bc"): true,
}
2 changes: 1 addition & 1 deletion core/chain_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func NewChainManager(blockDb, stateDb common.Database, pow pow.PoW, mux *event.T
bc.setLastState()

// Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
for _, hash := range badHashes {
for hash, _ := range BadHashes {
if block := bc.GetBlock(hash); block != nil {
glog.V(logger.Error).Infof("Found bad hash. Reorganising chain to state %x\n", block.ParentHash().Bytes()[:4])
block = bc.GetBlock(block.ParentHash())
Expand Down
6 changes: 0 additions & 6 deletions core/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ package core
import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/p2p"
)

// TODO move this to types?
Expand All @@ -14,11 +12,7 @@ type Backend interface {
BlockProcessor() *BlockProcessor
ChainManager() *ChainManager
TxPool() *TxPool
PeerCount() int
IsListening() bool
Peers() []*p2p.Peer
BlockDb() common.Database
StateDb() common.Database
EventMux() *event.TypeMux
Downloader() *downloader.Downloader
}
16 changes: 16 additions & 0 deletions eth/downloader/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -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(),
Expand All @@ -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
}

Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 1 addition & 2 deletions eth/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 29b0480

Please sign in to comment.