forked from cerc-io/plugeth
check and penalise td misreporting
- add ErrIncorrectTD - checkTD called after insertChain successful - fix tests, use blockPoolTester.tds to map block index to TD
This commit is contained in:
parent
a9926a289d
commit
137a9c9365
@ -62,6 +62,7 @@ const (
|
|||||||
ErrUnrequestedBlock
|
ErrUnrequestedBlock
|
||||||
ErrInsufficientChainInfo
|
ErrInsufficientChainInfo
|
||||||
ErrIdleTooLong
|
ErrIdleTooLong
|
||||||
|
ErrIncorrectTD
|
||||||
)
|
)
|
||||||
|
|
||||||
var errorToString = map[int]string{
|
var errorToString = map[int]string{
|
||||||
@ -70,6 +71,7 @@ var errorToString = map[int]string{
|
|||||||
ErrUnrequestedBlock: "Unrequested block",
|
ErrUnrequestedBlock: "Unrequested block",
|
||||||
ErrInsufficientChainInfo: "Insufficient chain info",
|
ErrInsufficientChainInfo: "Insufficient chain info",
|
||||||
ErrIdleTooLong: "Idle too long",
|
ErrIdleTooLong: "Idle too long",
|
||||||
|
ErrIncorrectTD: "Incorrect Total Difficulty",
|
||||||
}
|
}
|
||||||
|
|
||||||
// init initialises all your laundry
|
// init initialises all your laundry
|
||||||
@ -373,6 +375,7 @@ func (self *BlockPool) AddBlockHashes(next func() (common.Hash, bool), peerId st
|
|||||||
block: bestpeer.currentBlock,
|
block: bestpeer.currentBlock,
|
||||||
hashBy: peerId,
|
hashBy: peerId,
|
||||||
blockBy: peerId,
|
blockBy: peerId,
|
||||||
|
td: bestpeer.td,
|
||||||
}
|
}
|
||||||
// nodes is a list of nodes in one section ordered top-bottom (old to young)
|
// nodes is a list of nodes in one section ordered top-bottom (old to young)
|
||||||
nodes = append(nodes, node)
|
nodes = append(nodes, node)
|
||||||
@ -729,6 +732,17 @@ LOOP:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *BlockPool) checkTD(nodes ...*node) {
|
||||||
|
for _, n := range nodes {
|
||||||
|
if n.td != nil {
|
||||||
|
plog.DebugDetailf("peer td %v =?= block td %v", n.td, n.block.Td)
|
||||||
|
if n.td.Cmp(n.block.Td) != 0 {
|
||||||
|
self.peers.peerError(n.blockBy, ErrIncorrectTD, "on block %x", n.hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// must run in separate go routine, otherwise
|
// must run in separate go routine, otherwise
|
||||||
// switchpeer -> activateChain -> activate deadlocks on section process select and peers.lock
|
// switchpeer -> activateChain -> activate deadlocks on section process select and peers.lock
|
||||||
func (self *BlockPool) requestBlocks(attempts int, hashes []common.Hash) {
|
func (self *BlockPool) requestBlocks(attempts int, hashes []common.Hash) {
|
||||||
|
@ -51,9 +51,11 @@ func TestPeerPromotionByOptionalTdOnBlock(t *testing.T) {
|
|||||||
blockPoolTester.initRefBlockChain(4)
|
blockPoolTester.initRefBlockChain(4)
|
||||||
peer0 := blockPoolTester.newPeer("peer0", 2, 2)
|
peer0 := blockPoolTester.newPeer("peer0", 2, 2)
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 1)
|
peer1 := blockPoolTester.newPeer("peer1", 1, 1)
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 3, 4)
|
peer2 := blockPoolTester.newPeer("peer2", 4, 4)
|
||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
blockPoolTester.tds = make(map[int]int)
|
||||||
|
blockPoolTester.tds[3] = 3
|
||||||
|
|
||||||
// pool
|
// pool
|
||||||
peer0.AddPeer()
|
peer0.AddPeer()
|
||||||
@ -94,7 +96,7 @@ func TestSimpleChain(t *testing.T) {
|
|||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 2)
|
peer1 := blockPoolTester.newPeer("peer1", 2, 2)
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
peer1.serveBlocks(1, 2)
|
peer1.serveBlocks(1, 2)
|
||||||
go peer1.serveBlockHashes(2, 1, 0)
|
go peer1.serveBlockHashes(2, 1, 0)
|
||||||
@ -114,7 +116,7 @@ func TestChainConnectingWithParentHash(t *testing.T) {
|
|||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 3)
|
peer1 := blockPoolTester.newPeer("peer1", 3, 3)
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
go peer1.serveBlocks(2, 3)
|
go peer1.serveBlocks(2, 3)
|
||||||
go peer1.serveBlockHashes(3, 2, 1)
|
go peer1.serveBlockHashes(3, 2, 1)
|
||||||
@ -134,7 +136,7 @@ func TestMultiSectionChain(t *testing.T) {
|
|||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 5)
|
peer1 := blockPoolTester.newPeer("peer1", 5, 5)
|
||||||
|
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
go peer1.serveBlocks(4, 5)
|
go peer1.serveBlocks(4, 5)
|
||||||
@ -156,14 +158,16 @@ func TestNewBlocksOnPartialChain(t *testing.T) {
|
|||||||
blockPoolTester.initRefBlockChain(7)
|
blockPoolTester.initRefBlockChain(7)
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 5)
|
peer1 := blockPoolTester.newPeer("peer1", 5, 5)
|
||||||
|
blockPoolTester.tds = make(map[int]int)
|
||||||
|
blockPoolTester.tds[5] = 5
|
||||||
|
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
go peer1.serveBlocks(4, 5) // partially complete section
|
go peer1.serveBlocks(4, 5) // partially complete section
|
||||||
go peer1.serveBlockHashes(5, 4, 3)
|
go peer1.serveBlockHashes(5, 4, 3)
|
||||||
peer1.serveBlocks(3, 4) // partially complete section
|
peer1.serveBlocks(3, 4) // partially complete section
|
||||||
// peer1 found new blocks
|
// peer1 found new blocks
|
||||||
peer1.td = 2
|
peer1.td = 7
|
||||||
peer1.currentBlock = 7
|
peer1.currentBlock = 7
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
peer1.sendBlocks(6, 7)
|
peer1.sendBlocks(6, 7)
|
||||||
@ -188,16 +192,15 @@ func TestPeerSwitchUp(t *testing.T) {
|
|||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 6)
|
peer1 := blockPoolTester.newPeer("peer1", 6, 6)
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 2, 7)
|
peer2 := blockPoolTester.newPeer("peer2", 7, 7)
|
||||||
|
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
go peer1.serveBlocks(5, 6)
|
go peer1.serveBlocks(5, 6)
|
||||||
go peer1.serveBlockHashes(6, 5, 4, 3) //
|
go peer1.serveBlockHashes(6, 5, 4, 3) //
|
||||||
peer1.serveBlocks(2, 3) // section partially complete, block 3 will be preserved after peer demoted
|
peer1.serveBlocks(2, 3) // section partially complete, block 3 will be preserved after peer demoted
|
||||||
peer2.AddPeer() // peer2 is promoted as best peer, peer1 is demoted
|
peer2.AddPeer() // peer2 is promoted as best peer, peer1 is demoted
|
||||||
go peer2.serveBlocks(6, 7)
|
go peer2.serveBlocks(6, 7) //
|
||||||
// go peer2.serveBlockHashes(7, 6) //
|
|
||||||
go peer2.serveBlocks(4, 5) // tests that block request for earlier section is remembered
|
go peer2.serveBlocks(4, 5) // tests that block request for earlier section is remembered
|
||||||
go peer1.serveBlocks(3, 4) // tests that connecting section by demoted peer is remembered and blocks are accepted from demoted peer
|
go peer1.serveBlocks(3, 4) // tests that connecting section by demoted peer is remembered and blocks are accepted from demoted peer
|
||||||
go peer2.serveBlockHashes(3, 2, 1, 0) // tests that known chain section is activated, hash requests from 3 is remembered
|
go peer2.serveBlockHashes(3, 2, 1, 0) // tests that known chain section is activated, hash requests from 3 is remembered
|
||||||
@ -216,8 +219,8 @@ func TestPeerSwitchDownOverlapSectionWithoutRootBlock(t *testing.T) {
|
|||||||
blockPoolTester.initRefBlockChain(6)
|
blockPoolTester.initRefBlockChain(6)
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 4)
|
peer1 := blockPoolTester.newPeer("peer1", 4, 4)
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 2, 6)
|
peer2 := blockPoolTester.newPeer("peer2", 6, 6)
|
||||||
|
|
||||||
peer2.AddPeer()
|
peer2.AddPeer()
|
||||||
peer2.serveBlocks(5, 6) // partially complete, section will be preserved
|
peer2.serveBlocks(5, 6) // partially complete, section will be preserved
|
||||||
@ -242,8 +245,8 @@ func TestPeerSwitchDownOverlapSectionWithRootBlock(t *testing.T) {
|
|||||||
blockPoolTester.initRefBlockChain(6)
|
blockPoolTester.initRefBlockChain(6)
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 4)
|
peer1 := blockPoolTester.newPeer("peer1", 4, 4)
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 2, 6)
|
peer2 := blockPoolTester.newPeer("peer2", 6, 6)
|
||||||
|
|
||||||
peer2.AddPeer()
|
peer2.AddPeer()
|
||||||
peer2.serveBlocks(5, 6) // partially complete, section will be preserved
|
peer2.serveBlocks(5, 6) // partially complete, section will be preserved
|
||||||
@ -269,8 +272,8 @@ func TestPeerSwitchDownDisjointSection(t *testing.T) {
|
|||||||
blockPoolTester.initRefBlockChain(3)
|
blockPoolTester.initRefBlockChain(3)
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 3)
|
peer1 := blockPoolTester.newPeer("peer1", 3, 3)
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 2, 6)
|
peer2 := blockPoolTester.newPeer("peer2", 6, 6)
|
||||||
|
|
||||||
peer2.AddPeer()
|
peer2.AddPeer()
|
||||||
peer2.serveBlocks(5, 6) // partially complete, section will be preserved
|
peer2.serveBlocks(5, 6) // partially complete, section will be preserved
|
||||||
@ -297,8 +300,8 @@ func TestPeerSwitchBack(t *testing.T) {
|
|||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 2, 11)
|
peer1 := blockPoolTester.newPeer("peer1", 11, 11)
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 1, 8)
|
peer2 := blockPoolTester.newPeer("peer2", 8, 8)
|
||||||
|
|
||||||
peer2.AddPeer()
|
peer2.AddPeer()
|
||||||
go peer2.serveBlocks(7, 8)
|
go peer2.serveBlocks(7, 8)
|
||||||
@ -328,9 +331,10 @@ func TestForkSimple(t *testing.T) {
|
|||||||
delete(blockPoolTester.refBlockChain, 6)
|
delete(blockPoolTester.refBlockChain, 6)
|
||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
blockPoolTester.tds = make(map[int]int)
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 9)
|
blockPoolTester.tds[6] = 10
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 2, 6)
|
peer1 := blockPoolTester.newPeer("peer1", 9, 9)
|
||||||
|
peer2 := blockPoolTester.newPeer("peer2", 10, 6)
|
||||||
|
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
go peer1.serveBlocks(8, 9)
|
go peer1.serveBlocks(8, 9)
|
||||||
@ -363,9 +367,10 @@ func TestForkSwitchBackByNewBlocks(t *testing.T) {
|
|||||||
delete(blockPoolTester.refBlockChain, 6)
|
delete(blockPoolTester.refBlockChain, 6)
|
||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
blockPoolTester.tds = make(map[int]int)
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 9)
|
blockPoolTester.tds[6] = 10
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 2, 6)
|
peer1 := blockPoolTester.newPeer("peer1", 9, 9)
|
||||||
|
peer2 := blockPoolTester.newPeer("peer2", 10, 6)
|
||||||
|
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
go peer1.serveBlocks(8, 9) //
|
go peer1.serveBlocks(8, 9) //
|
||||||
@ -378,7 +383,7 @@ func TestForkSwitchBackByNewBlocks(t *testing.T) {
|
|||||||
peer2.serveBlocks(1, 2, 3, 4, 5) //
|
peer2.serveBlocks(1, 2, 3, 4, 5) //
|
||||||
|
|
||||||
// peer1 finds new blocks
|
// peer1 finds new blocks
|
||||||
peer1.td = 3
|
peer1.td = 11
|
||||||
peer1.currentBlock = 11
|
peer1.currentBlock = 11
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
go peer1.serveBlocks(10, 11)
|
go peer1.serveBlocks(10, 11)
|
||||||
@ -410,8 +415,14 @@ func TestForkSwitchBackByPeerSwitchBack(t *testing.T) {
|
|||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 9)
|
blockPoolTester.tds = make(map[int]int)
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 2, 6)
|
blockPoolTester.tds[6] = 10
|
||||||
|
|
||||||
|
blockPoolTester.tds = make(map[int]int)
|
||||||
|
blockPoolTester.tds[6] = 10
|
||||||
|
|
||||||
|
peer1 := blockPoolTester.newPeer("peer1", 9, 9)
|
||||||
|
peer2 := blockPoolTester.newPeer("peer2", 10, 6)
|
||||||
|
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
go peer1.serveBlocks(8, 9)
|
go peer1.serveBlocks(8, 9)
|
||||||
@ -448,8 +459,11 @@ func TestForkCompleteSectionSwitchBackByPeerSwitchBack(t *testing.T) {
|
|||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
|
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 1, 9)
|
blockPoolTester.tds = make(map[int]int)
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 2, 6)
|
blockPoolTester.tds[6] = 10
|
||||||
|
|
||||||
|
peer1 := blockPoolTester.newPeer("peer1", 9, 9)
|
||||||
|
peer2 := blockPoolTester.newPeer("peer2", 10, 6)
|
||||||
|
|
||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
go peer1.serveBlocks(8, 9)
|
go peer1.serveBlocks(8, 9)
|
||||||
|
@ -40,6 +40,7 @@ type blockPoolTester struct {
|
|||||||
blockPool *BlockPool
|
blockPool *BlockPool
|
||||||
t *testing.T
|
t *testing.T
|
||||||
chainEvents *event.TypeMux
|
chainEvents *event.TypeMux
|
||||||
|
tds map[int]int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestBlockPool(t *testing.T) (hashPool *test.TestHashPool, blockPool *BlockPool, b *blockPoolTester) {
|
func newTestBlockPool(t *testing.T) (hashPool *test.TestHashPool, blockPool *BlockPool, b *blockPoolTester) {
|
||||||
@ -84,6 +85,14 @@ func (self *blockPoolTester) insertChain(blocks types.Blocks) error {
|
|||||||
var ok bool
|
var ok bool
|
||||||
for _, block := range blocks {
|
for _, block := range blocks {
|
||||||
child = self.hashPool.HashesToIndexes([]common.Hash{block.Hash()})[0]
|
child = self.hashPool.HashesToIndexes([]common.Hash{block.Hash()})[0]
|
||||||
|
var td int
|
||||||
|
if self.tds != nil {
|
||||||
|
td, ok = self.tds[child]
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
td = child
|
||||||
|
}
|
||||||
|
block.Td = big.NewInt(int64(td))
|
||||||
_, ok = self.blockChain[child]
|
_, ok = self.blockChain[child]
|
||||||
if ok {
|
if ok {
|
||||||
fmt.Printf("block %v already in blockchain\n", child)
|
fmt.Printf("block %v already in blockchain\n", child)
|
||||||
|
@ -93,7 +93,6 @@ func TestUnrequestedBlock(t *testing.T) {
|
|||||||
peer1.AddPeer()
|
peer1.AddPeer()
|
||||||
peer1.sendBlocks(1, 2)
|
peer1.sendBlocks(1, 2)
|
||||||
|
|
||||||
// blockPool.Wait(waitTimeout)
|
|
||||||
blockPool.Stop()
|
blockPool.Stop()
|
||||||
if len(peer1.peerErrors) == 1 {
|
if len(peer1.peerErrors) == 1 {
|
||||||
if peer1.peerErrors[0] != ErrUnrequestedBlock {
|
if peer1.peerErrors[0] != ErrUnrequestedBlock {
|
||||||
@ -124,6 +123,33 @@ func TestErrInsufficientChainInfo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIncorrectTD(t *testing.T) {
|
||||||
|
test.LogInit()
|
||||||
|
_, blockPool, blockPoolTester := newTestBlockPool(t)
|
||||||
|
blockPoolTester.blockChain[0] = nil
|
||||||
|
blockPoolTester.initRefBlockChain(3)
|
||||||
|
|
||||||
|
blockPool.Start()
|
||||||
|
|
||||||
|
peer1 := blockPoolTester.newPeer("peer1", 1, 3)
|
||||||
|
peer1.AddPeer()
|
||||||
|
go peer1.serveBlocks(2, 3)
|
||||||
|
go peer1.serveBlockHashes(3, 2, 1, 0)
|
||||||
|
peer1.serveBlocks(0, 1, 2)
|
||||||
|
|
||||||
|
blockPool.Wait(waitTimeout)
|
||||||
|
blockPool.Stop()
|
||||||
|
blockPoolTester.refBlockChain[3] = []int{}
|
||||||
|
blockPoolTester.checkBlockChain(blockPoolTester.refBlockChain)
|
||||||
|
if len(peer1.peerErrors) == 1 {
|
||||||
|
if peer1.peerErrors[0] != ErrIncorrectTD {
|
||||||
|
t.Errorf("wrong error, got %v, expected %v", peer1.peerErrors[0], ErrIncorrectTD)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("expected %v error, got %v", ErrIncorrectTD, peer1.peerErrors)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPeerSuspension(t *testing.T) {
|
func TestPeerSuspension(t *testing.T) {
|
||||||
test.LogInit()
|
test.LogInit()
|
||||||
_, blockPool, blockPoolTester := newTestBlockPool(t)
|
_, blockPool, blockPoolTester := newTestBlockPool(t)
|
||||||
|
@ -452,8 +452,12 @@ func (self *peer) getBlockHashes() {
|
|||||||
self.addError(ErrInvalidBlock, "%v", err)
|
self.addError(ErrInvalidBlock, "%v", err)
|
||||||
self.bp.status.badPeers[self.id]++
|
self.bp.status.badPeers[self.id]++
|
||||||
} else {
|
} else {
|
||||||
|
if self.currentBlock.Td != nil {
|
||||||
|
if self.td.Cmp(self.currentBlock.Td) != 0 {
|
||||||
|
self.addError(ErrIncorrectTD, "on block %x", self.currentBlockHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
headKey := self.parentHash.Str()
|
headKey := self.parentHash.Str()
|
||||||
height := self.bp.status.chain[headKey] + 1
|
|
||||||
self.bp.status.chain[self.currentBlockHash.Str()] = height
|
self.bp.status.chain[self.currentBlockHash.Str()] = height
|
||||||
if height > self.bp.status.values.LongestChain {
|
if height > self.bp.status.values.LongestChain {
|
||||||
self.bp.status.values.LongestChain = height
|
self.bp.status.values.LongestChain = height
|
||||||
@ -471,6 +475,7 @@ func (self *peer) getBlockHashes() {
|
|||||||
block: self.currentBlock,
|
block: self.currentBlock,
|
||||||
hashBy: self.id,
|
hashBy: self.id,
|
||||||
blockBy: self.id,
|
blockBy: self.id,
|
||||||
|
td: self.td,
|
||||||
}
|
}
|
||||||
self.bp.newSection([]*node{n}).activate(self)
|
self.bp.newSection([]*node{n}).activate(self)
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,9 +15,9 @@ import (
|
|||||||
func TestAddPeer(t *testing.T) {
|
func TestAddPeer(t *testing.T) {
|
||||||
test.LogInit()
|
test.LogInit()
|
||||||
_, blockPool, blockPoolTester := newTestBlockPool(t)
|
_, blockPool, blockPoolTester := newTestBlockPool(t)
|
||||||
peer0 := blockPoolTester.newPeer("peer0", 1, 0)
|
peer0 := blockPoolTester.newPeer("peer0", 1, 1)
|
||||||
peer1 := blockPoolTester.newPeer("peer1", 2, 1)
|
peer1 := blockPoolTester.newPeer("peer1", 2, 2)
|
||||||
peer2 := blockPoolTester.newPeer("peer2", 3, 2)
|
peer2 := blockPoolTester.newPeer("peer2", 3, 3)
|
||||||
var bestpeer *peer
|
var bestpeer *peer
|
||||||
|
|
||||||
blockPool.Start()
|
blockPool.Start()
|
||||||
@ -38,7 +38,7 @@ func TestAddPeer(t *testing.T) {
|
|||||||
if blockPool.peers.best.id != "peer2" {
|
if blockPool.peers.best.id != "peer2" {
|
||||||
t.Errorf("peer2 (TD=3) not set as best")
|
t.Errorf("peer2 (TD=3) not set as best")
|
||||||
}
|
}
|
||||||
peer2.waitBlocksRequests(2)
|
peer2.waitBlocksRequests(3)
|
||||||
|
|
||||||
best = peer1.AddPeer()
|
best = peer1.AddPeer()
|
||||||
if best {
|
if best {
|
||||||
@ -52,7 +52,7 @@ func TestAddPeer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
peer2.td = 4
|
peer2.td = 4
|
||||||
peer2.currentBlock = 3
|
peer2.currentBlock = 4
|
||||||
best = peer2.AddPeer()
|
best = peer2.AddPeer()
|
||||||
if !best {
|
if !best {
|
||||||
t.Errorf("peer2 (TD=4) not accepted as best")
|
t.Errorf("peer2 (TD=4) not accepted as best")
|
||||||
@ -63,10 +63,10 @@ func TestAddPeer(t *testing.T) {
|
|||||||
if blockPool.peers.best.td.Cmp(big.NewInt(int64(4))) != 0 {
|
if blockPool.peers.best.td.Cmp(big.NewInt(int64(4))) != 0 {
|
||||||
t.Errorf("peer2 TD not updated")
|
t.Errorf("peer2 TD not updated")
|
||||||
}
|
}
|
||||||
peer2.waitBlocksRequests(3)
|
peer2.waitBlocksRequests(4)
|
||||||
|
|
||||||
peer1.td = 3
|
peer1.td = 3
|
||||||
peer1.currentBlock = 2
|
peer1.currentBlock = 3
|
||||||
best = peer1.AddPeer()
|
best = peer1.AddPeer()
|
||||||
if best {
|
if best {
|
||||||
t.Errorf("peer1 (TD=3) should not be set as best")
|
t.Errorf("peer1 (TD=3) should not be set as best")
|
||||||
@ -88,7 +88,7 @@ func TestAddPeer(t *testing.T) {
|
|||||||
if blockPool.peers.best.id != "peer1" {
|
if blockPool.peers.best.id != "peer1" {
|
||||||
t.Errorf("existing peer1 (TD=3) should be set as best peer")
|
t.Errorf("existing peer1 (TD=3) should be set as best peer")
|
||||||
}
|
}
|
||||||
peer1.waitBlocksRequests(2)
|
peer1.waitBlocksRequests(3)
|
||||||
|
|
||||||
blockPool.RemovePeer("peer1")
|
blockPool.RemovePeer("peer1")
|
||||||
bestpeer, best = blockPool.peers.getPeer("peer1")
|
bestpeer, best = blockPool.peers.getPeer("peer1")
|
||||||
@ -99,7 +99,7 @@ func TestAddPeer(t *testing.T) {
|
|||||||
if blockPool.peers.best.id != "peer0" {
|
if blockPool.peers.best.id != "peer0" {
|
||||||
t.Errorf("existing peer0 (TD=1) should be set as best peer")
|
t.Errorf("existing peer0 (TD=1) should be set as best peer")
|
||||||
}
|
}
|
||||||
peer0.waitBlocksRequests(0)
|
peer0.waitBlocksRequests(1)
|
||||||
|
|
||||||
blockPool.RemovePeer("peer0")
|
blockPool.RemovePeer("peer0")
|
||||||
bestpeer, best = blockPool.peers.getPeer("peer0")
|
bestpeer, best = blockPool.peers.getPeer("peer0")
|
||||||
|
@ -83,9 +83,9 @@ func (self *BlockPool) newSection(nodes []*node) *section {
|
|||||||
offC: make(chan bool),
|
offC: make(chan bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, node := range nodes {
|
for i, n := range nodes {
|
||||||
entry := &entry{node: node, section: sec, index: &index{i}}
|
entry := &entry{node: n, section: sec, index: &index{i}}
|
||||||
self.set(node.hash, entry)
|
self.set(n.hash, entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
plog.DebugDetailf("[%s] setup section process", sectionhex(sec))
|
plog.DebugDetailf("[%s] setup section process", sectionhex(sec))
|
||||||
@ -104,20 +104,22 @@ func (self *section) addSectionToBlockChain(p *peer) {
|
|||||||
self.bp.wg.Done()
|
self.bp.wg.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var node *node
|
var nodes []*node
|
||||||
|
var n *node
|
||||||
var keys []string
|
var keys []string
|
||||||
var blocks []*types.Block
|
var blocks []*types.Block
|
||||||
for self.poolRootIndex > 0 {
|
for self.poolRootIndex > 0 {
|
||||||
node = self.nodes[self.poolRootIndex-1]
|
n = self.nodes[self.poolRootIndex-1]
|
||||||
node.lock.RLock()
|
n.lock.RLock()
|
||||||
block := node.block
|
block := n.block
|
||||||
node.lock.RUnlock()
|
n.lock.RUnlock()
|
||||||
if block == nil {
|
if block == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
self.poolRootIndex--
|
self.poolRootIndex--
|
||||||
keys = append(keys, node.hash.Str())
|
keys = append(keys, node.hash.Str())
|
||||||
blocks = append(blocks, block)
|
blocks = append(blocks, block)
|
||||||
|
nodes = append(nodes, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(blocks) == 0 {
|
if len(blocks) == 0 {
|
||||||
@ -134,13 +136,20 @@ func (self *section) addSectionToBlockChain(p *peer) {
|
|||||||
err := self.bp.insertChain(blocks)
|
err := self.bp.insertChain(blocks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
self.invalid = true
|
self.invalid = true
|
||||||
self.bp.peers.peerError(node.blockBy, ErrInvalidBlock, "%v", err)
|
self.bp.peers.peerError(n.blockBy, ErrInvalidBlock, "%v", err)
|
||||||
plog.Warnf("invalid block %x", node.hash)
|
plog.Warnf("invalid block %x", n.hash)
|
||||||
plog.Warnf("penalise peers %v (hash), %v (block)", node.hashBy, node.blockBy)
|
plog.Warnf("penalise peers %v (hash), %v (block)", n.hashBy, n.blockBy)
|
||||||
|
|
||||||
// or invalid block and the entire chain needs to be removed
|
// or invalid block and the entire chain needs to be removed
|
||||||
self.removeChain()
|
self.removeChain()
|
||||||
} else {
|
} else {
|
||||||
|
// check tds
|
||||||
|
self.bp.wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
plog.DebugDetailf("checking td")
|
||||||
|
self.bp.checkTD(nodes...)
|
||||||
|
self.bp.wg.Done()
|
||||||
|
}()
|
||||||
// if all blocks inserted in this section
|
// if all blocks inserted in this section
|
||||||
// then need to try to insert blocks in child section
|
// then need to try to insert blocks in child section
|
||||||
if self.poolRootIndex == 0 {
|
if self.poolRootIndex == 0 {
|
||||||
@ -178,7 +187,7 @@ func (self *section) addSectionToBlockChain(p *peer) {
|
|||||||
self.bp.status.values.BlocksInChain += len(blocks)
|
self.bp.status.values.BlocksInChain += len(blocks)
|
||||||
self.bp.status.values.BlocksInPool -= len(blocks)
|
self.bp.status.values.BlocksInPool -= len(blocks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
self.bp.status.badPeers[node.blockBy]++
|
self.bp.status.badPeers[n.blockBy]++
|
||||||
}
|
}
|
||||||
self.bp.status.lock.Unlock()
|
self.bp.status.lock.Unlock()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user