aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-04-30 19:41:47 +0800
committerobscuren <geffobscura@gmail.com>2015-04-30 19:50:59 +0800
commit28b39267d990352883df1c093fd6c36cd532cfdf (patch)
tree251391a951ff57dac98a36f0b9ae0f0502dbdfda
parent9b6e8f6195da1d52ba35295d9d8a3a9f24ec30b0 (diff)
downloaddexon-28b39267d990352883df1c093fd6c36cd532cfdf.tar.gz
dexon-28b39267d990352883df1c093fd6c36cd532cfdf.tar.zst
dexon-28b39267d990352883df1c093fd6c36cd532cfdf.zip
core, eth: verify td of received blocks
-rw-r--r--core/chain_manager.go6
-rw-r--r--eth/handler.go22
2 files changed, 25 insertions, 3 deletions
diff --git a/core/chain_manager.go b/core/chain_manager.go
index 4fdb2edce..e97ed307c 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -511,6 +511,10 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
if block == nil {
continue
}
+ // Setting block.Td regardless of error (known for example) prevents errors down the line
+ // in the protocol handler
+ block.Td = new(big.Int).Set(CalculateTD(block, self.GetBlock(block.ParentHash())))
+
// Call in to the block processor and check for errors. It's likely that if one block fails
// all others will fail too (unless a known block is returned).
logs, err := self.processor.Process(block)
@@ -545,8 +549,6 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
return i, err
}
- block.Td = new(big.Int).Set(CalculateTD(block, self.GetBlock(block.ParentHash())))
-
self.mu.Lock()
{
cblock := self.currentBlock
diff --git a/eth/handler.go b/eth/handler.go
index 6cc69aa26..6c1a92c77 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -125,6 +125,7 @@ func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpo
func (pm *ProtocolManager) removePeer(peer *peer) {
pm.pmu.Lock()
defer pm.pmu.Unlock()
+ pm.downloader.UnregisterPeer(peer.id)
delete(pm.peers, peer.id)
}
@@ -223,7 +224,6 @@ func (pm *ProtocolManager) handle(p *peer) error {
pm.downloader.RegisterPeer(p.id, p.recentHash, p.requestHashes, p.requestBlocks)
defer func() {
- pm.downloader.UnregisterPeer(p.id)
pm.removePeer(p)
}()
@@ -392,6 +392,12 @@ func (self *ProtocolManager) handleMsg(p *peer) error {
return nil
}
+
+ if err := self.verifyTd(p, request); err != nil {
+ glog.V(logger.Error).Infoln(err)
+ // XXX for now return nil so it won't disconnect (we should in the future)
+ return nil
+ }
self.BroadcastBlock(hash, request.Block)
} else {
// adding blocks is synchronous
@@ -406,6 +412,10 @@ func (self *ProtocolManager) handleMsg(p *peer) error {
glog.V(logger.Detail).Infoln("downloader err:", err)
return
}
+ if err := self.verifyTd(p, request); err != nil {
+ glog.V(logger.Error).Infoln(err)
+ return
+ }
self.BroadcastBlock(hash, request.Block)
}()
}
@@ -415,6 +425,16 @@ func (self *ProtocolManager) handleMsg(p *peer) error {
return nil
}
+func (pm *ProtocolManager) verifyTd(peer *peer, request newBlockMsgData) error {
+ if request.Block.Td.Cmp(request.TD) != 0 {
+ glog.V(logger.Detail).Infoln(peer)
+
+ return fmt.Errorf("invalid TD on block(%v) from peer(%s): block.td=%v, request.td=%v", request.Block.Number(), peer.id, request.Block.Td, request.TD)
+ }
+
+ return nil
+}
+
// BroadcastBlock will propagate the block to its connected peers. It will sort
// out which peers do not contain the block in their block set and will do a
// sqrt(peers) to determine the amount of peers we broadcast to.