Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
47ca6904
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,体验更适合开发者的 AI 搜索 >>
提交
47ca6904
编写于
9月 18, 2015
作者:
G
Gustav Simonsson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
tests: use lastblockhash field to validate reorgs and block headers
上级
075815e5
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
58 addition
and
48 deletion
+58
-48
cmd/geth/blocktestcmd.go
cmd/geth/blocktestcmd.go
+9
-7
tests/block_test_util.go
tests/block_test_util.go
+49
-41
未找到文件。
cmd/geth/blocktestcmd.go
浏览文件 @
47ca6904
...
...
@@ -111,25 +111,27 @@ func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, er
if
err
!=
nil
{
return
nil
,
err
}
// if err := ethereum.Start(); err != nil {
// return nil, err
// }
// import the genesis block
ethereum
.
ResetWithGenesisBlock
(
test
.
Genesis
)
// import pre accounts
statedb
,
err
:
=
test
.
InsertPreState
(
ethereum
)
_
,
err
=
test
.
InsertPreState
(
ethereum
)
if
err
!=
nil
{
return
ethereum
,
fmt
.
Errorf
(
"InsertPreState: %v"
,
err
)
}
if
err
:=
test
.
TryBlocksInsert
(
ethereum
.
ChainManager
());
err
!=
nil
{
cm
:=
ethereum
.
ChainManager
()
validBlocks
,
err
:=
test
.
TryBlocksInsert
(
cm
)
if
err
!=
nil
{
return
ethereum
,
fmt
.
Errorf
(
"Block Test load error: %v"
,
err
)
}
if
err
:=
test
.
ValidatePostState
(
statedb
);
err
!=
nil
{
newDB
:=
cm
.
State
()
if
err
:=
test
.
ValidatePostState
(
newDB
);
err
!=
nil
{
return
ethereum
,
fmt
.
Errorf
(
"post state validation failed: %v"
,
err
)
}
return
ethereum
,
nil
return
ethereum
,
test
.
ValidateImportedHeaders
(
cm
,
validBlocks
)
}
tests/block_test_util.go
浏览文件 @
47ca6904
...
...
@@ -44,9 +44,10 @@ import (
type
BlockTest
struct
{
Genesis
*
types
.
Block
Json
*
btJSON
preAccounts
map
[
string
]
btAccount
postAccounts
map
[
string
]
btAccount
Json
*
btJSON
preAccounts
map
[
string
]
btAccount
postAccounts
map
[
string
]
btAccount
lastblockhash
string
}
type
btJSON
struct
{
...
...
@@ -54,6 +55,7 @@ type btJSON struct {
GenesisBlockHeader
btHeader
Pre
map
[
string
]
btAccount
PostState
map
[
string
]
btAccount
Lastblockhash
string
}
type
btBlock
struct
{
...
...
@@ -77,6 +79,7 @@ type btHeader struct {
MixHash
string
Nonce
string
Number
string
Hash
string
ParentHash
string
ReceiptTrie
string
SeedHash
string
...
...
@@ -178,16 +181,24 @@ func runBlockTest(test *BlockTest) error {
return
fmt
.
Errorf
(
"InsertPreState: %v"
,
err
)
}
err
=
test
.
TryBlocksInsert
(
ethereum
.
ChainManager
())
cm
:=
ethereum
.
ChainManager
()
validBlocks
,
err
:=
test
.
TryBlocksInsert
(
cm
)
if
err
!=
nil
{
return
err
}
newDB
:=
ethereum
.
ChainManager
()
.
State
()
lastblockhash
:=
common
.
HexToHash
(
test
.
lastblockhash
)
cmlast
:=
cm
.
LastBlockHash
()
if
lastblockhash
!=
cmlast
{
return
fmt
.
Errorf
(
"lastblockhash validation mismatch: want: %x, have: %x"
,
lastblockhash
,
cmlast
)
}
newDB
:=
cm
.
State
()
if
err
=
test
.
ValidatePostState
(
newDB
);
err
!=
nil
{
return
fmt
.
Errorf
(
"post state validation failed: %v"
,
err
)
}
return
nil
return
test
.
ValidateImportedHeaders
(
cm
,
validBlocks
)
}
func
(
test
*
BlockTest
)
makeEthConfig
()
*
eth
.
Config
{
...
...
@@ -265,8 +276,8 @@ func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, erro
expected we are expected to ignore it and continue processing and then validate the
post state.
*/
func
(
t
*
BlockTest
)
TryBlocksInsert
(
chainManager
*
core
.
ChainManager
)
error
{
blockNums
:=
make
(
map
[
string
]
bool
)
func
(
t
*
BlockTest
)
TryBlocksInsert
(
chainManager
*
core
.
ChainManager
)
([]
btBlock
,
error
)
{
validBlocks
:=
make
([]
btBlock
,
0
)
// insert the test blocks, which will execute all transactions
for
_
,
b
:=
range
t
.
Json
.
Blocks
{
cb
,
err
:=
mustConvertBlock
(
b
)
...
...
@@ -274,7 +285,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
if
b
.
BlockHeader
==
nil
{
continue
// OK - block is supposed to be invalid, continue with next block
}
else
{
return
fmt
.
Errorf
(
"Block RLP decoding failed when expected to succeed: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"Block RLP decoding failed when expected to succeed: %v"
,
err
)
}
}
// RLP decoding worked, try to insert into chain:
...
...
@@ -283,47 +294,23 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
if
b
.
BlockHeader
==
nil
{
continue
// OK - block is supposed to be invalid, continue with next block
}
else
{
return
fmt
.
Errorf
(
"Block insertion into chain failed: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"Block insertion into chain failed: %v"
,
err
)
}
}
if
b
.
BlockHeader
==
nil
{
return
fmt
.
Errorf
(
"Block insertion should have failed"
)
return
nil
,
fmt
.
Errorf
(
"Block insertion should have failed"
)
}
// validate RLP decoding by checking all values against test file JSON
if
err
=
t
.
validateBlockHeader
(
b
.
BlockHeader
,
cb
.
Header
());
err
!=
nil
{
return
fmt
.
Errorf
(
"Deserialised block header validation failed: %v"
,
err
)
}
// validate the imported header against test file JSON
/*
TODO: currently test files do not contain information on what
reorg is expected other than possibly the post state (which may
or may not depend on a specific chain).
discussed with winswega and it was agreed to add this information
to the test files explicitly.
meanwhile we skip header validation on blocks with the same block
number as a prior block, since this test code cannot know what
blocks are in the longest chain without making use of the very
protocol rules the tests verify or rely on the correctness of the
code that is being tested.
*/
if
!
blockNums
[
b
.
BlockHeader
.
Number
]
{
importedBlock
:=
chainManager
.
CurrentBlock
()
if
err
=
t
.
validateBlockHeader
(
b
.
BlockHeader
,
importedBlock
.
Header
());
err
!=
nil
{
return
fmt
.
Errorf
(
"Imported block header validation failed: %v"
,
err
)
}
blockNums
[
b
.
BlockHeader
.
Number
]
=
true
if
err
=
validateHeader
(
b
.
BlockHeader
,
cb
.
Header
());
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Deserialised block header validation failed: %v"
,
err
)
}
validBlocks
=
append
(
validBlocks
,
b
)
}
return
nil
return
validBlocks
,
nil
}
func
(
s
*
BlockTest
)
validateBlock
Header
(
h
*
btHeader
,
h2
*
types
.
Header
)
error
{
func
validate
Header
(
h
*
btHeader
,
h2
*
types
.
Header
)
error
{
expectedBloom
:=
mustConvertBytes
(
h
.
Bloom
)
if
!
bytes
.
Equal
(
expectedBloom
,
h2
.
Bloom
.
Bytes
())
{
return
fmt
.
Errorf
(
"Bloom: want: %x have: %x"
,
expectedBloom
,
h2
.
Bloom
.
Bytes
())
...
...
@@ -439,6 +426,27 @@ func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error {
return
nil
}
func
(
test
*
BlockTest
)
ValidateImportedHeaders
(
cm
*
core
.
ChainManager
,
validBlocks
[]
btBlock
)
error
{
// to get constant lookup when verifying block headers by hash (some tests have many blocks)
bmap
:=
make
(
map
[
string
]
btBlock
,
len
(
test
.
Json
.
Blocks
))
for
_
,
b
:=
range
validBlocks
{
bmap
[
b
.
BlockHeader
.
Hash
]
=
b
}
// iterate over blocks backwards from HEAD and validate imported
// headers vs test file. some tests have reorgs, and we import
// block-by-block, so we can only validate imported headers after
// all blocks have been processed by ChainManager, as they may not
// be part of the longest chain until last block is imported.
for
b
:=
cm
.
CurrentBlock
();
b
!=
nil
&&
b
.
NumberU64
()
!=
0
;
b
=
cm
.
GetBlock
(
b
.
Header
()
.
ParentHash
)
{
bHash
:=
common
.
Bytes2Hex
(
b
.
Hash
()
.
Bytes
())
// hex without 0x prefix
if
err
:=
validateHeader
(
bmap
[
bHash
]
.
BlockHeader
,
b
.
Header
());
err
!=
nil
{
return
fmt
.
Errorf
(
"Imported block header validation failed: %v"
,
err
)
}
}
return
nil
}
func
convertBlockTests
(
in
map
[
string
]
*
btJSON
)
(
map
[
string
]
*
BlockTest
,
error
)
{
out
:=
make
(
map
[
string
]
*
BlockTest
)
for
name
,
test
:=
range
in
{
...
...
@@ -461,7 +469,7 @@ func convertBlockTest(in *btJSON) (out *BlockTest, err error) {
err
=
fmt
.
Errorf
(
"%v
\n
%s"
,
recovered
,
buf
)
}
}()
out
=
&
BlockTest
{
preAccounts
:
in
.
Pre
,
postAccounts
:
in
.
PostState
,
Json
:
in
}
out
=
&
BlockTest
{
preAccounts
:
in
.
Pre
,
postAccounts
:
in
.
PostState
,
Json
:
in
,
lastblockhash
:
in
.
Lastblockhash
}
out
.
Genesis
=
mustConvertGenesis
(
in
.
GenesisBlockHeader
)
return
out
,
err
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录