forked from cerc-io/plugeth
core, eth/downloader: expose the bad hashes, check in downloader
This commit is contained in:
parent
27e0d2a973
commit
29b0480cfb
@ -2,7 +2,8 @@ package core
|
|||||||
|
|
||||||
import "github.com/ethereum/go-ethereum/common"
|
import "github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
var badHashes = []common.Hash{
|
// Set of manually tracked bad hashes (usually hard forks)
|
||||||
common.HexToHash("f269c503aed286caaa0d114d6a5320e70abbc2febe37953207e76a2873f2ba79"),
|
var BadHashes = map[common.Hash]bool{
|
||||||
common.HexToHash("38f5bbbffd74804820ffa4bab0cd540e9de229725afb98c1a7e57936f4a714bc"),
|
common.HexToHash("f269c503aed286caaa0d114d6a5320e70abbc2febe37953207e76a2873f2ba79"): true,
|
||||||
|
common.HexToHash("38f5bbbffd74804820ffa4bab0cd540e9de229725afb98c1a7e57936f4a714bc"): true,
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ func NewChainManager(blockDb, stateDb common.Database, pow pow.PoW, mux *event.T
|
|||||||
bc.setLastState()
|
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
|
// 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 {
|
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])
|
glog.V(logger.Error).Infof("Found bad hash. Reorganising chain to state %x\n", block.ParentHash().Bytes()[:4])
|
||||||
block = bc.GetBlock(block.ParentHash())
|
block = bc.GetBlock(block.ParentHash())
|
||||||
|
@ -3,9 +3,7 @@ package core
|
|||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO move this to types?
|
// TODO move this to types?
|
||||||
@ -14,11 +12,7 @@ type Backend interface {
|
|||||||
BlockProcessor() *BlockProcessor
|
BlockProcessor() *BlockProcessor
|
||||||
ChainManager() *ChainManager
|
ChainManager() *ChainManager
|
||||||
TxPool() *TxPool
|
TxPool() *TxPool
|
||||||
PeerCount() int
|
|
||||||
IsListening() bool
|
|
||||||
Peers() []*p2p.Peer
|
|
||||||
BlockDb() common.Database
|
BlockDb() common.Database
|
||||||
StateDb() common.Database
|
StateDb() common.Database
|
||||||
EventMux() *event.TypeMux
|
EventMux() *event.TypeMux
|
||||||
Downloader() *downloader.Downloader
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,10 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"gopkg.in/fatih/set.v0"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
@ -75,6 +78,7 @@ type Downloader struct {
|
|||||||
queue *queue // Scheduler for selecting the hashes to download
|
queue *queue // Scheduler for selecting the hashes to download
|
||||||
peers *peerSet // Set of active peers from which download can proceed
|
peers *peerSet // Set of active peers from which download can proceed
|
||||||
checks map[common.Hash]*crossCheck // Pending cross checks to verify a hash chain
|
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
|
// Callbacks
|
||||||
hasBlock hashCheckFn
|
hasBlock hashCheckFn
|
||||||
@ -100,6 +104,7 @@ type Block struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(mux *event.TypeMux, hasBlock hashCheckFn, getBlock getBlockFn) *Downloader {
|
func New(mux *event.TypeMux, hasBlock hashCheckFn, getBlock getBlockFn) *Downloader {
|
||||||
|
// Create the base downloader
|
||||||
downloader := &Downloader{
|
downloader := &Downloader{
|
||||||
mux: mux,
|
mux: mux,
|
||||||
queue: newQueue(),
|
queue: newQueue(),
|
||||||
@ -110,6 +115,11 @@ func New(mux *event.TypeMux, hasBlock hashCheckFn, getBlock getBlockFn) *Downloa
|
|||||||
hashCh: make(chan hashPack, 1),
|
hashCh: make(chan hashPack, 1),
|
||||||
blockCh: make(chan blockPack, 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
|
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)
|
glog.V(logger.Debug).Infof("Peer (%s) responded with empty hash set\n", active.id)
|
||||||
return errEmptyHashSet
|
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
|
// Determine if we're done fetching hashes (queue up all pending), and continue if not done
|
||||||
done, index := false, 0
|
done, index := false, 0
|
||||||
for index, head = range hashPack.hashes {
|
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
|
// Try to inset the blocks, drop the originating peer if there's an error
|
||||||
index, err := pm.chainman.InsertChain(raw)
|
index, err := pm.chainman.InsertChain(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
glog.V(logger.Debug).Infoln("Downloaded block import failed:", err)
|
||||||
pm.removePeer(blocks[index].OriginPeer)
|
pm.removePeer(blocks[index].OriginPeer)
|
||||||
pm.downloader.Cancel()
|
pm.downloader.Cancel()
|
||||||
return err
|
return err
|
||||||
@ -84,12 +85,10 @@ func (pm *ProtocolManager) processBlocks() error {
|
|||||||
func (pm *ProtocolManager) synchronise(peer *peer) {
|
func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||||
// Short circuit if no peers are available
|
// Short circuit if no peers are available
|
||||||
if peer == nil {
|
if peer == nil {
|
||||||
glog.V(logger.Debug).Infoln("Synchronisation canceled: no peers available")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Make sure the peer's TD is higher than our own. If not drop.
|
// Make sure the peer's TD is higher than our own. If not drop.
|
||||||
if peer.td.Cmp(pm.chainman.Td()) <= 0 {
|
if peer.td.Cmp(pm.chainman.Td()) <= 0 {
|
||||||
glog.V(logger.Debug).Infoln("Synchronisation canceled: peer's total difficulty is too small")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// FIXME if we have the hash in our chain and the TD of the peer is
|
// FIXME if we have the hash in our chain and the TD of the peer is
|
||||||
|
Loading…
Reference in New Issue
Block a user