github.com/theQRL/go-zond@v0.1.1/core/chain_makers_test.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  import (
    20  	"fmt"
    21  	"math/big"
    22  	"testing"
    23  
    24  	"github.com/theQRL/go-zond/common"
    25  	"github.com/theQRL/go-zond/consensus/beacon"
    26  	"github.com/theQRL/go-zond/consensus/ethash"
    27  	"github.com/theQRL/go-zond/core/rawdb"
    28  	"github.com/theQRL/go-zond/core/types"
    29  	"github.com/theQRL/go-zond/core/vm"
    30  	"github.com/theQRL/go-zond/params"
    31  	"github.com/theQRL/go-zond/pqcrypto"
    32  	"github.com/theQRL/go-zond/trie"
    33  )
    34  
    35  func TestGenerateWithdrawalChain(t *testing.T) {
    36  	var (
    37  		keyHex  = "9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c"
    38  		key, _  = pqcrypto.HexToDilithium(keyHex)
    39  		address = key.GetAddress() // 658bdf435d810c91414ec09147daa6db62406379
    40  		aa      = common.Address{0xaa}
    41  		bb      = common.Address{0xbb}
    42  		funds   = big.NewInt(0).Mul(big.NewInt(1337), big.NewInt(params.Ether))
    43  		config  = *params.AllEthashProtocolChanges
    44  		gspec   = &Genesis{
    45  			Config:     &config,
    46  			Alloc:      GenesisAlloc{address: {Balance: funds}},
    47  			BaseFee:    big.NewInt(params.InitialBaseFee),
    48  			Difficulty: common.Big1,
    49  			GasLimit:   5_000_000,
    50  		}
    51  		gendb  = rawdb.NewMemoryDatabase()
    52  		signer = types.LatestSigner(gspec.Config)
    53  		db     = rawdb.NewMemoryDatabase()
    54  	)
    55  
    56  	config.TerminalTotalDifficultyPassed = true
    57  	config.TerminalTotalDifficulty = common.Big0
    58  	config.ShanghaiTime = u64(0)
    59  
    60  	// init 0xaa with some storage elements
    61  	storage := make(map[common.Hash]common.Hash)
    62  	storage[common.Hash{0x00}] = common.Hash{0x00}
    63  	storage[common.Hash{0x01}] = common.Hash{0x01}
    64  	storage[common.Hash{0x02}] = common.Hash{0x02}
    65  	storage[common.Hash{0x03}] = common.HexToHash("0303")
    66  	gspec.Alloc[aa] = GenesisAccount{
    67  		Balance: common.Big1,
    68  		Nonce:   1,
    69  		Storage: storage,
    70  		Code:    common.Hex2Bytes("6042"),
    71  	}
    72  	gspec.Alloc[bb] = GenesisAccount{
    73  		Balance: common.Big2,
    74  		Nonce:   1,
    75  		Storage: storage,
    76  		Code:    common.Hex2Bytes("600154600354"),
    77  	}
    78  	genesis := gspec.MustCommit(gendb, trie.NewDatabase(gendb, trie.HashDefaults))
    79  
    80  	chain, _ := GenerateChain(gspec.Config, genesis, beacon.NewFaker(), gendb, 4, func(i int, gen *BlockGen) {
    81  		tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(address), address, big.NewInt(1000), params.TxGas, new(big.Int).Add(gen.BaseFee(), common.Big1), nil), signer, key)
    82  		gen.AddTx(tx)
    83  		if i == 1 {
    84  			gen.AddWithdrawal(&types.Withdrawal{
    85  				Validator: 42,
    86  				Address:   common.Address{0xee},
    87  				Amount:    1337,
    88  			})
    89  			gen.AddWithdrawal(&types.Withdrawal{
    90  				Validator: 13,
    91  				Address:   common.Address{0xee},
    92  				Amount:    1,
    93  			})
    94  		}
    95  		if i == 3 {
    96  			gen.AddWithdrawal(&types.Withdrawal{
    97  				Validator: 42,
    98  				Address:   common.Address{0xee},
    99  				Amount:    1337,
   100  			})
   101  			gen.AddWithdrawal(&types.Withdrawal{
   102  				Validator: 13,
   103  				Address:   common.Address{0xee},
   104  				Amount:    1,
   105  			})
   106  		}
   107  	})
   108  
   109  	// Import the chain. This runs all block validation rules.
   110  	blockchain, _ := NewBlockChain(db, nil, gspec, nil, beacon.NewFaker(), vm.Config{}, nil, nil)
   111  	defer blockchain.Stop()
   112  
   113  	if i, err := blockchain.InsertChain(chain); err != nil {
   114  		fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
   115  		return
   116  	}
   117  
   118  	// enforce that withdrawal indexes are monotonically increasing from 0
   119  	var (
   120  		withdrawalIndex uint64
   121  		head            = blockchain.CurrentBlock().Number.Uint64()
   122  	)
   123  	for i := 0; i < int(head); i++ {
   124  		block := blockchain.GetBlockByNumber(uint64(i))
   125  		if block == nil {
   126  			t.Fatalf("block %d not found", i)
   127  		}
   128  		if len(block.Withdrawals()) == 0 {
   129  			continue
   130  		}
   131  		for j := 0; j < len(block.Withdrawals()); j++ {
   132  			if block.Withdrawals()[j].Index != withdrawalIndex {
   133  				t.Fatalf("withdrawal index %d does not equal expected index %d", block.Withdrawals()[j].Index, withdrawalIndex)
   134  			}
   135  			withdrawalIndex += 1
   136  		}
   137  	}
   138  }
   139  
   140  func ExampleGenerateChain() {
   141  	var (
   142  		key1, _ = pqcrypto.HexToDilithium("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   143  		key2, _ = pqcrypto.HexToDilithium("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   144  		key3, _ = pqcrypto.HexToDilithium("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   145  		addr1   = key1.GetAddress()
   146  		addr2   = key2.GetAddress()
   147  		addr3   = key3.GetAddress()
   148  		db      = rawdb.NewMemoryDatabase()
   149  		genDb   = rawdb.NewMemoryDatabase()
   150  	)
   151  
   152  	// Ensure that key1 has some funds in the genesis block.
   153  	gspec := &Genesis{
   154  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
   155  		Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}},
   156  	}
   157  	genesis := gspec.MustCommit(genDb, trie.NewDatabase(genDb, trie.HashDefaults))
   158  
   159  	// This call generates a chain of 5 blocks. The function runs for
   160  	// each block and adds different features to gen based on the
   161  	// block index.
   162  	signer := types.HomesteadSigner{}
   163  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), genDb, 5, func(i int, gen *BlockGen) {
   164  		switch i {
   165  		case 0:
   166  			// In block 1, addr1 sends addr2 some ether.
   167  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil), signer, key1)
   168  			gen.AddTx(tx)
   169  		case 1:
   170  			// In block 2, addr1 sends some more ether to addr2.
   171  			// addr2 passes it on to addr3.
   172  			tx1, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   173  			tx2, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   174  			gen.AddTx(tx1)
   175  			gen.AddTx(tx2)
   176  		case 2:
   177  			// Block 3 is empty but was mined by addr3.
   178  			gen.SetCoinbase(addr3)
   179  			gen.SetExtra([]byte("yeehaw"))
   180  		case 3:
   181  			// Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data).
   182  			b2 := gen.PrevBlock(1).Header()
   183  			b2.Extra = []byte("foo")
   184  			gen.AddUncle(b2)
   185  			b3 := gen.PrevBlock(2).Header()
   186  			b3.Extra = []byte("foo")
   187  			gen.AddUncle(b3)
   188  		}
   189  	})
   190  
   191  	// Import the chain. This runs all block validation rules.
   192  	blockchain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.HashScheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
   193  	defer blockchain.Stop()
   194  
   195  	if i, err := blockchain.InsertChain(chain); err != nil {
   196  		fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
   197  		return
   198  	}
   199  
   200  	state, _ := blockchain.State()
   201  	fmt.Printf("last block: #%d\n", blockchain.CurrentBlock().Number)
   202  	fmt.Println("balance of addr1:", state.GetBalance(addr1))
   203  	fmt.Println("balance of addr2:", state.GetBalance(addr2))
   204  	fmt.Println("balance of addr3:", state.GetBalance(addr3))
   205  	// Output:
   206  	// last block: #5
   207  	// balance of addr1: 989000
   208  	// balance of addr2: 10000
   209  	// balance of addr3: 19687500000000001000
   210  }