github.com/klaytn/klaytn@v1.12.1/tests/klay_test.go (about)

     1  // Copyright 2018 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package tests
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/ecdsa"
    22  	"flag"
    23  	"fmt"
    24  	"math/big"
    25  	"math/rand"
    26  	"os"
    27  	"strconv"
    28  	"testing"
    29  	"time"
    30  
    31  	"github.com/klaytn/klaytn/blockchain"
    32  	"github.com/klaytn/klaytn/blockchain/types"
    33  	"github.com/klaytn/klaytn/common/profile"
    34  	"github.com/klaytn/klaytn/crypto"
    35  	"github.com/klaytn/klaytn/kerrors"
    36  	"github.com/klaytn/klaytn/log"
    37  	"github.com/klaytn/klaytn/params"
    38  	"github.com/klaytn/klaytn/rlp"
    39  	"github.com/stretchr/testify/assert"
    40  	"github.com/stretchr/testify/require"
    41  )
    42  
    43  var txPerBlock int
    44  
    45  func init() {
    46  	flag.IntVar(&txPerBlock, "txs-per-block", 1000,
    47  		"Specify the number of transactions per block")
    48  }
    49  
    50  ////////////////////////////////////////////////////////////////////////////////
    51  // TestValueTransfer
    52  ////////////////////////////////////////////////////////////////////////////////
    53  type testOption struct {
    54  	numTransactions    int
    55  	numMaxAccounts     int
    56  	numValidators      int
    57  	numGeneratedBlocks int
    58  	txdata             []byte
    59  	makeTransactions   func(*BCData, *AccountMap, types.Signer, int, *big.Int, []byte) (types.Transactions, error)
    60  }
    61  
    62  func makeTransactionsFrom(bcdata *BCData, accountMap *AccountMap, signer types.Signer, numTransactions int,
    63  	amount *big.Int, data []byte,
    64  ) (types.Transactions, error) {
    65  	from := *bcdata.addrs[0]
    66  	privKey := bcdata.privKeys[0]
    67  	toAddrs := bcdata.addrs
    68  	numAddrs := len(toAddrs)
    69  
    70  	txs := make(types.Transactions, 0, numTransactions)
    71  	nonce := accountMap.GetNonce(from)
    72  
    73  	for i := 0; i < numTransactions; i++ {
    74  		a := toAddrs[i%numAddrs]
    75  		txamount := amount
    76  		if txamount == nil {
    77  			txamount = big.NewInt(rand.Int63n(10))
    78  			txamount = txamount.Add(txamount, big.NewInt(1))
    79  		}
    80  		var gasLimit uint64 = 1000000
    81  		gasPrice := new(big.Int).SetInt64(0)
    82  
    83  		tx := types.NewTransaction(nonce, *a, txamount, gasLimit, gasPrice, data)
    84  		signedTx, err := types.SignTx(tx, signer, privKey)
    85  		if err != nil {
    86  			return nil, err
    87  		}
    88  
    89  		txs = append(txs, signedTx)
    90  
    91  		nonce++
    92  	}
    93  
    94  	return txs, nil
    95  }
    96  
    97  func makeIndependentTransactions(bcdata *BCData, accountMap *AccountMap, signer types.Signer, numTransactions int,
    98  	amount *big.Int, data []byte,
    99  ) (types.Transactions, error) {
   100  	numAddrs := len(bcdata.addrs) / 2
   101  	fromAddrs := bcdata.addrs[:numAddrs]
   102  	toAddrs := bcdata.addrs[numAddrs:]
   103  
   104  	fromNonces := make([]uint64, numAddrs)
   105  	for i, addr := range fromAddrs {
   106  		fromNonces[i] = accountMap.GetNonce(*addr)
   107  	}
   108  
   109  	txs := make(types.Transactions, 0, numTransactions)
   110  
   111  	for i := 0; i < numTransactions; i++ {
   112  		idx := i % numAddrs
   113  
   114  		txamount := amount
   115  		if txamount == nil {
   116  			txamount = big.NewInt(rand.Int63n(10))
   117  			txamount = txamount.Add(txamount, big.NewInt(1))
   118  		}
   119  		var gasLimit uint64 = 1000000
   120  		gasPrice := new(big.Int).SetInt64(0)
   121  
   122  		tx := types.NewTransaction(fromNonces[idx], *toAddrs[idx], txamount, gasLimit, gasPrice, data)
   123  		signedTx, err := types.SignTx(tx, signer, bcdata.privKeys[idx])
   124  		if err != nil {
   125  			return nil, err
   126  		}
   127  
   128  		txs = append(txs, signedTx)
   129  
   130  		fromNonces[idx]++
   131  	}
   132  
   133  	return txs, nil
   134  }
   135  
   136  // makeTransactionsToRandom makes `numTransactions` transactions which transfers a random amount of tokens
   137  // from accounts in `AccountMap` to a randomly generated account.
   138  // It returns the generated transactions if successful, or it returns an error if failed.
   139  func makeTransactionsToRandom(bcdata *BCData, accountMap *AccountMap, signer types.Signer, numTransactions int,
   140  	amount *big.Int, data []byte,
   141  ) (types.Transactions, error) {
   142  	numAddrs := len(bcdata.addrs)
   143  	fromAddrs := bcdata.addrs
   144  
   145  	fromNonces := make([]uint64, numAddrs)
   146  	for i, addr := range fromAddrs {
   147  		fromNonces[i] = accountMap.GetNonce(*addr)
   148  	}
   149  
   150  	txs := make(types.Transactions, 0, numTransactions)
   151  
   152  	for i := 0; i < numTransactions; i++ {
   153  		idx := i % numAddrs
   154  
   155  		txamount := amount
   156  		if txamount == nil {
   157  			txamount = big.NewInt(rand.Int63n(10))
   158  			txamount = txamount.Add(txamount, big.NewInt(1))
   159  		}
   160  		var gasLimit uint64 = 1000000
   161  		gasPrice := new(big.Int).SetInt64(0)
   162  
   163  		// generate a new address
   164  		k, err := crypto.GenerateKey()
   165  		if err != nil {
   166  			return nil, err
   167  		}
   168  		to := crypto.PubkeyToAddress(k.PublicKey)
   169  
   170  		tx := types.NewTransaction(fromNonces[idx], to, txamount, gasLimit, gasPrice, data)
   171  		signedTx, err := types.SignTx(tx, signer, bcdata.privKeys[idx])
   172  		if err != nil {
   173  			return nil, err
   174  		}
   175  
   176  		txs = append(txs, signedTx)
   177  
   178  		fromNonces[idx]++
   179  	}
   180  
   181  	return txs, nil
   182  }
   183  
   184  // makeTransactionsToRandom makes `numTransactions` transactions which transfers a random amount of KLAY
   185  // from accounts in `AccountMap` to a randomly generated account.
   186  // It returns the generated transactions if successful, or it returns an error if failed.
   187  func makeNewTransactionsToRandom(bcdata *BCData, accountMap *AccountMap, signer types.Signer, numTransactions int,
   188  	amount *big.Int, data []byte,
   189  ) (types.Transactions, error) {
   190  	numAddrs := len(bcdata.addrs)
   191  	fromAddrs := bcdata.addrs
   192  	fromNonces := make([]uint64, numAddrs)
   193  
   194  	for i, addr := range fromAddrs {
   195  		fromNonces[i] = accountMap.GetNonce(*addr)
   196  	}
   197  
   198  	txs := make(types.Transactions, 0, numTransactions)
   199  
   200  	for i := 0; i < numTransactions; i++ {
   201  		idx := i % numAddrs
   202  
   203  		txamount := amount
   204  		if txamount == nil {
   205  			txamount = big.NewInt(rand.Int63n(10))
   206  			txamount = txamount.Add(txamount, big.NewInt(1))
   207  		}
   208  		var gasLimit uint64 = 1000000
   209  		gasPrice := new(big.Int).SetInt64(0)
   210  
   211  		// generate a new address
   212  		k, err := crypto.GenerateKey()
   213  		if err != nil {
   214  			return nil, err
   215  		}
   216  		to := crypto.PubkeyToAddress(k.PublicKey)
   217  
   218  		tx, err := types.NewTransactionWithMap(types.TxTypeValueTransfer, map[types.TxValueKeyType]interface{}{
   219  			types.TxValueKeyNonce:    fromNonces[idx],
   220  			types.TxValueKeyTo:       to,
   221  			types.TxValueKeyAmount:   txamount,
   222  			types.TxValueKeyGasLimit: gasLimit,
   223  			types.TxValueKeyGasPrice: gasPrice,
   224  			types.TxValueKeyFrom:     *bcdata.addrs[idx],
   225  		})
   226  		signedTx, err := types.SignTx(tx, signer, bcdata.privKeys[idx])
   227  		if err != nil {
   228  			return nil, err
   229  		}
   230  
   231  		txs = append(txs, signedTx)
   232  
   233  		fromNonces[idx]++
   234  	}
   235  
   236  	return txs, nil
   237  }
   238  
   239  // makeNewTransactionsToRing makes `numTransactions` transactions which transfers a fixed amount of KLAY
   240  // from account with index i to account with index (i+1). To have same amount of balance before and after the test,
   241  // total number of transactions should be the multiple of number of addresses.
   242  // It returns the generated transactions if successful, or it returns an error if failed.
   243  func makeNewTransactionsToRing(bcdata *BCData, accountMap *AccountMap, signer types.Signer, numTransactions int,
   244  	amount *big.Int, data []byte,
   245  ) (types.Transactions, error) {
   246  	numAddrs := len(bcdata.addrs)
   247  	fromAddrs := bcdata.addrs
   248  
   249  	if numTransactions%numAddrs != 0 {
   250  		return nil, fmt.Errorf("numTranasctions should be divided by numAddrs! numTransactions: %v, numAddrs: %v", numTransactions, numAddrs)
   251  	}
   252  
   253  	fromNonces := make([]uint64, numAddrs)
   254  	for i, addr := range fromAddrs {
   255  		fromNonces[i] = accountMap.GetNonce(*addr)
   256  	}
   257  
   258  	txs := make(types.Transactions, 0, numTransactions)
   259  	txAmount := amount
   260  	if txAmount == nil {
   261  		txAmount = big.NewInt(rand.Int63n(10))
   262  		txAmount = txAmount.Add(txAmount, big.NewInt(1))
   263  	}
   264  	var gasLimit uint64 = 1000000
   265  	gasPrice := new(big.Int).SetInt64(0)
   266  	for i := 0; i < numTransactions; i++ {
   267  		fromIdx := i % numAddrs
   268  
   269  		toIdx := (fromIdx + 1) % numAddrs
   270  		toAddr := *bcdata.addrs[toIdx]
   271  
   272  		tx, err := types.NewTransactionWithMap(types.TxTypeValueTransfer, map[types.TxValueKeyType]interface{}{
   273  			types.TxValueKeyNonce:    fromNonces[fromIdx],
   274  			types.TxValueKeyTo:       toAddr,
   275  			types.TxValueKeyAmount:   txAmount,
   276  			types.TxValueKeyGasLimit: gasLimit,
   277  			types.TxValueKeyGasPrice: gasPrice,
   278  			types.TxValueKeyFrom:     *bcdata.addrs[fromIdx],
   279  		})
   280  
   281  		signedTx, err := types.SignTx(tx, signer, bcdata.privKeys[fromIdx])
   282  		if err != nil {
   283  			return nil, err
   284  		}
   285  
   286  		txs = append(txs, signedTx)
   287  		fromNonces[fromIdx]++
   288  	}
   289  
   290  	return txs, nil
   291  }
   292  
   293  func TestValueTransfer(t *testing.T) {
   294  	var nBlocks int = 3
   295  	var txPerBlock int = 10
   296  
   297  	if i, err := strconv.ParseInt(os.Getenv("NUM_BLOCKS"), 10, 32); err == nil {
   298  		nBlocks = int(i)
   299  	}
   300  
   301  	if i, err := strconv.ParseInt(os.Getenv("TXS_PER_BLOCK"), 10, 32); err == nil {
   302  		txPerBlock = int(i)
   303  	}
   304  
   305  	valueTransferTests := [...]struct {
   306  		name string
   307  		opt  testOption
   308  	}{
   309  		{
   310  			"SingleSenderMultipleRecipient",
   311  			testOption{txPerBlock, 1000, 4, nBlocks, []byte{}, makeTransactionsFrom},
   312  		},
   313  		{
   314  			"MultipleSenderMultipleRecipient",
   315  			testOption{txPerBlock, 2000, 4, nBlocks, []byte{}, makeIndependentTransactions},
   316  		},
   317  		{
   318  			"MultipleSenderRandomRecipient",
   319  			testOption{txPerBlock, 2000, 4, nBlocks, []byte{}, makeTransactionsToRandom},
   320  		},
   321  
   322  		// Below test cases execute one transaction per a block.
   323  		{
   324  			"SingleSenderMultipleRecipientSingleTxPerBlock",
   325  			testOption{1, 1000, 4, 10, []byte{}, makeTransactionsFrom},
   326  		},
   327  		{
   328  			"MultipleSenderMultipleRecipientSingleTxPerBlock",
   329  			testOption{1, 2000, 4, 10, []byte{}, makeIndependentTransactions},
   330  		},
   331  		{
   332  			"MultipleSenderRandomRecipientSingleTxPerBlock",
   333  			testOption{1, 2000, 4, 10, []byte{}, makeTransactionsToRandom},
   334  		},
   335  	}
   336  
   337  	for _, test := range valueTransferTests {
   338  		t.Run(test.name, func(t *testing.T) {
   339  			testValueTransfer(t, &test.opt)
   340  		})
   341  	}
   342  }
   343  
   344  func testValueTransfer(t *testing.T, opt *testOption) {
   345  	prof := profile.NewProfiler()
   346  
   347  	// Initialize blockchain
   348  	start := time.Now()
   349  	bcdata, err := NewBCData(opt.numMaxAccounts, opt.numValidators)
   350  	if err != nil {
   351  		t.Fatal(err)
   352  	}
   353  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
   354  	defer bcdata.Shutdown()
   355  
   356  	// Initialize address-balance map for verification
   357  	start = time.Now()
   358  	accountMap := NewAccountMap()
   359  	if err := accountMap.Initialize(bcdata); err != nil {
   360  		t.Fatal(err)
   361  	}
   362  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
   363  
   364  	for i := 0; i < opt.numGeneratedBlocks; i++ {
   365  		// fmt.Printf("iteration %d\n", i)
   366  		err := bcdata.GenABlock(accountMap, opt, opt.numTransactions, prof)
   367  		if err != nil {
   368  			t.Fatal(err)
   369  		}
   370  	}
   371  
   372  	if testing.Verbose() {
   373  		prof.PrintProfileInfo()
   374  	}
   375  }
   376  
   377  func TestValueTransferRing(t *testing.T) {
   378  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   379  	prof := profile.NewProfiler()
   380  
   381  	numTransactions := 20000
   382  	numAccounts := 2000
   383  
   384  	if numTransactions%numAccounts != 0 {
   385  		t.Fatalf("numTransactions should be divided by numAccounts! numTransactions: %v, numAccounts: %v", numTransactions, numAccounts)
   386  	}
   387  
   388  	opt := testOption{numTransactions, numAccounts, 4, 1, []byte{}, makeNewTransactionsToRing}
   389  
   390  	// Initialize blockchain
   391  	start := time.Now()
   392  	bcdata, err := NewBCData(opt.numMaxAccounts, opt.numValidators)
   393  	if err != nil {
   394  		t.Fatal(err)
   395  	}
   396  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
   397  	defer bcdata.Shutdown()
   398  
   399  	// Initialize address-balance map for verification
   400  	start = time.Now()
   401  	accountMap := NewAccountMap()
   402  	if err := accountMap.Initialize(bcdata); err != nil {
   403  		t.Fatal(err)
   404  	}
   405  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
   406  
   407  	// make txpool
   408  	txpool := makeTxPool(bcdata, opt.numTransactions)
   409  	signer := types.MakeSigner(bcdata.bc.Config(), bcdata.bc.CurrentHeader().Number)
   410  
   411  	// make ring transactions
   412  	txs, err := makeNewTransactionsToRing(bcdata, accountMap, signer, opt.numTransactions, nil, []byte{})
   413  	if err != nil {
   414  		t.Fatal(err)
   415  	}
   416  
   417  	txpool.AddRemotes(txs)
   418  
   419  	for {
   420  		if err := bcdata.GenABlockWithTxpool(accountMap, txpool, prof); err != nil {
   421  			if err == errEmptyPending {
   422  				break
   423  			}
   424  			t.Fatal(err)
   425  		}
   426  	}
   427  
   428  	if testing.Verbose() {
   429  		prof.PrintProfileInfo()
   430  	}
   431  }
   432  
   433  // TestWronglyEncodedAccountKey checks if accountKey field is encoded in a wrong way.
   434  // case 1. AccountUpdate
   435  // case 2. FeeDelegatedAccountUpdate
   436  // case 3. FeeDelegatedAccountUpdateWithRatio
   437  func TestWronglyEncodedAccountKey(t *testing.T) {
   438  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   439  	prof := profile.NewProfiler()
   440  
   441  	numTransactions := 20000
   442  	numAccounts := 2000
   443  
   444  	if numTransactions%numAccounts != 0 {
   445  		t.Fatalf("numTransactions should be divided by numAccounts! numTransactions: %v, numAccounts: %v", numTransactions, numAccounts)
   446  	}
   447  
   448  	opt := testOption{numTransactions, numAccounts, 4, 1, []byte{}, makeNewTransactionsToRing}
   449  
   450  	// Initialize blockchain
   451  	start := time.Now()
   452  	bcdata, err := NewBCData(opt.numMaxAccounts, opt.numValidators)
   453  	if err != nil {
   454  		t.Fatal(err)
   455  	}
   456  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
   457  	defer bcdata.Shutdown()
   458  
   459  	// Initialize address-balance map for verification
   460  	start = time.Now()
   461  	accountMap := NewAccountMap()
   462  	if err := accountMap.Initialize(bcdata); err != nil {
   463  		t.Fatal(err)
   464  	}
   465  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
   466  
   467  	// make txpool
   468  	// var txs types.Transactions
   469  	signer := types.MakeSigner(bcdata.bc.Config(), bcdata.bc.CurrentHeader().Number)
   470  
   471  	// case 1. AccountUpdate
   472  	{
   473  		tx := types.NewTx(&types.TxInternalDataAccountUpdate{})
   474  		txtype := types.TxTypeAccountUpdate
   475  
   476  		wrongEncodedKey := []byte{0x10}
   477  		serializedBytes, err := rlp.EncodeToBytes([]interface{}{
   478  			txtype,
   479  			uint64(0),
   480  			new(big.Int).SetUint64(25 * params.Ston),
   481  			uint64(100000),
   482  			*bcdata.addrs[0],
   483  			wrongEncodedKey,
   484  		})
   485  		require.Equal(t, nil, err)
   486  
   487  		h := rlpHash(struct {
   488  			Byte    []byte
   489  			ChainId *big.Int
   490  			R       uint
   491  			S       uint
   492  		}{
   493  			serializedBytes,
   494  			bcdata.bc.Config().ChainID,
   495  			uint(0),
   496  			uint(0),
   497  		})
   498  		sig, err := types.NewTxSignaturesWithValues(signer, tx, h, []*ecdsa.PrivateKey{bcdata.privKeys[0]})
   499  		if err != nil {
   500  			panic(err)
   501  		}
   502  
   503  		buffer := new(bytes.Buffer)
   504  		err = rlp.Encode(buffer, txtype)
   505  		assert.Equal(t, nil, err)
   506  
   507  		err = rlp.Encode(buffer, []interface{}{
   508  			uint64(0),
   509  			new(big.Int).SetUint64(25 * params.Ston),
   510  			uint64(100000),
   511  			*bcdata.addrs[0],
   512  			wrongEncodedKey,
   513  			sig,
   514  		})
   515  		require.Equal(t, nil, err)
   516  
   517  		err = rlp.DecodeBytes(buffer.Bytes(), tx)
   518  		require.Equal(t, kerrors.ErrUnserializableKey, err)
   519  	}
   520  
   521  	// case 2. FeeDelegatedAccountUpdate
   522  	{
   523  		tx := types.NewTx(&types.TxInternalDataFeeDelegatedAccountUpdate{})
   524  		txtype := types.TxTypeFeeDelegatedAccountUpdate
   525  
   526  		wrongEncodedKey := []byte{0x10}
   527  		serializedBytes, err := rlp.EncodeToBytes([]interface{}{
   528  			txtype,
   529  			uint64(0),
   530  			new(big.Int).SetUint64(25 * params.Ston),
   531  			uint64(100000),
   532  			*bcdata.addrs[0],
   533  			wrongEncodedKey,
   534  		})
   535  		require.Equal(t, nil, err)
   536  
   537  		h := rlpHash(struct {
   538  			Byte    []byte
   539  			ChainId *big.Int
   540  			R       uint
   541  			S       uint
   542  		}{
   543  			serializedBytes,
   544  			bcdata.bc.Config().ChainID,
   545  			uint(0),
   546  			uint(0),
   547  		})
   548  		sig, err := types.NewTxSignaturesWithValues(signer, tx, h, []*ecdsa.PrivateKey{bcdata.privKeys[0]})
   549  		if err != nil {
   550  			panic(err)
   551  		}
   552  
   553  		buffer := new(bytes.Buffer)
   554  		err = rlp.Encode(buffer, txtype)
   555  		assert.Equal(t, nil, err)
   556  
   557  		err = rlp.Encode(buffer, []interface{}{
   558  			uint64(0),
   559  			new(big.Int).SetUint64(25 * params.Ston),
   560  			uint64(100000),
   561  			*bcdata.addrs[0],
   562  			wrongEncodedKey,
   563  			sig,
   564  			*bcdata.addrs[0],
   565  			sig,
   566  		})
   567  		require.Equal(t, nil, err)
   568  
   569  		err = rlp.DecodeBytes(buffer.Bytes(), tx)
   570  		require.Equal(t, kerrors.ErrUnserializableKey, err)
   571  	}
   572  
   573  	// case 3. FeeDelegatedAccountUpdateWithRatio
   574  	{
   575  		tx := types.NewTx(&types.TxInternalDataFeeDelegatedAccountUpdateWithRatio{})
   576  		txtype := types.TxTypeFeeDelegatedAccountUpdateWithRatio
   577  
   578  		wrongEncodedKey := []byte{0x10}
   579  		serializedBytes, err := rlp.EncodeToBytes([]interface{}{
   580  			txtype,
   581  			uint64(0),
   582  			new(big.Int).SetUint64(25 * params.Ston),
   583  			uint64(100000),
   584  			*bcdata.addrs[0],
   585  			types.FeeRatio(10),
   586  			wrongEncodedKey,
   587  		})
   588  		require.Equal(t, nil, err)
   589  
   590  		h := rlpHash(struct {
   591  			Byte    []byte
   592  			ChainId *big.Int
   593  			R       uint
   594  			S       uint
   595  		}{
   596  			serializedBytes,
   597  			bcdata.bc.Config().ChainID,
   598  			uint(0),
   599  			uint(0),
   600  		})
   601  		sig, err := types.NewTxSignaturesWithValues(signer, tx, h, []*ecdsa.PrivateKey{bcdata.privKeys[0]})
   602  		if err != nil {
   603  			panic(err)
   604  		}
   605  
   606  		buffer := new(bytes.Buffer)
   607  		err = rlp.Encode(buffer, txtype)
   608  		assert.Equal(t, nil, err)
   609  
   610  		err = rlp.Encode(buffer, []interface{}{
   611  			uint64(0),
   612  			new(big.Int).SetUint64(25 * params.Ston),
   613  			uint64(100000),
   614  			*bcdata.addrs[0],
   615  			wrongEncodedKey,
   616  			types.FeeRatio(10),
   617  			sig,
   618  			*bcdata.addrs[0],
   619  			sig,
   620  		})
   621  		require.Equal(t, nil, err)
   622  
   623  		err = rlp.DecodeBytes(buffer.Bytes(), tx)
   624  		require.Equal(t, kerrors.ErrUnserializableKey, err)
   625  	}
   626  
   627  	// Below code is used to check the nil dereference case.
   628  	//txpool := makeTxPool(bcdata, opt.numTransactions)
   629  	//txpool.AddRemotes(txs)
   630  	//
   631  	//for {
   632  	//	if err := bcdata.GenABlockWithTxpool(accountMap, txpool, prof); err != nil {
   633  	//		if err == errEmptyPending {
   634  	//			break
   635  	//		}
   636  	//		t.Fatal(err)
   637  	//	}
   638  	//}
   639  
   640  	if testing.Verbose() {
   641  		prof.PrintProfileInfo()
   642  	}
   643  }
   644  
   645  // BenchmarkValueTransfer measures TPS without network traffics
   646  // while creating a block. As a disclaimer, this function does not tell that Klaytn
   647  // can perform this amount of TPS in real environment.
   648  func BenchmarkValueTransfer(t *testing.B) {
   649  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   650  	prof := profile.NewProfiler()
   651  	opt := testOption{t.N, 2000, 4, 1, []byte{}, makeTransactionsToRandom}
   652  
   653  	// Initialize blockchain
   654  	start := time.Now()
   655  	bcdata, err := NewBCData(opt.numMaxAccounts, opt.numValidators)
   656  	if err != nil {
   657  		t.Fatal(err)
   658  	}
   659  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
   660  	defer bcdata.Shutdown()
   661  
   662  	// Initialize address-balance map for verification
   663  	start = time.Now()
   664  	accountMap := NewAccountMap()
   665  	if err := accountMap.Initialize(bcdata); err != nil {
   666  		t.Fatal(err)
   667  	}
   668  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
   669  
   670  	// make txpool
   671  	txpool := makeTxPool(bcdata, t.N)
   672  	signer := types.MakeSigner(bcdata.bc.Config(), bcdata.bc.CurrentHeader().Number)
   673  
   674  	// make t.N transactions
   675  	txs, err := makeIndependentTransactions(bcdata, accountMap, signer, t.N, nil, []byte{})
   676  	if err != nil {
   677  		t.Fatal(err)
   678  	}
   679  
   680  	t.ResetTimer()
   681  
   682  	txpool.AddRemotes(txs)
   683  
   684  	for {
   685  		if err := bcdata.GenABlockWithTxpool(accountMap, txpool, prof); err != nil {
   686  			if err == errEmptyPending {
   687  				break
   688  			}
   689  			t.Fatal(err)
   690  		}
   691  	}
   692  	t.StopTimer()
   693  
   694  	if testing.Verbose() {
   695  		prof.PrintProfileInfo()
   696  	}
   697  }
   698  
   699  // BenchmarkNewValueTransfer measures TPS without network traffics
   700  // while creating a block. As a disclaimer, this function does not tell that Klaytn
   701  // can perform this amount of TPS in real environment.
   702  func BenchmarkNewValueTransfer(t *testing.B) {
   703  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   704  	prof := profile.NewProfiler()
   705  	opt := testOption{t.N, 2000, 4, 1, []byte{}, makeNewTransactionsToRandom}
   706  
   707  	// Initialize blockchain
   708  	start := time.Now()
   709  	bcdata, err := NewBCData(opt.numMaxAccounts, opt.numValidators)
   710  	if err != nil {
   711  		t.Fatal(err)
   712  	}
   713  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
   714  	defer bcdata.Shutdown()
   715  
   716  	// Initialize address-balance map for verification
   717  	start = time.Now()
   718  	accountMap := NewAccountMap()
   719  	if err := accountMap.Initialize(bcdata); err != nil {
   720  		t.Fatal(err)
   721  	}
   722  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
   723  
   724  	// make txpool
   725  	txpool := makeTxPool(bcdata, t.N)
   726  	signer := types.MakeSigner(bcdata.bc.Config(), bcdata.bc.CurrentHeader().Number)
   727  
   728  	// make t.N transactions
   729  	txs, err := makeIndependentTransactions(bcdata, accountMap, signer, t.N, nil, []byte{})
   730  	if err != nil {
   731  		t.Fatal(err)
   732  	}
   733  	txpool.AddRemotes(txs)
   734  
   735  	t.ResetTimer()
   736  	for {
   737  		if err := bcdata.GenABlockWithTxpool(accountMap, txpool, prof); err != nil {
   738  			if err == errEmptyPending {
   739  				break
   740  			}
   741  			t.Fatal(err)
   742  		}
   743  	}
   744  	t.StopTimer()
   745  
   746  	if testing.Verbose() {
   747  		prof.PrintProfileInfo()
   748  	}
   749  }
   750  
   751  func makeTxPool(bcdata *BCData, txPoolSize int) *blockchain.TxPool {
   752  	txpoolconfig := blockchain.DefaultTxPoolConfig
   753  	txpoolconfig.Journal = ""
   754  	txpoolconfig.ExecSlotsAccount = uint64(txPoolSize)
   755  	txpoolconfig.NonExecSlotsAccount = uint64(txPoolSize)
   756  	txpoolconfig.ExecSlotsAll = 2 * uint64(txPoolSize)
   757  	txpoolconfig.NonExecSlotsAll = 2 * uint64(txPoolSize)
   758  	return blockchain.NewTxPool(txpoolconfig, bcdata.bc.Config(), bcdata.bc)
   759  }