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
e8b22b92
Commit
e8b22b92
authored
May 21, 2015
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eth/downloader: prevent a peer from dripping bad hashes
parent
79042223
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
36 additions
and
9 deletions
+36
-9
downloader.go
eth/downloader/downloader.go
+12
-8
downloader_test.go
eth/downloader/downloader_test.go
+24
-1
No files found.
eth/downloader/downloader.go
View file @
e8b22b92
...
@@ -28,10 +28,11 @@ var (
...
@@ -28,10 +28,11 @@ var (
)
)
var
(
var
(
errLowTd
=
errors
.
New
(
"peer
'
s TD is too low"
)
errLowTd
=
errors
.
New
(
"peers TD is too low"
)
ErrBusy
=
errors
.
New
(
"busy"
)
ErrBusy
=
errors
.
New
(
"busy"
)
errUnknownPeer
=
errors
.
New
(
"peer
'
s unknown or unhealthy"
)
errUnknownPeer
=
errors
.
New
(
"peer
i
s unknown or unhealthy"
)
ErrBadPeer
=
errors
.
New
(
"action from bad peer ignored"
)
ErrBadPeer
=
errors
.
New
(
"action from bad peer ignored"
)
ErrStallingPeer
=
errors
.
New
(
"peer is stalling"
)
errNoPeers
=
errors
.
New
(
"no peers to keep download active"
)
errNoPeers
=
errors
.
New
(
"no peers to keep download active"
)
ErrPendingQueue
=
errors
.
New
(
"pending items in queue"
)
ErrPendingQueue
=
errors
.
New
(
"pending items in queue"
)
ErrTimeout
=
errors
.
New
(
"timeout"
)
ErrTimeout
=
errors
.
New
(
"timeout"
)
...
@@ -283,15 +284,18 @@ func (d *Downloader) fetchHashes(p *peer, h common.Hash) error {
...
@@ -283,15 +284,18 @@ func (d *Downloader) fetchHashes(p *peer, h common.Hash) error {
return
ErrBadPeer
return
ErrBadPeer
}
}
if
!
done
{
if
!
done
{
// Check that the peer is not stalling the sync
if
len
(
inserts
)
<
maxHashFetch
{
return
ErrStallingPeer
}
// Try and fetch a random block to verify the hash batch
// Try and fetch a random block to verify the hash batch
// Skip the last hash as the cross check races with the next hash fetch
// Skip the last hash as the cross check races with the next hash fetch
if
len
(
inserts
)
>
1
{
cross
:=
inserts
[
rand
.
Intn
(
len
(
inserts
)
-
1
)]
cross
:=
inserts
[
rand
.
Intn
(
len
(
inserts
)
-
1
)]
glog
.
V
(
logger
.
Detail
)
.
Infof
(
"Cross checking (%s) with %x"
,
active
.
id
,
cross
)
glog
.
V
(
logger
.
Detail
)
.
Infof
(
"Cross checking (%s) with %x"
,
active
.
id
,
cross
)
d
.
checks
[
cross
]
=
time
.
Now
()
.
Add
(
blockTTL
)
active
.
getBlocks
([]
common
.
Hash
{
cross
})
d
.
checks
[
cross
]
=
time
.
Now
()
.
Add
(
blockTTL
)
active
.
getBlocks
([]
common
.
Hash
{
cross
})
}
// Also fetch a fresh
// Also fetch a fresh
active
.
getHashes
(
head
)
active
.
getHashes
(
head
)
continue
continue
...
...
eth/downloader/downloader_test.go
View file @
e8b22b92
...
@@ -53,6 +53,8 @@ type downloadTester struct {
...
@@ -53,6 +53,8 @@ type downloadTester struct {
blocks
map
[
common
.
Hash
]
*
types
.
Block
// Blocks associated with the hashes
blocks
map
[
common
.
Hash
]
*
types
.
Block
// Blocks associated with the hashes
chain
[]
common
.
Hash
// Block-chain being constructed
chain
[]
common
.
Hash
// Block-chain being constructed
maxHashFetch
int
// Overrides the maximum number of retrieved hashes
t
*
testing
.
T
t
*
testing
.
T
pcount
int
pcount
int
done
chan
bool
done
chan
bool
...
@@ -133,8 +135,12 @@ func (dl *downloadTester) getBlock(hash common.Hash) *types.Block {
...
@@ -133,8 +135,12 @@ func (dl *downloadTester) getBlock(hash common.Hash) *types.Block {
// getHashes retrieves a batch of hashes for reconstructing the chain.
// getHashes retrieves a batch of hashes for reconstructing the chain.
func
(
dl
*
downloadTester
)
getHashes
(
head
common
.
Hash
)
error
{
func
(
dl
*
downloadTester
)
getHashes
(
head
common
.
Hash
)
error
{
limit
:=
maxHashFetch
if
dl
.
maxHashFetch
>
0
{
limit
=
dl
.
maxHashFetch
}
// Gather the next batch of hashes
// Gather the next batch of hashes
hashes
:=
make
([]
common
.
Hash
,
0
,
maxHashFetch
)
hashes
:=
make
([]
common
.
Hash
,
0
,
limit
)
for
i
,
hash
:=
range
dl
.
hashes
{
for
i
,
hash
:=
range
dl
.
hashes
{
if
hash
==
head
{
if
hash
==
head
{
i
++
i
++
...
@@ -469,6 +475,23 @@ func TestMadeupHashChainAttack(t *testing.T) {
...
@@ -469,6 +475,23 @@ func TestMadeupHashChainAttack(t *testing.T) {
}
}
}
}
// Tests that if a malicious peer makes up a random hash chain, and tries to push
// indefinitely, one hash at a time, it actually gets caught with it. The reason
// this is separate from the classical made up chain attack is that sending hashes
// one by one prevents reliable block/parent verification.
func
TestMadeupHashChainDrippingAttack
(
t
*
testing
.
T
)
{
// Create a random chain of hashes to drip
hashes
:=
createHashes
(
0
,
16
*
blockCacheLimit
)
tester
:=
newTester
(
t
,
hashes
,
nil
)
// Try and sync with the attacker, one hash at a time
tester
.
maxHashFetch
=
1
tester
.
newPeer
(
"attack"
,
big
.
NewInt
(
10000
),
hashes
[
0
])
if
_
,
err
:=
tester
.
syncTake
(
"attack"
,
hashes
[
0
]);
err
!=
ErrStallingPeer
{
t
.
Fatalf
(
"synchronisation error mismatch: have %v, want %v"
,
err
,
ErrStallingPeer
)
}
}
// Tests that if a malicious peer makes up a random block chain, and tried to
// Tests that if a malicious peer makes up a random block chain, and tried to
// push indefinitely, it actually gets caught with it.
// push indefinitely, it actually gets caught with it.
func
TestMadeupBlockChainAttack
(
t
*
testing
.
T
)
{
func
TestMadeupBlockChainAttack
(
t
*
testing
.
T
)
{
...
...
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