Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
f186b390
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,发现更多精彩内容 >>
提交
f186b390
编写于
9月 28, 2015
作者:
P
Péter Szilágyi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
eth/downloader: add fast and light sync strategies
上级
c33cc382
变更
11
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
1437 addition
and
809 deletion
+1437
-809
core/transaction_util.go
core/transaction_util.go
+5
-6
core/types/block.go
core/types/block.go
+5
-5
eth/downloader/downloader.go
eth/downloader/downloader.go
+438
-229
eth/downloader/downloader_test.go
eth/downloader/downloader_test.go
+452
-287
eth/downloader/metrics.go
eth/downloader/metrics.go
+5
-0
eth/downloader/modes.go
eth/downloader/modes.go
+26
-0
eth/downloader/peer.go
eth/downloader/peer.go
+123
-69
eth/downloader/queue.go
eth/downloader/queue.go
+344
-190
eth/handler.go
eth/handler.go
+31
-12
eth/handler_test.go
eth/handler_test.go
+5
-8
eth/peer.go
eth/peer.go
+3
-3
未找到文件。
core/transaction_util.go
浏览文件 @
f186b390
...
...
@@ -140,13 +140,12 @@ func GetBlockReceipts(db ethdb.Database, hash common.Hash) types.Receipts {
if
len
(
data
)
==
0
{
return
nil
}
var
receipts
types
.
Receipts
err
:=
rlp
.
DecodeBytes
(
data
,
&
receipts
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Core
)
.
Infoln
(
"GetReceiptse err"
,
err
)
receipts
:=
new
(
types
.
Receipts
)
if
err
:=
rlp
.
DecodeBytes
(
data
,
receipts
);
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"invalid receipt array RLP for hash %x: %v"
,
hash
,
err
)
return
nil
}
return
receipts
return
*
receipts
}
// PutBlockReceipts stores the block's transactions associated receipts
...
...
core/types/block.go
浏览文件 @
f186b390
...
...
@@ -172,8 +172,8 @@ type storageblock struct {
}
var
(
e
mptyRootHash
=
DeriveSha
(
Transactions
{})
e
mptyUncleHash
=
CalcUncleHash
(
nil
)
E
mptyRootHash
=
DeriveSha
(
Transactions
{})
E
mptyUncleHash
=
CalcUncleHash
(
nil
)
)
// NewBlock creates a new block. The input data is copied,
...
...
@@ -188,7 +188,7 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*
// TODO: panic if len(txs) != len(receipts)
if
len
(
txs
)
==
0
{
b
.
header
.
TxHash
=
e
mptyRootHash
b
.
header
.
TxHash
=
E
mptyRootHash
}
else
{
b
.
header
.
TxHash
=
DeriveSha
(
Transactions
(
txs
))
b
.
transactions
=
make
(
Transactions
,
len
(
txs
))
...
...
@@ -196,7 +196,7 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*
}
if
len
(
receipts
)
==
0
{
b
.
header
.
ReceiptHash
=
e
mptyRootHash
b
.
header
.
ReceiptHash
=
E
mptyRootHash
}
else
{
b
.
header
.
ReceiptHash
=
DeriveSha
(
Receipts
(
receipts
))
b
.
header
.
Bloom
=
CreateBloom
(
receipts
)
...
...
@@ -205,7 +205,7 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*
}
if
len
(
uncles
)
==
0
{
b
.
header
.
UncleHash
=
e
mptyUncleHash
b
.
header
.
UncleHash
=
E
mptyUncleHash
}
else
{
b
.
header
.
UncleHash
=
CalcUncleHash
(
uncles
)
b
.
uncles
=
make
([]
*
Header
,
len
(
uncles
))
...
...
eth/downloader/downloader.go
浏览文件 @
f186b390
此差异已折叠。
点击以展开。
eth/downloader/downloader_test.go
浏览文件 @
f186b390
此差异已折叠。
点击以展开。
eth/downloader/metrics.go
浏览文件 @
f186b390
...
...
@@ -42,4 +42,9 @@ var (
bodyReqTimer
=
metrics
.
NewTimer
(
"eth/downloader/bodies/req"
)
bodyDropMeter
=
metrics
.
NewMeter
(
"eth/downloader/bodies/drop"
)
bodyTimeoutMeter
=
metrics
.
NewMeter
(
"eth/downloader/bodies/timeout"
)
receiptInMeter
=
metrics
.
NewMeter
(
"eth/downloader/receipts/in"
)
receiptReqTimer
=
metrics
.
NewTimer
(
"eth/downloader/receipts/req"
)
receiptDropMeter
=
metrics
.
NewMeter
(
"eth/downloader/receipts/drop"
)
receiptTimeoutMeter
=
metrics
.
NewMeter
(
"eth/downloader/receipts/timeout"
)
)
eth/downloader/modes.go
0 → 100644
浏览文件 @
f186b390
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
downloader
// SyncMode represents the synchronisation mode of the downloader.
type
SyncMode
int
const
(
FullSync
SyncMode
=
iota
// Synchronise the entire block-chain history from full blocks
FastSync
// Quikcly download the headers, full sync only at the chain head
LightSync
// Download only the headers and terminate afterwards
)
eth/downloader/peer.go
浏览文件 @
f186b390
...
...
@@ -36,10 +36,11 @@ type relativeHashFetcherFn func(common.Hash) error
type
absoluteHashFetcherFn
func
(
uint64
,
int
)
error
type
blockFetcherFn
func
([]
common
.
Hash
)
error
// Block header and body fethers belonging to eth/62 and above
// Block header and body fet
c
hers belonging to eth/62 and above
type
relativeHeaderFetcherFn
func
(
common
.
Hash
,
int
,
int
,
bool
)
error
type
absoluteHeaderFetcherFn
func
(
uint64
,
int
,
int
,
bool
)
error
type
blockBodyFetcherFn
func
([]
common
.
Hash
)
error
type
receiptFetcherFn
func
([]
common
.
Hash
)
error
var
(
errAlreadyFetching
=
errors
.
New
(
"already fetching blocks from peer"
)
...
...
@@ -52,11 +53,14 @@ type peer struct {
id
string
// Unique identifier of the peer
head
common
.
Hash
// Hash of the peers latest known block
idle
int32
// Current activity state of the peer (idle = 0, active = 1)
rep
int32
// Simple peer reputation
blockIdle
int32
// Current block activity state of the peer (idle = 0, active = 1)
receiptIdle
int32
// Current receipt activity state of the peer (idle = 0, active = 1)
rep
int32
// Simple peer reputation
capacity
int32
// Number of blocks allowed to fetch per request
started
time
.
Time
// Time instance when the last fetch was started
blockCapacity
int32
// Number of blocks (bodies) allowed to fetch per request
receiptCapacity
int32
// Number of receipts allowed to fetch per request
blockStarted
time
.
Time
// Time instance when the last block (body)fetch was started
receiptStarted
time
.
Time
// Time instance when the last receipt fetch was started
ignored
*
set
.
Set
// Set of hashes not to request (didn't have previously)
...
...
@@ -68,6 +72,8 @@ type peer struct {
getAbsHeaders
absoluteHeaderFetcherFn
// [eth/62] Method to retrieve a batch of headers from an absolute position
getBlockBodies
blockBodyFetcherFn
// [eth/62] Method to retrieve a batch of block bodies
getReceipts
receiptFetcherFn
// [eth/63] Method to retrieve a batch of block transaction receipts
version
int
// Eth protocol version number to switch strategies
}
...
...
@@ -75,12 +81,14 @@ type peer struct {
// mechanisms.
func
newPeer
(
id
string
,
version
int
,
head
common
.
Hash
,
getRelHashes
relativeHashFetcherFn
,
getAbsHashes
absoluteHashFetcherFn
,
getBlocks
blockFetcherFn
,
// eth/61 callbacks, remove when upgrading
getRelHeaders
relativeHeaderFetcherFn
,
getAbsHeaders
absoluteHeaderFetcherFn
,
getBlockBodies
blockBodyFetcherFn
)
*
peer
{
getRelHeaders
relativeHeaderFetcherFn
,
getAbsHeaders
absoluteHeaderFetcherFn
,
getBlockBodies
blockBodyFetcherFn
,
getReceipts
receiptFetcherFn
)
*
peer
{
return
&
peer
{
id
:
id
,
head
:
head
,
capacity
:
1
,
ignored
:
set
.
New
(),
id
:
id
,
head
:
head
,
blockCapacity
:
1
,
receiptCapacity
:
1
,
ignored
:
set
.
New
(),
getRelHashes
:
getRelHashes
,
getAbsHashes
:
getAbsHashes
,
...
...
@@ -90,24 +98,28 @@ func newPeer(id string, version int, head common.Hash,
getAbsHeaders
:
getAbsHeaders
,
getBlockBodies
:
getBlockBodies
,
getReceipts
:
getReceipts
,
version
:
version
,
}
}
// Reset clears the internal state of a peer entity.
func
(
p
*
peer
)
Reset
()
{
atomic
.
StoreInt32
(
&
p
.
idle
,
0
)
atomic
.
StoreInt32
(
&
p
.
capacity
,
1
)
atomic
.
StoreInt32
(
&
p
.
blockIdle
,
0
)
atomic
.
StoreInt32
(
&
p
.
receiptIdle
,
0
)
atomic
.
StoreInt32
(
&
p
.
blockCapacity
,
1
)
atomic
.
StoreInt32
(
&
p
.
receiptCapacity
,
1
)
p
.
ignored
.
Clear
()
}
// Fetch61 sends a block retrieval request to the remote peer.
func
(
p
*
peer
)
Fetch61
(
request
*
fetchRequest
)
error
{
// Short circuit if the peer is already fetching
if
!
atomic
.
CompareAndSwapInt32
(
&
p
.
i
dle
,
0
,
1
)
{
if
!
atomic
.
CompareAndSwapInt32
(
&
p
.
blockI
dle
,
0
,
1
)
{
return
errAlreadyFetching
}
p
.
s
tarted
=
time
.
Now
()
p
.
blockS
tarted
=
time
.
Now
()
// Convert the hash set to a retrievable slice
hashes
:=
make
([]
common
.
Hash
,
0
,
len
(
request
.
Hashes
))
...
...
@@ -119,13 +131,13 @@ func (p *peer) Fetch61(request *fetchRequest) error {
return
nil
}
// Fetch sends a block body retrieval request to the remote peer.
func
(
p
*
peer
)
Fetch
(
request
*
fetchRequest
)
error
{
// Fetch
Bodies
sends a block body retrieval request to the remote peer.
func
(
p
*
peer
)
Fetch
Bodies
(
request
*
fetchRequest
)
error
{
// Short circuit if the peer is already fetching
if
!
atomic
.
CompareAndSwapInt32
(
&
p
.
i
dle
,
0
,
1
)
{
if
!
atomic
.
CompareAndSwapInt32
(
&
p
.
blockI
dle
,
0
,
1
)
{
return
errAlreadyFetching
}
p
.
s
tarted
=
time
.
Now
()
p
.
blockS
tarted
=
time
.
Now
()
// Convert the header set to a retrievable slice
hashes
:=
make
([]
common
.
Hash
,
0
,
len
(
request
.
Headers
))
...
...
@@ -137,55 +149,64 @@ func (p *peer) Fetch(request *fetchRequest) error {
return
nil
}
// SetIdle61 sets the peer to idle, allowing it to execute new retrieval requests.
// Its block retrieval allowance will also be updated either up- or downwards,
// depending on whether the previous fetch completed in time or not.
func
(
p
*
peer
)
SetIdle61
()
{
// Update the peer's download allowance based on previous performance
scale
:=
2.0
if
time
.
Since
(
p
.
started
)
>
blockSoftTTL
{
scale
=
0.5
if
time
.
Since
(
p
.
started
)
>
blockHardTTL
{
scale
=
1
/
float64
(
MaxBlockFetch
)
// reduces capacity to 1
}
// FetchReceipts sends a receipt retrieval request to the remote peer.
func
(
p
*
peer
)
FetchReceipts
(
request
*
fetchRequest
)
error
{
// Short circuit if the peer is already fetching
if
!
atomic
.
CompareAndSwapInt32
(
&
p
.
receiptIdle
,
0
,
1
)
{
return
errAlreadyFetching
}
for
{
// Calculate the new download bandwidth allowance
prev
:=
atomic
.
LoadInt32
(
&
p
.
capacity
)
next
:=
int32
(
math
.
Max
(
1
,
math
.
Min
(
float64
(
MaxBlockFetch
),
float64
(
prev
)
*
scale
)))
p
.
receiptStarted
=
time
.
Now
()
// Try to update the old value
if
atomic
.
CompareAndSwapInt32
(
&
p
.
capacity
,
prev
,
next
)
{
// If we're having problems at 1 capacity, try to find better peers
if
next
==
1
{
p
.
Demote
()
}
break
}
// Convert the header set to a retrievable slice
hashes
:=
make
([]
common
.
Hash
,
0
,
len
(
request
.
Headers
))
for
_
,
header
:=
range
request
.
Headers
{
hashes
=
append
(
hashes
,
header
.
Hash
())
}
// Set the peer to idle to allow further block requests
atomic
.
StoreInt32
(
&
p
.
idle
,
0
)
go
p
.
getReceipts
(
hashes
)
return
nil
}
// SetBlocksIdle sets the peer to idle, allowing it to execute new retrieval requests.
// Its block retrieval allowance will also be updated either up- or downwards,
// depending on whether the previous fetch completed in time or not.
func
(
p
*
peer
)
SetBlocksIdle
()
{
p
.
setIdle
(
p
.
blockStarted
,
blockSoftTTL
,
blockHardTTL
,
MaxBlockFetch
,
&
p
.
blockCapacity
,
&
p
.
blockIdle
)
}
// SetIdle sets the peer to idle, allowing it to execute new retrieval requests.
// Set
Bodies
Idle sets the peer to idle, allowing it to execute new retrieval requests.
// Its block body retrieval allowance will also be updated either up- or downwards,
// depending on whether the previous fetch completed in time or not.
func
(
p
*
peer
)
SetIdle
()
{
func
(
p
*
peer
)
SetBodiesIdle
()
{
p
.
setIdle
(
p
.
blockStarted
,
bodySoftTTL
,
bodyHardTTL
,
MaxBlockFetch
,
&
p
.
blockCapacity
,
&
p
.
blockIdle
)
}
// SetReceiptsIdle sets the peer to idle, allowing it to execute new retrieval requests.
// Its receipt retrieval allowance will also be updated either up- or downwards,
// depending on whether the previous fetch completed in time or not.
func
(
p
*
peer
)
SetReceiptsIdle
()
{
p
.
setIdle
(
p
.
receiptStarted
,
receiptSoftTTL
,
receiptHardTTL
,
MaxReceiptFetch
,
&
p
.
receiptCapacity
,
&
p
.
receiptIdle
)
}
// setIdle sets the peer to idle, allowing it to execute new retrieval requests.
// Its data retrieval allowance will also be updated either up- or downwards,
// depending on whether the previous fetch completed in time or not.
func
(
p
*
peer
)
setIdle
(
started
time
.
Time
,
softTTL
,
hardTTL
time
.
Duration
,
maxFetch
int
,
capacity
,
idle
*
int32
)
{
// Update the peer's download allowance based on previous performance
scale
:=
2.0
if
time
.
Since
(
p
.
started
)
>
bodyS
oftTTL
{
if
time
.
Since
(
started
)
>
s
oftTTL
{
scale
=
0.5
if
time
.
Since
(
p
.
started
)
>
bodyH
ardTTL
{
scale
=
1
/
float64
(
MaxBody
Fetch
)
// reduces capacity to 1
if
time
.
Since
(
started
)
>
h
ardTTL
{
scale
=
1
/
float64
(
max
Fetch
)
// reduces capacity to 1
}
}
for
{
// Calculate the new download bandwidth allowance
prev
:=
atomic
.
LoadInt32
(
&
p
.
capacity
)
next
:=
int32
(
math
.
Max
(
1
,
math
.
Min
(
float64
(
MaxBody
Fetch
),
float64
(
prev
)
*
scale
)))
prev
:=
atomic
.
LoadInt32
(
capacity
)
next
:=
int32
(
math
.
Max
(
1
,
math
.
Min
(
float64
(
max
Fetch
),
float64
(
prev
)
*
scale
)))
// Try to update the old value
if
atomic
.
CompareAndSwapInt32
(
&
p
.
capacity
,
prev
,
next
)
{
if
atomic
.
CompareAndSwapInt32
(
capacity
,
prev
,
next
)
{
// If we're having problems at 1 capacity, try to find better peers
if
next
==
1
{
p
.
Demote
()
...
...
@@ -193,14 +214,20 @@ func (p *peer) SetIdle() {
break
}
}
// Set the peer to idle to allow further block requests
atomic
.
StoreInt32
(
&
p
.
idle
,
0
)
// Set the peer to idle to allow further fetch requests
atomic
.
StoreInt32
(
idle
,
0
)
}
// BlockCapacity retrieves the peers block download allowance based on its
// previously discovered bandwidth capacity.
func
(
p
*
peer
)
BlockCapacity
()
int
{
return
int
(
atomic
.
LoadInt32
(
&
p
.
blockCapacity
))
}
//
Capacity retrieves the peers block download allowance based on its previously
// discovered bandwidth capacity.
func
(
p
*
peer
)
Capacity
()
int
{
return
int
(
atomic
.
LoadInt32
(
&
p
.
c
apacity
))
//
ReceiptCapacity retrieves the peers block download allowance based on its
//
previously
discovered bandwidth capacity.
func
(
p
*
peer
)
Receipt
Capacity
()
int
{
return
int
(
atomic
.
LoadInt32
(
&
p
.
receiptC
apacity
))
}
// Promote increases the peer's reputation.
...
...
@@ -226,7 +253,8 @@ func (p *peer) Demote() {
func
(
p
*
peer
)
String
()
string
{
return
fmt
.
Sprintf
(
"Peer %s [%s]"
,
p
.
id
,
fmt
.
Sprintf
(
"reputation %3d, "
,
atomic
.
LoadInt32
(
&
p
.
rep
))
+
fmt
.
Sprintf
(
"capacity %3d, "
,
atomic
.
LoadInt32
(
&
p
.
capacity
))
+
fmt
.
Sprintf
(
"block cap %3d, "
,
atomic
.
LoadInt32
(
&
p
.
blockCapacity
))
+
fmt
.
Sprintf
(
"receipt cap %3d, "
,
atomic
.
LoadInt32
(
&
p
.
receiptCapacity
))
+
fmt
.
Sprintf
(
"ignored %4d"
,
p
.
ignored
.
Size
()),
)
}
...
...
@@ -310,26 +338,52 @@ func (ps *peerSet) AllPeers() []*peer {
return
list
}
// IdlePeers retrieves a flat list of all the currently idle peers within the
//
Block
IdlePeers retrieves a flat list of all the currently idle peers within the
// active peer set, ordered by their reputation.
func
(
ps
*
peerSet
)
IdlePeers
(
version
int
)
[]
*
peer
{
func
(
ps
*
peerSet
)
BlockIdlePeers
(
version
int
)
([]
*
peer
,
int
)
{
ps
.
lock
.
RLock
()
defer
ps
.
lock
.
RUnlock
()
list
:=
make
([]
*
peer
,
0
,
len
(
ps
.
peers
))
idle
,
total
:=
make
([]
*
peer
,
0
,
len
(
ps
.
peers
)),
0
for
_
,
p
:=
range
ps
.
peers
{
if
(
version
==
eth61
&&
p
.
version
==
eth61
)
||
(
version
>=
eth62
&&
p
.
version
>=
eth
62
)
{
if
atomic
.
LoadInt32
(
&
p
.
i
dle
)
==
0
{
list
=
append
(
list
,
p
)
if
(
version
==
61
&&
p
.
version
==
61
)
||
(
version
>=
62
&&
p
.
version
>=
62
)
{
if
atomic
.
LoadInt32
(
&
p
.
blockI
dle
)
==
0
{
idle
=
append
(
idle
,
p
)
}
total
++
}
}
for
i
:=
0
;
i
<
len
(
list
);
i
++
{
for
j
:=
i
+
1
;
j
<
len
(
list
);
j
++
{
if
atomic
.
LoadInt32
(
&
list
[
i
]
.
rep
)
<
atomic
.
LoadInt32
(
&
list
[
j
]
.
rep
)
{
list
[
i
],
list
[
j
]
=
list
[
j
],
list
[
i
]
for
i
:=
0
;
i
<
len
(
idle
);
i
++
{
for
j
:=
i
+
1
;
j
<
len
(
idle
);
j
++
{
if
atomic
.
LoadInt32
(
&
idle
[
i
]
.
rep
)
<
atomic
.
LoadInt32
(
&
idle
[
j
]
.
rep
)
{
idle
[
i
],
idle
[
j
]
=
idle
[
j
],
idle
[
i
]
}
}
}
return
list
return
idle
,
total
}
// ReceiptIdlePeers retrieves a flat list of all the currently idle peers within the
// active peer set, ordered by their reputation.
func
(
ps
*
peerSet
)
ReceiptIdlePeers
()
([]
*
peer
,
int
)
{
ps
.
lock
.
RLock
()
defer
ps
.
lock
.
RUnlock
()
idle
,
total
:=
make
([]
*
peer
,
0
,
len
(
ps
.
peers
)),
0
for
_
,
p
:=
range
ps
.
peers
{
if
p
.
version
>=
63
{
if
atomic
.
LoadInt32
(
&
p
.
receiptIdle
)
==
0
{
idle
=
append
(
idle
,
p
)
}
total
++
}
}
for
i
:=
0
;
i
<
len
(
idle
);
i
++
{
for
j
:=
i
+
1
;
j
<
len
(
idle
);
j
++
{
if
atomic
.
LoadInt32
(
&
idle
[
i
]
.
rep
)
<
atomic
.
LoadInt32
(
&
idle
[
j
]
.
rep
)
{
idle
[
i
],
idle
[
j
]
=
idle
[
j
],
idle
[
i
]
}
}
}
return
idle
,
total
}
eth/downloader/queue.go
浏览文件 @
f186b390
此差异已折叠。
点击以展开。
eth/handler.go
浏览文件 @
f186b390
...
...
@@ -120,15 +120,25 @@ func NewProtocolManager(mode Mode, networkId int, mux *event.TypeMux, txpool txP
return
nil
,
errIncompatibleConfig
}
// Construct the different synchronisation mechanisms
manager
.
downloader
=
downloader
.
New
(
manager
.
eventMux
,
manager
.
blockchain
.
HasBlock
,
manager
.
blockchain
.
GetBlock
,
manager
.
blockchain
.
CurrentBlock
,
manager
.
blockchain
.
GetTd
,
manager
.
blockchain
.
InsertChain
,
manager
.
removePeer
)
var
syncMode
downloader
.
SyncMode
switch
mode
{
case
ArchiveMode
:
syncMode
=
downloader
.
FullSync
case
FullMode
:
syncMode
=
downloader
.
FastSync
case
LightMode
:
syncMode
=
downloader
.
LightSync
}
manager
.
downloader
=
downloader
.
New
(
syncMode
,
manager
.
eventMux
,
blockchain
.
HasHeader
,
blockchain
.
HasBlock
,
blockchain
.
GetHeader
,
blockchain
.
GetBlock
,
blockchain
.
CurrentHeader
,
blockchain
.
CurrentBlock
,
blockchain
.
GetTd
,
blockchain
.
InsertHeaderChain
,
blockchain
.
InsertChain
,
nil
,
manager
.
removePeer
)
validator
:=
func
(
block
*
types
.
Block
,
parent
*
types
.
Block
)
error
{
return
core
.
ValidateHeader
(
pow
,
block
.
Header
(),
parent
.
Header
(),
true
,
false
)
}
heighter
:=
func
()
uint64
{
return
manager
.
blockchain
.
CurrentBlock
()
.
NumberU64
()
return
blockchain
.
CurrentBlock
()
.
NumberU64
()
}
manager
.
fetcher
=
fetcher
.
New
(
manager
.
blockchain
.
GetBlock
,
validator
,
manager
.
BroadcastBlock
,
heighter
,
manager
.
blockchain
.
InsertChain
,
manager
.
removePeer
)
manager
.
fetcher
=
fetcher
.
New
(
blockchain
.
GetBlock
,
validator
,
manager
.
BroadcastBlock
,
heighter
,
blockchain
.
InsertChain
,
manager
.
removePeer
)
return
manager
,
nil
}
...
...
@@ -210,7 +220,7 @@ func (pm *ProtocolManager) handle(p *peer) error {
// Register the peer in the downloader. If the downloader considers it banned, we disconnect
if
err
:=
pm
.
downloader
.
RegisterPeer
(
p
.
id
,
p
.
version
,
p
.
Head
(),
p
.
RequestHashes
,
p
.
RequestHashesFromNumber
,
p
.
RequestBlocks
,
p
.
RequestHeadersByHash
,
p
.
RequestHeadersByNumber
,
p
.
RequestBodies
);
err
!=
nil
{
p
.
RequestHeadersByHash
,
p
.
RequestHeadersByNumber
,
p
.
RequestBodies
,
p
.
RequestReceipts
);
err
!=
nil
{
return
err
}
// Propagate existing transactions. new transactions appearing
...
...
@@ -514,22 +524,31 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
var
(
hash
common
.
Hash
bytes
int
receipts
[]
*
types
.
Receipt
receipts
[]
rlp
.
RawValue
)
for
bytes
<
softResponseLimit
&&
len
(
receipts
)
<
downloader
.
MaxReceipt
s
Fetch
{
// Retrieve the hash of the next
transaction receipt
for
bytes
<
softResponseLimit
&&
len
(
receipts
)
<
downloader
.
MaxReceiptFetch
{
// Retrieve the hash of the next
block
if
err
:=
msgStream
.
Decode
(
&
hash
);
err
==
rlp
.
EOL
{
break
}
else
if
err
!=
nil
{
return
errResp
(
ErrDecode
,
"msg %v: %v"
,
msg
,
err
)
}
// Retrieve the requested receipt, stopping if enough was found
if
receipt
:=
core
.
GetReceipt
(
pm
.
chaindb
,
hash
);
receipt
!=
nil
{
receipts
=
append
(
receipts
,
receipt
)
bytes
+=
len
(
receipt
.
RlpEncode
())
// Retrieve the requested block's receipts, skipping if unknown to us
results
:=
core
.
GetBlockReceipts
(
pm
.
chaindb
,
hash
)
if
results
==
nil
{
if
header
:=
pm
.
blockchain
.
GetHeader
(
hash
);
header
==
nil
||
header
.
ReceiptHash
!=
types
.
EmptyRootHash
{
continue
}
}
// If known, encode and queue for response packet
if
encoded
,
err
:=
rlp
.
EncodeToBytes
(
results
);
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"failed to encode receipt: %v"
,
err
)
}
else
{
receipts
=
append
(
receipts
,
encoded
)
bytes
+=
len
(
encoded
)
}
}
return
p
.
SendReceipts
(
receipts
)
return
p
.
SendReceipts
RLP
(
receipts
)
case
msg
.
Code
==
NewBlockHashesMsg
:
// Retrieve and deseralize the remote new block hashes notification
...
...
eth/handler_test.go
浏览文件 @
f186b390
...
...
@@ -535,15 +535,12 @@ func testGetReceipt(t *testing.T, protocol int) {
defer
peer
.
close
()
// Collect the hashes to request, and the response to expect
hashes
:=
[]
common
.
Hash
{}
hashes
,
receipts
:=
[]
common
.
Hash
{},
[]
types
.
Receipts
{}
for
i
:=
uint64
(
0
);
i
<=
pm
.
blockchain
.
CurrentBlock
()
.
NumberU64
();
i
++
{
for
_
,
tx
:=
range
pm
.
blockchain
.
GetBlockByNumber
(
i
)
.
Transactions
()
{
hashes
=
append
(
hashes
,
tx
.
Hash
())
}
}
receipts
:=
make
([]
*
types
.
Receipt
,
len
(
hashes
))
for
i
,
hash
:=
range
hashes
{
receipts
[
i
]
=
core
.
GetReceipt
(
pm
.
chaindb
,
hash
)
block
:=
pm
.
blockchain
.
GetBlockByNumber
(
i
)
hashes
=
append
(
hashes
,
block
.
Hash
())
receipts
=
append
(
receipts
,
core
.
GetBlockReceipts
(
pm
.
chaindb
,
block
.
Hash
()))
}
// Send the hash request and verify the response
p2p
.
Send
(
peer
.
app
,
0x0f
,
hashes
)
...
...
eth/peer.go
浏览文件 @
f186b390
...
...
@@ -197,9 +197,9 @@ func (p *peer) SendNodeData(data [][]byte) error {
return
p2p
.
Send
(
p
.
rw
,
NodeDataMsg
,
data
)
}
// SendReceipts
sends a batch of transaction receipts, corresponding to the ones
//
requested
.
func
(
p
*
peer
)
SendReceipts
(
receipts
[]
*
types
.
Receipt
)
error
{
// SendReceipts
RLP sends a batch of transaction receipts, corresponding to the
//
ones requested from an already RLP encoded format
.
func
(
p
*
peer
)
SendReceipts
RLP
(
receipts
[]
rlp
.
RawValue
)
error
{
return
p2p
.
Send
(
p
.
rw
,
ReceiptsMsg
,
receipts
)
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录