Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
a578db5d
Commit
a578db5d
authored
Mar 19, 2015
by
zelig
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improve documentation and move one test
parent
8767179d
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
202 additions
and
156 deletions
+202
-156
blockpool.go
blockpool/blockpool.go
+98
-78
blockpool_test.go
blockpool/blockpool_test.go
+7
-49
blockpool_util_test.go
blockpool/blockpool_util_test.go
+22
-14
config_test.go
blockpool/config_test.go
+3
-1
peers.go
blockpool/peers.go
+18
-5
peers_test.go
blockpool/peers_test.go
+44
-0
hash_pool.go
blockpool/test/hash_pool.go
+6
-9
logger.go
blockpool/test/logger.go
+2
-0
util.go
blockpool/test/util.go
+2
-0
No files found.
blockpool/blockpool.go
View file @
a578db5d
This diff is collapsed.
Click to expand it.
blockpool/blockpool_test.go
View file @
a578db5d
...
@@ -9,6 +9,9 @@ import (
...
@@ -9,6 +9,9 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types"
)
)
// using the mock framework in blockpool_util_test
// we test various scenarios here
func
TestPeerWithKnownBlock
(
t
*
testing
.
T
)
{
func
TestPeerWithKnownBlock
(
t
*
testing
.
T
)
{
test
.
LogInit
()
test
.
LogInit
()
_
,
blockPool
,
blockPoolTester
:=
newTestBlockPool
(
t
)
_
,
blockPool
,
blockPoolTester
:=
newTestBlockPool
(
t
)
...
@@ -44,50 +47,6 @@ func TestPeerWithKnownParentBlock(t *testing.T) {
...
@@ -44,50 +47,6 @@ func TestPeerWithKnownParentBlock(t *testing.T) {
blockPoolTester
.
checkBlockChain
(
blockPoolTester
.
refBlockChain
)
blockPoolTester
.
checkBlockChain
(
blockPoolTester
.
refBlockChain
)
}
}
func
TestPeerPromotionByOptionalTdOnBlock
(
t
*
testing
.
T
)
{
test
.
LogInit
()
_
,
blockPool
,
blockPoolTester
:=
newTestBlockPool
(
t
)
blockPoolTester
.
blockChain
[
0
]
=
nil
blockPoolTester
.
initRefBlockChain
(
4
)
peer0
:=
blockPoolTester
.
newPeer
(
"peer0"
,
2
,
2
)
peer1
:=
blockPoolTester
.
newPeer
(
"peer1"
,
1
,
1
)
peer2
:=
blockPoolTester
.
newPeer
(
"peer2"
,
4
,
4
)
blockPool
.
Start
()
blockPoolTester
.
tds
=
make
(
map
[
int
]
int
)
blockPoolTester
.
tds
[
3
]
=
3
// pool
peer0
.
AddPeer
()
peer0
.
serveBlocks
(
1
,
2
)
best
:=
peer1
.
AddPeer
()
// this tests that peer1 is not promoted over peer0 yet
if
best
{
t
.
Errorf
(
"peer1 (TD=1) should not be set as best"
)
}
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"
)
blockPool
.
RemovePeer
(
"peer2"
)
if
blockPool
.
peers
.
best
.
id
!=
"peer1"
{
t
.
Errorf
(
"peer1 (TD=3) should be set as best"
)
}
peer1
.
serveBlocks
(
0
,
1
,
2
)
blockPool
.
Wait
(
waitTimeout
)
blockPool
.
Stop
()
blockPoolTester
.
refBlockChain
[
4
]
=
[]
int
{}
blockPoolTester
.
checkBlockChain
(
blockPoolTester
.
refBlockChain
)
}
func
TestSimpleChain
(
t
*
testing
.
T
)
{
func
TestSimpleChain
(
t
*
testing
.
T
)
{
test
.
LogInit
()
test
.
LogInit
()
_
,
blockPool
,
blockPoolTester
:=
newTestBlockPool
(
t
)
_
,
blockPool
,
blockPoolTester
:=
newTestBlockPool
(
t
)
...
@@ -166,6 +125,7 @@ func TestNewBlocksOnPartialChain(t *testing.T) {
...
@@ -166,6 +125,7 @@ func TestNewBlocksOnPartialChain(t *testing.T) {
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
=
7
peer1
.
td
=
7
peer1
.
currentBlock
=
7
peer1
.
currentBlock
=
7
...
@@ -176,7 +136,6 @@ func TestNewBlocksOnPartialChain(t *testing.T) {
...
@@ -176,7 +136,6 @@ func TestNewBlocksOnPartialChain(t *testing.T) {
go
peer1
.
serveBlocks
(
5
,
6
)
go
peer1
.
serveBlocks
(
5
,
6
)
go
peer1
.
serveBlockHashes
(
3
,
2
,
1
)
// tests that hash request from known chain root is remembered
go
peer1
.
serveBlockHashes
(
3
,
2
,
1
)
// tests that hash request from known chain root is remembered
peer1
.
serveBlocks
(
0
,
1
,
2
)
peer1
.
serveBlocks
(
0
,
1
,
2
)
// blockPool.RemovePeer("peer1")
blockPool
.
Wait
(
waitTimeout
)
blockPool
.
Wait
(
waitTimeout
)
blockPool
.
Stop
()
blockPool
.
Stop
()
...
@@ -468,8 +427,8 @@ func TestForkCompleteSectionSwitchBackByPeerSwitchBack(t *testing.T) {
...
@@ -468,8 +427,8 @@ func TestForkCompleteSectionSwitchBackByPeerSwitchBack(t *testing.T) {
peer1
.
AddPeer
()
peer1
.
AddPeer
()
go
peer1
.
serveBlocks
(
8
,
9
)
go
peer1
.
serveBlocks
(
8
,
9
)
go
peer1
.
serveBlockHashes
(
9
,
8
,
7
)
go
peer1
.
serveBlockHashes
(
9
,
8
,
7
)
peer1
.
serveBlocks
(
3
,
7
,
8
)
// make sure this section is complete
peer1
.
serveBlocks
(
3
,
7
,
8
)
// make sure this section is complete
time
.
Sleep
(
1
*
time
.
Second
)
time
.
Sleep
(
1
*
time
.
Second
)
//
go
peer1
.
serveBlockHashes
(
7
,
3
,
2
)
// block 3/7 is section boundary
go
peer1
.
serveBlockHashes
(
7
,
3
,
2
)
// block 3/7 is section boundary
peer1
.
serveBlocks
(
2
,
3
)
// partially complete sections block 2 missing
peer1
.
serveBlocks
(
2
,
3
)
// partially complete sections block 2 missing
peer2
.
AddPeer
()
//
peer2
.
AddPeer
()
//
...
@@ -477,8 +436,7 @@ func TestForkCompleteSectionSwitchBackByPeerSwitchBack(t *testing.T) {
...
@@ -477,8 +436,7 @@ func TestForkCompleteSectionSwitchBackByPeerSwitchBack(t *testing.T) {
go
peer2
.
serveBlockHashes
(
6
,
5
,
4
,
3
,
2
)
// peer2 forks on block 3
go
peer2
.
serveBlockHashes
(
6
,
5
,
4
,
3
,
2
)
// peer2 forks on block 3
peer2
.
serveBlocks
(
2
,
3
,
4
,
5
)
// block 2 still missing.
peer2
.
serveBlocks
(
2
,
3
,
4
,
5
)
// block 2 still missing.
blockPool
.
RemovePeer
(
"peer2"
)
// peer2 disconnects, peer1 is promoted again as best peer
blockPool
.
RemovePeer
(
"peer2"
)
// peer2 disconnects, peer1 is promoted again as best peer
// peer1.serveBlockHashes(7, 3) // tests that hash request from fork root is remembered even though section process completed
go
peer1
.
serveBlockHashes
(
2
,
1
,
0
)
//
go
peer1
.
serveBlockHashes
(
2
,
1
,
0
)
//
peer1
.
serveBlocks
(
0
,
1
,
2
)
peer1
.
serveBlocks
(
0
,
1
,
2
)
blockPool
.
Wait
(
waitTimeout
)
blockPool
.
Wait
(
waitTimeout
)
...
...
blockpool/blockpool_util_test.go
View file @
a578db5d
...
@@ -66,7 +66,8 @@ func (self *blockPoolTester) Errorf(format string, params ...interface{}) {
...
@@ -66,7 +66,8 @@ func (self *blockPoolTester) Errorf(format string, params ...interface{}) {
}
}
// blockPoolTester implements the 3 callbacks needed by the blockPool:
// blockPoolTester implements the 3 callbacks needed by the blockPool:
// hasBlock, insetChain, verifyPoW
// hasBlock, insetChain, verifyPoW as well as provides the eventer
// to subscribe to head insertions
func
(
self
*
blockPoolTester
)
hasBlock
(
block
common
.
Hash
)
(
ok
bool
)
{
func
(
self
*
blockPoolTester
)
hasBlock
(
block
common
.
Hash
)
(
ok
bool
)
{
self
.
lock
.
RLock
()
self
.
lock
.
RLock
()
defer
self
.
lock
.
RUnlock
()
defer
self
.
lock
.
RUnlock
()
...
@@ -77,6 +78,7 @@ func (self *blockPoolTester) hasBlock(block common.Hash) (ok bool) {
...
@@ -77,6 +78,7 @@ func (self *blockPoolTester) hasBlock(block common.Hash) (ok bool) {
return
return
}
}
// mock insertChain relies on refBlockChain to determine block validity
func
(
self
*
blockPoolTester
)
insertChain
(
blocks
types
.
Blocks
)
error
{
func
(
self
*
blockPoolTester
)
insertChain
(
blocks
types
.
Blocks
)
error
{
self
.
lock
.
Lock
()
self
.
lock
.
Lock
()
defer
self
.
lock
.
Unlock
()
defer
self
.
lock
.
Unlock
()
...
@@ -127,6 +129,7 @@ func (self *blockPoolTester) insertChain(blocks types.Blocks) error {
...
@@ -127,6 +129,7 @@ func (self *blockPoolTester) insertChain(blocks types.Blocks) error {
return
nil
return
nil
}
}
// mock soft block validation always succeeds
func
(
self
*
blockPoolTester
)
verifyPoW
(
pblock
pow
.
Block
)
bool
{
func
(
self
*
blockPoolTester
)
verifyPoW
(
pblock
pow
.
Block
)
bool
{
return
true
return
true
}
}
...
@@ -152,24 +155,24 @@ func (self *blockPoolTester) checkBlockChain(blockChain map[int][]int) {
...
@@ -152,24 +155,24 @@ func (self *blockPoolTester) checkBlockChain(blockChain map[int][]int) {
}
}
}
}
//
// peerTester provides the peer callbacks for the blockPool
// peerTester provides the peer callbacks for the blockPool
// it registers actual callbacks so that the result can be compared to desired behaviour
// it registers actual callbacks so that the result can be compared to desired behaviour
// provides helper functions to mock the protocol calls to the blockPool
// provides helper functions to mock the protocol calls to the blockPool
type
peerTester
struct
{
type
peerTester
struct
{
// containers to record request and error callbacks
blockHashesRequests
[]
int
blockHashesRequests
[]
int
blocksRequests
[][]
int
blocksRequests
[][]
int
blocksRequestsMap
map
[
int
]
bool
blocksRequestsMap
map
[
int
]
bool
peerErrors
[]
int
peerErrors
[]
int
blockPool
*
BlockPool
hashPool
*
test
.
TestHashPool
blockPool
*
BlockPool
lock
sync
.
RWMutex
hashPool
*
test
.
TestHashPool
bt
*
blockPoolTester
lock
sync
.
RWMutex
id
string
bt
*
blockPoolTester
td
int
id
string
currentBlock
int
td
int
t
*
testing
.
T
currentBlock
int
t
*
testing
.
T
}
}
// peerTester constructor takes hashPool and blockPool from the blockPoolTester
// peerTester constructor takes hashPool and blockPool from the blockPoolTester
...
@@ -222,6 +225,7 @@ func (self *peerTester) checkBlockHashesRequests(blocksHashesRequests ...int) {
...
@@ -222,6 +225,7 @@ func (self *peerTester) checkBlockHashesRequests(blocksHashesRequests ...int) {
// waiter function used by peer.serveBlocks
// waiter function used by peer.serveBlocks
// blocking until requests appear
// blocking until requests appear
// this mocks proper wire protocol behaviour
// since block requests are sent to any random peers
// since block requests are sent to any random peers
// block request map is shared between peers
// block request map is shared between peers
// times out after waitTimeout
// times out after waitTimeout
...
@@ -254,6 +258,7 @@ func (self *peerTester) waitBlocksRequests(blocksRequest ...int) {
...
@@ -254,6 +258,7 @@ func (self *peerTester) waitBlocksRequests(blocksRequest ...int) {
// waiter function used by peer.serveBlockHashes
// waiter function used by peer.serveBlockHashes
// blocking until requests appear
// blocking until requests appear
// this mocks proper wire protocol behaviour
// times out after a period
// times out after a period
func
(
self
*
peerTester
)
waitBlockHashesRequests
(
blocksHashesRequest
int
)
{
func
(
self
*
peerTester
)
waitBlockHashesRequests
(
blocksHashesRequest
int
)
{
timeout
:=
time
.
After
(
waitTimeout
)
timeout
:=
time
.
After
(
waitTimeout
)
...
@@ -299,6 +304,7 @@ func (self *peerTester) serveBlockHashes(indexes ...int) {
...
@@ -299,6 +304,7 @@ func (self *peerTester) serveBlockHashes(indexes ...int) {
self
.
sendBlockHashes
(
indexes
...
)
self
.
sendBlockHashes
(
indexes
...
)
}
}
// peer sends blockhashes not waiting for request
func
(
self
*
peerTester
)
sendBlockHashes
(
indexes
...
int
)
{
func
(
self
*
peerTester
)
sendBlockHashes
(
indexes
...
int
)
{
// fmt.Printf("adding block hashes %v\n", indexes)
// fmt.Printf("adding block hashes %v\n", indexes)
hashes
:=
self
.
hashPool
.
IndexesToHashes
(
indexes
)
hashes
:=
self
.
hashPool
.
IndexesToHashes
(
indexes
)
...
@@ -315,13 +321,14 @@ func (self *peerTester) sendBlockHashes(indexes ...int) {
...
@@ -315,13 +321,14 @@ func (self *peerTester) sendBlockHashes(indexes ...int) {
}
}
// peer sends blocks if and when there is a request
// peer sends blocks if and when there is a request
// (in the shared request store, not necessarily to a
person
)
// (in the shared request store, not necessarily to a
specific peer
)
func
(
self
*
peerTester
)
serveBlocks
(
indexes
...
int
)
{
func
(
self
*
peerTester
)
serveBlocks
(
indexes
...
int
)
{
// fmt.Printf("ready to serve blocks %v\n", indexes[1:])
// fmt.Printf("ready to serve blocks %v\n", indexes[1:])
self
.
waitBlocksRequests
(
indexes
[
1
:
]
...
)
self
.
waitBlocksRequests
(
indexes
[
1
:
]
...
)
self
.
sendBlocks
(
indexes
...
)
self
.
sendBlocks
(
indexes
...
)
}
}
// peer sends blocks not waiting for request
func
(
self
*
peerTester
)
sendBlocks
(
indexes
...
int
)
{
func
(
self
*
peerTester
)
sendBlocks
(
indexes
...
int
)
{
// fmt.Printf("adding blocks %v \n", indexes)
// fmt.Printf("adding blocks %v \n", indexes)
hashes
:=
self
.
hashPool
.
IndexesToHashes
(
indexes
)
hashes
:=
self
.
hashPool
.
IndexesToHashes
(
indexes
)
...
@@ -331,9 +338,10 @@ func (self *peerTester) sendBlocks(indexes ...int) {
...
@@ -331,9 +338,10 @@ func (self *peerTester) sendBlocks(indexes ...int) {
}
}
}
}
// peer callbacks
//
the 3 mock
peer callbacks
// -1 is special: not found (a hash never seen)
// records block hashes requests by the blockPool
// records block hashes requests by the blockPool
// -1 is special: not found (a hash never seen)
func
(
self
*
peerTester
)
requestBlockHashes
(
hash
common
.
Hash
)
error
{
func
(
self
*
peerTester
)
requestBlockHashes
(
hash
common
.
Hash
)
error
{
indexes
:=
self
.
hashPool
.
HashesToIndexes
([]
common
.
Hash
{
hash
})
indexes
:=
self
.
hashPool
.
HashesToIndexes
([]
common
.
Hash
{
hash
})
// fmt.Printf("[%s] block hash request %v %x\n", self.id, indexes[0], hash[:4])
// fmt.Printf("[%s] block hash request %v %x\n", self.id, indexes[0], hash[:4])
...
...
blockpool/config_test.go
View file @
a578db5d
...
@@ -23,12 +23,13 @@ func TestBlockPoolConfig(t *testing.T) {
...
@@ -23,12 +23,13 @@ func TestBlockPoolConfig(t *testing.T) {
test
.
CheckDuration
(
"BlocksTimeout"
,
c
.
BlocksTimeout
,
blocksTimeout
,
t
)
test
.
CheckDuration
(
"BlocksTimeout"
,
c
.
BlocksTimeout
,
blocksTimeout
,
t
)
test
.
CheckDuration
(
"IdleBestPeerTimeout"
,
c
.
IdleBestPeerTimeout
,
idleBestPeerTimeout
,
t
)
test
.
CheckDuration
(
"IdleBestPeerTimeout"
,
c
.
IdleBestPeerTimeout
,
idleBestPeerTimeout
,
t
)
test
.
CheckDuration
(
"PeerSuspensionInterval"
,
c
.
PeerSuspensionInterval
,
peerSuspensionInterval
,
t
)
test
.
CheckDuration
(
"PeerSuspensionInterval"
,
c
.
PeerSuspensionInterval
,
peerSuspensionInterval
,
t
)
test
.
CheckDuration
(
"StatusUpdateInterval"
,
c
.
StatusUpdateInterval
,
statusUpdateInterval
,
t
)
}
}
func
TestBlockPoolOverrideConfig
(
t
*
testing
.
T
)
{
func
TestBlockPoolOverrideConfig
(
t
*
testing
.
T
)
{
test
.
LogInit
()
test
.
LogInit
()
blockPool
:=
&
BlockPool
{
Config
:
&
Config
{},
chainEvents
:
&
event
.
TypeMux
{}}
blockPool
:=
&
BlockPool
{
Config
:
&
Config
{},
chainEvents
:
&
event
.
TypeMux
{}}
c
:=
&
Config
{
128
,
32
,
1
,
0
,
300
*
time
.
Millisecond
,
100
*
time
.
Millisecond
,
90
*
time
.
Second
,
0
,
30
*
time
.
Second
,
30
*
time
.
Second
}
c
:=
&
Config
{
128
,
32
,
1
,
0
,
300
*
time
.
Millisecond
,
100
*
time
.
Millisecond
,
90
*
time
.
Second
,
0
,
30
*
time
.
Second
,
30
*
time
.
Second
,
4
*
time
.
Second
}
blockPool
.
Config
=
c
blockPool
.
Config
=
c
blockPool
.
Start
()
blockPool
.
Start
()
...
@@ -42,4 +43,5 @@ func TestBlockPoolOverrideConfig(t *testing.T) {
...
@@ -42,4 +43,5 @@ func TestBlockPoolOverrideConfig(t *testing.T) {
test
.
CheckDuration
(
"BlocksTimeout"
,
c
.
BlocksTimeout
,
blocksTimeout
,
t
)
test
.
CheckDuration
(
"BlocksTimeout"
,
c
.
BlocksTimeout
,
blocksTimeout
,
t
)
test
.
CheckDuration
(
"IdleBestPeerTimeout"
,
c
.
IdleBestPeerTimeout
,
30
*
time
.
Second
,
t
)
test
.
CheckDuration
(
"IdleBestPeerTimeout"
,
c
.
IdleBestPeerTimeout
,
30
*
time
.
Second
,
t
)
test
.
CheckDuration
(
"PeerSuspensionInterval"
,
c
.
PeerSuspensionInterval
,
30
*
time
.
Second
,
t
)
test
.
CheckDuration
(
"PeerSuspensionInterval"
,
c
.
PeerSuspensionInterval
,
30
*
time
.
Second
,
t
)
test
.
CheckDuration
(
"StatusUpdateInterval"
,
c
.
StatusUpdateInterval
,
4
*
time
.
Second
,
t
)
}
}
blockpool/peers.go
View file @
a578db5d
...
@@ -11,6 +11,7 @@ import (
...
@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/errs"
"github.com/ethereum/go-ethereum/errs"
)
)
// the blockpool's model of a peer
type
peer
struct
{
type
peer
struct
{
lock
sync
.
RWMutex
lock
sync
.
RWMutex
...
@@ -104,12 +105,14 @@ func (self *peers) peerError(id string, code int, format string, params ...inter
...
@@ -104,12 +105,14 @@ func (self *peers) peerError(id string, code int, format string, params ...inter
self
.
addToBlacklist
(
id
)
self
.
addToBlacklist
(
id
)
}
}
// record time of offence in blacklist to implement suspension for PeerSuspensionInterval
func
(
self
*
peers
)
addToBlacklist
(
id
string
)
{
func
(
self
*
peers
)
addToBlacklist
(
id
string
)
{
self
.
lock
.
Lock
()
self
.
lock
.
Lock
()
defer
self
.
lock
.
Unlock
()
defer
self
.
lock
.
Unlock
()
self
.
blacklist
[
id
]
=
time
.
Now
()
self
.
blacklist
[
id
]
=
time
.
Now
()
}
}
// suspended checks if peer is still suspended
func
(
self
*
peers
)
suspended
(
id
string
)
(
s
bool
)
{
func
(
self
*
peers
)
suspended
(
id
string
)
(
s
bool
)
{
self
.
lock
.
Lock
()
self
.
lock
.
Lock
()
defer
self
.
lock
.
Unlock
()
defer
self
.
lock
.
Unlock
()
...
@@ -160,8 +163,8 @@ func (self *peer) setChainInfoFromBlock(block *types.Block) {
...
@@ -160,8 +163,8 @@ func (self *peer) setChainInfoFromBlock(block *types.Block) {
}()
}()
}
}
// distribute block request among known peers
func
(
self
*
peers
)
requestBlocks
(
attempts
int
,
hashes
[]
common
.
Hash
)
{
func
(
self
*
peers
)
requestBlocks
(
attempts
int
,
hashes
[]
common
.
Hash
)
{
// distribute block request among known peers
self
.
lock
.
RLock
()
self
.
lock
.
RLock
()
defer
self
.
lock
.
RUnlock
()
defer
self
.
lock
.
RUnlock
()
peerCount
:=
len
(
self
.
peers
)
peerCount
:=
len
(
self
.
peers
)
...
@@ -196,7 +199,9 @@ func (self *peers) requestBlocks(attempts int, hashes []common.Hash) {
...
@@ -196,7 +199,9 @@ func (self *peers) requestBlocks(attempts int, hashes []common.Hash) {
}
}
// addPeer implements the logic for blockpool.AddPeer
// addPeer implements the logic for blockpool.AddPeer
// returns true iff peer is promoted as best peer in the pool
// returns 2 bool values
// 1. true iff peer is promoted as best peer in the pool
// 2. true iff peer is still suspended
func
(
self
*
peers
)
addPeer
(
func
(
self
*
peers
)
addPeer
(
td
*
big
.
Int
,
td
*
big
.
Int
,
currentBlockHash
common
.
Hash
,
currentBlockHash
common
.
Hash
,
...
@@ -214,10 +219,13 @@ func (self *peers) addPeer(
...
@@ -214,10 +219,13 @@ func (self *peers) addPeer(
self
.
lock
.
Lock
()
self
.
lock
.
Lock
()
p
,
found
:=
self
.
peers
[
id
]
p
,
found
:=
self
.
peers
[
id
]
if
found
{
if
found
{
// when called on an already connected peer, it means a newBlockMsg is received
// peer head info is updated
if
p
.
currentBlockHash
!=
currentBlockHash
{
if
p
.
currentBlockHash
!=
currentBlockHash
{
previousBlockHash
=
p
.
currentBlockHash
previousBlockHash
=
p
.
currentBlockHash
plog
.
Debugf
(
"addPeer: Update peer <%s> with td %v and current block %s (was %v)"
,
id
,
td
,
hex
(
currentBlockHash
),
hex
(
previousBlockHash
))
plog
.
Debugf
(
"addPeer: Update peer <%s> with td %v and current block %s (was %v)"
,
id
,
td
,
hex
(
currentBlockHash
),
hex
(
previousBlockHash
))
p
.
setChainInfo
(
td
,
currentBlockHash
)
p
.
setChainInfo
(
td
,
currentBlockHash
)
self
.
status
.
lock
.
Lock
()
self
.
status
.
lock
.
Lock
()
self
.
status
.
values
.
NewBlocks
++
self
.
status
.
values
.
NewBlocks
++
self
.
status
.
lock
.
Unlock
()
self
.
status
.
lock
.
Unlock
()
...
@@ -235,7 +243,7 @@ func (self *peers) addPeer(
...
@@ -235,7 +243,7 @@ func (self *peers) addPeer(
}
}
self
.
lock
.
Unlock
()
self
.
lock
.
Unlock
()
// check
peer current head
// check
if peer's current head block is known
if
self
.
bp
.
hasBlock
(
currentBlockHash
)
{
if
self
.
bp
.
hasBlock
(
currentBlockHash
)
{
// peer not ahead
// peer not ahead
plog
.
Debugf
(
"addPeer: peer <%v> with td %v and current block %s is behind"
,
id
,
td
,
hex
(
currentBlockHash
))
plog
.
Debugf
(
"addPeer: peer <%v> with td %v and current block %s is behind"
,
id
,
td
,
hex
(
currentBlockHash
))
...
@@ -255,6 +263,7 @@ func (self *peers) addPeer(
...
@@ -255,6 +263,7 @@ func (self *peers) addPeer(
}
}
best
=
true
best
=
true
}
else
{
}
else
{
// baseline is our own TD
currentTD
:=
self
.
bp
.
getTD
()
currentTD
:=
self
.
bp
.
getTD
()
if
self
.
best
!=
nil
{
if
self
.
best
!=
nil
{
currentTD
=
self
.
best
.
td
currentTD
=
self
.
best
.
td
...
@@ -314,6 +323,7 @@ func (self *peers) removePeer(id string) {
...
@@ -314,6 +323,7 @@ func (self *peers) removePeer(id string) {
func
(
self
*
BlockPool
)
switchPeer
(
oldp
,
newp
*
peer
)
{
func
(
self
*
BlockPool
)
switchPeer
(
oldp
,
newp
*
peer
)
{
// first quit AddBlockHashes, requestHeadSection and activateChain
// first quit AddBlockHashes, requestHeadSection and activateChain
// by closing the old peer's switchC channel
if
oldp
!=
nil
{
if
oldp
!=
nil
{
plog
.
DebugDetailf
(
"<%s> quit peer processes"
,
oldp
.
id
)
plog
.
DebugDetailf
(
"<%s> quit peer processes"
,
oldp
.
id
)
close
(
oldp
.
switchC
)
close
(
oldp
.
switchC
)
...
@@ -366,11 +376,12 @@ func (self *BlockPool) switchPeer(oldp, newp *peer) {
...
@@ -366,11 +376,12 @@ func (self *BlockPool) switchPeer(oldp, newp *peer) {
// newp activating section process changes the quit channel for this reason
// newp activating section process changes the quit channel for this reason
if
oldp
!=
nil
{
if
oldp
!=
nil
{
plog
.
DebugDetailf
(
"<%s> quit section processes"
,
oldp
.
id
)
plog
.
DebugDetailf
(
"<%s> quit section processes"
,
oldp
.
id
)
//
close
(
oldp
.
idleC
)
close
(
oldp
.
idleC
)
}
}
}
}
// getPeer looks up peer by id, returns peer and a bool value
// that is true iff peer is current best peer
func
(
self
*
peers
)
getPeer
(
id
string
)
(
p
*
peer
,
best
bool
)
{
func
(
self
*
peers
)
getPeer
(
id
string
)
(
p
*
peer
,
best
bool
)
{
self
.
lock
.
RLock
()
self
.
lock
.
RLock
()
defer
self
.
lock
.
RUnlock
()
defer
self
.
lock
.
RUnlock
()
...
@@ -381,6 +392,8 @@ func (self *peers) getPeer(id string) (p *peer, best bool) {
...
@@ -381,6 +392,8 @@ func (self *peers) getPeer(id string) (p *peer, best bool) {
return
return
}
}
// head section process
func
(
self
*
peer
)
handleSection
(
sec
*
section
)
{
func
(
self
*
peer
)
handleSection
(
sec
*
section
)
{
self
.
lock
.
Lock
()
self
.
lock
.
Lock
()
defer
self
.
lock
.
Unlock
()
defer
self
.
lock
.
Unlock
()
...
@@ -516,7 +529,7 @@ func (self *peer) run() {
...
@@ -516,7 +529,7 @@ func (self *peer) run() {
LOOP
:
LOOP
:
for
{
for
{
select
{
select
{
// to minitor section process behaviou
// to minitor section process behaviou
r
case
<-
ping
.
C
:
case
<-
ping
.
C
:
plog
.
Debugf
(
"HeadSection: <%s> section with head %s, idle: %v"
,
self
.
id
,
hex
(
self
.
currentBlockHash
),
self
.
idle
)
plog
.
Debugf
(
"HeadSection: <%s> section with head %s, idle: %v"
,
self
.
id
,
hex
(
self
.
currentBlockHash
),
self
.
idle
)
...
...
blockpool/peers_test.go
View file @
a578db5d
...
@@ -142,3 +142,47 @@ func TestAddPeer(t *testing.T) {
...
@@ -142,3 +142,47 @@ func TestAddPeer(t *testing.T) {
blockPool
.
Stop
()
blockPool
.
Stop
()
}
}
func
TestPeerPromotionByOptionalTdOnBlock
(
t
*
testing
.
T
)
{
test
.
LogInit
()
_
,
blockPool
,
blockPoolTester
:=
newTestBlockPool
(
t
)
blockPoolTester
.
blockChain
[
0
]
=
nil
blockPoolTester
.
initRefBlockChain
(
4
)
peer0
:=
blockPoolTester
.
newPeer
(
"peer0"
,
2
,
2
)
peer1
:=
blockPoolTester
.
newPeer
(
"peer1"
,
1
,
1
)
peer2
:=
blockPoolTester
.
newPeer
(
"peer2"
,
4
,
4
)
blockPool
.
Start
()
blockPoolTester
.
tds
=
make
(
map
[
int
]
int
)
blockPoolTester
.
tds
[
3
]
=
3
// pool
peer0
.
AddPeer
()
peer0
.
serveBlocks
(
1
,
2
)
best
:=
peer1
.
AddPeer
()
// this tests that peer1 is not promoted over peer0 yet
if
best
{
t
.
Errorf
(
"peer1 (TD=1) should not be set as best"
)
}
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
.
Bytes
(
hashes
[
1
]),
ParentHeaderHash
:
common
.
Bytes
(
hashes
[
0
]),
Td
:
common
.
Big3
,
},
"peer1"
)
blockPool
.
RemovePeer
(
"peer2"
)
if
blockPool
.
peers
.
best
.
id
!=
"peer1"
{
t
.
Errorf
(
"peer1 (TD=3) should be set as best"
)
}
peer1
.
serveBlocks
(
0
,
1
,
2
)
blockPool
.
Wait
(
waitTimeout
)
blockPool
.
Stop
()
blockPoolTester
.
refBlockChain
[
4
]
=
[]
int
{}
blockPoolTester
.
checkBlockChain
(
blockPoolTester
.
refBlockChain
)
}
blockpool/test/hash_pool.go
View file @
a578db5d
...
@@ -7,8 +7,12 @@ import (
...
@@ -7,8 +7,12 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
)
)
// test helpers
// hashPool is a test helper, that allows random hashes to be referred to by integers
// TODO: move into common test helper package (see p2p/crypto etc.)
type
TestHashPool
struct
{
intToHash
hashToInt
lock
sync
.
Mutex
}
func
NewHashPool
()
*
TestHashPool
{
func
NewHashPool
()
*
TestHashPool
{
return
&
TestHashPool
{
intToHash
:
make
(
intToHash
),
hashToInt
:
make
(
hashToInt
)}
return
&
TestHashPool
{
intToHash
:
make
(
intToHash
),
hashToInt
:
make
(
hashToInt
)}
...
@@ -18,13 +22,6 @@ type intToHash map[int]common.Hash
...
@@ -18,13 +22,6 @@ type intToHash map[int]common.Hash
type
hashToInt
map
[
common
.
Hash
]
int
type
hashToInt
map
[
common
.
Hash
]
int
// hashPool is a test helper, that allows random hashes to be referred to by integers
type
TestHashPool
struct
{
intToHash
hashToInt
lock
sync
.
Mutex
}
func
newHash
(
i
int
)
common
.
Hash
{
func
newHash
(
i
int
)
common
.
Hash
{
return
common
.
BytesToHash
(
crypto
.
Sha3
([]
byte
(
string
(
i
))))
return
common
.
BytesToHash
(
crypto
.
Sha3
([]
byte
(
string
(
i
))))
}
}
...
...
blockpool/test/logger.go
View file @
a578db5d
...
@@ -9,6 +9,8 @@ import (
...
@@ -9,6 +9,8 @@ import (
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger"
)
)
// logging in tests
var
once
sync
.
Once
var
once
sync
.
Once
/* usage:
/* usage:
...
...
blockpool/test/util.go
View file @
a578db5d
...
@@ -6,6 +6,8 @@ import (
...
@@ -6,6 +6,8 @@ import (
"time"
"time"
)
)
// miscellaneous test helpers
func
CheckInt
(
name
string
,
got
int
,
expected
int
,
t
*
testing
.
T
)
(
err
error
)
{
func
CheckInt
(
name
string
,
got
int
,
expected
int
,
t
*
testing
.
T
)
(
err
error
)
{
if
got
!=
expected
{
if
got
!=
expected
{
t
.
Errorf
(
"status for %v incorrect. expected %v, got %v"
,
name
,
expected
,
got
)
t
.
Errorf
(
"status for %v incorrect. expected %v, got %v"
,
name
,
expected
,
got
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment