From c5fd181ec5f7b4c93485ede0ceb512f9b5a205f3 Mon Sep 17 00:00:00 2001 From: Sonic Date: Mon, 26 Nov 2018 18:24:28 +0800 Subject: dex/downloader: fix tests --- dex/downloader/downloader_test.go | 269 +++++++------------------------------- dex/downloader/testchain_test.go | 87 +++++++++--- 2 files changed, 114 insertions(+), 242 deletions(-) (limited to 'dex/downloader') diff --git a/dex/downloader/downloader_test.go b/dex/downloader/downloader_test.go index 093b751ca..c5e1451f5 100644 --- a/dex/downloader/downloader_test.go +++ b/dex/downloader/downloader_test.go @@ -26,8 +26,11 @@ import ( "time" ethereum "github.com/dexon-foundation/dexon" + dexCore "github.com/dexon-foundation/dexon-consensus/core" "github.com/dexon-foundation/dexon/common" + "github.com/dexon-foundation/dexon/core/state" "github.com/dexon-foundation/dexon/core/types" + "github.com/dexon-foundation/dexon/core/vm" "github.com/dexon-foundation/dexon/ethdb" "github.com/dexon-foundation/dexon/event" "github.com/dexon-foundation/dexon/trie" @@ -122,6 +125,12 @@ func (dl *downloadTester) GetHeaderByHash(hash common.Hash) *types.Header { return dl.ownHeaders[hash] } +func (dl *downloadTester) GetHeaderByNumber(number uint64) *types.Header { + dl.lock.RLock() + defer dl.lock.RUnlock() + return dl.ownHeaders[dl.ownHashes[number]] +} + // GetBlock retrieves a block from the testers canonical chain. func (dl *downloadTester) GetBlockByHash(hash common.Hash) *types.Block { dl.lock.RLock() @@ -130,6 +139,18 @@ func (dl *downloadTester) GetBlockByHash(hash common.Hash) *types.Block { return dl.ownBlocks[hash] } +func (dl *downloadTester) GetGovStateByNumber(number uint64) (*types.GovState, error) { + header, ok := dl.ownHeaders[dl.ownHashes[number]] + if !ok { + return nil, fmt.Errorf("header with number %d not exists", number) + } + statedb, err := state.New(header.Root, state.NewDatabase(dl.peerDb)) + if err != nil { + return nil, err + } + return state.GetGovState(statedb, header, vm.GovernanceContractAddress) +} + // CurrentHeader retrieves the current head header from the canonical chain. func (dl *downloadTester) CurrentHeader() *types.Header { dl.lock.RLock() @@ -189,12 +210,12 @@ func (dl *downloadTester) GetTd(hash common.Hash, number uint64) *big.Int { return dl.ownChainTd[hash] } -// InsertHeaderChain injects a new batch of headers into the simulated chain. -func (dl *downloadTester) InsertHeaderChain(headers []*types.Header, checkFreq int) (i int, err error) { +// InsertDexonHeaderChain injects a new batch of headers into the simulated chain. +func (dl *downloadTester) InsertDexonHeaderChain(headers []*types.HeaderWithGovState, verifierCache *dexCore.TSigVerifierCache) (i int, err error) { dl.lock.Lock() defer dl.lock.Unlock() - // Do a quick check, as the blockchain.InsertHeaderChain doesn't insert anything in case of errors + // Do a quick check, as the blockchain.InsertDexonHeaderChain doesn't insert anything in case of errors if _, ok := dl.ownHeaders[headers[0].ParentHash]; !ok { return 0, errors.New("unknown parent") } @@ -212,14 +233,14 @@ func (dl *downloadTester) InsertHeaderChain(headers []*types.Header, checkFreq i return i, errors.New("unknown parent") } dl.ownHashes = append(dl.ownHashes, header.Hash()) - dl.ownHeaders[header.Hash()] = header + dl.ownHeaders[header.Hash()] = header.Header dl.ownChainTd[header.Hash()] = new(big.Int).Add(dl.ownChainTd[header.ParentHash], header.Difficulty) } return len(headers), nil } -// InsertChain injects a new batch of blocks into the simulated chain. -func (dl *downloadTester) InsertChain(blocks types.Blocks) (i int, err error) { +// InsertDexonChain injects a new batch of blocks into the simulated chain. +func (dl *downloadTester) InsertDexonChain(blocks types.Blocks) (i int, err error) { dl.lock.Lock() defer dl.lock.Unlock() @@ -311,7 +332,7 @@ func (dlp *downloadTesterPeer) Head() (common.Hash, *big.Int) { // RequestHeadersByHash constructs a GetBlockHeaders function based on a hashed // origin; associated with a particular peer in the download tester. The returned // function can be used to retrieve batches of headers from the particular peer. -func (dlp *downloadTesterPeer) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse bool) error { +func (dlp *downloadTesterPeer) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse, withGov bool) error { if reverse { panic("reverse header requests not supported") } @@ -324,7 +345,7 @@ func (dlp *downloadTesterPeer) RequestHeadersByHash(origin common.Hash, amount i // RequestHeadersByNumber constructs a GetBlockHeaders function based on a numbered // origin; associated with a particular peer in the download tester. The returned // function can be used to retrieve batches of headers from the particular peer. -func (dlp *downloadTesterPeer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool) error { +func (dlp *downloadTesterPeer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse, withGov bool) error { if reverse { panic("reverse header requests not supported") } @@ -334,6 +355,12 @@ func (dlp *downloadTesterPeer) RequestHeadersByNumber(origin uint64, amount int, return nil } +func (dlp *downloadTesterPeer) RequestGovStateByHash(hash common.Hash) error { + result := dlp.chain.govStateByHash(hash) + go dlp.dl.downloader.DeliverGovState(dlp.id, result) + return nil +} + // RequestBodies constructs a getBlockBodies method associated with a particular // peer in the download tester. The returned function can be used to retrieve // batches of block bodies from the particularly requested peer. @@ -517,140 +544,6 @@ func testThrottling(t *testing.T, protocol int, mode SyncMode) { } } -// Tests that simple synchronization against a forked chain works correctly. In -// this test common ancestor lookup should *not* be short circuited, and a full -// binary search should be executed. -func TestForkedSync62(t *testing.T) { testForkedSync(t, 62, FullSync) } -func TestForkedSync63Full(t *testing.T) { testForkedSync(t, 63, FullSync) } -func TestForkedSync63Fast(t *testing.T) { testForkedSync(t, 63, FastSync) } -func TestForkedSync64Full(t *testing.T) { testForkedSync(t, 64, FullSync) } -func TestForkedSync64Fast(t *testing.T) { testForkedSync(t, 64, FastSync) } -func TestForkedSync64Light(t *testing.T) { testForkedSync(t, 64, LightSync) } - -func testForkedSync(t *testing.T, protocol int, mode SyncMode) { - t.Parallel() - - tester := newTester() - defer tester.terminate() - - chainA := testChainForkLightA.shorten(testChainBase.len() + 80) - chainB := testChainForkLightB.shorten(testChainBase.len() + 80) - tester.newPeer("fork A", protocol, chainA) - tester.newPeer("fork B", protocol, chainB) - - // Synchronise with the peer and make sure all blocks were retrieved - if err := tester.sync("fork A", nil, mode); err != nil { - t.Fatalf("failed to synchronise blocks: %v", err) - } - assertOwnChain(t, tester, chainA.len()) - - // Synchronise with the second peer and make sure that fork is pulled too - if err := tester.sync("fork B", nil, mode); err != nil { - t.Fatalf("failed to synchronise blocks: %v", err) - } - assertOwnForkedChain(t, tester, testChainBase.len(), []int{chainA.len(), chainB.len()}) -} - -// Tests that synchronising against a much shorter but much heavyer fork works -// corrently and is not dropped. -func TestHeavyForkedSync62(t *testing.T) { testHeavyForkedSync(t, 62, FullSync) } -func TestHeavyForkedSync63Full(t *testing.T) { testHeavyForkedSync(t, 63, FullSync) } -func TestHeavyForkedSync63Fast(t *testing.T) { testHeavyForkedSync(t, 63, FastSync) } -func TestHeavyForkedSync64Full(t *testing.T) { testHeavyForkedSync(t, 64, FullSync) } -func TestHeavyForkedSync64Fast(t *testing.T) { testHeavyForkedSync(t, 64, FastSync) } -func TestHeavyForkedSync64Light(t *testing.T) { testHeavyForkedSync(t, 64, LightSync) } - -func testHeavyForkedSync(t *testing.T, protocol int, mode SyncMode) { - t.Parallel() - - tester := newTester() - defer tester.terminate() - - chainA := testChainForkLightA.shorten(testChainBase.len() + 80) - chainB := testChainForkHeavy.shorten(testChainBase.len() + 80) - tester.newPeer("light", protocol, chainA) - tester.newPeer("heavy", protocol, chainB) - - // Synchronise with the peer and make sure all blocks were retrieved - if err := tester.sync("light", nil, mode); err != nil { - t.Fatalf("failed to synchronise blocks: %v", err) - } - assertOwnChain(t, tester, chainA.len()) - - // Synchronise with the second peer and make sure that fork is pulled too - if err := tester.sync("heavy", nil, mode); err != nil { - t.Fatalf("failed to synchronise blocks: %v", err) - } - assertOwnForkedChain(t, tester, testChainBase.len(), []int{chainA.len(), chainB.len()}) -} - -// Tests that chain forks are contained within a certain interval of the current -// chain head, ensuring that malicious peers cannot waste resources by feeding -// long dead chains. -func TestBoundedForkedSync62(t *testing.T) { testBoundedForkedSync(t, 62, FullSync) } -func TestBoundedForkedSync63Full(t *testing.T) { testBoundedForkedSync(t, 63, FullSync) } -func TestBoundedForkedSync63Fast(t *testing.T) { testBoundedForkedSync(t, 63, FastSync) } -func TestBoundedForkedSync64Full(t *testing.T) { testBoundedForkedSync(t, 64, FullSync) } -func TestBoundedForkedSync64Fast(t *testing.T) { testBoundedForkedSync(t, 64, FastSync) } -func TestBoundedForkedSync64Light(t *testing.T) { testBoundedForkedSync(t, 64, LightSync) } - -func testBoundedForkedSync(t *testing.T, protocol int, mode SyncMode) { - t.Parallel() - - tester := newTester() - defer tester.terminate() - - chainA := testChainForkLightA - chainB := testChainForkLightB - tester.newPeer("original", protocol, chainA) - tester.newPeer("rewriter", protocol, chainB) - - // Synchronise with the peer and make sure all blocks were retrieved - if err := tester.sync("original", nil, mode); err != nil { - t.Fatalf("failed to synchronise blocks: %v", err) - } - assertOwnChain(t, tester, chainA.len()) - - // Synchronise with the second peer and ensure that the fork is rejected to being too old - if err := tester.sync("rewriter", nil, mode); err != errInvalidAncestor { - t.Fatalf("sync failure mismatch: have %v, want %v", err, errInvalidAncestor) - } -} - -// Tests that chain forks are contained within a certain interval of the current -// chain head for short but heavy forks too. These are a bit special because they -// take different ancestor lookup paths. -func TestBoundedHeavyForkedSync62(t *testing.T) { testBoundedHeavyForkedSync(t, 62, FullSync) } -func TestBoundedHeavyForkedSync63Full(t *testing.T) { testBoundedHeavyForkedSync(t, 63, FullSync) } -func TestBoundedHeavyForkedSync63Fast(t *testing.T) { testBoundedHeavyForkedSync(t, 63, FastSync) } -func TestBoundedHeavyForkedSync64Full(t *testing.T) { testBoundedHeavyForkedSync(t, 64, FullSync) } -func TestBoundedHeavyForkedSync64Fast(t *testing.T) { testBoundedHeavyForkedSync(t, 64, FastSync) } -func TestBoundedHeavyForkedSync64Light(t *testing.T) { testBoundedHeavyForkedSync(t, 64, LightSync) } - -func testBoundedHeavyForkedSync(t *testing.T, protocol int, mode SyncMode) { - t.Parallel() - - tester := newTester() - defer tester.terminate() - - // Create a long enough forked chain - chainA := testChainForkLightA - chainB := testChainForkHeavy - tester.newPeer("original", protocol, chainA) - tester.newPeer("heavy-rewriter", protocol, chainB) - - // Synchronise with the peer and make sure all blocks were retrieved - if err := tester.sync("original", nil, mode); err != nil { - t.Fatalf("failed to synchronise blocks: %v", err) - } - assertOwnChain(t, tester, chainA.len()) - - // Synchronise with the second peer and ensure that the fork is rejected to being too old - if err := tester.sync("heavy-rewriter", nil, mode); err != errInvalidAncestor { - t.Fatalf("sync failure mismatch: have %v, want %v", err, errInvalidAncestor) - } -} - // Tests that an inactive downloader will not accept incoming block headers and // bodies. func TestInactiveDownloader62(t *testing.T) { @@ -660,7 +553,7 @@ func TestInactiveDownloader62(t *testing.T) { defer tester.terminate() // Check that neither block headers nor bodies are accepted - if err := tester.downloader.DeliverHeaders("bad peer", []*types.Header{}); err != errNoSyncActive { + if err := tester.downloader.DeliverHeaders("bad peer", []*types.HeaderWithGovState{}); err != errNoSyncActive { t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive) } if err := tester.downloader.DeliverBodies("bad peer", [][]*types.Transaction{}, [][]*types.Header{}); err != errNoSyncActive { @@ -677,7 +570,7 @@ func TestInactiveDownloader63(t *testing.T) { defer tester.terminate() // Check that neither block headers nor bodies are accepted - if err := tester.downloader.DeliverHeaders("bad peer", []*types.Header{}); err != errNoSyncActive { + if err := tester.downloader.DeliverHeaders("bad peer", []*types.HeaderWithGovState{}); err != errNoSyncActive { t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive) } if err := tester.downloader.DeliverBodies("bad peer", [][]*types.Transaction{}, [][]*types.Header{}); err != errNoSyncActive { @@ -1158,81 +1051,6 @@ func checkProgress(t *testing.T, d *Downloader, stage string, want ethereum.Sync } } -// Tests that synchronisation progress (origin block number and highest block -// number) is tracked and updated correctly in case of a fork (or manual head -// revertal). -func TestForkedSyncProgress62(t *testing.T) { testForkedSyncProgress(t, 62, FullSync) } -func TestForkedSyncProgress63Full(t *testing.T) { testForkedSyncProgress(t, 63, FullSync) } -func TestForkedSyncProgress63Fast(t *testing.T) { testForkedSyncProgress(t, 63, FastSync) } -func TestForkedSyncProgress64Full(t *testing.T) { testForkedSyncProgress(t, 64, FullSync) } -func TestForkedSyncProgress64Fast(t *testing.T) { testForkedSyncProgress(t, 64, FastSync) } -func TestForkedSyncProgress64Light(t *testing.T) { testForkedSyncProgress(t, 64, LightSync) } - -func testForkedSyncProgress(t *testing.T, protocol int, mode SyncMode) { - t.Parallel() - - tester := newTester() - defer tester.terminate() - chainA := testChainForkLightA.shorten(testChainBase.len() + MaxHashFetch) - chainB := testChainForkLightB.shorten(testChainBase.len() + MaxHashFetch) - - // Set a sync init hook to catch progress changes - starting := make(chan struct{}) - progress := make(chan struct{}) - - tester.downloader.syncInitHook = func(origin, latest uint64) { - starting <- struct{}{} - <-progress - } - checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{}) - - // Synchronise with one of the forks and check progress - tester.newPeer("fork A", protocol, chainA) - pending := new(sync.WaitGroup) - pending.Add(1) - go func() { - defer pending.Done() - if err := tester.sync("fork A", nil, mode); err != nil { - panic(fmt.Sprintf("failed to synchronise blocks: %v", err)) - } - }() - <-starting - - checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{ - HighestBlock: uint64(chainA.len() - 1), - }) - progress <- struct{}{} - pending.Wait() - - // Simulate a successful sync above the fork - tester.downloader.syncStatsChainOrigin = tester.downloader.syncStatsChainHeight - - // Synchronise with the second fork and check progress resets - tester.newPeer("fork B", protocol, chainB) - pending.Add(1) - go func() { - defer pending.Done() - if err := tester.sync("fork B", nil, mode); err != nil { - panic(fmt.Sprintf("failed to synchronise blocks: %v", err)) - } - }() - <-starting - checkProgress(t, tester.downloader, "forking", ethereum.SyncProgress{ - StartingBlock: uint64(testChainBase.len()) - 1, - CurrentBlock: uint64(chainA.len() - 1), - HighestBlock: uint64(chainB.len() - 1), - }) - - // Check final progress after successful sync - progress <- struct{}{} - pending.Wait() - checkProgress(t, tester.downloader, "final", ethereum.SyncProgress{ - StartingBlock: uint64(testChainBase.len()) - 1, - CurrentBlock: uint64(chainB.len() - 1), - HighestBlock: uint64(chainB.len() - 1), - }) -} - // Tests that if synchronisation is aborted due to some failure, then the progress // origin is not updated in the next sync cycle, as it should be considered the // continuation of the previous sync and not a new instance. @@ -1435,8 +1253,11 @@ type floodingTestPeer struct { } func (ftp *floodingTestPeer) Head() (common.Hash, *big.Int) { return ftp.peer.Head() } -func (ftp *floodingTestPeer) RequestHeadersByHash(hash common.Hash, count int, skip int, reverse bool) error { - return ftp.peer.RequestHeadersByHash(hash, count, skip, reverse) +func (ftp *floodingTestPeer) RequestHeadersByHash(hash common.Hash, count int, skip int, reverse, withGov bool) error { + return ftp.peer.RequestHeadersByHash(hash, count, skip, reverse, withGov) +} +func (ftp *floodingTestPeer) RequestGovStateByHash(hash common.Hash) error { + return ftp.peer.RequestGovStateByHash(hash) } func (ftp *floodingTestPeer) RequestBodies(hashes []common.Hash) error { return ftp.peer.RequestBodies(hashes) @@ -1448,12 +1269,12 @@ func (ftp *floodingTestPeer) RequestNodeData(hashes []common.Hash) error { return ftp.peer.RequestNodeData(hashes) } -func (ftp *floodingTestPeer) RequestHeadersByNumber(from uint64, count, skip int, reverse bool) error { +func (ftp *floodingTestPeer) RequestHeadersByNumber(from uint64, count, skip int, reverse, withGov bool) error { deliveriesDone := make(chan struct{}, 500) for i := 0; i < cap(deliveriesDone)-1; i++ { peer := fmt.Sprintf("fake-peer%d", i) go func() { - ftp.tester.downloader.DeliverHeaders(peer, []*types.Header{{}, {}, {}, {}}) + ftp.tester.downloader.DeliverHeaders(peer, []*types.HeaderWithGovState{{}, {}, {}, {}}) deliveriesDone <- struct{}{} }() } @@ -1468,7 +1289,7 @@ func (ftp *floodingTestPeer) RequestHeadersByNumber(from uint64, count, skip int // Start delivering the requested headers // after one of the flooding responses has arrived. go func() { - ftp.peer.RequestHeadersByNumber(from, count, skip, reverse) + ftp.peer.RequestHeadersByNumber(from, count, skip, reverse, withGov) deliveriesDone <- struct{}{} }() launched = true diff --git a/dex/downloader/testchain_test.go b/dex/downloader/testchain_test.go index e73bed513..5dcc1f403 100644 --- a/dex/downloader/testchain_test.go +++ b/dex/downloader/testchain_test.go @@ -19,12 +19,13 @@ package downloader import ( "fmt" "math/big" - "sync" "github.com/dexon-foundation/dexon/common" "github.com/dexon-foundation/dexon/consensus/ethash" "github.com/dexon-foundation/dexon/core" + "github.com/dexon-foundation/dexon/core/state" "github.com/dexon-foundation/dexon/core/types" + "github.com/dexon-foundation/dexon/core/vm" "github.com/dexon-foundation/dexon/crypto" "github.com/dexon-foundation/dexon/ethdb" "github.com/dexon-foundation/dexon/params" @@ -35,23 +36,58 @@ var ( testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") testAddress = crypto.PubkeyToAddress(testKey.PublicKey) testDB = ethdb.NewMemDatabase() - testGenesis = core.GenesisBlockForTesting(testDB, testAddress, big.NewInt(1000000000)) + testGenesis = genesisBlockForTesting(testDB, testAddress, big.NewInt(1000000000)) ) // The common prefix of all test chains: var testChainBase = newTestChain(blockCacheItems+200, testGenesis) -// Different forks on top of the base chain: -var testChainForkLightA, testChainForkLightB, testChainForkHeavy *testChain +func genesisBlockForTesting(db ethdb.Database, + addr common.Address, balance *big.Int) *types.Block { + var ( + // genesis node set + nodekey1, _ = crypto.HexToECDSA("3cf5bdee098cc34536a7b0e80d85e07a380efca76fc12136299b9e5ba24193c8") + nodekey2, _ = crypto.HexToECDSA("96c9f1435d53577db18d45411326311529a0e8affb19218e27f65769a482c0fb") + nodekey3, _ = crypto.HexToECDSA("b25e955e30dd87cbaec83287beea6ec9c4c72498bc66905590756bf48da5d1fc") + nodekey4, _ = crypto.HexToECDSA("35577f65312f4a5e0b5391f5385043a6bc7b51fa4851a579e845b5fea33efded") + nodeaddr1 = crypto.PubkeyToAddress(nodekey1.PublicKey) + nodeaddr2 = crypto.PubkeyToAddress(nodekey2.PublicKey) + nodeaddr3 = crypto.PubkeyToAddress(nodekey3.PublicKey) + nodeaddr4 = crypto.PubkeyToAddress(nodekey4.PublicKey) + ) -func init() { - var forkLen = int(MaxForkAncestry + 50) - var wg sync.WaitGroup - wg.Add(3) - go func() { testChainForkLightA = testChainBase.makeFork(forkLen, false, 1); wg.Done() }() - go func() { testChainForkLightB = testChainBase.makeFork(forkLen, false, 2); wg.Done() }() - go func() { testChainForkHeavy = testChainBase.makeFork(forkLen, true, 3); wg.Done() }() - wg.Wait() + ether := big.NewInt(1e18) + gspec := core.Genesis{ + Config: params.TestnetChainConfig, + Alloc: core.GenesisAlloc{ + addr: { + Balance: balance, + Staked: new(big.Int), + }, + nodeaddr1: { + Balance: new(big.Int).Mul(big.NewInt(1000), ether), + Staked: new(big.Int).Mul(big.NewInt(500), ether), + PublicKey: crypto.FromECDSAPub(&nodekey1.PublicKey), + }, + nodeaddr2: { + Balance: new(big.Int).Mul(big.NewInt(1000), ether), + Staked: new(big.Int).Mul(big.NewInt(500), ether), + PublicKey: crypto.FromECDSAPub(&nodekey2.PublicKey), + }, + nodeaddr3: { + Balance: new(big.Int).Mul(big.NewInt(1000), ether), + Staked: new(big.Int).Mul(big.NewInt(500), ether), + PublicKey: crypto.FromECDSAPub(&nodekey3.PublicKey), + }, + nodeaddr4: { + Balance: new(big.Int).Mul(big.NewInt(1000), ether), + Staked: new(big.Int).Mul(big.NewInt(500), ether), + PublicKey: crypto.FromECDSAPub(&nodekey4.PublicKey), + }, + }, + } + genesis := gspec.MustCommit(db) + return genesis } type testChain struct { @@ -118,7 +154,7 @@ func (tc *testChain) generate(n int, seed byte, parent *types.Block, heavy bool) // start := time.Now() // defer func() { fmt.Printf("test chain generated in %v\n", time.Since(start)) }() - blocks, receipts := core.GenerateChain(params.TestChainConfig, parent, ethash.NewFaker(), testDB, n, func(i int, block *core.BlockGen) { + blocks, receipts := core.GenerateChain(params.TestnetChainConfig, parent, ethash.NewFaker(), testDB, n, func(i int, block *core.BlockGen) { block.SetCoinbase(common.Address{seed}) // If a heavy chain is requested, delay blocks to raise difficulty if heavy { @@ -126,7 +162,7 @@ func (tc *testChain) generate(n int, seed byte, parent *types.Block, heavy bool) } // Include transactions to the miner to make blocks more interesting. if parent == tc.genesis && i%22 == 0 { - signer := types.MakeSigner(params.TestChainConfig, block.Number()) + signer := types.MakeSigner(params.TestnetChainConfig, block.Number()) tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil), signer, testKey) if err != nil { panic(err) @@ -171,22 +207,37 @@ func (tc *testChain) td(hash common.Hash) *big.Int { } // headersByHash returns headers in ascending order from the given hash. -func (tc *testChain) headersByHash(origin common.Hash, amount int, skip int) []*types.Header { +func (tc *testChain) headersByHash(origin common.Hash, amount int, skip int) []*types.HeaderWithGovState { num, _ := tc.hashToNumber(origin) return tc.headersByNumber(num, amount, skip) } // headersByNumber returns headers in ascending order from the given number. -func (tc *testChain) headersByNumber(origin uint64, amount int, skip int) []*types.Header { - result := make([]*types.Header, 0, amount) +func (tc *testChain) headersByNumber(origin uint64, amount int, skip int) []*types.HeaderWithGovState { + result := make([]*types.HeaderWithGovState, 0, amount) for num := origin; num < uint64(len(tc.chain)) && len(result) < amount; num += uint64(skip) + 1 { if header, ok := tc.headerm[tc.chain[int(num)]]; ok { - result = append(result, header) + result = append(result, &types.HeaderWithGovState{Header: header}) } } return result } +func (tc *testChain) govStateByHash(hash common.Hash) *types.GovState { + header := tc.headersByHash(hash, 1, 0)[0] + statedb, err := state.New(header.Root, state.NewDatabase(testDB)) + if err != nil { + panic(err) + } + + govState, err := state.GetGovState(statedb, header.Header, + vm.GovernanceContractAddress) + if err != nil { + panic(err) + } + return govState +} + // receipts returns the receipts of the given block hashes. func (tc *testChain) receipts(hashes []common.Hash) [][]*types.Receipt { results := make([][]*types.Receipt, 0, len(hashes)) -- cgit v1.2.3