Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
9e011ff1
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,发现更多精彩内容 >>
提交
9e011ff1
编写于
12月 29, 2015
作者:
P
Péter Szilágyi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
core, eth/downloader: ensure state presence in ancestor lookup
上级
36137623
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
85 addition
and
61 deletion
+85
-61
core/blockchain.go
core/blockchain.go
+13
-0
core/state/statedb.go
core/state/statedb.go
+0
-1
eth/downloader/downloader.go
eth/downloader/downloader.go
+52
-52
eth/downloader/downloader_test.go
eth/downloader/downloader_test.go
+14
-3
eth/downloader/types.go
eth/downloader/types.go
+2
-2
eth/handler.go
eth/handler.go
+4
-3
未找到文件。
core/blockchain.go
浏览文件 @
9e011ff1
...
...
@@ -587,6 +587,19 @@ func (bc *BlockChain) HasBlock(hash common.Hash) bool {
return
bc
.
GetBlock
(
hash
)
!=
nil
}
// HasBlockAndState checks if a block and associated state trie is fully present
// in the database or not, caching it if present.
func
(
bc
*
BlockChain
)
HasBlockAndState
(
hash
common
.
Hash
)
bool
{
// Check first that the block itself is known
block
:=
bc
.
GetBlock
(
hash
)
if
block
==
nil
{
return
false
}
// Ensure the associated state is also present
_
,
err
:=
state
.
New
(
block
.
Root
(),
bc
.
chainDb
)
return
err
==
nil
}
// GetBlock retrieves a block from the database by hash, caching it if found.
func
(
self
*
BlockChain
)
GetBlock
(
hash
common
.
Hash
)
*
types
.
Block
{
// Short circuit if the block's already in the cache, retrieve otherwise
...
...
core/state/statedb.go
浏览文件 @
9e011ff1
...
...
@@ -57,7 +57,6 @@ type StateDB struct {
func
New
(
root
common
.
Hash
,
db
ethdb
.
Database
)
(
*
StateDB
,
error
)
{
tr
,
err
:=
trie
.
NewSecure
(
root
,
db
)
if
err
!=
nil
{
glog
.
Errorf
(
"can't create state trie with root %x: %v"
,
root
[
:
],
err
)
return
nil
,
err
}
return
&
StateDB
{
...
...
eth/downloader/downloader.go
浏览文件 @
9e011ff1
...
...
@@ -112,20 +112,20 @@ type Downloader struct {
syncStatsLock
sync
.
RWMutex
// Lock protecting the sync stats fields
// Callbacks
hasHeader
headerCheckFn
// Checks if a header is present in the chain
hasBlock
blockCheckFn
// Checks if a block
is present in the chain
getHeader
headerRetrievalFn
// Retrieves a header from the chain
getBlock
blockRetrievalFn
// Retrieves a block from the chain
headHeader
headHeaderRetrievalFn
// Retrieves the head header from the chain
headBlock
headBlockRetrievalFn
// Retrieves the head block from the chain
headFastBlock
headFastBlockRetrievalFn
// Retrieves the head fast-sync block from the chain
commitHeadBlock
headBlockCommitterFn
// Commits a manually assembled block as the chain head
getTd
tdRetrievalFn
// Retrieves the TD of a block from the chain
insertHeaders
headerChainInsertFn
// Injects a batch of headers into the chain
insertBlocks
blockChainInsertFn
// Injects a batch of blocks into the chain
insertReceipts
receiptChainInsertFn
// Injects a batch of blocks and their receipts into the chain
rollback
chainRollbackFn
// Removes a batch of recently added chain links
dropPeer
peerDropFn
// Drops a peer for misbehaving
hasHeader
headerCheckFn
// Checks if a header is present in the chain
hasBlock
AndState
blockAndStateCheckFn
// Checks if a block and associated state
is present in the chain
getHeader
headerRetrievalFn
// Retrieves a header from the chain
getBlock
blockRetrievalFn
// Retrieves a block from the chain
headHeader
headHeaderRetrievalFn
// Retrieves the head header from the chain
headBlock
headBlockRetrievalFn
// Retrieves the head block from the chain
headFastBlock
headFastBlockRetrievalFn
// Retrieves the head fast-sync block from the chain
commitHeadBlock
headBlockCommitterFn
// Commits a manually assembled block as the chain head
getTd
tdRetrievalFn
// Retrieves the TD of a block from the chain
insertHeaders
headerChainInsertFn
// Injects a batch of headers into the chain
insertBlocks
blockChainInsertFn
// Injects a batch of blocks into the chain
insertReceipts
receiptChainInsertFn
// Injects a batch of blocks and their receipts into the chain
rollback
chainRollbackFn
// Removes a batch of recently added chain links
dropPeer
peerDropFn
// Drops a peer for misbehaving
// Status
synchroniseMock
func
(
id
string
,
hash
common
.
Hash
)
error
// Replacement for synchronise during testing
...
...
@@ -156,41 +156,41 @@ type Downloader struct {
}
// New creates a new downloader to fetch hashes and blocks from remote peers.
func
New
(
stateDb
ethdb
.
Database
,
mux
*
event
.
TypeMux
,
hasHeader
headerCheckFn
,
hasBlock
blockCheckFn
,
getHeader
headerRetrieval
Fn
,
get
Block
blockRetrievalFn
,
headHeader
headHeaderRetrievalFn
,
headBlock
headBlockRetrievalFn
,
headFastBlock
headFast
BlockRetrievalFn
,
commitHeadBlock
headBlockCommitterFn
,
getTd
tdRetrievalFn
,
insertHeaders
headerChainInsertFn
,
insertBlocks
block
ChainInsertFn
,
insertReceipts
receiptChainInsertFn
,
rollback
chainRollbackFn
,
dropPeer
peerDropFn
)
*
Downloader
{
func
New
(
stateDb
ethdb
.
Database
,
mux
*
event
.
TypeMux
,
hasHeader
headerCheckFn
,
hasBlock
AndState
blockAndStateCheck
Fn
,
get
Header
headerRetrievalFn
,
getBlock
blockRetrievalFn
,
headHeader
headHeaderRetrievalFn
,
headBlock
head
BlockRetrievalFn
,
headFastBlock
headFastBlockRetrievalFn
,
commitHeadBlock
headBlockCommitterFn
,
getTd
tdRetrievalFn
,
insertHeaders
header
ChainInsertFn
,
insert
Blocks
blockChainInsertFn
,
insert
Receipts
receiptChainInsertFn
,
rollback
chainRollbackFn
,
dropPeer
peerDropFn
)
*
Downloader
{
return
&
Downloader
{
mode
:
FullSync
,
mux
:
mux
,
queue
:
newQueue
(
stateDb
),
peers
:
newPeerSet
(),
hasHeader
:
hasHeader
,
hasBlock
:
hasBlock
,
getHeader
:
getHeader
,
getBlock
:
getBlock
,
headHeader
:
headHeader
,
headBlock
:
headBlock
,
headFastBlock
:
headFastBlock
,
commitHeadBlock
:
commitHeadBlock
,
getTd
:
getTd
,
insertHeaders
:
insertHeaders
,
insertBlocks
:
insertBlocks
,
insertReceipts
:
insertReceipts
,
rollback
:
rollback
,
dropPeer
:
dropPeer
,
newPeerCh
:
make
(
chan
*
peer
,
1
),
hashCh
:
make
(
chan
dataPack
,
1
),
blockCh
:
make
(
chan
dataPack
,
1
),
headerCh
:
make
(
chan
dataPack
,
1
),
bodyCh
:
make
(
chan
dataPack
,
1
),
receiptCh
:
make
(
chan
dataPack
,
1
),
stateCh
:
make
(
chan
dataPack
,
1
),
blockWakeCh
:
make
(
chan
bool
,
1
),
bodyWakeCh
:
make
(
chan
bool
,
1
),
receiptWakeCh
:
make
(
chan
bool
,
1
),
stateWakeCh
:
make
(
chan
bool
,
1
),
mode
:
FullSync
,
mux
:
mux
,
queue
:
newQueue
(
stateDb
),
peers
:
newPeerSet
(),
hasHeader
:
hasHeader
,
hasBlock
AndState
:
hasBlockAndState
,
getHeader
:
getHeader
,
getBlock
:
getBlock
,
headHeader
:
headHeader
,
headBlock
:
headBlock
,
headFastBlock
:
headFastBlock
,
commitHeadBlock
:
commitHeadBlock
,
getTd
:
getTd
,
insertHeaders
:
insertHeaders
,
insertBlocks
:
insertBlocks
,
insertReceipts
:
insertReceipts
,
rollback
:
rollback
,
dropPeer
:
dropPeer
,
newPeerCh
:
make
(
chan
*
peer
,
1
),
hashCh
:
make
(
chan
dataPack
,
1
),
blockCh
:
make
(
chan
dataPack
,
1
),
headerCh
:
make
(
chan
dataPack
,
1
),
bodyCh
:
make
(
chan
dataPack
,
1
),
receiptCh
:
make
(
chan
dataPack
,
1
),
stateCh
:
make
(
chan
dataPack
,
1
),
blockWakeCh
:
make
(
chan
bool
,
1
),
bodyWakeCh
:
make
(
chan
bool
,
1
),
receiptWakeCh
:
make
(
chan
bool
,
1
),
stateWakeCh
:
make
(
chan
bool
,
1
),
}
}
...
...
@@ -564,7 +564,7 @@ func (d *Downloader) findAncestor61(p *peer) (uint64, error) {
// Check if a common ancestor was found
finished
=
true
for
i
:=
len
(
hashes
)
-
1
;
i
>=
0
;
i
--
{
if
d
.
hasBlock
(
hashes
[
i
])
{
if
d
.
hasBlock
AndState
(
hashes
[
i
])
{
number
,
hash
=
uint64
(
from
)
+
uint64
(
i
),
hashes
[
i
]
break
}
...
...
@@ -620,11 +620,11 @@ func (d *Downloader) findAncestor61(p *peer) (uint64, error) {
arrived
=
true
// Modify the search interval based on the response
block
:=
d
.
getBlock
(
hashes
[
0
])
if
block
==
nil
{
if
!
d
.
hasBlockAndState
(
hashes
[
0
])
{
end
=
check
break
}
block
:=
d
.
getBlock
(
hashes
[
0
])
// this doesn't check state, hence the above explicit check
if
block
.
NumberU64
()
!=
check
{
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"%v: non requested hash #%d [%x…], instead of #%d"
,
p
,
block
.
NumberU64
(),
block
.
Hash
()
.
Bytes
()[
:
4
],
check
)
return
0
,
errBadPeer
...
...
@@ -989,7 +989,7 @@ func (d *Downloader) findAncestor(p *peer) (uint64, error) {
// Check if a common ancestor was found
finished
=
true
for
i
:=
len
(
headers
)
-
1
;
i
>=
0
;
i
--
{
if
(
d
.
mode
!=
LightSync
&&
d
.
hasBlock
(
headers
[
i
]
.
Hash
()))
||
(
d
.
mode
==
LightSync
&&
d
.
hasHeader
(
headers
[
i
]
.
Hash
()))
{
if
(
d
.
mode
!=
LightSync
&&
d
.
hasBlock
AndState
(
headers
[
i
]
.
Hash
()))
||
(
d
.
mode
==
LightSync
&&
d
.
hasHeader
(
headers
[
i
]
.
Hash
()))
{
number
,
hash
=
headers
[
i
]
.
Number
.
Uint64
(),
headers
[
i
]
.
Hash
()
break
}
...
...
@@ -1045,7 +1045,7 @@ func (d *Downloader) findAncestor(p *peer) (uint64, error) {
arrived
=
true
// Modify the search interval based on the response
if
(
d
.
mode
==
FullSync
&&
!
d
.
hasBlock
(
headers
[
0
]
.
Hash
()))
||
(
d
.
mode
!=
FullSync
&&
!
d
.
hasHeader
(
headers
[
0
]
.
Hash
()))
{
if
(
d
.
mode
==
FullSync
&&
!
d
.
hasBlock
AndState
(
headers
[
0
]
.
Hash
()))
||
(
d
.
mode
!=
FullSync
&&
!
d
.
hasHeader
(
headers
[
0
]
.
Hash
()))
{
end
=
check
break
}
...
...
eth/downloader/downloader_test.go
浏览文件 @
9e011ff1
...
...
@@ -153,6 +153,8 @@ func newTester() *downloadTester {
peerChainTds
:
make
(
map
[
string
]
map
[
common
.
Hash
]
*
big
.
Int
),
}
tester
.
stateDb
,
_
=
ethdb
.
NewMemDatabase
()
tester
.
stateDb
.
Put
(
genesis
.
Root
()
.
Bytes
(),
[]
byte
{
0x00
})
tester
.
downloader
=
New
(
tester
.
stateDb
,
new
(
event
.
TypeMux
),
tester
.
hasHeader
,
tester
.
hasBlock
,
tester
.
getHeader
,
tester
.
getBlock
,
tester
.
headHeader
,
tester
.
headBlock
,
tester
.
headFastBlock
,
tester
.
commitHeadBlock
,
tester
.
getTd
,
tester
.
insertHeaders
,
tester
.
insertBlocks
,
tester
.
insertReceipts
,
tester
.
rollback
,
tester
.
dropPeer
)
...
...
@@ -180,9 +182,14 @@ func (dl *downloadTester) hasHeader(hash common.Hash) bool {
return
dl
.
getHeader
(
hash
)
!=
nil
}
// hasBlock checks if a block is present in the testers canonical chain.
// hasBlock checks if a block
and associated state
is present in the testers canonical chain.
func
(
dl
*
downloadTester
)
hasBlock
(
hash
common
.
Hash
)
bool
{
return
dl
.
getBlock
(
hash
)
!=
nil
block
:=
dl
.
getBlock
(
hash
)
if
block
==
nil
{
return
false
}
_
,
err
:=
dl
.
stateDb
.
Get
(
block
.
Root
()
.
Bytes
())
return
err
==
nil
}
// getHeader retrieves a header from the testers canonical chain.
...
...
@@ -295,8 +302,10 @@ func (dl *downloadTester) insertBlocks(blocks types.Blocks) (int, error) {
defer
dl
.
lock
.
Unlock
()
for
i
,
block
:=
range
blocks
{
if
_
,
ok
:=
dl
.
ownBlocks
[
block
.
ParentHash
()];
!
ok
{
if
parent
,
ok
:=
dl
.
ownBlocks
[
block
.
ParentHash
()];
!
ok
{
return
i
,
errors
.
New
(
"unknown parent"
)
}
else
if
_
,
err
:=
dl
.
stateDb
.
Get
(
parent
.
Root
()
.
Bytes
());
err
!=
nil
{
return
i
,
fmt
.
Errorf
(
"unknown parent state %x: %v"
,
parent
.
Root
(),
err
)
}
if
_
,
ok
:=
dl
.
ownHeaders
[
block
.
Hash
()];
!
ok
{
dl
.
ownHashes
=
append
(
dl
.
ownHashes
,
block
.
Hash
())
...
...
@@ -1103,6 +1112,8 @@ func testShiftedHeaderAttack(t *testing.T, protocol int, mode SyncMode) {
}
// Tests that upon detecting an invalid header, the recent ones are rolled back
// for various failure scenarios. Afterwards a full sync is attempted to make
// sure no state was corrupted.
func
TestInvalidHeaderRollback63Fast
(
t
*
testing
.
T
)
{
testInvalidHeaderRollback
(
t
,
63
,
FastSync
)
}
func
TestInvalidHeaderRollback64Fast
(
t
*
testing
.
T
)
{
testInvalidHeaderRollback
(
t
,
64
,
FastSync
)
}
func
TestInvalidHeaderRollback64Light
(
t
*
testing
.
T
)
{
testInvalidHeaderRollback
(
t
,
64
,
LightSync
)
}
...
...
eth/downloader/types.go
浏览文件 @
9e011ff1
...
...
@@ -27,8 +27,8 @@ import (
// headerCheckFn is a callback type for verifying a header's presence in the local chain.
type
headerCheckFn
func
(
common
.
Hash
)
bool
// block
CheckFn is a callback type for verifying a block's
presence in the local chain.
type
blockCheckFn
func
(
common
.
Hash
)
bool
// block
AndStateCheckFn is a callback type for verifying block and associated states'
presence in the local chain.
type
block
AndState
CheckFn
func
(
common
.
Hash
)
bool
// headerRetrievalFn is a callback type for retrieving a header from the local chain.
type
headerRetrievalFn
func
(
common
.
Hash
)
*
types
.
Header
...
...
eth/handler.go
浏览文件 @
9e011ff1
...
...
@@ -138,9 +138,10 @@ func NewProtocolManager(fastSync bool, networkId int, mux *event.TypeMux, txpool
return
nil
,
errIncompatibleConfig
}
// Construct the different synchronisation mechanisms
manager
.
downloader
=
downloader
.
New
(
chaindb
,
manager
.
eventMux
,
blockchain
.
HasHeader
,
blockchain
.
HasBlock
,
blockchain
.
GetHeader
,
blockchain
.
GetBlock
,
blockchain
.
CurrentHeader
,
blockchain
.
CurrentBlock
,
blockchain
.
CurrentFastBlock
,
blockchain
.
FastSyncCommitHead
,
blockchain
.
GetTd
,
blockchain
.
InsertHeaderChain
,
blockchain
.
InsertChain
,
blockchain
.
InsertReceiptChain
,
blockchain
.
Rollback
,
manager
.
removePeer
)
manager
.
downloader
=
downloader
.
New
(
chaindb
,
manager
.
eventMux
,
blockchain
.
HasHeader
,
blockchain
.
HasBlockAndState
,
blockchain
.
GetHeader
,
blockchain
.
GetBlock
,
blockchain
.
CurrentHeader
,
blockchain
.
CurrentBlock
,
blockchain
.
CurrentFastBlock
,
blockchain
.
FastSyncCommitHead
,
blockchain
.
GetTd
,
blockchain
.
InsertHeaderChain
,
blockchain
.
InsertChain
,
blockchain
.
InsertReceiptChain
,
blockchain
.
Rollback
,
manager
.
removePeer
)
validator
:=
func
(
block
*
types
.
Block
,
parent
*
types
.
Block
)
error
{
return
core
.
ValidateHeader
(
pow
,
block
.
Header
(),
parent
.
Header
(),
true
,
false
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录