2015-07-07 02:54:22 +02:00
|
|
|
// Copyright 2015 The go-ethereum Authors
|
2015-07-22 18:48:40 +02:00
|
|
|
// This file is part of the go-ethereum library.
|
2015-07-07 02:54:22 +02:00
|
|
|
//
|
2015-07-23 18:35:11 +02:00
|
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
2015-07-07 02:54:22 +02:00
|
|
|
// 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.
|
|
|
|
//
|
2015-07-22 18:48:40 +02:00
|
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
2015-07-07 02:54:22 +02:00
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2015-07-22 18:48:40 +02:00
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2015-07-07 02:54:22 +02:00
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
2015-07-22 18:48:40 +02:00
|
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
2015-07-07 02:54:22 +02:00
|
|
|
|
2017-07-11 13:49:14 +02:00
|
|
|
// Package tests implements execution of Ethereum JSON tests.
|
2015-03-13 18:01:51 +01:00
|
|
|
package tests
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/hex"
|
2017-07-11 13:49:14 +02:00
|
|
|
"encoding/json"
|
2015-03-13 18:01:51 +01:00
|
|
|
"fmt"
|
|
|
|
"math/big"
|
2021-06-07 14:37:56 +02:00
|
|
|
"os"
|
2023-02-06 14:52:51 -05:00
|
|
|
"reflect"
|
2015-03-13 18:01:51 +01:00
|
|
|
|
2015-03-16 11:27:38 +01:00
|
|
|
"github.com/ethereum/go-ethereum/common"
|
2017-07-11 13:49:14 +02:00
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
|
|
"github.com/ethereum/go-ethereum/common/math"
|
2022-12-20 09:56:52 -05:00
|
|
|
"github.com/ethereum/go-ethereum/consensus/beacon"
|
2017-04-05 01:16:29 +03:00
|
|
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
2015-04-17 16:30:15 +02:00
|
|
|
"github.com/ethereum/go-ethereum/core"
|
2018-09-24 15:57:49 +03:00
|
|
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
2015-03-23 22:05:12 +01:00
|
|
|
"github.com/ethereum/go-ethereum/core/state"
|
2015-03-16 23:10:26 +01:00
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
2017-01-17 11:19:50 +00:00
|
|
|
"github.com/ethereum/go-ethereum/core/vm"
|
2016-10-20 13:36:29 +02:00
|
|
|
"github.com/ethereum/go-ethereum/params"
|
2015-03-13 18:01:51 +01:00
|
|
|
"github.com/ethereum/go-ethereum/rlp"
|
|
|
|
)
|
|
|
|
|
2017-07-11 13:49:14 +02:00
|
|
|
// A BlockTest checks handling of entire blocks.
|
2015-04-20 18:14:57 +02:00
|
|
|
type BlockTest struct {
|
2017-07-11 13:49:14 +02:00
|
|
|
json btJSON
|
|
|
|
}
|
2015-04-20 18:14:57 +02:00
|
|
|
|
2018-06-05 03:31:34 -07:00
|
|
|
// UnmarshalJSON implements json.Unmarshaler interface.
|
2017-07-11 13:49:14 +02:00
|
|
|
func (t *BlockTest) UnmarshalJSON(in []byte) error {
|
|
|
|
return json.Unmarshal(in, &t.json)
|
2015-04-20 18:14:57 +02:00
|
|
|
}
|
|
|
|
|
2015-03-13 18:01:51 +01:00
|
|
|
type btJSON struct {
|
2018-10-16 00:26:47 +02:00
|
|
|
Blocks []btBlock `json:"blocks"`
|
|
|
|
Genesis btHeader `json:"genesisBlockHeader"`
|
|
|
|
Pre core.GenesisAlloc `json:"pre"`
|
|
|
|
Post core.GenesisAlloc `json:"postState"`
|
|
|
|
BestBlock common.UnprefixedHash `json:"lastblockhash"`
|
|
|
|
Network string `json:"network"`
|
|
|
|
SealEngine string `json:"sealEngine"`
|
2015-03-13 18:01:51 +01:00
|
|
|
}
|
|
|
|
|
2015-04-20 18:14:57 +02:00
|
|
|
type btBlock struct {
|
2021-06-07 14:37:56 +02:00
|
|
|
BlockHeader *btHeader
|
|
|
|
ExpectException string
|
|
|
|
Rlp string
|
|
|
|
UncleHeaders []*btHeader
|
2015-04-20 18:14:57 +02:00
|
|
|
}
|
|
|
|
|
2022-04-13 02:24:02 +08:00
|
|
|
//go:generate go run github.com/fjl/gencodec -type btHeader -field-override btHeaderMarshaling -out gen_btheader.go
|
2015-03-13 18:01:51 +01:00
|
|
|
|
|
|
|
type btHeader struct {
|
2017-07-11 13:49:14 +02:00
|
|
|
Bloom types.Bloom
|
|
|
|
Coinbase common.Address
|
|
|
|
MixHash common.Hash
|
|
|
|
Nonce types.BlockNonce
|
|
|
|
Number *big.Int
|
|
|
|
Hash common.Hash
|
|
|
|
ParentHash common.Hash
|
|
|
|
ReceiptTrie common.Hash
|
|
|
|
StateRoot common.Hash
|
|
|
|
TransactionsTrie common.Hash
|
|
|
|
UncleHash common.Hash
|
|
|
|
ExtraData []byte
|
|
|
|
Difficulty *big.Int
|
2017-11-13 13:47:27 +02:00
|
|
|
GasLimit uint64
|
|
|
|
GasUsed uint64
|
2019-04-02 22:28:48 +02:00
|
|
|
Timestamp uint64
|
2021-07-29 14:05:22 +02:00
|
|
|
BaseFeePerGas *big.Int
|
2023-02-06 14:52:51 -05:00
|
|
|
WithdrawalsRoot *common.Hash
|
2015-03-13 18:01:51 +01:00
|
|
|
}
|
|
|
|
|
2017-07-11 13:49:14 +02:00
|
|
|
type btHeaderMarshaling struct {
|
2021-07-29 14:05:22 +02:00
|
|
|
ExtraData hexutil.Bytes
|
|
|
|
Number *math.HexOrDecimal256
|
|
|
|
Difficulty *math.HexOrDecimal256
|
|
|
|
GasLimit math.HexOrDecimal64
|
|
|
|
GasUsed math.HexOrDecimal64
|
|
|
|
Timestamp math.HexOrDecimal64
|
|
|
|
BaseFeePerGas *math.HexOrDecimal256
|
2015-06-14 17:55:03 -04:00
|
|
|
}
|
|
|
|
|
2023-06-06 04:27:40 -04:00
|
|
|
func (t *BlockTest) Run(snapshotter bool, tracer vm.EVMLogger) error {
|
2017-08-10 11:38:17 +02:00
|
|
|
config, ok := Forks[t.json.Network]
|
|
|
|
if !ok {
|
|
|
|
return UnsupportedForkError{t.json.Network}
|
|
|
|
}
|
|
|
|
|
2017-07-11 13:49:14 +02:00
|
|
|
// import pre accounts & construct test genesis block & state root
|
2018-09-24 15:57:49 +03:00
|
|
|
db := rawdb.NewMemoryDatabase()
|
2022-08-31 00:22:28 +08:00
|
|
|
gspec := t.genesis(config)
|
2022-11-28 21:31:28 +08:00
|
|
|
gblock := gspec.MustCommit(db)
|
2017-07-11 13:49:14 +02:00
|
|
|
if gblock.Hash() != t.json.Genesis.Hash {
|
2018-05-02 01:20:19 -07:00
|
|
|
return fmt.Errorf("genesis block hash doesn't match test: computed=%x, test=%x", gblock.Hash().Bytes()[:6], t.json.Genesis.Hash[:6])
|
2015-06-10 12:04:56 -04:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if gblock.Root() != t.json.Genesis.StateRoot {
|
|
|
|
return fmt.Errorf("genesis block state root does not match test: computed=%x, test=%x", gblock.Root().Bytes()[:6], t.json.Genesis.StateRoot[:6])
|
2015-06-10 12:04:56 -04:00
|
|
|
}
|
2022-12-20 09:56:52 -05:00
|
|
|
// Wrap the original engine within the beacon-engine
|
2023-05-03 12:58:39 +03:00
|
|
|
engine := beacon.New(ethash.NewFaker())
|
2022-12-20 09:56:52 -05:00
|
|
|
|
2020-03-03 09:10:23 +02:00
|
|
|
cache := &core.CacheConfig{TrieCleanLimit: 0}
|
|
|
|
if snapshotter {
|
|
|
|
cache.SnapshotLimit = 1
|
|
|
|
cache.SnapshotWait = true
|
|
|
|
}
|
2023-06-06 04:27:40 -04:00
|
|
|
chain, err := core.NewBlockChain(db, cache, gspec, nil, engine, vm.Config{
|
|
|
|
Tracer: tracer,
|
|
|
|
}, nil, nil)
|
2015-06-10 12:04:56 -04:00
|
|
|
if err != nil {
|
2015-10-06 16:35:55 +02:00
|
|
|
return err
|
2015-06-10 12:04:56 -04:00
|
|
|
}
|
2017-02-20 12:54:23 +02:00
|
|
|
defer chain.Stop()
|
2016-03-21 23:00:39 +01:00
|
|
|
|
2017-07-11 13:49:14 +02:00
|
|
|
validBlocks, err := t.insertBlocks(chain)
|
2015-06-10 12:04:56 -04:00
|
|
|
if err != nil {
|
2015-06-10 16:10:33 -04:00
|
|
|
return err
|
2015-06-10 12:04:56 -04:00
|
|
|
}
|
2018-01-30 18:39:32 +02:00
|
|
|
cmlast := chain.CurrentBlock().Hash()
|
2017-07-11 13:49:14 +02:00
|
|
|
if common.Hash(t.json.BestBlock) != cmlast {
|
|
|
|
return fmt.Errorf("last block hash validation mismatch: want: %x, have: %x", t.json.BestBlock, cmlast)
|
2015-09-18 17:15:59 +02:00
|
|
|
}
|
2016-03-21 23:00:39 +01:00
|
|
|
newDB, err := chain.State()
|
2015-10-06 16:35:55 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if err = t.validatePostState(newDB); err != nil {
|
2015-06-10 16:10:33 -04:00
|
|
|
return fmt.Errorf("post state validation failed: %v", err)
|
2015-06-10 12:04:56 -04:00
|
|
|
}
|
2020-03-31 10:25:41 +02:00
|
|
|
// Cross-check the snapshot-to-hash against the trie hash
|
|
|
|
if snapshotter {
|
2023-03-02 08:29:15 +02:00
|
|
|
if err := chain.Snapshots().Verify(chain.CurrentBlock().Root); err != nil {
|
2020-04-29 17:53:08 +08:00
|
|
|
return err
|
2020-03-31 10:25:41 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
return t.validateImportedHeaders(chain, validBlocks)
|
2015-06-10 12:04:56 -04:00
|
|
|
}
|
|
|
|
|
2017-07-11 13:49:14 +02:00
|
|
|
func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis {
|
|
|
|
return &core.Genesis{
|
|
|
|
Config: config,
|
|
|
|
Nonce: t.json.Genesis.Nonce.Uint64(),
|
2019-04-02 22:28:48 +02:00
|
|
|
Timestamp: t.json.Genesis.Timestamp,
|
2017-07-11 13:49:14 +02:00
|
|
|
ParentHash: t.json.Genesis.ParentHash,
|
|
|
|
ExtraData: t.json.Genesis.ExtraData,
|
2017-11-13 13:47:27 +02:00
|
|
|
GasLimit: t.json.Genesis.GasLimit,
|
|
|
|
GasUsed: t.json.Genesis.GasUsed,
|
2017-07-11 13:49:14 +02:00
|
|
|
Difficulty: t.json.Genesis.Difficulty,
|
|
|
|
Mixhash: t.json.Genesis.MixHash,
|
|
|
|
Coinbase: t.json.Genesis.Coinbase,
|
|
|
|
Alloc: t.json.Pre,
|
2021-07-29 14:05:22 +02:00
|
|
|
BaseFee: t.json.Genesis.BaseFeePerGas,
|
2015-03-20 09:10:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-10 13:25:40 +02:00
|
|
|
/*
|
|
|
|
See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II
|
2015-04-20 18:14:57 +02:00
|
|
|
|
2022-09-10 13:25:40 +02:00
|
|
|
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.
|
2015-04-20 18:14:57 +02:00
|
|
|
|
2022-09-10 13:25:40 +02:00
|
|
|
Since some tests mix valid and invalid blocks we need to check this for every block.
|
2015-04-20 18:14:57 +02:00
|
|
|
|
2022-09-10 13:25:40 +02:00
|
|
|
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.
|
2015-04-20 18:14:57 +02:00
|
|
|
*/
|
2017-07-11 13:49:14 +02:00
|
|
|
func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error) {
|
2015-09-18 17:15:59 +02:00
|
|
|
validBlocks := make([]btBlock, 0)
|
2015-04-20 18:14:57 +02:00
|
|
|
// insert the test blocks, which will execute all transactions
|
2021-06-07 14:37:56 +02:00
|
|
|
for bi, b := range t.json.Blocks {
|
2017-07-11 13:49:14 +02:00
|
|
|
cb, err := b.decode()
|
2015-04-20 18:14:57 +02:00
|
|
|
if err != nil {
|
|
|
|
if b.BlockHeader == nil {
|
|
|
|
continue // OK - block is supposed to be invalid, continue with next block
|
|
|
|
} else {
|
2019-11-23 12:51:37 +01:00
|
|
|
return nil, fmt.Errorf("block RLP decoding failed when expected to succeed: %v", err)
|
2015-04-20 18:14:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// RLP decoding worked, try to insert into chain:
|
2016-01-19 23:48:50 +01:00
|
|
|
blocks := types.Blocks{cb}
|
|
|
|
i, err := blockchain.InsertChain(blocks)
|
2015-04-20 18:14:57 +02:00
|
|
|
if err != nil {
|
|
|
|
if b.BlockHeader == nil {
|
|
|
|
continue // OK - block is supposed to be invalid, continue with next block
|
|
|
|
} else {
|
2019-11-23 12:51:37 +01:00
|
|
|
return nil, fmt.Errorf("block #%v insertion into chain failed: %v", blocks[i].Number(), err)
|
2015-04-20 18:14:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if b.BlockHeader == nil {
|
2021-06-07 14:37:56 +02:00
|
|
|
if data, err := json.MarshalIndent(cb.Header(), "", " "); err == nil {
|
|
|
|
fmt.Fprintf(os.Stderr, "block (index %d) insertion should have failed due to: %v:\n%v\n",
|
|
|
|
bi, b.ExpectException, string(data))
|
|
|
|
}
|
|
|
|
return nil, fmt.Errorf("block (index %d) insertion should have failed due to: %v",
|
|
|
|
bi, b.ExpectException)
|
2015-04-20 18:14:57 +02:00
|
|
|
}
|
2015-09-14 14:27:25 +02:00
|
|
|
|
|
|
|
// validate RLP decoding by checking all values against test file JSON
|
2015-09-18 17:15:59 +02:00
|
|
|
if err = validateHeader(b.BlockHeader, cb.Header()); err != nil {
|
2019-11-23 12:51:37 +01:00
|
|
|
return nil, fmt.Errorf("deserialised block header validation failed: %v", err)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2015-09-18 17:15:59 +02:00
|
|
|
validBlocks = append(validBlocks, b)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2015-09-18 17:15:59 +02:00
|
|
|
return validBlocks, nil
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
|
|
|
|
2015-09-18 17:15:59 +02:00
|
|
|
func validateHeader(h *btHeader, h2 *types.Header) error {
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.Bloom != h2.Bloom {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("bloom: want: %x have: %x", h.Bloom, h2.Bloom)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.Coinbase != h2.Coinbase {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("coinbase: want: %x have: %x", h.Coinbase, h2.Coinbase)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.MixHash != h2.MixDigest {
|
|
|
|
return fmt.Errorf("MixHash: want: %x have: %x", h.MixHash, h2.MixDigest)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.Nonce != h2.Nonce {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("nonce: want: %x have: %x", h.Nonce, h2.Nonce)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.Number.Cmp(h2.Number) != 0 {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("number: want: %v have: %v", h.Number, h2.Number)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.ParentHash != h2.ParentHash {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("parent hash: want: %x have: %x", h.ParentHash, h2.ParentHash)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.ReceiptTrie != h2.ReceiptHash {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("receipt hash: want: %x have: %x", h.ReceiptTrie, h2.ReceiptHash)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.TransactionsTrie != h2.TxHash {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("tx hash: want: %x have: %x", h.TransactionsTrie, h2.TxHash)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.StateRoot != h2.Root {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("state hash: want: %x have: %x", h.StateRoot, h2.Root)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.UncleHash != h2.UncleHash {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("uncle hash: want: %x have: %x", h.UncleHash, h2.UncleHash)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if !bytes.Equal(h.ExtraData, h2.Extra) {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("extra data: want: %x have: %x", h.ExtraData, h2.Extra)
|
2015-04-17 16:30:15 +02:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if h.Difficulty.Cmp(h2.Difficulty) != 0 {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("difficulty: want: %v have: %v", h.Difficulty, h2.Difficulty)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-11-13 13:47:27 +02:00
|
|
|
if h.GasLimit != h2.GasLimit {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("gasLimit: want: %d have: %d", h.GasLimit, h2.GasLimit)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2017-11-13 13:47:27 +02:00
|
|
|
if h.GasUsed != h2.GasUsed {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("gasUsed: want: %d have: %d", h.GasUsed, h2.GasUsed)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2019-04-02 22:28:48 +02:00
|
|
|
if h.Timestamp != h2.Time {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("timestamp: want: %v have: %v", h.Timestamp, h2.Time)
|
2015-04-23 04:38:47 +02:00
|
|
|
}
|
2023-02-06 14:52:51 -05:00
|
|
|
if !reflect.DeepEqual(h.BaseFeePerGas, h2.BaseFee) {
|
|
|
|
return fmt.Errorf("baseFeePerGas: want: %v have: %v", h.BaseFeePerGas, h2.BaseFee)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(h.WithdrawalsRoot, h2.WithdrawalsHash) {
|
|
|
|
return fmt.Errorf("withdrawalsRoot: want: %v have: %v", h.WithdrawalsRoot, h2.WithdrawalsHash)
|
|
|
|
}
|
2015-04-20 18:14:57 +02:00
|
|
|
return nil
|
2015-04-17 16:30:15 +02:00
|
|
|
}
|
|
|
|
|
2017-07-11 13:49:14 +02:00
|
|
|
func (t *BlockTest) validatePostState(statedb *state.StateDB) error {
|
2015-09-14 14:27:25 +02:00
|
|
|
// validate post state accounts in test file against what we have in state db
|
2017-07-11 13:49:14 +02:00
|
|
|
for addr, acct := range t.json.Post {
|
2015-03-20 09:10:13 +01:00
|
|
|
// address is indirectly verified by the other fields, as it's the db key
|
2017-07-11 13:49:14 +02:00
|
|
|
code2 := statedb.GetCode(addr)
|
|
|
|
balance2 := statedb.GetBalance(addr)
|
|
|
|
nonce2 := statedb.GetNonce(addr)
|
|
|
|
if !bytes.Equal(code2, acct.Code) {
|
|
|
|
return fmt.Errorf("account code mismatch for addr: %s want: %v have: %s", addr, acct.Code, hex.EncodeToString(code2))
|
2015-03-20 09:10:13 +01:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if balance2.Cmp(acct.Balance) != 0 {
|
|
|
|
return fmt.Errorf("account balance mismatch for addr: %s, want: %d, have: %d", addr, acct.Balance, balance2)
|
2015-03-20 09:10:13 +01:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
if nonce2 != acct.Nonce {
|
|
|
|
return fmt.Errorf("account nonce mismatch for addr: %s want: %d have: %d", addr, acct.Nonce, nonce2)
|
2015-03-20 09:10:13 +01:00
|
|
|
}
|
2015-03-13 18:01:51 +01:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-07-11 13:49:14 +02:00
|
|
|
func (t *BlockTest) validateImportedHeaders(cm *core.BlockChain, validBlocks []btBlock) error {
|
2015-09-18 17:15:59 +02:00
|
|
|
// to get constant lookup when verifying block headers by hash (some tests have many blocks)
|
2017-07-11 13:49:14 +02:00
|
|
|
bmap := make(map[common.Hash]btBlock, len(t.json.Blocks))
|
2015-09-18 17:15:59 +02:00
|
|
|
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
|
2017-07-11 13:49:14 +02:00
|
|
|
// all blocks have been processed by BlockChain, as they may not
|
2015-09-18 17:15:59 +02:00
|
|
|
// be part of the longest chain until last block is imported.
|
2023-03-02 08:29:15 +02:00
|
|
|
for b := cm.CurrentBlock(); b != nil && b.Number.Uint64() != 0; b = cm.GetBlockByHash(b.ParentHash).Header() {
|
|
|
|
if err := validateHeader(bmap[b.Hash()].BlockHeader, b); err != nil {
|
2019-11-23 12:51:37 +01:00
|
|
|
return fmt.Errorf("imported block header validation failed: %v", err)
|
2015-09-18 17:15:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-07-11 13:49:14 +02:00
|
|
|
func (bb *btBlock) decode() (*types.Block, error) {
|
|
|
|
data, err := hexutil.Decode(bb.Rlp)
|
2015-03-13 18:01:51 +01:00
|
|
|
if err != nil {
|
2015-06-10 18:11:30 -04:00
|
|
|
return nil, err
|
2015-03-13 18:01:51 +01:00
|
|
|
}
|
2017-07-11 13:49:14 +02:00
|
|
|
var b types.Block
|
|
|
|
err = rlp.DecodeBytes(data, &b)
|
|
|
|
return &b, err
|
2015-04-15 22:37:16 +02:00
|
|
|
}
|