github.com/theQRL/go-zond@v0.2.1/miner/payload_building_test.go (about)

     1  // Copyright 2022 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 miner
    18  
    19  import (
    20  	"math/big"
    21  	"reflect"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/theQRL/go-zond/beacon/engine"
    26  	"github.com/theQRL/go-zond/common"
    27  	"github.com/theQRL/go-zond/consensus"
    28  	"github.com/theQRL/go-zond/consensus/beacon"
    29  	"github.com/theQRL/go-zond/core"
    30  	"github.com/theQRL/go-zond/core/rawdb"
    31  	"github.com/theQRL/go-zond/core/txpool"
    32  	"github.com/theQRL/go-zond/core/txpool/legacypool"
    33  	"github.com/theQRL/go-zond/core/types"
    34  	"github.com/theQRL/go-zond/core/vm"
    35  	"github.com/theQRL/go-zond/crypto"
    36  	"github.com/theQRL/go-zond/params"
    37  	"github.com/theQRL/go-zond/zonddb"
    38  )
    39  
    40  var (
    41  	// Test chain configurations
    42  	testTxPoolConfig  legacypool.Config
    43  	beaconChainConfig *params.ChainConfig
    44  
    45  	// Test accounts
    46  	testBankKey, _  = crypto.GenerateDilithiumKey()
    47  	testBankAddress = testBankKey.GetAddress()
    48  	testBankFunds   = big.NewInt(1000000000000000000)
    49  
    50  	testUserKey, _  = crypto.GenerateKey()
    51  	testUserAddress = crypto.PubkeyToAddress(testUserKey.PublicKey)
    52  
    53  	// Test transactions
    54  	pendingTxs []*types.Transaction
    55  	newTxs     []*types.Transaction
    56  
    57  	testConfig = Config{
    58  		PendingFeeRecipient: testBankAddress,
    59  		Recommit:            time.Second,
    60  		GasCeil:             params.GenesisGasLimit,
    61  	}
    62  )
    63  
    64  func init() {
    65  	testTxPoolConfig = legacypool.DefaultConfig
    66  	testTxPoolConfig.Journal = ""
    67  	beaconChainConfig = new(params.ChainConfig)
    68  	*beaconChainConfig = *params.TestChainConfig
    69  
    70  	signer := types.LatestSigner(params.TestChainConfig)
    71  	tx1 := types.MustSignNewTx(testBankKey, signer, &types.DynamicFeeTx{
    72  		ChainID:   params.TestChainConfig.ChainID,
    73  		Nonce:     0,
    74  		To:        &testUserAddress,
    75  		Value:     big.NewInt(1000),
    76  		Gas:       params.TxGas,
    77  		GasFeeCap: big.NewInt(params.InitialBaseFee),
    78  	})
    79  	pendingTxs = append(pendingTxs, tx1)
    80  
    81  	tx2 := types.MustSignNewTx(testBankKey, signer, &types.DynamicFeeTx{
    82  		Nonce:     1,
    83  		To:        &testUserAddress,
    84  		Value:     big.NewInt(1000),
    85  		Gas:       params.TxGas,
    86  		GasFeeCap: big.NewInt(params.InitialBaseFee),
    87  	})
    88  	newTxs = append(newTxs, tx2)
    89  }
    90  
    91  // testWorkerBackend implements worker.Backend interfaces and wraps all information needed during the testing.
    92  type testWorkerBackend struct {
    93  	db      zonddb.Database
    94  	txPool  *txpool.TxPool
    95  	chain   *core.BlockChain
    96  	genesis *core.Genesis
    97  }
    98  
    99  func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, db zonddb.Database, n int) *testWorkerBackend {
   100  	var gspec = &core.Genesis{
   101  		Config: chainConfig,
   102  		Alloc:  core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
   103  	}
   104  	switch engine.(type) {
   105  	case *beacon.Beacon:
   106  	default:
   107  		t.Fatalf("unexpected consensus engine type: %T", engine)
   108  	}
   109  	chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieDirtyDisabled: true}, gspec, engine, vm.Config{}, nil)
   110  	if err != nil {
   111  		t.Fatalf("core.NewBlockChain failed: %v", err)
   112  	}
   113  	pool := legacypool.New(testTxPoolConfig, chain)
   114  	txpool, _ := txpool.New(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), chain, []txpool.SubPool{pool})
   115  
   116  	return &testWorkerBackend{
   117  		db:      db,
   118  		chain:   chain,
   119  		txPool:  txpool,
   120  		genesis: gspec,
   121  	}
   122  }
   123  
   124  func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain }
   125  func (b *testWorkerBackend) TxPool() *txpool.TxPool       { return b.txPool }
   126  
   127  func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, db zonddb.Database, blocks int) (*Miner, *testWorkerBackend) {
   128  	backend := newTestWorkerBackend(t, chainConfig, engine, db, blocks)
   129  	backend.txPool.Add(pendingTxs, true, true)
   130  	w := New(backend, testConfig, engine)
   131  	return w, backend
   132  }
   133  
   134  func TestBuildPayload(t *testing.T) {
   135  	var (
   136  		db           = rawdb.NewMemoryDatabase()
   137  		recipient, _ = common.NewAddressFromString("Z00000000000000000000000000000000deadbeef")
   138  	)
   139  	w, b := newTestWorker(t, params.TestChainConfig, beacon.NewFaker(), db, 0)
   140  
   141  	timestamp := uint64(time.Now().Unix())
   142  	args := &BuildPayloadArgs{
   143  		Parent:       b.chain.CurrentBlock().Hash(),
   144  		Timestamp:    timestamp,
   145  		Random:       common.Hash{},
   146  		FeeRecipient: recipient,
   147  	}
   148  	payload, err := w.buildPayload(args)
   149  	if err != nil {
   150  		t.Fatalf("Failed to build payload %v", err)
   151  	}
   152  	verify := func(outer *engine.ExecutionPayloadEnvelope, txs int) {
   153  		payload := outer.ExecutionPayload
   154  		if payload.ParentHash != b.chain.CurrentBlock().Hash() {
   155  			t.Fatal("Unexpected parent hash")
   156  		}
   157  		if payload.Random != (common.Hash{}) {
   158  			t.Fatal("Unexpected random value")
   159  		}
   160  		if payload.Timestamp != timestamp {
   161  			t.Fatal("Unexpected timestamp")
   162  		}
   163  		if payload.FeeRecipient != recipient {
   164  			t.Fatal("Unexpected fee recipient")
   165  		}
   166  		if len(payload.Transactions) != txs {
   167  			t.Fatal("Unexpected transaction set")
   168  		}
   169  	}
   170  	empty := payload.ResolveEmpty()
   171  	verify(empty, 0)
   172  
   173  	full := payload.ResolveFull()
   174  	verify(full, len(pendingTxs))
   175  
   176  	// Ensure resolve can be called multiple times and the
   177  	// result should be unchanged
   178  	dataOne := payload.Resolve()
   179  	dataTwo := payload.Resolve()
   180  	if !reflect.DeepEqual(dataOne, dataTwo) {
   181  		t.Fatal("Unexpected payload data")
   182  	}
   183  }
   184  
   185  func TestPayloadId(t *testing.T) {
   186  	t.Parallel()
   187  	ids := make(map[string]int)
   188  	for i, tt := range []*BuildPayloadArgs{
   189  		{
   190  			Parent:       common.Hash{1},
   191  			Timestamp:    1,
   192  			Random:       common.Hash{0x1},
   193  			FeeRecipient: common.Address{0x1},
   194  		},
   195  		// Different parent
   196  		{
   197  			Parent:       common.Hash{2},
   198  			Timestamp:    1,
   199  			Random:       common.Hash{0x1},
   200  			FeeRecipient: common.Address{0x1},
   201  		},
   202  		// Different timestamp
   203  		{
   204  			Parent:       common.Hash{2},
   205  			Timestamp:    2,
   206  			Random:       common.Hash{0x1},
   207  			FeeRecipient: common.Address{0x1},
   208  		},
   209  		// Different Random
   210  		{
   211  			Parent:       common.Hash{2},
   212  			Timestamp:    2,
   213  			Random:       common.Hash{0x2},
   214  			FeeRecipient: common.Address{0x1},
   215  		},
   216  		// Different fee-recipient
   217  		{
   218  			Parent:       common.Hash{2},
   219  			Timestamp:    2,
   220  			Random:       common.Hash{0x2},
   221  			FeeRecipient: common.Address{0x2},
   222  		},
   223  		// Different withdrawals (non-empty)
   224  		{
   225  			Parent:       common.Hash{2},
   226  			Timestamp:    2,
   227  			Random:       common.Hash{0x2},
   228  			FeeRecipient: common.Address{0x2},
   229  			Withdrawals: []*types.Withdrawal{
   230  				{
   231  					Index:     0,
   232  					Validator: 0,
   233  					Address:   common.Address{},
   234  					Amount:    0,
   235  				},
   236  			},
   237  		},
   238  		// Different withdrawals (non-empty)
   239  		{
   240  			Parent:       common.Hash{2},
   241  			Timestamp:    2,
   242  			Random:       common.Hash{0x2},
   243  			FeeRecipient: common.Address{0x2},
   244  			Withdrawals: []*types.Withdrawal{
   245  				{
   246  					Index:     2,
   247  					Validator: 0,
   248  					Address:   common.Address{},
   249  					Amount:    0,
   250  				},
   251  			},
   252  		},
   253  	} {
   254  		id := tt.Id().String()
   255  		if prev, exists := ids[id]; exists {
   256  			t.Errorf("ID collision, case %d and case %d: id %v", prev, i, id)
   257  		}
   258  		ids[id] = i
   259  	}
   260  }