Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
63c6cedb
G
go-ethereum
项目概览
whqwjb
/
go-ethereum
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
go-ethereum
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
63c6cedb
编写于
6月 08, 2015
作者:
P
Péter Szilágyi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
eth/downloader: cap the hash ban set, add test for it
上级
4b2dd447
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
64 addition
and
12 deletion
+64
-12
eth/downloader/downloader.go
eth/downloader/downloader.go
+16
-7
eth/downloader/downloader_test.go
eth/downloader/downloader_test.go
+43
-0
eth/downloader/peer.go
eth/downloader/peer.go
+1
-1
eth/downloader/queue.go
eth/downloader/queue.go
+1
-1
eth/handler.go
eth/handler.go
+2
-2
eth/peer.go
eth/peer.go
+1
-1
未找到文件。
eth/downloader/downloader.go
浏览文件 @
63c6cedb
...
...
@@ -17,18 +17,17 @@ import (
"gopkg.in/fatih/set.v0"
)
const
(
var
(
MinHashFetch
=
512
// Minimum amount of hashes to not consider a peer stalling
MaxHashFetch
=
2048
// Amount of hashes to be fetched per retrieval request
MaxBlockFetch
=
128
// Amount of blocks to be fetched per retrieval request
hashTTL
=
5
*
time
.
Second
// Time it takes for a hash request to time out
)
var
(
hashTTL
=
5
*
time
.
Second
// Time it takes for a hash request to time out
blockSoftTTL
=
3
*
time
.
Second
// Request completion threshold for increasing or decreasing a peer's bandwidth
blockHardTTL
=
3
*
blockSoftTTL
// Maximum time allowance before a block request is considered expired
crossCheckCycle
=
time
.
Second
// Period after which to check for expired cross checks
maxBannedHashes
=
4096
// Number of bannable hashes before phasing old ones out
)
var
(
...
...
@@ -602,9 +601,19 @@ func (d *Downloader) banBlocks(peerId string, head common.Hash) error {
}
index
++
}
// Ban the head hash and phase out any excess
d
.
banned
.
Add
(
blocks
[
index
]
.
Hash
())
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Banned %d blocks from: %s
\n
"
,
index
+
1
,
peerId
)
for
d
.
banned
.
Size
()
>
maxBannedHashes
{
d
.
banned
.
Each
(
func
(
item
interface
{})
bool
{
// Skip any hard coded bans
if
core
.
BadHashes
[
item
.
(
common
.
Hash
)]
{
return
true
}
d
.
banned
.
Remove
(
item
)
return
false
})
}
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Banned %d blocks from: %s"
,
index
+
1
,
peerId
)
return
nil
}
}
...
...
eth/downloader/downloader_test.go
浏览文件 @
63c6cedb
...
...
@@ -7,6 +7,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
...
...
@@ -559,3 +560,45 @@ func TestBannedChainStarvationAttack(t *testing.T) {
banned
=
bans
}
}
// Tests that if a peer sends excessively many/large invalid chains that are
// gradually banned, it will have an upper limit on the consumed memory and also
// the origin bad hashes will not be evacuated.
func
TestBannedChainMemoryExhaustionAttack
(
t
*
testing
.
T
)
{
// Reduce the test size a bit
MaxBlockFetch
=
4
maxBannedHashes
=
256
// Construct a banned chain with more chunks than the ban limit
hashes
:=
createHashes
(
0
,
maxBannedHashes
*
MaxBlockFetch
)
hashes
[
len
(
hashes
)
-
1
]
=
bannedHash
// weird index to have non multiple of ban chunk size
blocks
:=
createBlocksFromHashes
(
hashes
)
// Create the tester and ban the selected hash
tester
:=
newTester
(
t
,
hashes
,
blocks
)
tester
.
downloader
.
banned
.
Add
(
bannedHash
)
// Iteratively try to sync, and verify that the banned hash list grows until
// the head of the invalid chain is blocked too.
tester
.
newPeer
(
"attack"
,
big
.
NewInt
(
10000
),
hashes
[
0
])
for
{
// Try to sync with the attacker, check hash chain failure
if
_
,
err
:=
tester
.
syncTake
(
"attack"
,
hashes
[
0
]);
err
!=
ErrInvalidChain
{
t
.
Fatalf
(
"synchronisation error mismatch: have %v, want %v"
,
err
,
ErrInvalidChain
)
}
// Short circuit if the entire chain was banned
if
tester
.
downloader
.
banned
.
Has
(
hashes
[
0
])
{
break
}
// Otherwise ensure we never exceed the memory allowance and the hard coded bans are untouched
if
bans
:=
tester
.
downloader
.
banned
.
Size
();
bans
>
maxBannedHashes
{
t
.
Fatalf
(
"ban cap exceeded: have %v, want max %v"
,
bans
,
maxBannedHashes
)
}
for
hash
,
_
:=
range
core
.
BadHashes
{
if
!
tester
.
downloader
.
banned
.
Has
(
hash
)
{
t
.
Fatalf
(
"hard coded ban evacuated: %x"
,
hash
)
}
}
}
}
eth/downloader/peer.go
浏览文件 @
63c6cedb
...
...
@@ -94,7 +94,7 @@ func (p *peer) SetIdle() {
for
{
// Calculate the new download bandwidth allowance
prev
:=
atomic
.
LoadInt32
(
&
p
.
capacity
)
next
:=
int32
(
math
.
Max
(
1
,
math
.
Min
(
MaxBlockFetch
,
float64
(
prev
)
*
scale
)))
next
:=
int32
(
math
.
Max
(
1
,
math
.
Min
(
float64
(
MaxBlockFetch
)
,
float64
(
prev
)
*
scale
)))
// Try to update the old value
if
atomic
.
CompareAndSwapInt32
(
&
p
.
capacity
,
prev
,
next
)
{
...
...
eth/downloader/queue.go
浏览文件 @
63c6cedb
...
...
@@ -16,7 +16,7 @@ import (
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
)
const
(
var
(
blockCacheLimit
=
8
*
MaxBlockFetch
// Maximum number of blocks to cache before throttling the download
)
...
...
eth/handler.go
浏览文件 @
63c6cedb
...
...
@@ -213,8 +213,8 @@ func (self *ProtocolManager) handleMsg(p *peer) error {
return
errResp
(
ErrDecode
,
"->msg %v: %v"
,
msg
,
err
)
}
if
request
.
Amount
>
downloader
.
MaxHashFetch
{
request
.
Amount
=
downloader
.
MaxHashFetch
if
request
.
Amount
>
uint64
(
downloader
.
MaxHashFetch
)
{
request
.
Amount
=
uint64
(
downloader
.
MaxHashFetch
)
}
hashes
:=
self
.
chainman
.
GetBlockHashesFromHash
(
request
.
Hash
,
request
.
Amount
)
...
...
eth/peer.go
浏览文件 @
63c6cedb
...
...
@@ -102,7 +102,7 @@ func (p *peer) sendTransaction(tx *types.Transaction) error {
func
(
p
*
peer
)
requestHashes
(
from
common
.
Hash
)
error
{
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"[%s] fetching hashes (%d) %x...
\n
"
,
p
.
id
,
downloader
.
MaxHashFetch
,
from
[
:
4
])
return
p2p
.
Send
(
p
.
rw
,
GetBlockHashesMsg
,
getBlockHashesMsgData
{
from
,
downloader
.
MaxHashFetch
})
return
p2p
.
Send
(
p
.
rw
,
GetBlockHashesMsg
,
getBlockHashesMsgData
{
from
,
uint64
(
downloader
.
MaxHashFetch
)
})
}
func
(
p
*
peer
)
requestBlocks
(
hashes
[]
common
.
Hash
)
error
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录