github.com/theQRL/go-zond@v0.2.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/core/rawdb"
    27  	"github.com/theQRL/go-zond/core/types"
    28  	"github.com/theQRL/go-zond/core/vm"
    29  	"github.com/theQRL/go-zond/crypto/pqcrypto"
    30  	"github.com/theQRL/go-zond/params"
    31  	"github.com/theQRL/go-zond/trie"
    32  )
    33  
    34  func TestGenerateWithdrawalChain(t *testing.T) {
    35  	var (
    36  		keyHex  = "9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c"
    37  		key, _  = pqcrypto.HexToDilithium(keyHex)
    38  		address = key.GetAddress()
    39  		aa      = common.Address{0xaa}
    40  		bb      = common.Address{0xbb}
    41  		funds   = big.NewInt(0).Mul(big.NewInt(1337), big.NewInt(params.Ether))
    42  		config  = *params.AllBeaconProtocolChanges
    43  		gspec   = &Genesis{
    44  			Config:   &config,
    45  			Alloc:    GenesisAlloc{address: {Balance: funds}},
    46  			BaseFee:  big.NewInt(params.InitialBaseFee),
    47  			GasLimit: 5_000_000,
    48  		}
    49  		gendb  = rawdb.NewMemoryDatabase()
    50  		signer = types.LatestSigner(gspec.Config)
    51  		db     = rawdb.NewMemoryDatabase()
    52  	)
    53  
    54  	// init 0xaa with some storage elements
    55  	storage := make(map[common.Hash]common.Hash)
    56  	storage[common.Hash{0x00}] = common.Hash{0x00}
    57  	storage[common.Hash{0x01}] = common.Hash{0x01}
    58  	storage[common.Hash{0x02}] = common.Hash{0x02}
    59  	storage[common.Hash{0x03}] = common.HexToHash("0303")
    60  	gspec.Alloc[aa] = GenesisAccount{
    61  		Balance: common.Big1,
    62  		Nonce:   1,
    63  		Storage: storage,
    64  		Code:    common.Hex2Bytes("6042"),
    65  	}
    66  	gspec.Alloc[bb] = GenesisAccount{
    67  		Balance: common.Big2,
    68  		Nonce:   1,
    69  		Storage: storage,
    70  		Code:    common.Hex2Bytes("600154600354"),
    71  	}
    72  	genesis := gspec.MustCommit(gendb, trie.NewDatabase(gendb, trie.HashDefaults))
    73  
    74  	chain, _ := GenerateChain(gspec.Config, genesis, beacon.NewFaker(), gendb, 4, func(i int, gen *BlockGen) {
    75  		to := common.Address(address)
    76  		tx := types.NewTx(&types.DynamicFeeTx{
    77  			Nonce:     gen.TxNonce(address),
    78  			To:        &to,
    79  			Value:     big.NewInt(1000),
    80  			Gas:       params.TxGas,
    81  			GasFeeCap: new(big.Int).Add(gen.BaseFee(), common.Big1),
    82  			Data:      nil,
    83  		})
    84  		signedTx, _ := types.SignTx(tx, signer, key)
    85  		gen.AddTx(signedTx)
    86  		if i == 1 {
    87  			gen.AddWithdrawal(&types.Withdrawal{
    88  				Validator: 42,
    89  				Address:   common.Address{0xee},
    90  				Amount:    1337,
    91  			})
    92  			gen.AddWithdrawal(&types.Withdrawal{
    93  				Validator: 13,
    94  				Address:   common.Address{0xee},
    95  				Amount:    1,
    96  			})
    97  		}
    98  		if i == 3 {
    99  			gen.AddWithdrawal(&types.Withdrawal{
   100  				Validator: 42,
   101  				Address:   common.Address{0xee},
   102  				Amount:    1337,
   103  			})
   104  			gen.AddWithdrawal(&types.Withdrawal{
   105  				Validator: 13,
   106  				Address:   common.Address{0xee},
   107  				Amount:    1,
   108  			})
   109  		}
   110  	})
   111  
   112  	// Import the chain. This runs all block validation rules.
   113  	blockchain, _ := NewBlockChain(db, nil, gspec, beacon.NewFaker(), vm.Config{}, nil)
   114  	defer blockchain.Stop()
   115  
   116  	if i, err := blockchain.InsertChain(chain); err != nil {
   117  		fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
   118  		return
   119  	}
   120  
   121  	// enforce that withdrawal indexes are monotonically increasing from 0
   122  	var (
   123  		withdrawalIndex uint64
   124  		head            = blockchain.CurrentBlock().Number.Uint64()
   125  	)
   126  	for i := 0; i < int(head); i++ {
   127  		block := blockchain.GetBlockByNumber(uint64(i))
   128  		if block == nil {
   129  			t.Fatalf("block %d not found", i)
   130  		}
   131  		if len(block.Withdrawals()) == 0 {
   132  			continue
   133  		}
   134  		for j := 0; j < len(block.Withdrawals()); j++ {
   135  			if block.Withdrawals()[j].Index != withdrawalIndex {
   136  				t.Fatalf("withdrawal index %d does not equal expected index %d", block.Withdrawals()[j].Index, withdrawalIndex)
   137  			}
   138  			withdrawalIndex += 1
   139  		}
   140  	}
   141  }
   142  
   143  func ExampleGenerateChain() {
   144  	var (
   145  		key1, _ = pqcrypto.HexToDilithium("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   146  		key2, _ = pqcrypto.HexToDilithium("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   147  		key3, _ = pqcrypto.HexToDilithium("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   148  		addr1   = key1.GetAddress()
   149  		addr2   = key2.GetAddress()
   150  		addr3   = key3.GetAddress()
   151  		db      = rawdb.NewMemoryDatabase()
   152  		genDb   = rawdb.NewMemoryDatabase()
   153  	)
   154  
   155  	// Ensure that key1 has some funds in the genesis block.
   156  	gspec := &Genesis{
   157  		Config: &params.ChainConfig{
   158  			ChainID: big.NewInt(1),
   159  		},
   160  		Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(2000000000000000)}},
   161  	}
   162  	genesis := gspec.MustCommit(genDb, trie.NewDatabase(genDb, trie.HashDefaults))
   163  
   164  	// This call generates a chain of 5 blocks. The function runs for
   165  	// each block and adds different features to gen based on the
   166  	// block index.
   167  	signer := types.ShanghaiSigner{ChainId: big.NewInt(1)}
   168  	chain, _ := GenerateChain(gspec.Config, genesis, beacon.NewFaker(), genDb, 5, func(i int, gen *BlockGen) {
   169  		switch i {
   170  		case 0:
   171  			// In block 1, addr1 sends addr2 some ether.
   172  			to := common.Address(addr2)
   173  			tx := types.NewTx(&types.DynamicFeeTx{
   174  				Nonce:     gen.TxNonce(addr1),
   175  				To:        &to,
   176  				Value:     big.NewInt(10000000000000),
   177  				Gas:       params.TxGas,
   178  				GasFeeCap: gen.header.BaseFee,
   179  				Data:      nil,
   180  			})
   181  			signedTx, _ := types.SignTx(tx, signer, key1)
   182  			gen.AddTx(signedTx)
   183  
   184  		case 1:
   185  			// In block 2, addr1 sends some more ether to addr2.
   186  			// addr2 passes it on to addr3.
   187  			to2 := common.Address(addr2)
   188  			to3 := common.Address(addr3)
   189  			tx1 := types.NewTx(&types.DynamicFeeTx{
   190  				Nonce:     gen.TxNonce(addr1),
   191  				To:        &to2,
   192  				Value:     big.NewInt(10000000000000),
   193  				Gas:       params.TxGas,
   194  				GasFeeCap: gen.header.BaseFee,
   195  				Data:      nil,
   196  			})
   197  			tx2 := types.NewTx(&types.DynamicFeeTx{
   198  				Nonce:     gen.TxNonce(addr2),
   199  				To:        &to3,
   200  				Value:     big.NewInt(10000000),
   201  				Gas:       params.TxGas,
   202  				GasFeeCap: gen.header.BaseFee,
   203  				Data:      nil,
   204  			})
   205  			signedTx1, _ := types.SignTx(tx1, signer, key1)
   206  			signedTx2, _ := types.SignTx(tx2, signer, key2)
   207  			gen.AddTx(signedTx1)
   208  			gen.AddTx(signedTx2)
   209  		case 2:
   210  			// Block 3 is empty but was mined by addr3.
   211  			gen.SetCoinbase(addr3)
   212  			gen.SetExtra([]byte("yeehaw"))
   213  		case 3:
   214  			// Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data).
   215  			b2 := gen.PrevBlock(1).Header()
   216  			b2.Extra = []byte("foo")
   217  			b3 := gen.PrevBlock(2).Header()
   218  			b3.Extra = []byte("foo")
   219  		}
   220  	})
   221  
   222  	// Import the chain. This runs all block validation rules.
   223  	blockchain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.HashScheme), gspec, beacon.NewFaker(), vm.Config{}, nil)
   224  	defer blockchain.Stop()
   225  
   226  	if i, err := blockchain.InsertChain(chain); err != nil {
   227  		fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
   228  		return
   229  	}
   230  
   231  	state, _ := blockchain.State()
   232  	fmt.Printf("last block: #%d\n", blockchain.CurrentBlock().Number)
   233  	fmt.Println("balance of addr1:", state.GetBalance(addr1))
   234  	fmt.Println("balance of addr2:", state.GetBalance(addr2))
   235  	fmt.Println("balance of addr3:", state.GetBalance(addr3))
   236  	// Output:
   237  	// last block: #5
   238  	// balance of addr1: 1945526403675000
   239  	// balance of addr2: 3901393675000
   240  	// balance of addr3: 10000000
   241  }