Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
05509579
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,发现更多精彩内容 >>
提交
05509579
编写于
6月 27, 2017
作者:
N
Nick Johnson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
eth, les, light: Refactor downloader to use blockchain interface
上级
dfd07624
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
134 addition
and
146 deletion
+134
-146
eth/downloader/downloader.go
eth/downloader/downloader.go
+82
-61
eth/downloader/downloader_test.go
eth/downloader/downloader_test.go
+35
-37
eth/downloader/types.go
eth/downloader/types.go
+0
-41
eth/handler.go
eth/handler.go
+1
-4
les/handler.go
les/handler.go
+1
-3
light/lightchain.go
light/lightchain.go
+15
-0
未找到文件。
eth/downloader/downloader.go
浏览文件 @
05509579
...
...
@@ -114,21 +114,11 @@ type Downloader struct {
syncStatsState
stateSyncStats
syncStatsLock
sync
.
RWMutex
// Lock protecting the sync stats fields
lightchain
LightChain
chain
BlockChain
// Callbacks
hasHeader
headerCheckFn
// Checks if a header is present in the chain
hasBlockAndState
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
dropPeer
peerDropFn
// Drops a peer for misbehaving
// Status
synchroniseMock
func
(
id
string
,
hash
common
.
Hash
)
error
// Replacement for synchronise during testing
...
...
@@ -163,11 +153,56 @@ type Downloader struct {
chainInsertHook
func
([]
*
fetchResult
)
// Method to call upon inserting a chain of blocks (possibly in multiple invocations)
}
type
LightChain
interface
{
// HasHeader verifies a header's presence in the local chain.
HasHeader
(
common
.
Hash
)
bool
// GetHeaderByHash retrieves a header from the local chain.
GetHeaderByHash
(
common
.
Hash
)
*
types
.
Header
// CurrentHeader retrieves the head header from the local chain.
CurrentHeader
()
*
types
.
Header
// GetTdByHash returns the total difficulty of a local block.
GetTdByHash
(
common
.
Hash
)
*
big
.
Int
// InsertHeaderChain inserts a batch of headers into the local chain.
InsertHeaderChain
([]
*
types
.
Header
,
int
)
(
int
,
error
)
// Rollback removes a few recently added elements from the local chain.
Rollback
([]
common
.
Hash
)
}
type
BlockChain
interface
{
LightChain
// HasBlockAndState verifies block and associated states' presence in the local chain.
HasBlockAndState
(
common
.
Hash
)
bool
// GetBlockByHash retrieves a block from the local chain.
GetBlockByHash
(
common
.
Hash
)
*
types
.
Block
// CurrentBlock retrieves the head block from the local chain.
CurrentBlock
()
*
types
.
Block
// CurrentFastBlock retrieves the head fast block from the local chain.
CurrentFastBlock
()
*
types
.
Block
// FastSyncCommitHead directly commits the head block to a certain entity.
FastSyncCommitHead
(
common
.
Hash
)
error
// InsertChain inserts a batch of blocks into the local chain.
InsertChain
(
types
.
Blocks
)
(
int
,
error
)
// InsertReceiptChain inserts a batch of receipts into the local chain.
InsertReceiptChain
(
types
.
Blocks
,
[]
types
.
Receipts
)
(
int
,
error
)
}
// New creates a new downloader to fetch hashes and blocks from remote peers.
func
New
(
mode
SyncMode
,
stateDb
ethdb
.
Database
,
mux
*
event
.
TypeMux
,
hasHeader
headerCheckFn
,
hasBlockAndState
blockAndStateCheckFn
,
getHeader
headerRetrievalFn
,
getBlock
blockRetrievalFn
,
headHeader
headHeaderRetrievalFn
,
headBlock
headBlockRetrievalFn
,
headFastBlock
headFastBlockRetrievalFn
,
commitHeadBlock
headBlockCommitterFn
,
getTd
tdRetrievalFn
,
insertHeaders
headerChainInsertFn
,
insertBlocks
blockChainInsertFn
,
insertReceipts
receiptChainInsertFn
,
rollback
chainRollbackFn
,
dropPeer
peerDropFn
)
*
Downloader
{
func
New
(
mode
SyncMode
,
stateDb
ethdb
.
Database
,
mux
*
event
.
TypeMux
,
chain
BlockChain
,
lightchain
LightChain
,
dropPeer
peerDropFn
)
*
Downloader
{
if
lightchain
==
nil
{
lightchain
=
chain
}
dl
:=
&
Downloader
{
mode
:
mode
,
...
...
@@ -177,19 +212,8 @@ func New(mode SyncMode, stateDb ethdb.Database, mux *event.TypeMux, hasHeader he
stateDB
:
stateDb
,
rttEstimate
:
uint64
(
rttMaxEstimate
),
rttConfidence
:
uint64
(
1000000
),
hasHeader
:
hasHeader
,
hasBlockAndState
:
hasBlockAndState
,
getHeader
:
getHeader
,
getBlock
:
getBlock
,
headHeader
:
headHeader
,
headBlock
:
headBlock
,
headFastBlock
:
headFastBlock
,
commitHeadBlock
:
commitHeadBlock
,
getTd
:
getTd
,
insertHeaders
:
insertHeaders
,
insertBlocks
:
insertBlocks
,
insertReceipts
:
insertReceipts
,
rollback
:
rollback
,
chain
:
chain
,
lightchain
:
lightchain
,
dropPeer
:
dropPeer
,
headerCh
:
make
(
chan
dataPack
,
1
),
bodyCh
:
make
(
chan
dataPack
,
1
),
...
...
@@ -223,11 +247,11 @@ func (d *Downloader) Progress() ethereum.SyncProgress {
current
:=
uint64
(
0
)
switch
d
.
mode
{
case
FullSync
:
current
=
d
.
head
Block
()
.
NumberU64
()
current
=
d
.
chain
.
Current
Block
()
.
NumberU64
()
case
FastSync
:
current
=
d
.
head
FastBlock
()
.
NumberU64
()
current
=
d
.
chain
.
Current
FastBlock
()
.
NumberU64
()
case
LightSync
:
current
=
d
.
head
Header
()
.
Number
.
Uint64
()
current
=
d
.
lightchain
.
Current
Header
()
.
Number
.
Uint64
()
}
return
ethereum
.
SyncProgress
{
StartingBlock
:
d
.
syncStatsChainOrigin
,
...
...
@@ -572,13 +596,13 @@ func (d *Downloader) fetchHeight(p *peer) (*types.Header, error) {
// the head links match), we do a binary search to find the common ancestor.
func
(
d
*
Downloader
)
findAncestor
(
p
*
peer
,
height
uint64
)
(
uint64
,
error
)
{
// Figure out the valid ancestor range to prevent rewrite attacks
floor
,
ceil
:=
int64
(
-
1
),
d
.
head
Header
()
.
Number
.
Uint64
()
floor
,
ceil
:=
int64
(
-
1
),
d
.
lightchain
.
Current
Header
()
.
Number
.
Uint64
()
p
.
log
.
Debug
(
"Looking for common ancestor"
,
"local"
,
ceil
,
"remote"
,
height
)
if
d
.
mode
==
FullSync
{
ceil
=
d
.
head
Block
()
.
NumberU64
()
ceil
=
d
.
chain
.
Current
Block
()
.
NumberU64
()
}
else
if
d
.
mode
==
FastSync
{
ceil
=
d
.
head
FastBlock
()
.
NumberU64
()
ceil
=
d
.
chain
.
Current
FastBlock
()
.
NumberU64
()
}
if
ceil
>=
MaxForkAncestry
{
floor
=
int64
(
ceil
-
MaxForkAncestry
)
...
...
@@ -638,7 +662,7 @@ func (d *Downloader) findAncestor(p *peer, height uint64) (uint64, error) {
continue
}
// Otherwise check if we already know the header or not
if
(
d
.
mode
==
FullSync
&&
d
.
hasBlockAndState
(
headers
[
i
]
.
Hash
()))
||
(
d
.
mode
!=
FullSync
&&
d
.
h
asHeader
(
headers
[
i
]
.
Hash
()))
{
if
(
d
.
mode
==
FullSync
&&
d
.
chain
.
HasBlockAndState
(
headers
[
i
]
.
Hash
()))
||
(
d
.
mode
!=
FullSync
&&
d
.
lightchain
.
H
asHeader
(
headers
[
i
]
.
Hash
()))
{
number
,
hash
=
headers
[
i
]
.
Number
.
Uint64
(),
headers
[
i
]
.
Hash
()
// If every header is known, even future ones, the peer straight out lied about its head
...
...
@@ -703,11 +727,11 @@ func (d *Downloader) findAncestor(p *peer, height uint64) (uint64, error) {
arrived
=
true
// Modify the search interval based on the response
if
(
d
.
mode
==
FullSync
&&
!
d
.
hasBlockAndState
(
headers
[
0
]
.
Hash
()))
||
(
d
.
mode
!=
FullSync
&&
!
d
.
h
asHeader
(
headers
[
0
]
.
Hash
()))
{
if
(
d
.
mode
==
FullSync
&&
!
d
.
chain
.
HasBlockAndState
(
headers
[
0
]
.
Hash
()))
||
(
d
.
mode
!=
FullSync
&&
!
d
.
lightchain
.
H
asHeader
(
headers
[
0
]
.
Hash
()))
{
end
=
check
break
}
header
:=
d
.
getHeader
(
headers
[
0
]
.
Hash
())
// Independent of sync mode, header surely exists
header
:=
d
.
lightchain
.
GetHeaderByHash
(
headers
[
0
]
.
Hash
())
// Independent of sync mode, header surely exists
if
header
.
Number
.
Uint64
()
!=
check
{
p
.
log
.
Debug
(
"Received non requested header"
,
"number"
,
header
.
Number
,
"hash"
,
header
.
Hash
(),
"request"
,
check
)
return
0
,
errBadPeer
...
...
@@ -1124,23 +1148,19 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error {
for
i
,
header
:=
range
rollback
{
hashes
[
i
]
=
header
.
Hash
()
}
lastHeader
,
lastFastBlock
,
lastBlock
:=
d
.
headHeader
()
.
Number
,
common
.
Big0
,
common
.
Big0
if
d
.
headFastBlock
!=
nil
{
lastFastBlock
=
d
.
headFastBlock
()
.
Number
()
}
if
d
.
headBlock
!=
nil
{
lastBlock
=
d
.
headBlock
()
.
Number
()
lastHeader
,
lastFastBlock
,
lastBlock
:=
d
.
lightchain
.
CurrentHeader
()
.
Number
,
common
.
Big0
,
common
.
Big0
if
d
.
mode
!=
LightSync
{
lastFastBlock
=
d
.
chain
.
CurrentFastBlock
()
.
Number
()
lastBlock
=
d
.
chain
.
CurrentBlock
()
.
Number
()
}
d
.
r
ollback
(
hashes
)
d
.
lightchain
.
R
ollback
(
hashes
)
curFastBlock
,
curBlock
:=
common
.
Big0
,
common
.
Big0
if
d
.
headFastBlock
!=
nil
{
curFastBlock
=
d
.
headFastBlock
()
.
Number
()
}
if
d
.
headBlock
!=
nil
{
curBlock
=
d
.
headBlock
()
.
Number
()
if
d
.
mode
!=
LightSync
{
curFastBlock
=
d
.
chain
.
CurrentFastBlock
()
.
Number
()
curBlock
=
d
.
chain
.
CurrentBlock
()
.
Number
()
}
log
.
Warn
(
"Rolled back headers"
,
"count"
,
len
(
hashes
),
"header"
,
fmt
.
Sprintf
(
"%d->%d"
,
lastHeader
,
d
.
head
Header
()
.
Number
),
"header"
,
fmt
.
Sprintf
(
"%d->%d"
,
lastHeader
,
d
.
lightchain
.
Current
Header
()
.
Number
),
"fast"
,
fmt
.
Sprintf
(
"%d->%d"
,
lastFastBlock
,
curFastBlock
),
"block"
,
fmt
.
Sprintf
(
"%d->%d"
,
lastBlock
,
curBlock
))
...
...
@@ -1190,7 +1210,7 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error {
// L: Request new headers up from 11 (R's TD was higher, it must have something)
// R: Nothing to give
if
d
.
mode
!=
LightSync
{
if
!
gotHeaders
&&
td
.
Cmp
(
d
.
getTd
(
d
.
head
Block
()
.
Hash
()))
>
0
{
if
!
gotHeaders
&&
td
.
Cmp
(
d
.
chain
.
GetTdByHash
(
d
.
chain
.
Current
Block
()
.
Hash
()))
>
0
{
return
errStallingPeer
}
}
...
...
@@ -1202,7 +1222,7 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error {
// queued for processing when the header download completes. However, as long as the
// peer gave us something useful, we're already happy/progressed (above check).
if
d
.
mode
==
FastSync
||
d
.
mode
==
LightSync
{
if
td
.
Cmp
(
d
.
getTd
(
d
.
head
Header
()
.
Hash
()))
>
0
{
if
td
.
Cmp
(
d
.
lightchain
.
GetTdByHash
(
d
.
lightchain
.
Current
Header
()
.
Hash
()))
>
0
{
return
errStallingPeer
}
}
...
...
@@ -1232,7 +1252,7 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error {
// Collect the yet unknown headers to mark them as uncertain
unknown
:=
make
([]
*
types
.
Header
,
0
,
len
(
headers
))
for
_
,
header
:=
range
chunk
{
if
!
d
.
h
asHeader
(
header
.
Hash
())
{
if
!
d
.
lightchain
.
H
asHeader
(
header
.
Hash
())
{
unknown
=
append
(
unknown
,
header
)
}
}
...
...
@@ -1241,7 +1261,7 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error {
if
chunk
[
len
(
chunk
)
-
1
]
.
Number
.
Uint64
()
+
uint64
(
fsHeaderForceVerify
)
>
pivot
{
frequency
=
1
}
if
n
,
err
:=
d
.
insertHeaders
(
chunk
,
frequency
);
err
!=
nil
{
if
n
,
err
:=
d
.
chain
.
InsertHeaderChain
(
chunk
,
frequency
);
err
!=
nil
{
// If some headers were inserted, add them too to the rollback list
if
n
>
0
{
rollback
=
append
(
rollback
,
chunk
[
:
n
]
...
)
...
...
@@ -1328,7 +1348,7 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error {
for
i
,
result
:=
range
results
[
:
items
]
{
blocks
[
i
]
=
types
.
NewBlockWithHeader
(
result
.
Header
)
.
WithBody
(
result
.
Transactions
,
result
.
Uncles
)
}
if
index
,
err
:=
d
.
insertBlocks
(
blocks
);
err
!=
nil
{
if
index
,
err
:=
d
.
chain
.
InsertChain
(
blocks
);
err
!=
nil
{
log
.
Debug
(
"Downloaded item processing failed"
,
"number"
,
results
[
index
]
.
Header
.
Number
,
"hash"
,
results
[
index
]
.
Header
.
Hash
(),
"err"
,
err
)
return
errInvalidChain
}
...
...
@@ -1368,6 +1388,7 @@ func (d *Downloader) processFastSyncContent(latest *types.Header) error {
stateSync
.
Cancel
()
if
err
:=
d
.
commitPivotBlock
(
P
);
err
!=
nil
{
return
err
}
}
if
err
:=
d
.
importBlockResults
(
afterP
);
err
!=
nil
{
...
...
@@ -1416,7 +1437,7 @@ func (d *Downloader) commitFastSyncData(results []*fetchResult, stateSync *state
blocks
[
i
]
=
types
.
NewBlockWithHeader
(
result
.
Header
)
.
WithBody
(
result
.
Transactions
,
result
.
Uncles
)
receipts
[
i
]
=
result
.
Receipts
}
if
index
,
err
:=
d
.
insertReceipts
(
blocks
,
receipts
);
err
!=
nil
{
if
index
,
err
:=
d
.
chain
.
InsertReceiptChain
(
blocks
,
receipts
);
err
!=
nil
{
log
.
Debug
(
"Downloaded item processing failed"
,
"number"
,
results
[
index
]
.
Header
.
Number
,
"hash"
,
results
[
index
]
.
Header
.
Hash
(),
"err"
,
err
)
return
errInvalidChain
}
...
...
@@ -1434,10 +1455,10 @@ func (d *Downloader) commitPivotBlock(result *fetchResult) error {
return
err
}
log
.
Debug
(
"Committing fast sync pivot as new head"
,
"number"
,
b
.
Number
(),
"hash"
,
b
.
Hash
())
if
_
,
err
:=
d
.
insertReceipts
([]
*
types
.
Block
{
b
},
[]
types
.
Receipts
{
result
.
Receipts
});
err
!=
nil
{
if
_
,
err
:=
d
.
chain
.
InsertReceiptChain
([]
*
types
.
Block
{
b
},
[]
types
.
Receipts
{
result
.
Receipts
});
err
!=
nil
{
return
err
}
return
d
.
c
ommitHeadBlock
(
b
.
Hash
())
return
d
.
c
hain
.
FastSyncCommitHead
(
b
.
Hash
())
}
// DeliverHeaders injects a new batch of block headers received from a remote
...
...
eth/downloader/downloader_test.go
浏览文件 @
05509579
...
...
@@ -96,9 +96,7 @@ func newTester() *downloadTester {
tester
.
stateDb
,
_
=
ethdb
.
NewMemDatabase
()
tester
.
stateDb
.
Put
(
genesis
.
Root
()
.
Bytes
(),
[]
byte
{
0x00
})
tester
.
downloader
=
New
(
FullSync
,
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
)
tester
.
downloader
=
New
(
FullSync
,
tester
.
stateDb
,
new
(
event
.
TypeMux
),
tester
,
nil
,
tester
.
dropPeer
)
return
tester
}
...
...
@@ -218,14 +216,14 @@ func (dl *downloadTester) sync(id string, td *big.Int, mode SyncMode) error {
return
err
}
//
h
asHeader checks if a header is present in the testers canonical chain.
func
(
dl
*
downloadTester
)
h
asHeader
(
hash
common
.
Hash
)
bool
{
return
dl
.
getHeader
(
hash
)
!=
nil
//
H
asHeader checks if a header is present in the testers canonical chain.
func
(
dl
*
downloadTester
)
H
asHeader
(
hash
common
.
Hash
)
bool
{
return
dl
.
GetHeaderByHash
(
hash
)
!=
nil
}
//
hasBlock
checks if a block and associated state is present in the testers canonical chain.
func
(
dl
*
downloadTester
)
hasBlock
(
hash
common
.
Hash
)
bool
{
block
:=
dl
.
getBlock
(
hash
)
//
HasBlockAndState
checks if a block and associated state is present in the testers canonical chain.
func
(
dl
*
downloadTester
)
HasBlockAndState
(
hash
common
.
Hash
)
bool
{
block
:=
dl
.
GetBlockByHash
(
hash
)
if
block
==
nil
{
return
false
}
...
...
@@ -233,24 +231,24 @@ func (dl *downloadTester) hasBlock(hash common.Hash) bool {
return
err
==
nil
}
//
g
etHeader retrieves a header from the testers canonical chain.
func
(
dl
*
downloadTester
)
getHeader
(
hash
common
.
Hash
)
*
types
.
Header
{
//
G
etHeader retrieves a header from the testers canonical chain.
func
(
dl
*
downloadTester
)
GetHeaderByHash
(
hash
common
.
Hash
)
*
types
.
Header
{
dl
.
lock
.
RLock
()
defer
dl
.
lock
.
RUnlock
()
return
dl
.
ownHeaders
[
hash
]
}
//
g
etBlock retrieves a block from the testers canonical chain.
func
(
dl
*
downloadTester
)
getBlock
(
hash
common
.
Hash
)
*
types
.
Block
{
//
G
etBlock retrieves a block from the testers canonical chain.
func
(
dl
*
downloadTester
)
GetBlockByHash
(
hash
common
.
Hash
)
*
types
.
Block
{
dl
.
lock
.
RLock
()
defer
dl
.
lock
.
RUnlock
()
return
dl
.
ownBlocks
[
hash
]
}
//
head
Header retrieves the current head header from the canonical chain.
func
(
dl
*
downloadTester
)
head
Header
()
*
types
.
Header
{
//
Current
Header retrieves the current head header from the canonical chain.
func
(
dl
*
downloadTester
)
Current
Header
()
*
types
.
Header
{
dl
.
lock
.
RLock
()
defer
dl
.
lock
.
RUnlock
()
...
...
@@ -262,8 +260,8 @@ func (dl *downloadTester) headHeader() *types.Header {
return
dl
.
genesis
.
Header
()
}
//
head
Block retrieves the current head block from the canonical chain.
func
(
dl
*
downloadTester
)
head
Block
()
*
types
.
Block
{
//
Current
Block retrieves the current head block from the canonical chain.
func
(
dl
*
downloadTester
)
Current
Block
()
*
types
.
Block
{
dl
.
lock
.
RLock
()
defer
dl
.
lock
.
RUnlock
()
...
...
@@ -277,8 +275,8 @@ func (dl *downloadTester) headBlock() *types.Block {
return
dl
.
genesis
}
//
head
FastBlock retrieves the current head fast-sync block from the canonical chain.
func
(
dl
*
downloadTester
)
head
FastBlock
()
*
types
.
Block
{
//
Current
FastBlock retrieves the current head fast-sync block from the canonical chain.
func
(
dl
*
downloadTester
)
Current
FastBlock
()
*
types
.
Block
{
dl
.
lock
.
RLock
()
defer
dl
.
lock
.
RUnlock
()
...
...
@@ -290,26 +288,26 @@ func (dl *downloadTester) headFastBlock() *types.Block {
return
dl
.
genesis
}
//
commitHeadBlock
manually sets the head block to a given hash.
func
(
dl
*
downloadTester
)
commitHeadBlock
(
hash
common
.
Hash
)
error
{
//
FastSynccommitHead
manually sets the head block to a given hash.
func
(
dl
*
downloadTester
)
FastSyncCommitHead
(
hash
common
.
Hash
)
error
{
// For now only check that the state trie is correct
if
block
:=
dl
.
getBlock
(
hash
);
block
!=
nil
{
if
block
:=
dl
.
GetBlockByHash
(
hash
);
block
!=
nil
{
_
,
err
:=
trie
.
NewSecure
(
block
.
Root
(),
dl
.
stateDb
,
0
)
return
err
}
return
fmt
.
Errorf
(
"non existent block: %x"
,
hash
[
:
4
])
}
//
getTd
retrieves the block's total difficulty from the canonical chain.
func
(
dl
*
downloadTester
)
getTd
(
hash
common
.
Hash
)
*
big
.
Int
{
//
GetTdByHash
retrieves the block's total difficulty from the canonical chain.
func
(
dl
*
downloadTester
)
GetTdByHash
(
hash
common
.
Hash
)
*
big
.
Int
{
dl
.
lock
.
RLock
()
defer
dl
.
lock
.
RUnlock
()
return
dl
.
ownChainTd
[
hash
]
}
//
insertHeaders
injects a new batch of headers into the simulated chain.
func
(
dl
*
downloadTester
)
insertHeaders
(
headers
[]
*
types
.
Header
,
checkFreq
int
)
(
int
,
error
)
{
//
InsertHeaderChain
injects a new batch of headers into the simulated chain.
func
(
dl
*
downloadTester
)
InsertHeaderChain
(
headers
[]
*
types
.
Header
,
checkFreq
int
)
(
int
,
error
)
{
dl
.
lock
.
Lock
()
defer
dl
.
lock
.
Unlock
()
...
...
@@ -337,8 +335,8 @@ func (dl *downloadTester) insertHeaders(headers []*types.Header, checkFreq int)
return
len
(
headers
),
nil
}
//
insertBlocks
injects a new batch of blocks into the simulated chain.
func
(
dl
*
downloadTester
)
insertBlocks
(
blocks
types
.
Blocks
)
(
int
,
error
)
{
//
InsertChain
injects a new batch of blocks into the simulated chain.
func
(
dl
*
downloadTester
)
InsertChain
(
blocks
types
.
Blocks
)
(
int
,
error
)
{
dl
.
lock
.
Lock
()
defer
dl
.
lock
.
Unlock
()
...
...
@@ -359,8 +357,8 @@ func (dl *downloadTester) insertBlocks(blocks types.Blocks) (int, error) {
return
len
(
blocks
),
nil
}
//
insertReceipts
injects a new batch of receipts into the simulated chain.
func
(
dl
*
downloadTester
)
insertReceipts
(
blocks
types
.
Blocks
,
receipts
[]
types
.
Receipts
)
(
int
,
error
)
{
//
InsertReceiptChain
injects a new batch of receipts into the simulated chain.
func
(
dl
*
downloadTester
)
InsertReceiptChain
(
blocks
types
.
Blocks
,
receipts
[]
types
.
Receipts
)
(
int
,
error
)
{
dl
.
lock
.
Lock
()
defer
dl
.
lock
.
Unlock
()
...
...
@@ -377,8 +375,8 @@ func (dl *downloadTester) insertReceipts(blocks types.Blocks, receipts []types.R
return
len
(
blocks
),
nil
}
//
r
ollback removes some recently added elements from the chain.
func
(
dl
*
downloadTester
)
r
ollback
(
hashes
[]
common
.
Hash
)
{
//
R
ollback removes some recently added elements from the chain.
func
(
dl
*
downloadTester
)
R
ollback
(
hashes
[]
common
.
Hash
)
{
dl
.
lock
.
Lock
()
defer
dl
.
lock
.
Unlock
()
...
...
@@ -1212,7 +1210,7 @@ func testInvalidHeaderRollback(t *testing.T, protocol int, mode SyncMode) {
if
err
:=
tester
.
sync
(
"fast-attack"
,
nil
,
mode
);
err
==
nil
{
t
.
Fatalf
(
"succeeded fast attacker synchronisation"
)
}
if
head
:=
tester
.
head
Header
()
.
Number
.
Int64
();
int
(
head
)
>
MaxHeaderFetch
{
if
head
:=
tester
.
Current
Header
()
.
Number
.
Int64
();
int
(
head
)
>
MaxHeaderFetch
{
t
.
Errorf
(
"rollback head mismatch: have %v, want at most %v"
,
head
,
MaxHeaderFetch
)
}
// Attempt to sync with an attacker that feeds junk during the block import phase.
...
...
@@ -1226,11 +1224,11 @@ func testInvalidHeaderRollback(t *testing.T, protocol int, mode SyncMode) {
if
err
:=
tester
.
sync
(
"block-attack"
,
nil
,
mode
);
err
==
nil
{
t
.
Fatalf
(
"succeeded block attacker synchronisation"
)
}
if
head
:=
tester
.
head
Header
()
.
Number
.
Int64
();
int
(
head
)
>
2
*
fsHeaderSafetyNet
+
MaxHeaderFetch
{
if
head
:=
tester
.
Current
Header
()
.
Number
.
Int64
();
int
(
head
)
>
2
*
fsHeaderSafetyNet
+
MaxHeaderFetch
{
t
.
Errorf
(
"rollback head mismatch: have %v, want at most %v"
,
head
,
2
*
fsHeaderSafetyNet
+
MaxHeaderFetch
)
}
if
mode
==
FastSync
{
if
head
:=
tester
.
head
Block
()
.
NumberU64
();
head
!=
0
{
if
head
:=
tester
.
Current
Block
()
.
NumberU64
();
head
!=
0
{
t
.
Errorf
(
"fast sync pivot block #%d not rolled back"
,
head
)
}
}
...
...
@@ -1251,11 +1249,11 @@ func testInvalidHeaderRollback(t *testing.T, protocol int, mode SyncMode) {
if
err
:=
tester
.
sync
(
"withhold-attack"
,
nil
,
mode
);
err
==
nil
{
t
.
Fatalf
(
"succeeded withholding attacker synchronisation"
)
}
if
head
:=
tester
.
head
Header
()
.
Number
.
Int64
();
int
(
head
)
>
2
*
fsHeaderSafetyNet
+
MaxHeaderFetch
{
if
head
:=
tester
.
Current
Header
()
.
Number
.
Int64
();
int
(
head
)
>
2
*
fsHeaderSafetyNet
+
MaxHeaderFetch
{
t
.
Errorf
(
"rollback head mismatch: have %v, want at most %v"
,
head
,
2
*
fsHeaderSafetyNet
+
MaxHeaderFetch
)
}
if
mode
==
FastSync
{
if
head
:=
tester
.
head
Block
()
.
NumberU64
();
head
!=
0
{
if
head
:=
tester
.
Current
Block
()
.
NumberU64
();
head
!=
0
{
t
.
Errorf
(
"fast sync pivot block #%d not rolled back"
,
head
)
}
}
...
...
eth/downloader/types.go
浏览文件 @
05509579
...
...
@@ -18,51 +18,10 @@ package downloader
import
(
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)
// headerCheckFn is a callback type for verifying a header's presence in the local chain.
type
headerCheckFn
func
(
common
.
Hash
)
bool
// blockAndStateCheckFn is a callback type for verifying block and associated states' presence in the local chain.
type
blockAndStateCheckFn
func
(
common
.
Hash
)
bool
// headerRetrievalFn is a callback type for retrieving a header from the local chain.
type
headerRetrievalFn
func
(
common
.
Hash
)
*
types
.
Header
// blockRetrievalFn is a callback type for retrieving a block from the local chain.
type
blockRetrievalFn
func
(
common
.
Hash
)
*
types
.
Block
// headHeaderRetrievalFn is a callback type for retrieving the head header from the local chain.
type
headHeaderRetrievalFn
func
()
*
types
.
Header
// headBlockRetrievalFn is a callback type for retrieving the head block from the local chain.
type
headBlockRetrievalFn
func
()
*
types
.
Block
// headFastBlockRetrievalFn is a callback type for retrieving the head fast block from the local chain.
type
headFastBlockRetrievalFn
func
()
*
types
.
Block
// headBlockCommitterFn is a callback for directly committing the head block to a certain entity.
type
headBlockCommitterFn
func
(
common
.
Hash
)
error
// tdRetrievalFn is a callback type for retrieving the total difficulty of a local block.
type
tdRetrievalFn
func
(
common
.
Hash
)
*
big
.
Int
// headerChainInsertFn is a callback type to insert a batch of headers into the local chain.
type
headerChainInsertFn
func
([]
*
types
.
Header
,
int
)
(
int
,
error
)
// blockChainInsertFn is a callback type to insert a batch of blocks into the local chain.
type
blockChainInsertFn
func
(
types
.
Blocks
)
(
int
,
error
)
// receiptChainInsertFn is a callback type to insert a batch of receipts into the local chain.
type
receiptChainInsertFn
func
(
types
.
Blocks
,
[]
types
.
Receipts
)
(
int
,
error
)
// chainRollbackFn is a callback type to remove a few recently added elements from the local chain.
type
chainRollbackFn
func
([]
common
.
Hash
)
// peerDropFn is a callback type for dropping a peer detected as malicious.
type
peerDropFn
func
(
id
string
)
...
...
eth/handler.go
浏览文件 @
05509579
...
...
@@ -157,10 +157,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
return
nil
,
errIncompatibleConfig
}
// Construct the different synchronisation mechanisms
manager
.
downloader
=
downloader
.
New
(
mode
,
chaindb
,
manager
.
eventMux
,
blockchain
.
HasHeader
,
blockchain
.
HasBlockAndState
,
blockchain
.
GetHeaderByHash
,
blockchain
.
GetBlockByHash
,
blockchain
.
CurrentHeader
,
blockchain
.
CurrentBlock
,
blockchain
.
CurrentFastBlock
,
blockchain
.
FastSyncCommitHead
,
blockchain
.
GetTdByHash
,
blockchain
.
InsertHeaderChain
,
manager
.
blockchain
.
InsertChain
,
blockchain
.
InsertReceiptChain
,
blockchain
.
Rollback
,
manager
.
removePeer
)
manager
.
downloader
=
downloader
.
New
(
mode
,
chaindb
,
manager
.
eventMux
,
blockchain
,
nil
,
manager
.
removePeer
)
validator
:=
func
(
header
*
types
.
Header
)
error
{
return
engine
.
VerifyHeader
(
blockchain
,
header
,
true
)
...
...
les/handler.go
浏览文件 @
05509579
...
...
@@ -206,9 +206,7 @@ func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, network
}
if
lightSync
{
manager
.
downloader
=
downloader
.
New
(
downloader
.
LightSync
,
chainDb
,
manager
.
eventMux
,
blockchain
.
HasHeader
,
nil
,
blockchain
.
GetHeaderByHash
,
nil
,
blockchain
.
CurrentHeader
,
nil
,
nil
,
nil
,
blockchain
.
GetTdByHash
,
blockchain
.
InsertHeaderChain
,
nil
,
nil
,
blockchain
.
Rollback
,
removePeer
)
manager
.
downloader
=
downloader
.
New
(
downloader
.
LightSync
,
chainDb
,
manager
.
eventMux
,
nil
,
blockchain
,
removePeer
)
manager
.
peers
.
notify
((
*
downloaderPeerNotify
)(
manager
))
manager
.
fetcher
=
newLightFetcher
(
manager
)
}
...
...
light/lightchain.go
浏览文件 @
05509579
...
...
@@ -389,6 +389,21 @@ func (self *LightChain) CurrentHeader() *types.Header {
return
self
.
hc
.
CurrentHeader
()
}
// CurrentBlock exists for interface compatibility and always returns nil
func
(
self
*
LightChain
)
CurrentBlock
()
*
types
.
Block
{
return
nil
}
// CurrentFastBlock exists for interface compatibility and always returns nil
func
(
self
*
LightChain
)
CurrentFastBlock
()
*
types
.
Block
{
return
nil
}
// FastSyncCommitHead exists for interface compatibility and does nothing
func
(
self
*
LightChain
)
FastSyncCommitHead
(
h
common
.
Hash
)
error
{
return
nil
}
// GetTd retrieves a block's total difficulty in the canonical chain from the
// database by hash and number, caching it if found.
func
(
self
*
LightChain
)
GetTd
(
hash
common
.
Hash
,
number
uint64
)
*
big
.
Int
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录