Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
049f5b35
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,发现更多精彩内容 >>
提交
049f5b35
编写于
6月 12, 2018
作者:
F
Felföldi Zsolt
提交者:
Péter Szilágyi
6月 12, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
core, eth, les: more efficient hash-based header chain retrieval (#16946)
上级
02559515
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
106 addition
and
27 deletion
+106
-27
core/blockchain.go
core/blockchain.go
+12
-0
core/headerchain.go
core/headerchain.go
+37
-0
eth/handler.go
eth/handler.go
+23
-14
les/handler.go
les/handler.go
+22
-13
light/lightchain.go
light/lightchain.go
+12
-0
未找到文件。
core/blockchain.go
浏览文件 @
049f5b35
...
...
@@ -1524,6 +1524,18 @@ func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []com
return
bc
.
hc
.
GetBlockHashesFromHash
(
hash
,
max
)
}
// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
// number of blocks to be individually checked before we reach the canonical chain.
//
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
func
(
bc
*
BlockChain
)
GetAncestor
(
hash
common
.
Hash
,
number
,
ancestor
uint64
,
maxNonCanonical
*
uint64
)
(
common
.
Hash
,
uint64
)
{
bc
.
chainmu
.
Lock
()
defer
bc
.
chainmu
.
Unlock
()
return
bc
.
hc
.
GetAncestor
(
hash
,
number
,
ancestor
,
maxNonCanonical
)
}
// GetHeaderByNumber retrieves a block header from the database by number,
// caching it (associated with its hash) if found.
func
(
bc
*
BlockChain
)
GetHeaderByNumber
(
number
uint64
)
*
types
.
Header
{
...
...
core/headerchain.go
浏览文件 @
049f5b35
...
...
@@ -307,6 +307,43 @@ func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []co
return
chain
}
// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
// number of blocks to be individually checked before we reach the canonical chain.
//
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
func
(
hc
*
HeaderChain
)
GetAncestor
(
hash
common
.
Hash
,
number
,
ancestor
uint64
,
maxNonCanonical
*
uint64
)
(
common
.
Hash
,
uint64
)
{
if
ancestor
>
number
{
return
common
.
Hash
{},
0
}
if
ancestor
==
1
{
// in this case it is cheaper to just read the header
if
header
:=
hc
.
GetHeader
(
hash
,
number
);
header
!=
nil
{
return
header
.
ParentHash
,
number
-
1
}
else
{
return
common
.
Hash
{},
0
}
}
for
ancestor
!=
0
{
if
rawdb
.
ReadCanonicalHash
(
hc
.
chainDb
,
number
)
==
hash
{
number
-=
ancestor
return
rawdb
.
ReadCanonicalHash
(
hc
.
chainDb
,
number
),
number
}
if
*
maxNonCanonical
==
0
{
return
common
.
Hash
{},
0
}
*
maxNonCanonical
--
ancestor
--
header
:=
hc
.
GetHeader
(
hash
,
number
)
if
header
==
nil
{
return
common
.
Hash
{},
0
}
hash
=
header
.
ParentHash
number
--
}
return
hash
,
number
}
// GetTd retrieves a block's total difficulty in the canonical chain from the
// database by hash and number, caching it if found.
func
(
hc
*
HeaderChain
)
GetTd
(
hash
common
.
Hash
,
number
uint64
)
*
big
.
Int
{
...
...
eth/handler.go
浏览文件 @
049f5b35
...
...
@@ -340,6 +340,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
return
errResp
(
ErrDecode
,
"%v: %v"
,
msg
,
err
)
}
hashMode
:=
query
.
Origin
.
Hash
!=
(
common
.
Hash
{})
first
:=
true
maxNonCanonical
:=
uint64
(
100
)
// Gather headers until the fetch or network limits is reached
var
(
...
...
@@ -351,31 +353,36 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
// Retrieve the next header satisfying the query
var
origin
*
types
.
Header
if
hashMode
{
origin
=
pm
.
blockchain
.
GetHeaderByHash
(
query
.
Origin
.
Hash
)
if
first
{
first
=
false
origin
=
pm
.
blockchain
.
GetHeaderByHash
(
query
.
Origin
.
Hash
)
if
origin
!=
nil
{
query
.
Origin
.
Number
=
origin
.
Number
.
Uint64
()
}
}
else
{
origin
=
pm
.
blockchain
.
GetHeader
(
query
.
Origin
.
Hash
,
query
.
Origin
.
Number
)
}
}
else
{
origin
=
pm
.
blockchain
.
GetHeaderByNumber
(
query
.
Origin
.
Number
)
}
if
origin
==
nil
{
break
}
number
:=
origin
.
Number
.
Uint64
()
headers
=
append
(
headers
,
origin
)
bytes
+=
estHeaderRlpSize
// Advance to the next header of the query
switch
{
case
query
.
Origin
.
Hash
!=
(
common
.
Hash
{})
&&
query
.
Reverse
:
case
hashMode
&&
query
.
Reverse
:
// Hash based traversal towards the genesis block
for
i
:=
0
;
i
<
int
(
query
.
Skip
)
+
1
;
i
++
{
if
header
:=
pm
.
blockchain
.
GetHeader
(
query
.
Origin
.
Hash
,
number
);
header
!=
nil
{
query
.
Origin
.
Hash
=
header
.
ParentHash
number
--
}
else
{
unknown
=
true
break
}
ancestor
:=
query
.
Skip
+
1
if
ancestor
==
0
{
unknown
=
true
}
else
{
query
.
Origin
.
Hash
,
query
.
Origin
.
Number
=
pm
.
blockchain
.
GetAncestor
(
query
.
Origin
.
Hash
,
query
.
Origin
.
Number
,
ancestor
,
&
maxNonCanonical
)
unknown
=
(
query
.
Origin
.
Hash
==
common
.
Hash
{})
}
case
query
.
Origin
.
Hash
!=
(
common
.
Hash
{})
&&
!
query
.
Reverse
:
case
hashMode
&&
!
query
.
Reverse
:
// Hash based traversal towards the leaf block
var
(
current
=
origin
.
Number
.
Uint64
()
...
...
@@ -387,8 +394,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
unknown
=
true
}
else
{
if
header
:=
pm
.
blockchain
.
GetHeaderByNumber
(
next
);
header
!=
nil
{
if
pm
.
blockchain
.
GetBlockHashesFromHash
(
header
.
Hash
(),
query
.
Skip
+
1
)[
query
.
Skip
]
==
query
.
Origin
.
Hash
{
query
.
Origin
.
Hash
=
header
.
Hash
()
nextHash
:=
header
.
Hash
()
expOldHash
,
_
:=
pm
.
blockchain
.
GetAncestor
(
nextHash
,
next
,
query
.
Skip
+
1
,
&
maxNonCanonical
)
if
expOldHash
==
query
.
Origin
.
Hash
{
query
.
Origin
.
Hash
,
query
.
Origin
.
Number
=
nextHash
,
next
}
else
{
unknown
=
true
}
...
...
les/handler.go
浏览文件 @
049f5b35
...
...
@@ -83,7 +83,7 @@ type BlockChain interface {
InsertHeaderChain
(
chain
[]
*
types
.
Header
,
checkFreq
int
)
(
int
,
error
)
Rollback
(
chain
[]
common
.
Hash
)
GetHeaderByNumber
(
number
uint64
)
*
types
.
Header
Get
BlockHashesFromHash
(
hash
common
.
Hash
,
max
uint64
)
[]
common
.
Hash
Get
Ancestor
(
hash
common
.
Hash
,
number
,
ancestor
uint64
,
maxNonCanonical
*
uint64
)
(
common
.
Hash
,
uint64
)
Genesis
()
*
types
.
Block
SubscribeChainHeadEvent
(
ch
chan
<-
core
.
ChainHeadEvent
)
event
.
Subscription
}
...
...
@@ -419,6 +419,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
hashMode
:=
query
.
Origin
.
Hash
!=
(
common
.
Hash
{})
first
:=
true
maxNonCanonical
:=
uint64
(
100
)
// Gather headers until the fetch or network limits is reached
var
(
...
...
@@ -430,14 +432,21 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
// Retrieve the next header satisfying the query
var
origin
*
types
.
Header
if
hashMode
{
origin
=
pm
.
blockchain
.
GetHeaderByHash
(
query
.
Origin
.
Hash
)
if
first
{
first
=
false
origin
=
pm
.
blockchain
.
GetHeaderByHash
(
query
.
Origin
.
Hash
)
if
origin
!=
nil
{
query
.
Origin
.
Number
=
origin
.
Number
.
Uint64
()
}
}
else
{
origin
=
pm
.
blockchain
.
GetHeader
(
query
.
Origin
.
Hash
,
query
.
Origin
.
Number
)
}
}
else
{
origin
=
pm
.
blockchain
.
GetHeaderByNumber
(
query
.
Origin
.
Number
)
}
if
origin
==
nil
{
break
}
number
:=
origin
.
Number
.
Uint64
()
headers
=
append
(
headers
,
origin
)
bytes
+=
estHeaderRlpSize
...
...
@@ -445,14 +454,12 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
switch
{
case
hashMode
&&
query
.
Reverse
:
// Hash based traversal towards the genesis block
for
i
:=
0
;
i
<
int
(
query
.
Skip
)
+
1
;
i
++
{
if
header
:=
pm
.
blockchain
.
GetHeader
(
query
.
Origin
.
Hash
,
number
);
header
!=
nil
{
query
.
Origin
.
Hash
=
header
.
ParentHash
number
--
}
else
{
unknown
=
true
break
}
ancestor
:=
query
.
Skip
+
1
if
ancestor
==
0
{
unknown
=
true
}
else
{
query
.
Origin
.
Hash
,
query
.
Origin
.
Number
=
pm
.
blockchain
.
GetAncestor
(
query
.
Origin
.
Hash
,
query
.
Origin
.
Number
,
ancestor
,
&
maxNonCanonical
)
unknown
=
(
query
.
Origin
.
Hash
==
common
.
Hash
{})
}
case
hashMode
&&
!
query
.
Reverse
:
// Hash based traversal towards the leaf block
...
...
@@ -466,8 +473,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
unknown
=
true
}
else
{
if
header
:=
pm
.
blockchain
.
GetHeaderByNumber
(
next
);
header
!=
nil
{
if
pm
.
blockchain
.
GetBlockHashesFromHash
(
header
.
Hash
(),
query
.
Skip
+
1
)[
query
.
Skip
]
==
query
.
Origin
.
Hash
{
query
.
Origin
.
Hash
=
header
.
Hash
()
nextHash
:=
header
.
Hash
()
expOldHash
,
_
:=
pm
.
blockchain
.
GetAncestor
(
nextHash
,
next
,
query
.
Skip
+
1
,
&
maxNonCanonical
)
if
expOldHash
==
query
.
Origin
.
Hash
{
query
.
Origin
.
Hash
,
query
.
Origin
.
Number
=
nextHash
,
next
}
else
{
unknown
=
true
}
...
...
light/lightchain.go
浏览文件 @
049f5b35
...
...
@@ -433,6 +433,18 @@ func (self *LightChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []c
return
self
.
hc
.
GetBlockHashesFromHash
(
hash
,
max
)
}
// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
// number of blocks to be individually checked before we reach the canonical chain.
//
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
func
(
bc
*
LightChain
)
GetAncestor
(
hash
common
.
Hash
,
number
,
ancestor
uint64
,
maxNonCanonical
*
uint64
)
(
common
.
Hash
,
uint64
)
{
bc
.
chainmu
.
Lock
()
defer
bc
.
chainmu
.
Unlock
()
return
bc
.
hc
.
GetAncestor
(
hash
,
number
,
ancestor
,
maxNonCanonical
)
}
// GetHeaderByNumber retrieves a block header from the database by number,
// caching it (associated with its hash) if found.
func
(
self
*
LightChain
)
GetHeaderByNumber
(
number
uint64
)
*
types
.
Header
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录