diff options
author | obscuren <geffobscura@gmail.com> | 2014-10-02 23:03:48 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2014-10-02 23:03:48 +0800 |
commit | a75c92000fab997a41479c8f92e62f6b0d3f3434 (patch) | |
tree | 608ee0538946d1fa780d1fbfb8701ce544b09e3d /block_pool.go | |
parent | b55e017e620d8049788eda91424d4944ac934613 (diff) | |
download | dexon-a75c92000fab997a41479c8f92e62f6b0d3f3434.tar.gz dexon-a75c92000fab997a41479c8f92e62f6b0d3f3434.tar.zst dexon-a75c92000fab997a41479c8f92e62f6b0d3f3434.zip |
Black listing of bad peers
Diffstat (limited to 'block_pool.go')
-rw-r--r-- | block_pool.go | 82 |
1 files changed, 76 insertions, 6 deletions
diff --git a/block_pool.go b/block_pool.go index f5c53b9f7..e31babfd6 100644 --- a/block_pool.go +++ b/block_pool.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethwire" ) var poollogger = ethlog.NewLogger("BPOOL") @@ -38,6 +39,8 @@ type BlockPool struct { downloadStartedAt time.Time ChainLength, BlocksProcessed int + + peer *Peer } func NewBlockPool(eth *Ethereum) *BlockPool { @@ -74,6 +77,27 @@ func (self *BlockPool) Blocks() (blocks ethchain.Blocks) { return } +func (self *BlockPool) FetchHashes(peer *Peer) { + highestTd := self.eth.HighestTDPeer() + + if (self.peer == nil && peer.td.Cmp(highestTd) >= 0) || (self.peer != nil && peer.td.Cmp(self.peer.td) >= 0) || self.peer == peer { + if self.peer != peer { + poollogger.Debugf("Found better suitable peer (%v vs %v)\n", self.td, peer.td) + } + + self.peer = peer + self.td = peer.td + + if !self.HasLatestHash() { + peer.doneFetchingHashes = false + + const amount = 256 + peerlogger.Debugf("Fetching hashes (%d)\n", amount) + peer.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{peer.lastReceivedHash, uint32(amount)})) + } + } +} + func (self *BlockPool) AddHash(hash []byte, peer *Peer) { self.mut.Lock() defer self.mut.Unlock() @@ -99,7 +123,7 @@ func (self *BlockPool) Add(b *ethchain.Block, peer *Peer) { if !self.eth.BlockChain().HasBlock(b.PrevHash) && self.pool[string(b.PrevHash)] == nil && !self.fetchingHashes { poollogger.Infof("Unknown block, requesting parent (%x...)\n", b.PrevHash[0:4]) - //peer.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{b.Hash(), uint32(256)})) + peer.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{b.Hash(), uint32(256)})) } } else if self.pool[hash] != nil { self.pool[hash].block = b @@ -227,7 +251,7 @@ out: } func (self *BlockPool) chainThread() { - procTimer := time.NewTicker(500 * time.Millisecond) + procTimer := time.NewTicker(1000 * time.Millisecond) out: for { select { @@ -237,6 +261,14 @@ out: blocks := self.Blocks() ethchain.BlockBy(ethchain.Number).Sort(blocks) + // Find common block + for i, block := range blocks { + if self.eth.BlockChain().HasBlock(block.PrevHash) { + blocks = blocks[i:] + break + } + } + if len(blocks) > 0 { if self.eth.BlockChain().HasBlock(blocks[0].PrevHash) { for i, block := range blocks[1:] { @@ -253,13 +285,51 @@ out: } } - // Handle in batches of 4k - max := int(math.Min(4000, float64(len(blocks)))) - for _, block := range blocks[:max] { - self.eth.Eventer().Post("block", block) + if len(blocks) > 0 { + self.eth.Eventer().Post("blocks", blocks) + + } + + var err error + for i, block := range blocks { + //self.eth.Eventer().Post("block", block) + err = self.eth.StateManager().Process(block, false) + if err != nil { + poollogger.Infoln(err) + poollogger.Debugf("Block #%v failed (%x...)\n", block.Number, block.Hash()[0:4]) + poollogger.Debugln(block) + + blocks = blocks[i:] + + break + } self.Remove(block.Hash()) } + + if err != nil { + // Remove this bad chain + for _, block := range blocks { + self.Remove(block.Hash()) + } + + poollogger.Debugf("Punishing peer for supplying bad chain (%v)\n", self.peer.conn.RemoteAddr()) + // This peer gave us bad hashes and made us fetch a bad chain, therefor he shall be punished. + self.eth.BlacklistPeer(self.peer) + self.peer.StopWithReason(DiscBadPeer) + self.td = ethutil.Big0 + self.peer = nil + } + + /* + // Handle in batches of 4k + //max := int(math.Min(4000, float64(len(blocks)))) + for _, block := range blocks { + self.eth.Eventer().Post("block", block) + + self.Remove(block.Hash()) + } + */ } } } |