good morning!!!!
Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
B
bor
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Harbor Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
open
bor
Commits
47ca6904
Commit
47ca6904
authored
9 years ago
by
Gustav Simonsson
Browse files
Options
Downloads
Patches
Plain Diff
tests: use lastblockhash field to validate reorgs and block headers
parent
075815e5
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
cmd/geth/blocktestcmd.go
+9
-7
9 additions, 7 deletions
cmd/geth/blocktestcmd.go
tests/block_test_util.go
+49
-41
49 additions, 41 deletions
tests/block_test_util.go
with
58 additions
and
48 deletions
cmd/geth/blocktestcmd.go
+
9
−
7
View file @
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
)
}
This diff is collapsed.
Click to expand it.
tests/block_test_util.go
+
49
−
41
View file @
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
{
b
lock
Num
s
:=
make
(
map
[
string
]
bool
)
func
(
t
*
BlockTest
)
TryBlocksInsert
(
chainManager
*
core
.
ChainManager
)
([]
btBlock
,
error
)
{
validB
locks
:=
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
)
validate
Block
Header
(
h
*
btHeader
,
h2
*
types
.
Header
)
error
{
func
validateHeader
(
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
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment