mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
core: add support for contract state in genesis block in tests
This commit is contained in:
parent
3af101ccc1
commit
bb7b830a1a
6 changed files with 120 additions and 14 deletions
|
|
@ -162,7 +162,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
|
||||||
|
|
||||||
// Generate a chain of b.N blocks using the supplied block
|
// Generate a chain of b.N blocks using the supplied block
|
||||||
// generator function.
|
// generator function.
|
||||||
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{benchRootAddr, benchRootFunds})
|
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{Address: benchRootAddr, Balance: benchRootFunds})
|
||||||
chain, _ := GenerateChain(genesis, db, b.N, gen)
|
chain, _ := GenerateChain(genesis, db, b.N, gen)
|
||||||
|
|
||||||
// Time the insertion of the new chain.
|
// Time the insertion of the new chain.
|
||||||
|
|
|
||||||
|
|
@ -732,7 +732,7 @@ func TestFastVsFullChains(t *testing.T) {
|
||||||
})
|
})
|
||||||
// Import the chain as an archive node for the comparison baseline
|
// Import the chain as an archive node for the comparison baseline
|
||||||
archiveDb, _ := ethdb.NewMemDatabase()
|
archiveDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
|
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{Address: address, Balance: funds})
|
||||||
|
|
||||||
archive, _ := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux))
|
archive, _ := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux))
|
||||||
|
|
||||||
|
|
@ -741,7 +741,7 @@ func TestFastVsFullChains(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Fast import the chain as a non-archive node to test
|
// Fast import the chain as a non-archive node to test
|
||||||
fastDb, _ := ethdb.NewMemDatabase()
|
fastDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
|
WriteGenesisBlockForTesting(fastDb, GenesisAccount{Address: address, Balance: funds})
|
||||||
fast, _ := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux))
|
fast, _ := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux))
|
||||||
|
|
||||||
headers := make([]*types.Header, len(blocks))
|
headers := make([]*types.Header, len(blocks))
|
||||||
|
|
@ -816,7 +816,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Import the chain as an archive node and ensure all pointers are updated
|
// Import the chain as an archive node and ensure all pointers are updated
|
||||||
archiveDb, _ := ethdb.NewMemDatabase()
|
archiveDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
|
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{Address: address, Balance: funds})
|
||||||
|
|
||||||
archive, _ := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux))
|
archive, _ := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux))
|
||||||
|
|
||||||
|
|
@ -829,7 +829,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
||||||
|
|
||||||
// Import the chain as a non-archive node and ensure all pointers are updated
|
// Import the chain as a non-archive node and ensure all pointers are updated
|
||||||
fastDb, _ := ethdb.NewMemDatabase()
|
fastDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
|
WriteGenesisBlockForTesting(fastDb, GenesisAccount{Address: address, Balance: funds})
|
||||||
fast, _ := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux))
|
fast, _ := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux))
|
||||||
|
|
||||||
headers := make([]*types.Header, len(blocks))
|
headers := make([]*types.Header, len(blocks))
|
||||||
|
|
@ -848,7 +848,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
||||||
|
|
||||||
// Import the chain as a light node and ensure all pointers are updated
|
// Import the chain as a light node and ensure all pointers are updated
|
||||||
lightDb, _ := ethdb.NewMemDatabase()
|
lightDb, _ := ethdb.NewMemDatabase()
|
||||||
WriteGenesisBlockForTesting(lightDb, GenesisAccount{address, funds})
|
WriteGenesisBlockForTesting(lightDb, GenesisAccount{Address: address, Balance: funds})
|
||||||
light, _ := NewBlockChain(lightDb, testChainConfig(), FakePow{}, new(event.TypeMux))
|
light, _ := NewBlockChain(lightDb, testChainConfig(), FakePow{}, new(event.TypeMux))
|
||||||
|
|
||||||
if n, err := light.InsertHeaderChain(headers, 1); err != nil {
|
if n, err := light.InsertHeaderChain(headers, 1); err != nil {
|
||||||
|
|
@ -874,9 +874,9 @@ func TestChainTxReorgs(t *testing.T) {
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
)
|
)
|
||||||
genesis := WriteGenesisBlockForTesting(db,
|
genesis := WriteGenesisBlockForTesting(db,
|
||||||
GenesisAccount{addr1, big.NewInt(1000000)},
|
GenesisAccount{Address: addr1, Balance: big.NewInt(1000000)},
|
||||||
GenesisAccount{addr2, big.NewInt(1000000)},
|
GenesisAccount{Address: addr2, Balance: big.NewInt(1000000)},
|
||||||
GenesisAccount{addr3, big.NewInt(1000000)},
|
GenesisAccount{Address: addr3, Balance: big.NewInt(1000000)},
|
||||||
)
|
)
|
||||||
// Create two transactions shared between the chains:
|
// Create two transactions shared between the chains:
|
||||||
// - postponed: transaction included at a later block in the forked chain
|
// - postponed: transaction included at a later block in the forked chain
|
||||||
|
|
@ -983,7 +983,7 @@ func TestLogReorgs(t *testing.T) {
|
||||||
code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
|
code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
|
||||||
)
|
)
|
||||||
genesis := WriteGenesisBlockForTesting(db,
|
genesis := WriteGenesisBlockForTesting(db,
|
||||||
GenesisAccount{addr1, big.NewInt(10000000000000)},
|
GenesisAccount{Address: addr1, Balance: big.NewInt(10000000000000)},
|
||||||
)
|
)
|
||||||
|
|
||||||
evmux := &event.TypeMux{}
|
evmux := &event.TypeMux{}
|
||||||
|
|
@ -1019,7 +1019,7 @@ func TestReorgSideEvent(t *testing.T) {
|
||||||
db, _ = ethdb.NewMemDatabase()
|
db, _ = ethdb.NewMemDatabase()
|
||||||
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
genesis = WriteGenesisBlockForTesting(db, GenesisAccount{addr1, big.NewInt(10000000000000)})
|
genesis = WriteGenesisBlockForTesting(db, GenesisAccount{Address: addr1, Balance: big.NewInt(10000000000000)})
|
||||||
)
|
)
|
||||||
|
|
||||||
evmux := &event.TypeMux{}
|
evmux := &event.TypeMux{}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ func ExampleGenerateChain() {
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure that key1 has some funds in the genesis block.
|
// Ensure that key1 has some funds in the genesis block.
|
||||||
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{addr1, big.NewInt(1000000)})
|
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{Address: addr1, Balance: big.NewInt(1000000)})
|
||||||
|
|
||||||
// This call generates a chain of 5 blocks. The function runs for
|
// This call generates a chain of 5 blocks. The function runs for
|
||||||
// each block and adds different features to gen based on the
|
// each block and adds different features to gen based on the
|
||||||
|
|
|
||||||
|
|
@ -560,7 +560,7 @@ func TestMipmapChain(t *testing.T) {
|
||||||
)
|
)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{addr, big.NewInt(1000000)})
|
genesis := WriteGenesisBlockForTesting(db, GenesisAccount{Address: addr, Balance: big.NewInt(1000000)})
|
||||||
chain, receipts := GenerateChain(genesis, db, 1010, func(i int, gen *BlockGen) {
|
chain, receipts := GenerateChain(genesis, db, 1010, func(i int, gen *BlockGen) {
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
switch i {
|
switch i {
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,8 @@ func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big
|
||||||
type GenesisAccount struct {
|
type GenesisAccount struct {
|
||||||
Address common.Address
|
Address common.Address
|
||||||
Balance *big.Int
|
Balance *big.Int
|
||||||
|
Code []byte // runtime code
|
||||||
|
Storage map[common.Hash]common.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
func WriteGenesisBlockForTesting(db ethdb.Database, accounts ...GenesisAccount) *types.Block {
|
func WriteGenesisBlockForTesting(db ethdb.Database, accounts ...GenesisAccount) *types.Block {
|
||||||
|
|
@ -151,7 +153,21 @@ func WriteGenesisBlockForTesting(db ethdb.Database, accounts ...GenesisAccount)
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
accountJson += ","
|
accountJson += ","
|
||||||
}
|
}
|
||||||
accountJson += fmt.Sprintf(`"0x%x":{"balance":"0x%x"}`, account.Address, account.Balance.Bytes())
|
if len(account.Storage) == 0 {
|
||||||
|
accountJson += fmt.Sprintf(`"0x%x":{"balance":"0x%x","code":"%x"}`, account.Address, account.Balance.Bytes(), account.Code)
|
||||||
|
} else {
|
||||||
|
accountJson += fmt.Sprintf(`"0x%x":{"balance":"0x%x","code":"%x", "storage": {`, account.Address, account.Balance.Bytes(), account.Code)
|
||||||
|
prefixComma := false
|
||||||
|
for key, value := range account.Storage {
|
||||||
|
if prefixComma {
|
||||||
|
accountJson += fmt.Sprintf(`,"%x": "%x"`, key, value)
|
||||||
|
} else {
|
||||||
|
accountJson += fmt.Sprintf(`"%x": "%x"`, key, value)
|
||||||
|
}
|
||||||
|
prefixComma = true
|
||||||
|
}
|
||||||
|
accountJson += "}}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
accountJson += "}"
|
accountJson += "}"
|
||||||
|
|
||||||
|
|
|
||||||
90
core/genesis_test.go
Normal file
90
core/genesis_test.go
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Test if genesis block is deployed with correct state.
|
||||||
|
func TestWriteGenesisBlockForTesting(t *testing.T) {
|
||||||
|
type Expected struct {
|
||||||
|
code []byte
|
||||||
|
balance *big.Int
|
||||||
|
storage map[common.Hash]common.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
stor := map[common.Hash]common.Hash{
|
||||||
|
common.HexToHash("0x00"): common.HexToHash("0x01"),
|
||||||
|
common.HexToHash("0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"): common.HexToHash("abcdef"),
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
account GenesisAccount
|
||||||
|
expected Expected
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
account: GenesisAccount{
|
||||||
|
Address: common.HexToAddress("0x0000000000000000000000000000000000000001"),
|
||||||
|
Balance: big.NewInt(11111),
|
||||||
|
},
|
||||||
|
expected: Expected{
|
||||||
|
balance: big.NewInt(11111),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
account: GenesisAccount{
|
||||||
|
Address: common.HexToAddress("0x0000000000000000000000000000000000000002"),
|
||||||
|
Balance: big.NewInt(22222),
|
||||||
|
Code: common.FromHex("60606040526008565b00"), // contract Storage { uint a; mapping(address => uint) map; }
|
||||||
|
Storage: stor,
|
||||||
|
},
|
||||||
|
expected: Expected{
|
||||||
|
code: common.FromHex("60606040526008565b00"),
|
||||||
|
balance: big.NewInt(22222),
|
||||||
|
storage: stor,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := ethdb.NewMemDatabase()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var accounts []GenesisAccount
|
||||||
|
for _, test := range tests {
|
||||||
|
accounts = append(accounts, test.account)
|
||||||
|
}
|
||||||
|
block := WriteGenesisBlockForTesting(db, accounts...)
|
||||||
|
|
||||||
|
s, err := state.New(block.Root(), db)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
if test.expected.balance != nil {
|
||||||
|
balance := s.GetBalance(test.account.Address)
|
||||||
|
if test.expected.balance.Cmp(balance) != 0 {
|
||||||
|
t.Errorf("invalid balance for test %d: want %d, got %d", i, test.expected.balance, balance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(test.expected.code) > 0 {
|
||||||
|
code := s.GetCode(test.account.Address)
|
||||||
|
if !bytes.Equal(test.expected.code, code) {
|
||||||
|
t.Errorf("invalid code stored for test %d: want %x, got %x", i, test.expected.code, code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k, v := range test.expected.storage {
|
||||||
|
val := s.GetState(test.account.Address, k)
|
||||||
|
if v != val {
|
||||||
|
t.Errorf("invalid storage for test %d: want %x, got %x", i, v, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue