aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzelig <viktor.tron@gmail.com>2015-04-08 10:34:20 +0800
committerzelig <viktor.tron@gmail.com>2015-04-09 20:58:35 +0800
commitf546b486bf444d9601cf97b934b2974a9b4d58f8 (patch)
tree17d53a2c6719d7c147854197fb25d3d2a01b5525
parent42fb9652f56321d2752ffe7773806df11f3087b8 (diff)
downloaddexon-f546b486bf444d9601cf97b934b2974a9b4d58f8.tar.gz
dexon-f546b486bf444d9601cf97b934b2974a9b4d58f8.tar.zst
dexon-f546b486bf444d9601cf97b934b2974a9b4d58f8.zip
introduce peers registry on nodes
- TestPeerPromotionByTdOnBlock renamed and skipped for now test should pass iff if TD is updated based on an agreement - senders register in AddBlock, flag records if they are coming from newblock message (and therefore advertise their TD with the block) or block message (TODO: latter are stored on the cache and updated by checkTD call; protocol should also call AddBlock on newblock messages by non-best peers) - remove TD update from optional TD field in addBlock: this is no longer part of the eth protocol spec -> TODO: reflect in wiki - only initialise peer map if at least two
-rw-r--r--blockpool/blockpool.go72
-rw-r--r--blockpool/peers_test.go12
2 files changed, 41 insertions, 43 deletions
diff --git a/blockpool/blockpool.go b/blockpool/blockpool.go
index 9871c5036..f9c8a64ab 100644
--- a/blockpool/blockpool.go
+++ b/blockpool/blockpool.go
@@ -132,6 +132,7 @@ type node struct {
block *types.Block
hashBy string
blockBy string
+ peers map[string]bool
td *big.Int
}
@@ -396,6 +397,7 @@ func (self *BlockPool) AddBlockHashes(next func() (common.Hash, bool), peerId st
if entry := self.get(bestpeer.currentBlockHash); entry == nil {
plog.DebugDetailf("AddBlockHashes: peer <%s> (head: %s) head section starting from [%s] ", peerId, hex(bestpeer.currentBlockHash), hex(bestpeer.parentHash))
// if head block is not yet in the pool, create entry and start node list for section
+
node := &node{
hash: bestpeer.currentBlockHash,
block: bestpeer.currentBlock,
@@ -622,10 +624,14 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
self.status.lock.Unlock()
entry := self.get(hash)
-
- // a peer's current head block is appearing the first time
+ blockIsCurrentHead := false
sender.lock.Lock()
+ // a peer's current head block is appearing the first time
if hash == sender.currentBlockHash {
+ // this happens when block came in a newblock message but
+ // also if sent in a blockmsg (for instance, if we requested, only if we
+ // dont apply on blockrequests the restriction of flood control)
+ blockIsCurrentHead = true
if sender.currentBlock == nil {
plog.Debugf("AddBlock: add head block %s for peer <%s> (head: %s)", hex(hash), peerId, hex(sender.currentBlockHash))
sender.setChainInfoFromBlock(block)
@@ -643,46 +649,29 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
plog.DebugDetailf("AddBlock: head block %s for peer <%s> (head: %s) already known", hex(hash), peerId, hex(sender.currentBlockHash))
// signal to head section process
}
- // self.wg.Add(1)
- // go func() {
- // timeout := time.After(1 * time.Second)
- // select {
- // case sender.currentBlockC <- block:
- // case <-timeout:
- // }
- // self.wg.Done()
- // }()
-
} else {
plog.DebugDetailf("AddBlock: block %s received from peer <%s> (head: %s)", hex(hash), peerId, hex(sender.currentBlockHash))
- // update peer chain info if more recent than what we registered
- if block.Td != nil && block.Td.Cmp(sender.td) > 0 {
- sender.td = block.Td
- sender.currentBlockHash = block.Hash()
- sender.parentHash = block.ParentHash()
- sender.currentBlock = block
- sender.headSection = nil
- }
-
/* @zelig !!!
- requested 5 hashes from both A & B. A responds sooner then B, process blocks. Close section.
- delayed B sends you block ... UNREQUESTED. Blocked
- if entry == nil {
- plog.DebugDetailf("AddBlock: unrequested block %s received from peer <%s> (head: %s)", hex(hash), peerId, hex(sender.currentBlockHash))
- sender.addError(ErrUnrequestedBlock, "%x", hash)
-
- self.status.lock.Lock()
- self.status.badPeers[peerId]++
- self.status.lock.Unlock()
- return
- }
+ requested 5 hashes from both A & B. A responds sooner then B, process blocks. Close section.
+ delayed B sends you block ... UNREQUESTED. Blocked
+ if entry == nil {
+ plog.DebugDetailf("AddBlock: unrequested block %s received from peer <%s> (head: %s)", hex(hash), peerId, hex(sender.currentBlockHash))
+ sender.addError(ErrUnrequestedBlock, "%x", hash)
+
+ self.status.lock.Lock()
+ self.status.badPeers[peerId]++
+ self.status.lock.Unlock()
+ return
+ }
*/
}
sender.lock.Unlock()
if entry == nil {
+ // FIXME: here check the cache find or create node -
+ // put peer as blockBy!
return
}
@@ -690,10 +679,22 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
node.lock.Lock()
defer node.lock.Unlock()
+ // register peer on node as source
+ if node.peers == nil {
+ node.peers = make(map[string]bool)
+ }
+ FoundBlockCurrentHead, found := node.peers[sender.id]
+ if !found || FoundBlockCurrentHead {
+ // if found but not FoundBlockCurrentHead, then no update
+ // necessary (||)
+ node.peers[sender.id] = blockIsCurrentHead
+ // for those that are false, TD will update their head
+ // for those that are true, TD is checked !
+ // this is checked at the time of TD calculation in checkTD
+ }
// check if block already received
if node.block != nil {
plog.DebugDetailf("AddBlock: block %s from peer <%s> (head: %s) already sent by <%s> ", hex(hash), peerId, hex(sender.currentBlockHash), node.blockBy)
- return
}
// check if block is already inserted in the blockchain
@@ -704,6 +705,8 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
/*
@zelig needs discussing
+ Viktor: pow check can be delayed in a go routine and therefore cache
+ creation is not blocking
// validate block for PoW
if !self.verifyPoW(block) {
plog.Warnf("AddBlock: invalid PoW on block %s from peer <%s> (head: %s)", hex(hash), peerId, hex(sender.currentBlockHash))
@@ -718,8 +721,7 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
*/
node.block = block
- node.blockBy = peerId
- node.td = block.Td // optional field
+ // node.blockBy = peerId
self.status.lock.Lock()
self.status.values.Blocks++
diff --git a/blockpool/peers_test.go b/blockpool/peers_test.go
index 62e059337..e32bb6fc8 100644
--- a/blockpool/peers_test.go
+++ b/blockpool/peers_test.go
@@ -144,7 +144,8 @@ func TestAddPeer(t *testing.T) {
blockPool.Stop()
}
-func TestPeerPromotionByOptionalTdOnBlock(t *testing.T) {
+func TestPeerPromotionByTdOnBlock(t *testing.T) {
+ t.Skip()
test.LogInit()
_, blockPool, blockPoolTester := newTestBlockPool(t)
blockPoolTester.blockChain[0] = nil
@@ -168,13 +169,8 @@ func TestPeerPromotionByOptionalTdOnBlock(t *testing.T) {
best = peer2.AddPeer()
peer2.serveBlocks(3, 4)
peer2.serveBlockHashes(4, 3, 2, 1)
- hashes := blockPoolTester.hashPool.IndexesToHashes([]int{2, 3})
- peer1.waitBlocksRequests(3)
- blockPool.AddBlock(&types.Block{
- HeaderHash: common.Hash(hashes[1]),
- ParentHeaderHash: common.Hash(hashes[0]),
- Td: common.Big3,
- }, "peer1")
+ // hashes := blockPoolTester.hashPool.IndexesToHashes([]int{2, 3})
+ peer1.serveBlocks(2, 3)
blockPool.RemovePeer("peer2")
if blockPool.peers.best.id != "peer1" {