aboutsummaryrefslogtreecommitdiffstats
path: root/tests/block_test_util.go
diff options
context:
space:
mode:
Diffstat (limited to 'tests/block_test_util.go')
-rw-r--r--tests/block_test_util.go103
1 files changed, 56 insertions, 47 deletions
diff --git a/tests/block_test_util.go b/tests/block_test_util.go
index 5c42ae18c..ed2a9fca2 100644
--- a/tests/block_test_util.go
+++ b/tests/block_test_util.go
@@ -19,6 +19,13 @@ import (
)
// Block Test JSON Format
+type BlockTest struct {
+ Genesis *types.Block
+
+ Json *btJSON
+ preAccounts map[string]btAccount
+}
+
type btJSON struct {
Blocks []btBlock
GenesisBlockHeader btHeader
@@ -26,6 +33,13 @@ type btJSON struct {
PostState map[string]btAccount
}
+type btBlock struct {
+ BlockHeader *btHeader
+ Rlp string
+ Transactions []btTransaction
+ UncleHeaders []*btHeader
+}
+
type btAccount struct {
Balance string
Code string
@@ -65,20 +79,6 @@ type btTransaction struct {
Value string
}
-type btBlock struct {
- BlockHeader *btHeader
- Rlp string
- Transactions []btTransaction
- UncleHeaders []*btHeader
-}
-
-type BlockTest struct {
- Genesis *types.Block
-
- json *btJSON
- preAccounts map[string]btAccount
-}
-
// LoadBlockTests loads a block test JSON file.
func LoadBlockTests(file string) (map[string]*BlockTest, error) {
bt := make(map[string]*btJSON)
@@ -125,13 +125,43 @@ func (t *BlockTest) InsertPreState(db common.Database) (*state.StateDB, error) {
return statedb, nil
}
-// InsertBlocks loads the test's blocks into the given chain.
-func (t *BlockTest) InsertBlocks(chain *core.ChainManager) error {
- blocks, err := t.convertBlocks()
- if err != nil {
- return err
+/* See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II
+
+ Whether a block is valid or not is a bit subtle, it's defined by presence of
+ blockHeader, transactions and uncleHeaders fields. If they are missing, the block is
+ invalid and we must verify that we do not accept it.
+
+ Since some tests mix valid and invalid blocks we need to check this for every block.
+
+ If a block is invalid it does not necessarily fail the test, if it's invalidness is
+ expected we are expected to ignore it and continue processing and then validate the
+ post state.
+*/
+func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
+ // insert the test blocks, which will execute all transactions
+ for _, b := range t.Json.Blocks {
+ cb, err := mustConvertBlock(b)
+ if err != nil {
+ 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: ", err)
+ }
+ }
+ // RLP decoding worked, try to insert into chain:
+ err = chainManager.InsertChain(types.Blocks{cb})
+ if err != nil {
+ 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: ", err)
+ }
+ }
+ if b.BlockHeader == nil {
+ return fmt.Errorf("Block insertion should have failed")
+ }
}
- return chain.InsertChain(blocks)
+ return nil
}
func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error {
@@ -159,21 +189,6 @@ func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error {
return nil
}
-func (t *BlockTest) convertBlocks() (blocks []*types.Block, err error) {
- // the conversion handles errors by catching panics.
- // you might consider this ugly, but the alternative (passing errors)
- // would be much harder to read.
- defer func() {
- if recovered := recover(); recovered != nil {
- buf := make([]byte, 64<<10)
- buf = buf[:runtime.Stack(buf, false)]
- err = fmt.Errorf("%v\n%s", recovered, buf)
- }
- }()
- blocks = mustConvertBlocks(t.json.Blocks)
- return blocks, nil
-}
-
func convertTest(in *btJSON) (out *BlockTest, err error) {
// the conversion handles errors by catching panics.
// you might consider this ugly, but the alternative (passing errors)
@@ -185,7 +200,7 @@ func convertTest(in *btJSON) (out *BlockTest, err error) {
err = fmt.Errorf("%v\n%s", recovered, buf)
}
}()
- out = &BlockTest{preAccounts: in.Pre, json: in}
+ out = &BlockTest{preAccounts: in.Pre, Json: in}
out.Genesis = mustConvertGenesis(in.GenesisBlockHeader)
return out, err
}
@@ -221,17 +236,11 @@ func mustConvertHeader(in btHeader) *types.Header {
return header
}
-func mustConvertBlocks(testBlocks []btBlock) []*types.Block {
- var out []*types.Block
- for i, inb := range testBlocks {
- var b types.Block
- r := bytes.NewReader(mustConvertBytes(inb.Rlp))
- if err := rlp.Decode(r, &b); err != nil {
- panic(fmt.Errorf("invalid block %d: %q\nerror: %v", i, inb.Rlp, err))
- }
- out = append(out, &b)
- }
- return out
+func mustConvertBlock(testBlock btBlock) (*types.Block, error) {
+ var b types.Block
+ r := bytes.NewReader(mustConvertBytes(testBlock.Rlp))
+ err := rlp.Decode(r, &b)
+ return &b, err
}
func mustConvertBytes(in string) []byte {