github.com/klaytn/klaytn@v1.10.2/tests/tx_validation_test.go (about)

     1  // Copyright 2019 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  	"crypto/ecdsa"
    21  	"errors"
    22  	"fmt"
    23  	"math/big"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/klaytn/klaytn/blockchain"
    28  	"github.com/klaytn/klaytn/blockchain/types"
    29  	"github.com/klaytn/klaytn/blockchain/types/accountkey"
    30  	"github.com/klaytn/klaytn/blockchain/vm"
    31  	"github.com/klaytn/klaytn/common"
    32  	"github.com/klaytn/klaytn/common/profile"
    33  	"github.com/klaytn/klaytn/crypto"
    34  	"github.com/klaytn/klaytn/kerrors"
    35  	"github.com/klaytn/klaytn/log"
    36  	"github.com/klaytn/klaytn/params"
    37  	"github.com/klaytn/klaytn/rlp"
    38  	"github.com/stretchr/testify/assert"
    39  )
    40  
    41  type txValueMap map[types.TxValueKeyType]interface{}
    42  
    43  type testTxType struct {
    44  	name   string
    45  	txType types.TxType
    46  }
    47  
    48  func toBasicType(txType types.TxType) types.TxType {
    49  	return txType &^ ((1 << types.SubTxTypeBits) - 1)
    50  }
    51  
    52  func genMapForTxTypes(from TestAccount, to TestAccount, txType types.TxType) (txValueMap, uint64) {
    53  	var valueMap txValueMap
    54  	gas := uint64(0)
    55  	gasPrice := big.NewInt(25 * params.Ston)
    56  	newAccount, err := createDefaultAccount(accountkey.AccountKeyTypePublic)
    57  	if err != nil {
    58  		return nil, 0
    59  	}
    60  
    61  	// switch to basic tx type representation and generate a map
    62  	switch toBasicType(txType) {
    63  	case types.TxTypeLegacyTransaction:
    64  		valueMap, gas = genMapForLegacyTransaction(from, to, gasPrice, txType)
    65  	case types.TxTypeValueTransfer:
    66  		valueMap, gas = genMapForValueTransfer(from, to, gasPrice, txType)
    67  	case types.TxTypeValueTransferMemo:
    68  		valueMap, gas = genMapForValueTransferWithMemo(from, to, gasPrice, txType)
    69  	case types.TxTypeAccountUpdate:
    70  		valueMap, gas = genMapForUpdate(from, to, gasPrice, newAccount.AccKey, txType)
    71  	case types.TxTypeSmartContractDeploy:
    72  		valueMap, gas = genMapForDeploy(from, nil, gasPrice, txType)
    73  	case types.TxTypeSmartContractExecution:
    74  		valueMap, gas = genMapForExecution(from, to, gasPrice, txType)
    75  	case types.TxTypeCancel:
    76  		valueMap, gas = genMapForCancel(from, gasPrice, txType)
    77  	case types.TxTypeChainDataAnchoring:
    78  		valueMap, gas = genMapForChainDataAnchoring(from, gasPrice, txType)
    79  	}
    80  
    81  	if txType.IsFeeDelegatedTransaction() {
    82  		valueMap[types.TxValueKeyFeePayer] = from.GetAddr()
    83  	}
    84  
    85  	if txType.IsFeeDelegatedWithRatioTransaction() {
    86  		valueMap[types.TxValueKeyFeeRatioOfFeePayer] = types.FeeRatio(30)
    87  	}
    88  
    89  	if txType == types.TxTypeEthereumAccessList {
    90  		valueMap, gas = genMapForAccessListTransaction(from, to, gasPrice, txType)
    91  	}
    92  
    93  	if txType == types.TxTypeEthereumDynamicFee {
    94  		valueMap, gas = genMapForDynamicFeeTransaction(from, to, gasPrice, txType)
    95  	}
    96  
    97  	return valueMap, gas
    98  }
    99  
   100  // TestValidationPoolInsert generates invalid txs which will be invalidated during txPool insert process.
   101  func TestValidationPoolInsert(t *testing.T) {
   102  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   103  
   104  	testTxTypes := []testTxType{}
   105  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
   106  		if i == types.TxTypeKlaytnLast {
   107  			i = types.TxTypeEthereumAccessList
   108  		}
   109  
   110  		_, err := types.NewTxInternalData(i)
   111  		if err == nil {
   112  			testTxTypes = append(testTxTypes, testTxType{i.String(), i})
   113  		}
   114  	}
   115  
   116  	invalidCases := []struct {
   117  		Name string
   118  		fn   func(types.TxType, txValueMap, common.Address) (txValueMap, error)
   119  	}{
   120  		{"invalidNonce", decreaseNonce},
   121  		{"invalidGasPrice", decreaseGasPrice},
   122  		{"invalidTxSize", exceedSizeLimit},
   123  		{"invalidRecipientProgram", valueTransferToContract},
   124  		{"invalidRecipientNotProgram", executeToEOA},
   125  		{"invalidCodeFormat", invalidCodeFormat},
   126  	}
   127  
   128  	prof := profile.NewProfiler()
   129  
   130  	// Initialize blockchain
   131  	bcdata, err := NewBCData(6, 4)
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  	bcdata.bc.Config().IstanbulCompatibleBlock = big.NewInt(0)
   136  	bcdata.bc.Config().LondonCompatibleBlock = big.NewInt(0)
   137  	bcdata.bc.Config().EthTxTypeCompatibleBlock = big.NewInt(0)
   138  	defer bcdata.Shutdown()
   139  
   140  	// Initialize address-balance map for verification
   141  	accountMap := NewAccountMap()
   142  	if err := accountMap.Initialize(bcdata); err != nil {
   143  		t.Fatal(err)
   144  	}
   145  
   146  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
   147  
   148  	// reservoir account
   149  	reservoir := &TestAccountType{
   150  		Addr:  *bcdata.addrs[0],
   151  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   152  		Nonce: uint64(0),
   153  	}
   154  
   155  	// for contract execution txs
   156  	contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989")
   157  	assert.Equal(t, nil, err)
   158  
   159  	// deploy a contract for contract execution tx type
   160  	{
   161  		var txs types.Transactions
   162  
   163  		values := map[types.TxValueKeyType]interface{}{
   164  			types.TxValueKeyNonce:         reservoir.GetNonce(),
   165  			types.TxValueKeyFrom:          reservoir.GetAddr(),
   166  			types.TxValueKeyTo:            (*common.Address)(nil),
   167  			types.TxValueKeyAmount:        big.NewInt(0),
   168  			types.TxValueKeyGasLimit:      gasLimit,
   169  			types.TxValueKeyGasPrice:      big.NewInt(25 * params.Ston),
   170  			types.TxValueKeyHumanReadable: false,
   171  			types.TxValueKeyData:          common.FromHex(code),
   172  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
   173  		}
   174  
   175  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
   176  		assert.Equal(t, nil, err)
   177  
   178  		err = tx.SignWithKeys(signer, reservoir.Keys)
   179  		assert.Equal(t, nil, err)
   180  
   181  		txs = append(txs, tx)
   182  
   183  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   184  			t.Fatal(err)
   185  		}
   186  
   187  		contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
   188  
   189  		reservoir.AddNonce()
   190  	}
   191  
   192  	// make TxPool to test validation in 'TxPool add' process
   193  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
   194  
   195  	// test for all tx types
   196  	for _, testTxType := range testTxTypes {
   197  		txType := testTxType.txType
   198  
   199  		// generate invalid txs and check the return error
   200  		for _, invalidCase := range invalidCases {
   201  			to := reservoir
   202  			if toBasicType(testTxType.txType) == types.TxTypeSmartContractExecution {
   203  				to = contract
   204  			}
   205  
   206  			// generate a new tx and mutate it
   207  			valueMap, _ := genMapForTxTypes(reservoir, to, txType)
   208  			invalidMap, expectedErr := invalidCase.fn(txType, valueMap, contract.Addr)
   209  
   210  			tx, err := types.NewTransactionWithMap(txType, invalidMap)
   211  			assert.Equal(t, nil, err)
   212  
   213  			err = tx.SignWithKeys(signer, reservoir.Keys)
   214  			assert.Equal(t, nil, err)
   215  
   216  			if txType.IsFeeDelegatedTransaction() {
   217  				tx.SignFeePayerWithKeys(signer, reservoir.Keys)
   218  				assert.Equal(t, nil, err)
   219  			}
   220  
   221  			err = txpool.AddRemote(tx)
   222  			assert.Equal(t, expectedErr, err)
   223  			if expectedErr == nil {
   224  				reservoir.Nonce += 1
   225  			}
   226  		}
   227  	}
   228  }
   229  
   230  func TestValidationPoolInsertMagma(t *testing.T) {
   231  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   232  
   233  	testTxTypes := []testTxType{}
   234  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
   235  		if i == types.TxTypeKlaytnLast {
   236  			i = types.TxTypeEthereumAccessList
   237  		}
   238  
   239  		_, err := types.NewTxInternalData(i)
   240  		if err == nil {
   241  			testTxTypes = append(testTxTypes, testTxType{i.String(), i})
   242  		}
   243  	}
   244  
   245  	invalidCases := []struct {
   246  		Name string
   247  		fn   func(types.TxType, txValueMap, common.Address) (txValueMap, error)
   248  	}{
   249  		{"invalidGasPrice", decreaseGasPriceMagma},
   250  	}
   251  
   252  	prof := profile.NewProfiler()
   253  
   254  	// Initialize blockchain
   255  	bcdata, err := NewBCData(6, 4)
   256  	if err != nil {
   257  		t.Fatal(err)
   258  	}
   259  	bcdata.bc.Config().IstanbulCompatibleBlock = big.NewInt(0)
   260  	bcdata.bc.Config().LondonCompatibleBlock = big.NewInt(0)
   261  	bcdata.bc.Config().EthTxTypeCompatibleBlock = big.NewInt(0)
   262  	bcdata.bc.Config().MagmaCompatibleBlock = big.NewInt(0)
   263  	defer bcdata.Shutdown()
   264  
   265  	// Initialize address-balance map for verification
   266  	accountMap := NewAccountMap()
   267  	if err := accountMap.Initialize(bcdata); err != nil {
   268  		t.Fatal(err)
   269  	}
   270  
   271  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
   272  
   273  	// reservoir account
   274  	reservoir := &TestAccountType{
   275  		Addr:  *bcdata.addrs[0],
   276  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   277  		Nonce: uint64(0),
   278  	}
   279  
   280  	// for contract execution txs
   281  	contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989")
   282  	assert.Equal(t, nil, err)
   283  
   284  	// deploy a contract for contract execution tx type
   285  	{
   286  		var txs types.Transactions
   287  
   288  		values := map[types.TxValueKeyType]interface{}{
   289  			types.TxValueKeyNonce:         reservoir.GetNonce(),
   290  			types.TxValueKeyFrom:          reservoir.GetAddr(),
   291  			types.TxValueKeyTo:            (*common.Address)(nil),
   292  			types.TxValueKeyAmount:        big.NewInt(0),
   293  			types.TxValueKeyGasLimit:      gasLimit,
   294  			types.TxValueKeyGasPrice:      big.NewInt(25 * params.Ston),
   295  			types.TxValueKeyHumanReadable: false,
   296  			types.TxValueKeyData:          common.FromHex(code),
   297  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
   298  		}
   299  
   300  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
   301  		assert.Equal(t, nil, err)
   302  
   303  		err = tx.SignWithKeys(signer, reservoir.Keys)
   304  		assert.Equal(t, nil, err)
   305  
   306  		txs = append(txs, tx)
   307  
   308  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   309  			t.Fatal(err)
   310  		}
   311  
   312  		contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
   313  
   314  		reservoir.AddNonce()
   315  	}
   316  
   317  	// make TxPool to test validation in 'TxPool add' process
   318  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
   319  
   320  	// test for all tx types
   321  	for _, testTxType := range testTxTypes {
   322  		txType := testTxType.txType
   323  
   324  		// generate invalid txs and check the return error
   325  		for _, invalidCase := range invalidCases {
   326  			to := reservoir
   327  			if toBasicType(testTxType.txType) == types.TxTypeSmartContractExecution {
   328  				to = contract
   329  			}
   330  
   331  			// generate a new tx and mutate it
   332  			valueMap, _ := genMapForTxTypes(reservoir, to, txType)
   333  			invalidMap, expectedErr := invalidCase.fn(txType, valueMap, contract.Addr)
   334  
   335  			tx, err := types.NewTransactionWithMap(txType, invalidMap)
   336  			assert.Equal(t, nil, err)
   337  
   338  			err = tx.SignWithKeys(signer, reservoir.Keys)
   339  			assert.Equal(t, nil, err)
   340  
   341  			if txType.IsFeeDelegatedTransaction() {
   342  				tx.SignFeePayerWithKeys(signer, reservoir.Keys)
   343  				assert.Equal(t, nil, err)
   344  			}
   345  
   346  			err = txpool.AddRemote(tx)
   347  			assert.Equal(t, expectedErr, err)
   348  			if expectedErr == nil {
   349  				reservoir.Nonce += 1
   350  			}
   351  		}
   352  	}
   353  }
   354  
   355  // TestValidationBlockTx generates invalid txs which will be invalidated during block insert process.
   356  func TestValidationBlockTx(t *testing.T) {
   357  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   358  
   359  	testTxTypes := []testTxType{}
   360  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
   361  		if i == types.TxTypeKlaytnLast {
   362  			i = types.TxTypeEthereumAccessList
   363  		}
   364  
   365  		_, err := types.NewTxInternalData(i)
   366  		if err == nil {
   367  			testTxTypes = append(testTxTypes, testTxType{i.String(), i})
   368  		}
   369  	}
   370  
   371  	invalidCases := []struct {
   372  		Name string
   373  		fn   func(types.TxType, txValueMap, common.Address) (txValueMap, error)
   374  	}{
   375  		{"invalidNonce", decreaseNonce},
   376  		{"invalidRecipientProgram", valueTransferToContract},
   377  		{"invalidRecipientNotProgram", executeToEOA},
   378  		{"invalidCodeFormat", invalidCodeFormat},
   379  	}
   380  
   381  	prof := profile.NewProfiler()
   382  
   383  	// Initialize blockchain
   384  	bcdata, err := NewBCData(6, 4)
   385  	if err != nil {
   386  		t.Fatal(err)
   387  	}
   388  	bcdata.bc.Config().IstanbulCompatibleBlock = big.NewInt(0)
   389  	bcdata.bc.Config().LondonCompatibleBlock = big.NewInt(0)
   390  	bcdata.bc.Config().EthTxTypeCompatibleBlock = big.NewInt(0)
   391  	defer bcdata.Shutdown()
   392  
   393  	// Initialize address-balance map for verification
   394  	accountMap := NewAccountMap()
   395  	if err := accountMap.Initialize(bcdata); err != nil {
   396  		t.Fatal(err)
   397  	}
   398  
   399  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
   400  
   401  	// reservoir account
   402  	reservoir := &TestAccountType{
   403  		Addr:  *bcdata.addrs[0],
   404  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   405  		Nonce: uint64(0),
   406  	}
   407  
   408  	// for contract execution txs
   409  	contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989")
   410  	assert.Equal(t, nil, err)
   411  
   412  	// deploy a contract for contract execution tx type
   413  	{
   414  		var txs types.Transactions
   415  
   416  		values := map[types.TxValueKeyType]interface{}{
   417  			types.TxValueKeyNonce:         reservoir.GetNonce(),
   418  			types.TxValueKeyFrom:          reservoir.GetAddr(),
   419  			types.TxValueKeyTo:            (*common.Address)(nil),
   420  			types.TxValueKeyAmount:        big.NewInt(0),
   421  			types.TxValueKeyGasLimit:      gasLimit,
   422  			types.TxValueKeyGasPrice:      big.NewInt(25 * params.Ston),
   423  			types.TxValueKeyHumanReadable: false,
   424  			types.TxValueKeyData:          common.FromHex(code),
   425  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
   426  		}
   427  
   428  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
   429  		assert.Equal(t, nil, err)
   430  
   431  		err = tx.SignWithKeys(signer, reservoir.Keys)
   432  		assert.Equal(t, nil, err)
   433  
   434  		txs = append(txs, tx)
   435  
   436  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   437  			t.Fatal(err)
   438  		}
   439  
   440  		contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
   441  
   442  		reservoir.AddNonce()
   443  	}
   444  
   445  	// test for all tx types
   446  	for _, testTxType := range testTxTypes {
   447  		txType := testTxType.txType
   448  
   449  		// generate invalid txs and check the return error
   450  		for _, invalidCase := range invalidCases {
   451  			to := reservoir
   452  			if toBasicType(testTxType.txType) == types.TxTypeSmartContractExecution {
   453  				to = contract
   454  			}
   455  			// generate a new tx and mutate it
   456  			valueMap, _ := genMapForTxTypes(reservoir, to, txType)
   457  			invalidMap, expectedErr := invalidCase.fn(txType, valueMap, contract.Addr)
   458  
   459  			tx, err := types.NewTransactionWithMap(txType, invalidMap)
   460  			assert.Equal(t, nil, err)
   461  
   462  			err = tx.SignWithKeys(signer, reservoir.Keys)
   463  			assert.Equal(t, nil, err)
   464  
   465  			if txType.IsFeeDelegatedTransaction() {
   466  				tx.SignFeePayerWithKeys(signer, reservoir.Keys)
   467  				assert.Equal(t, nil, err)
   468  			}
   469  
   470  			receipt, err := applyTransaction(t, bcdata, tx)
   471  			assert.Equal(t, expectedErr, err)
   472  			if expectedErr == nil {
   473  				assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
   474  			}
   475  		}
   476  	}
   477  }
   478  
   479  // decreaseNonce changes nonce to zero.
   480  func decreaseNonce(txType types.TxType, values txValueMap, contract common.Address) (txValueMap, error) {
   481  	values[types.TxValueKeyNonce] = uint64(0)
   482  
   483  	return values, blockchain.ErrNonceTooLow
   484  }
   485  
   486  // decreaseGasPrice changes gasPrice to 12345678
   487  func decreaseGasPrice(txType types.TxType, values txValueMap, contract common.Address) (txValueMap, error) {
   488  	var err error
   489  	if txType == types.TxTypeEthereumDynamicFee {
   490  		(*big.Int).SetUint64(values[types.TxValueKeyGasFeeCap].(*big.Int), 12345678)
   491  		(*big.Int).SetUint64(values[types.TxValueKeyGasTipCap].(*big.Int), 12345678)
   492  		err = blockchain.ErrInvalidGasTipCap
   493  	} else {
   494  		(*big.Int).SetUint64(values[types.TxValueKeyGasPrice].(*big.Int), 12345678)
   495  		err = blockchain.ErrInvalidUnitPrice
   496  
   497  	}
   498  
   499  	return values, err
   500  }
   501  
   502  // decreaseGasPrice changes gasPrice to 12345678 and return an error with magma policy
   503  func decreaseGasPriceMagma(txType types.TxType, values txValueMap, contract common.Address) (txValueMap, error) {
   504  	var err error
   505  	if txType == types.TxTypeEthereumDynamicFee {
   506  		(*big.Int).SetUint64(values[types.TxValueKeyGasFeeCap].(*big.Int), 12345678)
   507  		(*big.Int).SetUint64(values[types.TxValueKeyGasTipCap].(*big.Int), 12345678)
   508  		err = blockchain.ErrFeeCapBelowBaseFee
   509  	} else {
   510  		(*big.Int).SetUint64(values[types.TxValueKeyGasPrice].(*big.Int), 12345678)
   511  		err = blockchain.ErrGasPriceBelowBaseFee
   512  	}
   513  
   514  	return values, err
   515  }
   516  
   517  // exceedSizeLimit assigns tx data bigger than MaxTxDataSize.
   518  func exceedSizeLimit(txType types.TxType, values txValueMap, contract common.Address) (txValueMap, error) {
   519  	invalidData := make([]byte, blockchain.MaxTxDataSize+1)
   520  
   521  	if values[types.TxValueKeyData] != nil {
   522  		values[types.TxValueKeyData] = invalidData
   523  		return values, blockchain.ErrOversizedData
   524  	}
   525  
   526  	if values[types.TxValueKeyAnchoredData] != nil {
   527  		values[types.TxValueKeyAnchoredData] = invalidData
   528  		return values, blockchain.ErrOversizedData
   529  	}
   530  
   531  	return values, nil
   532  }
   533  
   534  // valueTransferToContract changes recipient address of value transfer txs to the contract address.
   535  func valueTransferToContract(txType types.TxType, values txValueMap, contract common.Address) (txValueMap, error) {
   536  	txType = toBasicType(txType)
   537  	if txType == types.TxTypeValueTransfer || txType == types.TxTypeValueTransferMemo {
   538  		values[types.TxValueKeyTo] = contract
   539  		return values, kerrors.ErrNotForProgramAccount
   540  	}
   541  
   542  	return values, nil
   543  }
   544  
   545  // executeToEOA changes the recipient of contract execution txs to an EOA address (the same with the sender).
   546  func executeToEOA(txType types.TxType, values txValueMap, contract common.Address) (txValueMap, error) {
   547  	if toBasicType(txType) == types.TxTypeSmartContractExecution {
   548  		values[types.TxValueKeyTo] = values[types.TxValueKeyFrom].(common.Address)
   549  		return values, kerrors.ErrNotProgramAccount
   550  	}
   551  
   552  	return values, nil
   553  }
   554  
   555  func invalidCodeFormat(txType types.TxType, values txValueMap, contract common.Address) (txValueMap, error) {
   556  	if txType.IsContractDeploy() {
   557  		values[types.TxValueKeyCodeFormat] = params.CodeFormatLast
   558  		return values, kerrors.ErrInvalidCodeFormat
   559  	}
   560  	return values, nil
   561  }
   562  
   563  // TestValidationInvalidSig generates txs signed by an invalid sender or a fee payer.
   564  func TestValidationInvalidSig(t *testing.T) {
   565  	testTxTypes := []testTxType{}
   566  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
   567  		if i == types.TxTypeKlaytnLast {
   568  			i = types.TxTypeEthereumAccessList
   569  		}
   570  
   571  		_, err := types.NewTxInternalData(i)
   572  		if err == nil {
   573  			testTxTypes = append(testTxTypes, testTxType{i.String(), i})
   574  		}
   575  	}
   576  
   577  	invalidCases := []struct {
   578  		Name string
   579  		fn   func(*testing.T, types.TxType, *TestAccountType, *TestAccountType, types.Signer) (*types.Transaction, error)
   580  	}{
   581  		{"invalidSender", testInvalidSenderSig},
   582  		{"invalidFeePayer", testInvalidFeePayerSig},
   583  	}
   584  
   585  	prof := profile.NewProfiler()
   586  
   587  	// Initialize blockchain
   588  	bcdata, err := NewBCData(6, 4)
   589  	if err != nil {
   590  		t.Fatal(err)
   591  	}
   592  	bcdata.bc.Config().IstanbulCompatibleBlock = big.NewInt(0)
   593  	bcdata.bc.Config().LondonCompatibleBlock = big.NewInt(0)
   594  	bcdata.bc.Config().EthTxTypeCompatibleBlock = big.NewInt(0)
   595  	defer bcdata.Shutdown()
   596  
   597  	// Initialize address-balance map for verification
   598  	accountMap := NewAccountMap()
   599  	if err := accountMap.Initialize(bcdata); err != nil {
   600  		t.Fatal(err)
   601  	}
   602  
   603  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
   604  
   605  	// reservoir account
   606  	reservoir := &TestAccountType{
   607  		Addr:  *bcdata.addrs[0],
   608  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   609  		Nonce: uint64(0),
   610  	}
   611  
   612  	// for contract execution txs
   613  	contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989")
   614  	assert.Equal(t, nil, err)
   615  
   616  	// deploy a contract for contract execution tx type
   617  	{
   618  		var txs types.Transactions
   619  
   620  		values := map[types.TxValueKeyType]interface{}{
   621  			types.TxValueKeyNonce:         reservoir.GetNonce(),
   622  			types.TxValueKeyFrom:          reservoir.GetAddr(),
   623  			types.TxValueKeyTo:            (*common.Address)(nil),
   624  			types.TxValueKeyAmount:        big.NewInt(0),
   625  			types.TxValueKeyGasLimit:      gasLimit,
   626  			types.TxValueKeyGasPrice:      big.NewInt(25 * params.Ston),
   627  			types.TxValueKeyHumanReadable: false,
   628  			types.TxValueKeyData:          common.FromHex(code),
   629  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
   630  		}
   631  
   632  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
   633  		assert.Equal(t, nil, err)
   634  
   635  		err = tx.SignWithKeys(signer, reservoir.Keys)
   636  		assert.Equal(t, nil, err)
   637  
   638  		txs = append(txs, tx)
   639  
   640  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   641  			t.Fatal(err)
   642  		}
   643  
   644  		contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
   645  
   646  		reservoir.AddNonce()
   647  	}
   648  
   649  	// make TxPool to test validation in 'TxPool add' process
   650  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
   651  
   652  	// test for all tx types
   653  	for _, testTxType := range testTxTypes {
   654  		txType := testTxType.txType
   655  
   656  		for _, invalidCase := range invalidCases {
   657  			tx, expectedErr := invalidCase.fn(t, txType, reservoir, contract, signer)
   658  
   659  			if tx != nil {
   660  				// For tx pool validation test
   661  				err = txpool.AddRemote(tx)
   662  				assert.Equal(t, expectedErr, err)
   663  
   664  				// For block tx validation test
   665  				if expectedErr == blockchain.ErrInvalidFeePayer {
   666  					expectedErr = types.ErrInvalidSigFeePayer
   667  				}
   668  				receipt, err := applyTransaction(t, bcdata, tx)
   669  				assert.Equal(t, expectedErr, err)
   670  				assert.Equal(t, (*types.Receipt)(nil), receipt)
   671  			}
   672  		}
   673  	}
   674  }
   675  
   676  // testInvalidSenderSig generates invalid txs signed by an invalid sender.
   677  func testInvalidSenderSig(t *testing.T, txType types.TxType, reservoir *TestAccountType, contract *TestAccountType, signer types.Signer) (*types.Transaction, error) {
   678  	if !txType.IsLegacyTransaction() && !txType.IsEthTypedTransaction() {
   679  		newAcc, err := createDefaultAccount(accountkey.AccountKeyTypePublic)
   680  		assert.Equal(t, nil, err)
   681  
   682  		to := reservoir
   683  		if toBasicType(txType) == types.TxTypeSmartContractExecution {
   684  			to = contract
   685  		}
   686  
   687  		valueMap, _ := genMapForTxTypes(reservoir, to, txType)
   688  		tx, err := types.NewTransactionWithMap(txType, valueMap)
   689  		assert.Equal(t, nil, err)
   690  
   691  		err = tx.SignWithKeys(signer, newAcc.Keys)
   692  		assert.Equal(t, nil, err)
   693  
   694  		if txType.IsFeeDelegatedTransaction() {
   695  			tx.SignFeePayerWithKeys(signer, reservoir.Keys)
   696  			assert.Equal(t, nil, err)
   697  		}
   698  		return tx, types.ErrInvalidSigSender
   699  	}
   700  	return nil, nil
   701  }
   702  
   703  // testInvalidFeePayerSig generates invalid txs signed by an invalid fee payer.
   704  func testInvalidFeePayerSig(t *testing.T, txType types.TxType, reservoir *TestAccountType, contract *TestAccountType, signer types.Signer) (*types.Transaction, error) {
   705  	if txType.IsFeeDelegatedTransaction() {
   706  		newAcc, err := createDefaultAccount(accountkey.AccountKeyTypePublic)
   707  		assert.Equal(t, nil, err)
   708  
   709  		to := reservoir
   710  		if toBasicType(txType) == types.TxTypeSmartContractExecution {
   711  			to = contract
   712  		}
   713  
   714  		valueMap, _ := genMapForTxTypes(reservoir, to, txType)
   715  		tx, err := types.NewTransactionWithMap(txType, valueMap)
   716  		assert.Equal(t, nil, err)
   717  
   718  		err = tx.SignWithKeys(signer, reservoir.Keys)
   719  		assert.Equal(t, nil, err)
   720  
   721  		tx.SignFeePayerWithKeys(signer, newAcc.Keys)
   722  		assert.Equal(t, nil, err)
   723  
   724  		return tx, blockchain.ErrInvalidFeePayer
   725  	}
   726  	return nil, nil
   727  }
   728  
   729  // TestLegacyTxFromNonLegacyAcc generates legacy tx from non-legacy account, and it will be invalidated during txPool insert process.
   730  func TestLegacyTxFromNonLegacyAcc(t *testing.T) {
   731  	prof := profile.NewProfiler()
   732  
   733  	// Initialize blockchain
   734  	bcdata, err := NewBCData(6, 4)
   735  	if err != nil {
   736  		t.Fatal(err)
   737  	}
   738  	defer bcdata.Shutdown()
   739  
   740  	// Initialize address-balance map for verification
   741  	accountMap := NewAccountMap()
   742  	if err := accountMap.Initialize(bcdata); err != nil {
   743  		t.Fatal(err)
   744  	}
   745  
   746  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
   747  
   748  	// reservoir account
   749  	reservoir := &TestAccountType{
   750  		Addr:  *bcdata.addrs[0],
   751  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   752  		Nonce: uint64(0),
   753  	}
   754  
   755  	var txs types.Transactions
   756  	acc1, err := createDefaultAccount(accountkey.AccountKeyTypePublic)
   757  
   758  	valueMap, _ := genMapForTxTypes(reservoir, reservoir, types.TxTypeAccountUpdate)
   759  	valueMap[types.TxValueKeyAccountKey] = acc1.AccKey
   760  
   761  	tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, valueMap)
   762  	assert.Equal(t, nil, err)
   763  
   764  	err = tx.SignWithKeys(signer, reservoir.Keys)
   765  	assert.Equal(t, nil, err)
   766  
   767  	txs = append(txs, tx)
   768  
   769  	if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   770  		t.Fatal(err)
   771  	}
   772  	reservoir.AddNonce()
   773  
   774  	// make TxPool to test validation in 'TxPool add' process
   775  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
   776  
   777  	valueMap, _ = genMapForTxTypes(reservoir, reservoir, types.TxTypeLegacyTransaction)
   778  	tx, err = types.NewTransactionWithMap(types.TxTypeLegacyTransaction, valueMap)
   779  	assert.Equal(t, nil, err)
   780  
   781  	err = tx.SignWithKeys(signer, reservoir.Keys)
   782  	assert.Equal(t, nil, err)
   783  
   784  	err = txpool.AddRemote(tx)
   785  	assert.Equal(t, kerrors.ErrLegacyTransactionMustBeWithLegacyKey, err)
   786  }
   787  
   788  // TestInvalidBalance generates invalid txs which don't have enough KLAY, and will be invalidated during txPool insert process.
   789  func TestInvalidBalance(t *testing.T) {
   790  	testTxTypes := []testTxType{}
   791  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
   792  		if i == types.TxTypeKlaytnLast {
   793  			i = types.TxTypeEthereumAccessList
   794  		}
   795  
   796  		_, err := types.NewTxInternalData(i)
   797  		if err == nil {
   798  			testTxTypes = append(testTxTypes, testTxType{i.String(), i})
   799  		}
   800  	}
   801  
   802  	prof := profile.NewProfiler()
   803  
   804  	// Initialize blockchain
   805  	bcdata, err := NewBCData(6, 4)
   806  	if err != nil {
   807  		t.Fatal(err)
   808  	}
   809  	bcdata.bc.Config().IstanbulCompatibleBlock = big.NewInt(0)
   810  	bcdata.bc.Config().LondonCompatibleBlock = big.NewInt(0)
   811  	bcdata.bc.Config().EthTxTypeCompatibleBlock = big.NewInt(0)
   812  	defer bcdata.Shutdown()
   813  
   814  	// Initialize address-balance map for verification
   815  	accountMap := NewAccountMap()
   816  	if err := accountMap.Initialize(bcdata); err != nil {
   817  		t.Fatal(err)
   818  	}
   819  
   820  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
   821  
   822  	// reservoir account
   823  	reservoir := &TestAccountType{
   824  		Addr:  *bcdata.addrs[0],
   825  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   826  		Nonce: uint64(0),
   827  	}
   828  
   829  	// for contract execution txs
   830  	contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989")
   831  	assert.Equal(t, nil, err)
   832  
   833  	// test account will be lack of KLAY
   834  	testAcc, err := createDefaultAccount(accountkey.AccountKeyTypeLegacy)
   835  	assert.Equal(t, nil, err)
   836  
   837  	gasLimit := uint64(100000000000)
   838  	gasPrice := big.NewInt(25 * params.Ston)
   839  	amount := uint64(25 * params.Ston)
   840  	cost := new(big.Int).Mul(new(big.Int).SetUint64(gasLimit), gasPrice)
   841  	cost.Add(cost, new(big.Int).SetUint64(amount))
   842  
   843  	// deploy a contract for contract execution tx type
   844  	{
   845  		var txs types.Transactions
   846  
   847  		values := map[types.TxValueKeyType]interface{}{
   848  			types.TxValueKeyNonce:         reservoir.GetNonce(),
   849  			types.TxValueKeyFrom:          reservoir.GetAddr(),
   850  			types.TxValueKeyTo:            (*common.Address)(nil),
   851  			types.TxValueKeyAmount:        big.NewInt(0),
   852  			types.TxValueKeyGasLimit:      gasLimit,
   853  			types.TxValueKeyGasPrice:      big.NewInt(25 * params.Ston),
   854  			types.TxValueKeyHumanReadable: false,
   855  			types.TxValueKeyData:          common.FromHex(code),
   856  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
   857  		}
   858  
   859  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
   860  		assert.Equal(t, nil, err)
   861  
   862  		err = tx.SignWithKeys(signer, reservoir.Keys)
   863  		assert.Equal(t, nil, err)
   864  
   865  		txs = append(txs, tx)
   866  
   867  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   868  			t.Fatal(err)
   869  		}
   870  
   871  		contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
   872  
   873  		reservoir.AddNonce()
   874  	}
   875  
   876  	// generate a test account with a specific amount of KLAY
   877  	{
   878  		var txs types.Transactions
   879  
   880  		valueMapForCreation, _ := genMapForTxTypes(reservoir, testAcc, types.TxTypeValueTransfer)
   881  		valueMapForCreation[types.TxValueKeyAmount] = cost
   882  
   883  		tx, err := types.NewTransactionWithMap(types.TxTypeValueTransfer, valueMapForCreation)
   884  		assert.Equal(t, nil, err)
   885  
   886  		err = tx.SignWithKeys(signer, reservoir.Keys)
   887  		assert.Equal(t, nil, err)
   888  
   889  		txs = append(txs, tx)
   890  
   891  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   892  			t.Fatal(err)
   893  		}
   894  		reservoir.AddNonce()
   895  	}
   896  
   897  	// make TxPool to test validation in 'TxPool add' process
   898  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
   899  
   900  	// test for all tx types
   901  	for _, testTxType := range testTxTypes {
   902  		txType := testTxType.txType
   903  
   904  		if !txType.IsFeeDelegatedTransaction() {
   905  			// tx with a specific amount or a gasLimit requiring more KLAY than the sender has.
   906  			{
   907  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
   908  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
   909  					valueMap[types.TxValueKeyTo] = contract.Addr
   910  				}
   911  				if valueMap[types.TxValueKeyAmount] != nil {
   912  					valueMap[types.TxValueKeyAmount] = new(big.Int).SetUint64(amount)
   913  					valueMap[types.TxValueKeyGasLimit] = gasLimit + 1 // requires 1 more gas
   914  				} else {
   915  					valueMap[types.TxValueKeyGasLimit] = gasLimit + (amount / gasPrice.Uint64()) + 1 // requires 1 more gas
   916  				}
   917  
   918  				tx, err := types.NewTransactionWithMap(txType, valueMap)
   919  				assert.Equal(t, nil, err)
   920  
   921  				err = tx.SignWithKeys(signer, testAcc.Keys)
   922  				assert.Equal(t, nil, err)
   923  
   924  				err = txpool.AddRemote(tx)
   925  				assert.Equal(t, blockchain.ErrInsufficientFundsFrom, err)
   926  			}
   927  
   928  			// tx with a specific amount or a gasLimit requiring the exact KLAY the sender has.
   929  			{
   930  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
   931  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
   932  					valueMap[types.TxValueKeyTo] = contract.Addr
   933  				}
   934  				if valueMap[types.TxValueKeyAmount] != nil {
   935  					valueMap[types.TxValueKeyAmount] = new(big.Int).SetUint64(amount)
   936  					valueMap[types.TxValueKeyGasLimit] = gasLimit
   937  				} else {
   938  					valueMap[types.TxValueKeyGasLimit] = gasLimit + (amount / gasPrice.Uint64())
   939  				}
   940  
   941  				tx, err := types.NewTransactionWithMap(txType, valueMap)
   942  				assert.Equal(t, nil, err)
   943  
   944  				err = tx.SignWithKeys(signer, testAcc.Keys)
   945  				assert.Equal(t, nil, err)
   946  
   947  				// Since `txpool.AddRemote` does not make a block,
   948  				// the sender can send txs to txpool in multiple times (by the for loop) with limited KLAY.
   949  				err = txpool.AddRemote(tx)
   950  				assert.Equal(t, nil, err)
   951  				testAcc.AddNonce()
   952  			}
   953  		}
   954  
   955  		if txType.IsFeeDelegatedTransaction() && !txType.IsFeeDelegatedWithRatioTransaction() {
   956  			// tx with a specific amount requiring more KLAY than the sender has.
   957  			{
   958  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
   959  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
   960  					valueMap[types.TxValueKeyTo] = contract.Addr
   961  				}
   962  				if valueMap[types.TxValueKeyAmount] != nil {
   963  					valueMap[types.TxValueKeyFeePayer] = reservoir.Addr
   964  					valueMap[types.TxValueKeyAmount] = new(big.Int).Add(cost, new(big.Int).SetUint64(1)) // requires 1 more amount
   965  
   966  					tx, err := types.NewTransactionWithMap(txType, valueMap)
   967  					assert.Equal(t, nil, err)
   968  
   969  					err = tx.SignWithKeys(signer, testAcc.Keys)
   970  					assert.Equal(t, nil, err)
   971  
   972  					tx.SignFeePayerWithKeys(signer, reservoir.Keys)
   973  					assert.Equal(t, nil, err)
   974  
   975  					err = txpool.AddRemote(tx)
   976  					assert.Equal(t, blockchain.ErrInsufficientFundsFrom, err)
   977  				}
   978  			}
   979  
   980  			// tx with a specific gasLimit (or amount) requiring more KLAY than the feePayer has.
   981  			{
   982  				valueMap, _ := genMapForTxTypes(reservoir, testAcc, txType)
   983  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
   984  					valueMap[types.TxValueKeyTo] = contract.Addr
   985  				}
   986  				valueMap[types.TxValueKeyFeePayer] = testAcc.Addr
   987  				valueMap[types.TxValueKeyGasLimit] = gasLimit + (amount / gasPrice.Uint64()) + 1 // requires 1 more gas
   988  
   989  				tx, err := types.NewTransactionWithMap(txType, valueMap)
   990  				assert.Equal(t, nil, err)
   991  
   992  				err = tx.SignWithKeys(signer, reservoir.Keys)
   993  				assert.Equal(t, nil, err)
   994  
   995  				tx.SignFeePayerWithKeys(signer, testAcc.Keys)
   996  				assert.Equal(t, nil, err)
   997  
   998  				err = txpool.AddRemote(tx)
   999  				assert.Equal(t, blockchain.ErrInsufficientFundsFeePayer, err)
  1000  			}
  1001  
  1002  			// tx with a specific amount requiring the exact KLAY the sender has.
  1003  			{
  1004  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
  1005  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1006  					valueMap[types.TxValueKeyTo] = contract.Addr
  1007  				}
  1008  				if valueMap[types.TxValueKeyAmount] != nil {
  1009  					valueMap[types.TxValueKeyFeePayer] = reservoir.Addr
  1010  					valueMap[types.TxValueKeyAmount] = cost
  1011  
  1012  					tx, err := types.NewTransactionWithMap(txType, valueMap)
  1013  					assert.Equal(t, nil, err)
  1014  
  1015  					err = tx.SignWithKeys(signer, testAcc.Keys)
  1016  					assert.Equal(t, nil, err)
  1017  
  1018  					tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1019  					assert.Equal(t, nil, err)
  1020  
  1021  					// Since `txpool.AddRemote` does not make a block,
  1022  					// the sender can send txs to txpool in multiple times (by the for loop) with limited KLAY.
  1023  					err = txpool.AddRemote(tx)
  1024  					assert.Equal(t, nil, err)
  1025  					testAcc.AddNonce()
  1026  				}
  1027  			}
  1028  
  1029  			// tx with a specific gasLimit (or amount) requiring the exact KLAY the feePayer has.
  1030  			{
  1031  				valueMap, _ := genMapForTxTypes(reservoir, testAcc, txType)
  1032  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1033  					valueMap[types.TxValueKeyTo] = contract.Addr
  1034  				}
  1035  				valueMap[types.TxValueKeyFeePayer] = testAcc.Addr
  1036  				valueMap[types.TxValueKeyGasLimit] = gasLimit + (amount / gasPrice.Uint64())
  1037  
  1038  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1039  				assert.Equal(t, nil, err)
  1040  
  1041  				err = tx.SignWithKeys(signer, reservoir.Keys)
  1042  				assert.Equal(t, nil, err)
  1043  
  1044  				tx.SignFeePayerWithKeys(signer, testAcc.Keys)
  1045  				assert.Equal(t, nil, err)
  1046  
  1047  				// Since `txpool.AddRemote` does not make a block,
  1048  				// the sender can send txs to txpool in multiple times (by the for loop) with limited KLAY.
  1049  				err = txpool.AddRemote(tx)
  1050  				assert.Equal(t, nil, err)
  1051  				reservoir.AddNonce()
  1052  			}
  1053  		}
  1054  
  1055  		if txType.IsFeeDelegatedWithRatioTransaction() {
  1056  			// tx with a specific amount and a gasLimit requiring more KLAY than the sender has.
  1057  			{
  1058  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
  1059  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1060  					valueMap[types.TxValueKeyTo] = contract.Addr
  1061  				}
  1062  				valueMap[types.TxValueKeyFeePayer] = reservoir.Addr
  1063  				valueMap[types.TxValueKeyFeeRatioOfFeePayer] = types.FeeRatio(90)
  1064  				if valueMap[types.TxValueKeyAmount] != nil {
  1065  					valueMap[types.TxValueKeyAmount] = new(big.Int).SetUint64(amount)
  1066  					// Gas testAcc will charge = tx gasLimit * sender's feeRatio
  1067  					// = (gasLimit + 1) * 10 * (100 - 90) * 0.01 = gasLimit + 1
  1068  					valueMap[types.TxValueKeyGasLimit] = (gasLimit + 1) * 10 // requires 1 more gas
  1069  				} else {
  1070  					// Gas testAcc will charge = tx gasLimit * sender's feeRatio
  1071  					// = (gasLimit + (amount / gasPrice.Uint64()) + 1) * 10 * (100 - 90) * 0.01 = gasLimit + (amount / gasPrice.Uint64()) + 1
  1072  					valueMap[types.TxValueKeyGasLimit] = (gasLimit + (amount / gasPrice.Uint64()) + 1) * 10 // requires 1 more gas
  1073  				}
  1074  
  1075  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1076  				assert.Equal(t, nil, err)
  1077  
  1078  				err = tx.SignWithKeys(signer, testAcc.Keys)
  1079  				assert.Equal(t, nil, err)
  1080  
  1081  				tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1082  				assert.Equal(t, nil, err)
  1083  
  1084  				err = txpool.AddRemote(tx)
  1085  				assert.Equal(t, blockchain.ErrInsufficientFundsFrom, err)
  1086  			}
  1087  
  1088  			// tx with a specific amount and a gasLimit requiring more KLAY than the feePayer has.
  1089  			{
  1090  				valueMap, _ := genMapForTxTypes(reservoir, testAcc, txType)
  1091  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1092  					valueMap[types.TxValueKeyTo] = contract.Addr
  1093  				}
  1094  				valueMap[types.TxValueKeyFeePayer] = testAcc.Addr
  1095  				valueMap[types.TxValueKeyFeeRatioOfFeePayer] = types.FeeRatio(10)
  1096  				// Gas testAcc will charge = tx gasLimit * fee-payer's feeRatio
  1097  				// = (gasLimit + (amount / gasPrice.Uint64()) + 1) * 10 * 10 * 0.01 = gasLimit + (amount / gasPrice.Uint64()) + 1
  1098  				valueMap[types.TxValueKeyGasLimit] = (gasLimit + (amount / gasPrice.Uint64()) + 1) * 10 // requires 1 more gas
  1099  
  1100  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1101  				assert.Equal(t, nil, err)
  1102  
  1103  				err = tx.SignWithKeys(signer, reservoir.Keys)
  1104  				assert.Equal(t, nil, err)
  1105  
  1106  				tx.SignFeePayerWithKeys(signer, testAcc.Keys)
  1107  				assert.Equal(t, nil, err)
  1108  
  1109  				err = txpool.AddRemote(tx)
  1110  				assert.Equal(t, blockchain.ErrInsufficientFundsFeePayer, err)
  1111  			}
  1112  
  1113  			// tx with a specific amount and a gasLimit requiring the exact KLAY the sender has.
  1114  			{
  1115  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
  1116  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1117  					valueMap[types.TxValueKeyTo] = contract.Addr
  1118  				}
  1119  				valueMap[types.TxValueKeyFeePayer] = reservoir.Addr
  1120  				valueMap[types.TxValueKeyFeeRatioOfFeePayer] = types.FeeRatio(90)
  1121  				if valueMap[types.TxValueKeyAmount] != nil {
  1122  					valueMap[types.TxValueKeyAmount] = new(big.Int).SetUint64(amount)
  1123  					// Gas testAcc will charge = tx gasLimit * sender's feeRatio
  1124  					// = gasLimit * 10 * (100 - 90) * 0.01 = gasLimit
  1125  					valueMap[types.TxValueKeyGasLimit] = gasLimit * 10
  1126  				} else {
  1127  					// Gas testAcc will charge = tx gasLimit * sender's feeRatio
  1128  					// = (gasLimit + (amount / gasPrice.Uint64())) * 10 * (100 - 90) * 0.01 = gasLimit + (amount / gasPrice.Uint64())
  1129  					valueMap[types.TxValueKeyGasLimit] = (gasLimit + (amount / gasPrice.Uint64())) * 10
  1130  				}
  1131  
  1132  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1133  				assert.Equal(t, nil, err)
  1134  
  1135  				err = tx.SignWithKeys(signer, testAcc.Keys)
  1136  				assert.Equal(t, nil, err)
  1137  
  1138  				tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1139  				assert.Equal(t, nil, err)
  1140  
  1141  				// Since `txpool.AddRemote` does not make a block,
  1142  				// the sender can send txs to txpool in multiple times (by the for loop) with limited KLAY.
  1143  				err = txpool.AddRemote(tx)
  1144  				assert.Equal(t, nil, err)
  1145  				testAcc.AddNonce()
  1146  			}
  1147  
  1148  			// tx with a specific amount and a gasLimit requiring the exact KLAY the feePayer has.
  1149  			{
  1150  				valueMap, _ := genMapForTxTypes(reservoir, testAcc, txType)
  1151  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1152  					valueMap[types.TxValueKeyTo] = contract.Addr
  1153  				}
  1154  				valueMap[types.TxValueKeyFeePayer] = testAcc.Addr
  1155  				valueMap[types.TxValueKeyFeeRatioOfFeePayer] = types.FeeRatio(10)
  1156  				// Gas testAcc will charge = tx gasLimit * fee-payer's feeRatio
  1157  				// = (gasLimit + (amount / gasPrice.Uint64())) * 10 * 10 * 0.01 = gasLimit + (amount / gasPrice.Uint64())
  1158  				valueMap[types.TxValueKeyGasLimit] = (gasLimit + (amount / gasPrice.Uint64())) * 10
  1159  
  1160  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1161  				assert.Equal(t, nil, err)
  1162  
  1163  				err = tx.SignWithKeys(signer, reservoir.Keys)
  1164  				assert.Equal(t, nil, err)
  1165  
  1166  				tx.SignFeePayerWithKeys(signer, testAcc.Keys)
  1167  				assert.Equal(t, nil, err)
  1168  
  1169  				// Since `txpool.AddRemote` does not make a block,
  1170  				// the sender can send txs to txpool in multiple times (by the for loop) with limited KLAY.
  1171  				err = txpool.AddRemote(tx)
  1172  				assert.Equal(t, nil, err)
  1173  				reservoir.AddNonce()
  1174  			}
  1175  		}
  1176  	}
  1177  }
  1178  
  1179  // TestInvalidBalanceBlockTx generates invalid txs which don't have enough KLAY, and will be invalidated during block insert process.
  1180  func TestInvalidBalanceBlockTx(t *testing.T) {
  1181  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1182  
  1183  	testTxTypes := []testTxType{}
  1184  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
  1185  		if i == types.TxTypeKlaytnLast {
  1186  			i = types.TxTypeEthereumAccessList
  1187  		}
  1188  
  1189  		_, err := types.NewTxInternalData(i)
  1190  		if err == nil {
  1191  			testTxTypes = append(testTxTypes, testTxType{i.String(), i})
  1192  		}
  1193  	}
  1194  
  1195  	// re-declare errors since those errors are private variables in 'blockchain' package.
  1196  	errInsufficientBalanceForGas := errors.New("insufficient balance of the sender to pay for gas")
  1197  	errInsufficientBalanceForGasFeePayer := errors.New("insufficient balance of the fee payer to pay for gas")
  1198  
  1199  	prof := profile.NewProfiler()
  1200  
  1201  	// Initialize blockchain
  1202  	bcdata, err := NewBCData(6, 4)
  1203  	if err != nil {
  1204  		t.Fatal(err)
  1205  	}
  1206  	bcdata.bc.Config().IstanbulCompatibleBlock = big.NewInt(0)
  1207  	bcdata.bc.Config().LondonCompatibleBlock = big.NewInt(0)
  1208  	bcdata.bc.Config().EthTxTypeCompatibleBlock = big.NewInt(0)
  1209  	defer bcdata.Shutdown()
  1210  
  1211  	// Initialize address-balance map for verification
  1212  	accountMap := NewAccountMap()
  1213  	if err := accountMap.Initialize(bcdata); err != nil {
  1214  		t.Fatal(err)
  1215  	}
  1216  
  1217  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  1218  
  1219  	// reservoir account
  1220  	reservoir := &TestAccountType{
  1221  		Addr:  *bcdata.addrs[0],
  1222  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
  1223  		Nonce: uint64(0),
  1224  	}
  1225  
  1226  	// for contract execution txs
  1227  	contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989")
  1228  	assert.Equal(t, nil, err)
  1229  
  1230  	// test account will be lack of KLAY
  1231  	testAcc, err := createDefaultAccount(accountkey.AccountKeyTypeLegacy)
  1232  	assert.Equal(t, nil, err)
  1233  
  1234  	gasLimit := uint64(100000000000)
  1235  	gasPrice := big.NewInt(25 * params.Ston)
  1236  	amount := uint64(25 * params.Ston)
  1237  	cost := new(big.Int).Mul(new(big.Int).SetUint64(gasLimit), gasPrice)
  1238  	cost.Add(cost, new(big.Int).SetUint64(amount))
  1239  
  1240  	// deploy a contract for contract execution tx type
  1241  	{
  1242  		var txs types.Transactions
  1243  
  1244  		values := map[types.TxValueKeyType]interface{}{
  1245  			types.TxValueKeyNonce:         reservoir.GetNonce(),
  1246  			types.TxValueKeyFrom:          reservoir.GetAddr(),
  1247  			types.TxValueKeyTo:            (*common.Address)(nil),
  1248  			types.TxValueKeyAmount:        big.NewInt(0),
  1249  			types.TxValueKeyGasLimit:      gasLimit,
  1250  			types.TxValueKeyGasPrice:      big.NewInt(25 * params.Ston),
  1251  			types.TxValueKeyHumanReadable: false,
  1252  			types.TxValueKeyData:          common.FromHex(code),
  1253  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
  1254  		}
  1255  
  1256  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
  1257  		assert.Equal(t, nil, err)
  1258  
  1259  		err = tx.SignWithKeys(signer, reservoir.Keys)
  1260  		assert.Equal(t, nil, err)
  1261  
  1262  		txs = append(txs, tx)
  1263  
  1264  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1265  			t.Fatal(err)
  1266  		}
  1267  
  1268  		contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
  1269  
  1270  		reservoir.AddNonce()
  1271  	}
  1272  
  1273  	// generate a test account with a specific amount of KLAY
  1274  	{
  1275  		var txs types.Transactions
  1276  
  1277  		valueMapForCreation, _ := genMapForTxTypes(reservoir, testAcc, types.TxTypeValueTransfer)
  1278  		valueMapForCreation[types.TxValueKeyAmount] = cost
  1279  
  1280  		tx, err := types.NewTransactionWithMap(types.TxTypeValueTransfer, valueMapForCreation)
  1281  		assert.Equal(t, nil, err)
  1282  
  1283  		err = tx.SignWithKeys(signer, reservoir.Keys)
  1284  		assert.Equal(t, nil, err)
  1285  
  1286  		txs = append(txs, tx)
  1287  
  1288  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1289  			t.Fatal(err)
  1290  		}
  1291  		reservoir.AddNonce()
  1292  	}
  1293  
  1294  	// test for all tx types
  1295  	for _, testTxType := range testTxTypes {
  1296  		txType := testTxType.txType
  1297  
  1298  		if !txType.IsFeeDelegatedTransaction() {
  1299  			// tx with a specific amount or a gasLimit requiring more KLAY than the sender has.
  1300  			{
  1301  				var expectedErr error
  1302  
  1303  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
  1304  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1305  					valueMap[types.TxValueKeyTo] = contract.Addr
  1306  				}
  1307  				if valueMap[types.TxValueKeyAmount] != nil {
  1308  					valueMap[types.TxValueKeyAmount] = new(big.Int).SetUint64(amount)
  1309  					valueMap[types.TxValueKeyGasLimit] = gasLimit + 1 // requires 1 more gas
  1310  					// The tx will be failed in vm since it can buy gas but cannot send enough value
  1311  					expectedErr = vm.ErrInsufficientBalance
  1312  				} else {
  1313  					valueMap[types.TxValueKeyGasLimit] = gasLimit + (amount / gasPrice.Uint64()) + 1 // requires 1 more gas
  1314  					// The tx will be failed in buyGas() since it cannot buy enough gas
  1315  					expectedErr = errInsufficientBalanceForGasFeePayer
  1316  				}
  1317  
  1318  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1319  				assert.Equal(t, nil, err)
  1320  
  1321  				err = tx.SignWithKeys(signer, testAcc.Keys)
  1322  				assert.Equal(t, nil, err)
  1323  
  1324  				receipt, err := applyTransaction(t, bcdata, tx)
  1325  				assert.Equal(t, expectedErr, err)
  1326  				assert.Equal(t, (*types.Receipt)(nil), receipt)
  1327  			}
  1328  
  1329  			// tx with a specific amount or a gasLimit requiring the exact KLAY the sender has.
  1330  			{
  1331  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
  1332  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1333  					valueMap[types.TxValueKeyTo] = contract.Addr
  1334  				}
  1335  				if valueMap[types.TxValueKeyAmount] != nil {
  1336  					valueMap[types.TxValueKeyAmount] = new(big.Int).SetUint64(amount)
  1337  					valueMap[types.TxValueKeyGasLimit] = gasLimit
  1338  				} else {
  1339  					valueMap[types.TxValueKeyGasLimit] = gasLimit + (amount / gasPrice.Uint64())
  1340  				}
  1341  
  1342  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1343  				assert.Equal(t, nil, err)
  1344  
  1345  				err = tx.SignWithKeys(signer, testAcc.Keys)
  1346  				assert.Equal(t, nil, err)
  1347  
  1348  				receipt, err := applyTransaction(t, bcdata, tx)
  1349  				assert.Equal(t, nil, err)
  1350  				// contract deploy tx with non-zero value will be failed in vm because test functions do not support it.
  1351  				if txType.IsContractDeploy() {
  1352  					assert.Equal(t, types.ReceiptStatusErrExecutionReverted, receipt.Status)
  1353  				} else {
  1354  					assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
  1355  				}
  1356  			}
  1357  		}
  1358  
  1359  		if txType.IsFeeDelegatedTransaction() && !txType.IsFeeDelegatedWithRatioTransaction() {
  1360  			// tx with a specific amount requiring more KLAY than the sender has.
  1361  			{
  1362  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
  1363  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1364  					valueMap[types.TxValueKeyTo] = contract.Addr
  1365  				}
  1366  				if valueMap[types.TxValueKeyAmount] != nil {
  1367  					valueMap[types.TxValueKeyFeePayer] = reservoir.Addr
  1368  					valueMap[types.TxValueKeyAmount] = new(big.Int).Add(cost, new(big.Int).SetUint64(1)) // requires 1 more amount
  1369  
  1370  					tx, err := types.NewTransactionWithMap(txType, valueMap)
  1371  					assert.Equal(t, nil, err)
  1372  
  1373  					err = tx.SignWithKeys(signer, testAcc.Keys)
  1374  					assert.Equal(t, nil, err)
  1375  
  1376  					tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1377  					assert.Equal(t, nil, err)
  1378  
  1379  					receipt, err := applyTransaction(t, bcdata, tx)
  1380  					assert.Equal(t, vm.ErrInsufficientBalance, err)
  1381  					assert.Equal(t, (*types.Receipt)(nil), receipt)
  1382  				}
  1383  			}
  1384  
  1385  			// tx with a specific gasLimit (or amount) requiring more KLAY than the feePayer has.
  1386  			{
  1387  				valueMap, _ := genMapForTxTypes(reservoir, reservoir, txType)
  1388  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1389  					valueMap[types.TxValueKeyTo] = contract.Addr
  1390  				}
  1391  				valueMap[types.TxValueKeyFeePayer] = testAcc.Addr
  1392  				valueMap[types.TxValueKeyGasLimit] = gasLimit + (amount / gasPrice.Uint64()) + 1 // requires 1 more gas
  1393  
  1394  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1395  				assert.Equal(t, nil, err)
  1396  
  1397  				err = tx.SignWithKeys(signer, reservoir.Keys)
  1398  				assert.Equal(t, nil, err)
  1399  
  1400  				tx.SignFeePayerWithKeys(signer, testAcc.Keys)
  1401  				assert.Equal(t, nil, err)
  1402  
  1403  				receipt, err := applyTransaction(t, bcdata, tx)
  1404  				assert.Equal(t, errInsufficientBalanceForGasFeePayer, err)
  1405  				assert.Equal(t, (*types.Receipt)(nil), receipt)
  1406  			}
  1407  
  1408  			// tx with a specific amount requiring the exact KLAY the sender has.
  1409  			{
  1410  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
  1411  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1412  					valueMap[types.TxValueKeyTo] = contract.Addr
  1413  				}
  1414  				if valueMap[types.TxValueKeyAmount] != nil {
  1415  					valueMap[types.TxValueKeyFeePayer] = reservoir.Addr
  1416  					valueMap[types.TxValueKeyAmount] = cost
  1417  
  1418  					tx, err := types.NewTransactionWithMap(txType, valueMap)
  1419  					assert.Equal(t, nil, err)
  1420  
  1421  					err = tx.SignWithKeys(signer, testAcc.Keys)
  1422  					assert.Equal(t, nil, err)
  1423  
  1424  					tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1425  					assert.Equal(t, nil, err)
  1426  
  1427  					receipt, err := applyTransaction(t, bcdata, tx)
  1428  					assert.Equal(t, nil, err)
  1429  					// contract deploy tx with non-zero value will be failed in vm because test functions do not support it.
  1430  					if txType.IsContractDeploy() {
  1431  						assert.Equal(t, types.ReceiptStatusErrExecutionReverted, receipt.Status)
  1432  					} else {
  1433  						assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
  1434  					}
  1435  				}
  1436  			}
  1437  
  1438  			// tx with a specific gasLimit (or amount) requiring the exact KLAY the feePayer has.
  1439  			{
  1440  				valueMap, _ := genMapForTxTypes(reservoir, reservoir, txType)
  1441  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1442  					valueMap[types.TxValueKeyTo] = contract.Addr
  1443  				}
  1444  				valueMap[types.TxValueKeyFeePayer] = testAcc.Addr
  1445  				valueMap[types.TxValueKeyGasLimit] = gasLimit + (amount / gasPrice.Uint64())
  1446  
  1447  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1448  				assert.Equal(t, nil, err)
  1449  
  1450  				err = tx.SignWithKeys(signer, reservoir.Keys)
  1451  				assert.Equal(t, nil, err)
  1452  
  1453  				tx.SignFeePayerWithKeys(signer, testAcc.Keys)
  1454  				assert.Equal(t, nil, err)
  1455  
  1456  				receipt, err := applyTransaction(t, bcdata, tx)
  1457  				assert.Equal(t, nil, err)
  1458  				assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
  1459  			}
  1460  		}
  1461  
  1462  		if txType.IsFeeDelegatedWithRatioTransaction() {
  1463  			// tx with a specific amount and a gasLimit requiring more KLAY than the sender has.
  1464  			{
  1465  				var expectedErr error
  1466  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
  1467  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1468  					valueMap[types.TxValueKeyTo] = contract.Addr
  1469  				}
  1470  				valueMap[types.TxValueKeyFeePayer] = reservoir.Addr
  1471  				valueMap[types.TxValueKeyFeeRatioOfFeePayer] = types.FeeRatio(90)
  1472  				if valueMap[types.TxValueKeyAmount] != nil {
  1473  					valueMap[types.TxValueKeyAmount] = new(big.Int).SetUint64(amount)
  1474  					// Gas testAcc will charge = tx gasLimit * sender's feeRatio
  1475  					// = (gasLimit + 1) * 10 * (100 - 90) * 0.01 = gasLimit + 1
  1476  					valueMap[types.TxValueKeyGasLimit] = (gasLimit + 1) * 10 // requires 1 more gas
  1477  					// The tx will be failed in vm since it can buy gas but cannot send enough value
  1478  					expectedErr = vm.ErrInsufficientBalance
  1479  				} else {
  1480  					// Gas testAcc will charge = tx gasLimit * sender's feeRatio
  1481  					// = (gasLimit + (amount / gasPrice.Uint64()) + 1) * 10 * (100 - 90) * 0.01 = gasLimit + (amount / gasPrice.Uint64()) + 1
  1482  					valueMap[types.TxValueKeyGasLimit] = (gasLimit + (amount / gasPrice.Uint64()) + 1) * 10 // requires 1 more gas
  1483  					// The tx will be failed in buyGas() since it cannot buy enough gas
  1484  					expectedErr = errInsufficientBalanceForGas
  1485  				}
  1486  
  1487  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1488  				assert.Equal(t, nil, err)
  1489  
  1490  				err = tx.SignWithKeys(signer, testAcc.Keys)
  1491  				assert.Equal(t, nil, err)
  1492  
  1493  				tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1494  				assert.Equal(t, nil, err)
  1495  
  1496  				receipt, err := applyTransaction(t, bcdata, tx)
  1497  				assert.Equal(t, expectedErr, err)
  1498  				assert.Equal(t, (*types.Receipt)(nil), receipt)
  1499  			}
  1500  
  1501  			// tx with a specific amount and a gasLimit requiring more KLAY than the feePayer has.
  1502  			{
  1503  				valueMap, _ := genMapForTxTypes(reservoir, reservoir, txType)
  1504  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1505  					valueMap[types.TxValueKeyTo] = contract.Addr
  1506  				}
  1507  				valueMap[types.TxValueKeyFeePayer] = testAcc.Addr
  1508  				valueMap[types.TxValueKeyFeeRatioOfFeePayer] = types.FeeRatio(10)
  1509  				// Gas testAcc will charge = tx gasLimit * fee-payer's feeRatio
  1510  				// = (gasLimit + (amount / gasPrice.Uint64()) + 1) * 10 * 10 * 0.01 = gasLimit + (amount / gasPrice.Uint64()) + 1
  1511  				valueMap[types.TxValueKeyGasLimit] = (gasLimit + (amount / gasPrice.Uint64()) + 1) * 10 // requires 1 more gas
  1512  
  1513  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1514  				assert.Equal(t, nil, err)
  1515  
  1516  				err = tx.SignWithKeys(signer, reservoir.Keys)
  1517  				assert.Equal(t, nil, err)
  1518  
  1519  				tx.SignFeePayerWithKeys(signer, testAcc.Keys)
  1520  				assert.Equal(t, nil, err)
  1521  
  1522  				receipt, err := applyTransaction(t, bcdata, tx)
  1523  				assert.Equal(t, errInsufficientBalanceForGasFeePayer, err)
  1524  				assert.Equal(t, (*types.Receipt)(nil), receipt)
  1525  			}
  1526  
  1527  			// tx with a specific amount and a gasLimit requiring the exact KLAY the sender has.
  1528  			{
  1529  				valueMap, _ := genMapForTxTypes(testAcc, reservoir, txType)
  1530  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1531  					valueMap[types.TxValueKeyTo] = contract.Addr
  1532  				}
  1533  				valueMap[types.TxValueKeyFeePayer] = reservoir.Addr
  1534  				valueMap[types.TxValueKeyFeeRatioOfFeePayer] = types.FeeRatio(90)
  1535  				if valueMap[types.TxValueKeyAmount] != nil {
  1536  					valueMap[types.TxValueKeyAmount] = new(big.Int).SetUint64(amount)
  1537  					// Gas testAcc will charge = tx gasLimit * sender's feeRatio
  1538  					// = gasLimit * 10 * (100 - 90) * 0.01 = gasLimit
  1539  					valueMap[types.TxValueKeyGasLimit] = gasLimit * 10
  1540  				} else {
  1541  					// Gas testAcc will charge = tx gasLimit * sender's feeRatio
  1542  					// = (gasLimit + (amount / gasPrice.Uint64())) * 10 * (100 - 90) * 0.01 = gasLimit + (amount / gasPrice.Uint64())
  1543  					valueMap[types.TxValueKeyGasLimit] = (gasLimit + (amount / gasPrice.Uint64())) * 10
  1544  				}
  1545  
  1546  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1547  				assert.Equal(t, nil, err)
  1548  
  1549  				err = tx.SignWithKeys(signer, testAcc.Keys)
  1550  				assert.Equal(t, nil, err)
  1551  
  1552  				tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1553  				assert.Equal(t, nil, err)
  1554  
  1555  				receipt, err := applyTransaction(t, bcdata, tx)
  1556  				assert.Equal(t, nil, err)
  1557  				// contract deploy tx with non-zero value will be failed in vm because test functions do not support it.
  1558  				if txType.IsContractDeploy() {
  1559  					assert.Equal(t, types.ReceiptStatusErrExecutionReverted, receipt.Status)
  1560  				} else {
  1561  					assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
  1562  				}
  1563  			}
  1564  
  1565  			// tx with a specific amount and a gasLimit requiring the exact KLAY the feePayer has.
  1566  			{
  1567  				valueMap, _ := genMapForTxTypes(reservoir, reservoir, txType)
  1568  				if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1569  					valueMap[types.TxValueKeyTo] = contract.Addr
  1570  				}
  1571  				valueMap[types.TxValueKeyFeePayer] = testAcc.Addr
  1572  				valueMap[types.TxValueKeyFeeRatioOfFeePayer] = types.FeeRatio(10)
  1573  				// Gas testAcc will charge = tx gasLimit * fee-payer's feeRatio
  1574  				// = (gasLimit + (amount / gasPrice.Uint64())) * 10 * 10 * 0.01 = gasLimit + (amount / gasPrice.Uint64())
  1575  				valueMap[types.TxValueKeyGasLimit] = (gasLimit + (amount / gasPrice.Uint64())) * 10
  1576  
  1577  				tx, err := types.NewTransactionWithMap(txType, valueMap)
  1578  				assert.Equal(t, nil, err)
  1579  
  1580  				err = tx.SignWithKeys(signer, reservoir.Keys)
  1581  				assert.Equal(t, nil, err)
  1582  
  1583  				tx.SignFeePayerWithKeys(signer, testAcc.Keys)
  1584  				assert.Equal(t, nil, err)
  1585  
  1586  				receipt, err := applyTransaction(t, bcdata, tx)
  1587  				assert.Equal(t, nil, err)
  1588  				assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
  1589  			}
  1590  		}
  1591  	}
  1592  }
  1593  
  1594  // TestValidationTxSizeAfterRLP tests tx size validation during txPool insert process.
  1595  // Since the size is RLP encoded tx size, the test also includes RLP encoding/decoding process which may raise an issue.
  1596  func TestValidationTxSizeAfterRLP(t *testing.T) {
  1597  	testTxTypes := []types.TxType{}
  1598  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
  1599  		if i == types.TxTypeKlaytnLast {
  1600  			i = types.TxTypeEthereumAccessList
  1601  		}
  1602  
  1603  		tx, err := types.NewTxInternalData(i)
  1604  		if err == nil {
  1605  			// Since this test is for payload size, tx types without payload field will not be tested.
  1606  			if _, ok := tx.(types.TxInternalDataPayload); ok {
  1607  				testTxTypes = append(testTxTypes, i)
  1608  			}
  1609  		}
  1610  	}
  1611  
  1612  	prof := profile.NewProfiler()
  1613  
  1614  	// Initialize blockchain
  1615  	bcdata, err := NewBCData(6, 4)
  1616  	if err != nil {
  1617  		t.Fatal(err)
  1618  	}
  1619  	bcdata.bc.Config().IstanbulCompatibleBlock = big.NewInt(0)
  1620  	bcdata.bc.Config().LondonCompatibleBlock = big.NewInt(0)
  1621  	bcdata.bc.Config().EthTxTypeCompatibleBlock = big.NewInt(0)
  1622  	defer bcdata.Shutdown()
  1623  
  1624  	// Initialize address-balance map for verification
  1625  	accountMap := NewAccountMap()
  1626  	if err := accountMap.Initialize(bcdata); err != nil {
  1627  		t.Fatal(err)
  1628  	}
  1629  
  1630  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  1631  
  1632  	// reservoir account
  1633  	reservoir := &TestAccountType{
  1634  		Addr:  *bcdata.addrs[0],
  1635  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
  1636  		Nonce: uint64(0),
  1637  	}
  1638  
  1639  	// for contract execution txs
  1640  	contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989")
  1641  	assert.Equal(t, nil, err)
  1642  
  1643  	// deploy a contract for contract execution tx type
  1644  	{
  1645  		var txs types.Transactions
  1646  
  1647  		values := map[types.TxValueKeyType]interface{}{
  1648  			types.TxValueKeyNonce:         reservoir.GetNonce(),
  1649  			types.TxValueKeyFrom:          reservoir.GetAddr(),
  1650  			types.TxValueKeyTo:            (*common.Address)(nil),
  1651  			types.TxValueKeyAmount:        big.NewInt(0),
  1652  			types.TxValueKeyGasLimit:      gasLimit,
  1653  			types.TxValueKeyGasPrice:      big.NewInt(25 * params.Ston),
  1654  			types.TxValueKeyHumanReadable: false,
  1655  			types.TxValueKeyData:          common.FromHex(code),
  1656  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
  1657  		}
  1658  
  1659  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
  1660  		assert.Equal(t, nil, err)
  1661  
  1662  		err = tx.SignWithKeys(signer, reservoir.Keys)
  1663  		assert.Equal(t, nil, err)
  1664  
  1665  		txs = append(txs, tx)
  1666  
  1667  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1668  			t.Fatal(err)
  1669  		}
  1670  
  1671  		contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
  1672  
  1673  		reservoir.AddNonce()
  1674  	}
  1675  
  1676  	// make TxPool to test validation in 'TxPool add' process
  1677  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
  1678  
  1679  	// test for all tx types
  1680  	for _, txType := range testTxTypes {
  1681  		// test for invalid tx size
  1682  		{
  1683  			// generate invalid txs which size is around (32 * 1024) ~ (33 * 1024)
  1684  			valueMap, _ := genMapForTxTypes(reservoir, reservoir, txType)
  1685  			valueMap, _ = exceedSizeLimit(txType, valueMap, contract.Addr)
  1686  
  1687  			tx, err := types.NewTransactionWithMap(txType, valueMap)
  1688  			assert.Equal(t, nil, err)
  1689  
  1690  			err = tx.SignWithKeys(signer, reservoir.Keys)
  1691  			assert.Equal(t, nil, err)
  1692  
  1693  			if txType.IsFeeDelegatedTransaction() {
  1694  				tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1695  				assert.Equal(t, nil, err)
  1696  			}
  1697  
  1698  			// check the rlp encoded tx size
  1699  			encodedTx, err := rlp.EncodeToBytes(tx)
  1700  			if len(encodedTx) < blockchain.MaxTxDataSize {
  1701  				t.Fatalf("test data size is smaller than MaxTxDataSize")
  1702  			}
  1703  
  1704  			// RLP decode and re-generate the tx
  1705  			newTx := &types.Transaction{}
  1706  			err = rlp.DecodeBytes(encodedTx, newTx)
  1707  
  1708  			// test for tx pool insert validation
  1709  			err = txpool.AddRemote(newTx)
  1710  			assert.Equal(t, blockchain.ErrOversizedData, err)
  1711  		}
  1712  
  1713  		// test for valid tx size
  1714  		{
  1715  			// generate valid txs which size is around (31 * 1024) ~ (32 * 1024)
  1716  			to := reservoir
  1717  			if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1718  				to = contract
  1719  			}
  1720  			valueMap, _ := genMapForTxTypes(reservoir, to, txType)
  1721  			validData := make([]byte, blockchain.MaxTxDataSize-1024)
  1722  
  1723  			if valueMap[types.TxValueKeyData] != nil {
  1724  				valueMap[types.TxValueKeyData] = validData
  1725  			}
  1726  
  1727  			if valueMap[types.TxValueKeyAnchoredData] != nil {
  1728  				valueMap[types.TxValueKeyAnchoredData] = validData
  1729  			}
  1730  
  1731  			tx, err := types.NewTransactionWithMap(txType, valueMap)
  1732  			assert.Equal(t, nil, err)
  1733  
  1734  			err = tx.SignWithKeys(signer, reservoir.Keys)
  1735  			assert.Equal(t, nil, err)
  1736  
  1737  			if txType.IsFeeDelegatedTransaction() {
  1738  				tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1739  				assert.Equal(t, nil, err)
  1740  			}
  1741  
  1742  			// check the rlp encoded tx size
  1743  			encodedTx, err := rlp.EncodeToBytes(tx)
  1744  			if len(encodedTx) > blockchain.MaxTxDataSize {
  1745  				t.Fatalf("test data size is bigger than MaxTxDataSize")
  1746  			}
  1747  
  1748  			// RLP decode and re-generate the tx
  1749  			newTx := &types.Transaction{}
  1750  			err = rlp.DecodeBytes(encodedTx, newTx)
  1751  
  1752  			// test for tx pool insert validation
  1753  			err = txpool.AddRemote(newTx)
  1754  			assert.Equal(t, nil, err)
  1755  			reservoir.AddNonce()
  1756  		}
  1757  	}
  1758  }
  1759  
  1760  // TestValidationPoolResetAfterSenderKeyChange puts txs in the pending pool and generates a block only with the first tx.
  1761  // Since the tx changes the sender's account key, all rest txs should drop from the pending pool.
  1762  func TestValidationPoolResetAfterSenderKeyChange(t *testing.T) {
  1763  	txTypes := []types.TxType{}
  1764  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
  1765  		if i == types.TxTypeKlaytnLast {
  1766  			i = types.TxTypeEthereumAccessList
  1767  		}
  1768  
  1769  		_, err := types.NewTxInternalData(i)
  1770  		if err == nil {
  1771  			txTypes = append(txTypes, i)
  1772  		}
  1773  	}
  1774  
  1775  	prof := profile.NewProfiler()
  1776  
  1777  	// Initialize blockchain
  1778  	bcdata, err := NewBCData(6, 4)
  1779  	if err != nil {
  1780  		t.Fatal(err)
  1781  	}
  1782  	bcdata.bc.Config().IstanbulCompatibleBlock = big.NewInt(0)
  1783  	bcdata.bc.Config().LondonCompatibleBlock = big.NewInt(0)
  1784  	bcdata.bc.Config().EthTxTypeCompatibleBlock = big.NewInt(0)
  1785  	defer bcdata.Shutdown()
  1786  
  1787  	// Initialize address-balance map for verification
  1788  	accountMap := NewAccountMap()
  1789  	if err := accountMap.Initialize(bcdata); err != nil {
  1790  		t.Fatal(err)
  1791  	}
  1792  
  1793  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  1794  
  1795  	// reservoir account
  1796  	reservoir := &TestAccountType{
  1797  		Addr:  *bcdata.addrs[0],
  1798  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
  1799  		Nonce: uint64(0),
  1800  	}
  1801  
  1802  	// for contract execution txs
  1803  	contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989")
  1804  	assert.Equal(t, nil, err)
  1805  
  1806  	// deploy a contract for contract execution tx type
  1807  	{
  1808  		var txs types.Transactions
  1809  
  1810  		values := map[types.TxValueKeyType]interface{}{
  1811  			types.TxValueKeyNonce:         reservoir.GetNonce(),
  1812  			types.TxValueKeyFrom:          reservoir.GetAddr(),
  1813  			types.TxValueKeyTo:            (*common.Address)(nil),
  1814  			types.TxValueKeyAmount:        big.NewInt(0),
  1815  			types.TxValueKeyGasLimit:      gasLimit,
  1816  			types.TxValueKeyGasPrice:      big.NewInt(0),
  1817  			types.TxValueKeyHumanReadable: false,
  1818  			types.TxValueKeyData:          common.FromHex(code),
  1819  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
  1820  		}
  1821  
  1822  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
  1823  		assert.Equal(t, nil, err)
  1824  
  1825  		err = tx.SignWithKeys(signer, reservoir.Keys)
  1826  		assert.Equal(t, nil, err)
  1827  
  1828  		txs = append(txs, tx)
  1829  
  1830  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1831  			t.Fatal(err)
  1832  		}
  1833  
  1834  		contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
  1835  
  1836  		reservoir.AddNonce()
  1837  	}
  1838  
  1839  	// make TxPool to test validation in 'TxPool add' process
  1840  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
  1841  
  1842  	// state changing tx which will invalidate other txs when it is contained in a block.
  1843  	var txs types.Transactions
  1844  	{
  1845  		valueMap, _ := genMapForTxTypes(reservoir, reservoir, types.TxTypeAccountUpdate)
  1846  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, valueMap)
  1847  
  1848  		assert.Equal(t, nil, err)
  1849  
  1850  		err = tx.SignWithKeys(signer, reservoir.Keys)
  1851  		assert.Equal(t, nil, err)
  1852  
  1853  		txs = append(txs, tx)
  1854  
  1855  		err = txpool.AddRemote(tx)
  1856  		assert.Equal(t, nil, err)
  1857  		reservoir.AddNonce()
  1858  	}
  1859  
  1860  	// generate valid txs with all tx types.
  1861  	for _, txType := range txTypes {
  1862  		to := reservoir
  1863  		if toBasicType(txType) == types.TxTypeSmartContractExecution {
  1864  			to = contract
  1865  		}
  1866  		valueMap, _ := genMapForTxTypes(reservoir, to, txType)
  1867  		tx, err := types.NewTransactionWithMap(txType, valueMap)
  1868  		assert.Equal(t, nil, err)
  1869  
  1870  		err = tx.SignWithKeys(signer, reservoir.Keys)
  1871  		assert.Equal(t, nil, err)
  1872  
  1873  		if txType.IsFeeDelegatedTransaction() {
  1874  			tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1875  			assert.Equal(t, nil, err)
  1876  		}
  1877  
  1878  		err = txpool.AddRemote(tx)
  1879  		if err != nil {
  1880  			fmt.Println(tx)
  1881  			statedb, _ := bcdata.bc.State()
  1882  			fmt.Println(statedb.GetCode(tx.ValidatedSender()))
  1883  		}
  1884  		assert.Equal(t, nil, err)
  1885  		reservoir.AddNonce()
  1886  	}
  1887  
  1888  	// check pending whether it contains all txs
  1889  	pendingLen, _ := txpool.Stats()
  1890  	assert.Equal(t, len(txTypes)+1, pendingLen)
  1891  
  1892  	// generate a block with a state changing tx
  1893  	if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1894  		t.Fatal(err)
  1895  	}
  1896  
  1897  	// Wait 1 second until txpool.reset() is called.
  1898  	time.Sleep(1 * time.Second)
  1899  
  1900  	// check pending whether it contains zero tx
  1901  	pendingLen, _ = txpool.Stats()
  1902  	assert.Equal(t, 0, pendingLen)
  1903  }
  1904  
  1905  // TestValidationPoolResetAfterFeePayerKeyChange puts txs in the pending pool and generates a block only with the first tx.
  1906  // Since the tx changes the fee payer's account key, all rest txs should drop from the pending pool.
  1907  func TestValidationPoolResetAfterFeePayerKeyChange(t *testing.T) {
  1908  	txTypes := []types.TxType{}
  1909  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
  1910  		if i == types.TxTypeKlaytnLast {
  1911  			i = types.TxTypeEthereumAccessList
  1912  		}
  1913  
  1914  		_, err := types.NewTxInternalData(i)
  1915  		if err == nil {
  1916  			// This test is only for fee-delegated tx types
  1917  			if i.IsFeeDelegatedTransaction() {
  1918  				txTypes = append(txTypes, i)
  1919  			}
  1920  		}
  1921  	}
  1922  
  1923  	prof := profile.NewProfiler()
  1924  
  1925  	// Initialize blockchain
  1926  	bcdata, err := NewBCData(6, 4)
  1927  	if err != nil {
  1928  		t.Fatal(err)
  1929  	}
  1930  	defer bcdata.Shutdown()
  1931  
  1932  	// Initialize address-balance map for verification
  1933  	accountMap := NewAccountMap()
  1934  	if err := accountMap.Initialize(bcdata); err != nil {
  1935  		t.Fatal(err)
  1936  	}
  1937  
  1938  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  1939  
  1940  	// reservoir account
  1941  	reservoir := &TestAccountType{
  1942  		Addr:  *bcdata.addrs[0],
  1943  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
  1944  		Nonce: uint64(0),
  1945  	}
  1946  
  1947  	// for contract execution txs
  1948  	contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989")
  1949  	assert.Equal(t, nil, err)
  1950  
  1951  	// fee payer account
  1952  	feePayer, err := createDefaultAccount(accountkey.AccountKeyTypeLegacy)
  1953  	assert.Equal(t, nil, err)
  1954  
  1955  	// deploy a contract for contract execution tx type
  1956  	{
  1957  		var txs types.Transactions
  1958  
  1959  		values := map[types.TxValueKeyType]interface{}{
  1960  			types.TxValueKeyNonce:         reservoir.GetNonce(),
  1961  			types.TxValueKeyFrom:          reservoir.GetAddr(),
  1962  			types.TxValueKeyTo:            (*common.Address)(nil),
  1963  			types.TxValueKeyAmount:        big.NewInt(0),
  1964  			types.TxValueKeyGasLimit:      gasLimit,
  1965  			types.TxValueKeyGasPrice:      big.NewInt(25 * params.Ston),
  1966  			types.TxValueKeyHumanReadable: false,
  1967  			types.TxValueKeyData:          common.FromHex(code),
  1968  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
  1969  		}
  1970  
  1971  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
  1972  		assert.Equal(t, nil, err)
  1973  
  1974  		err = tx.SignWithKeys(signer, reservoir.Keys)
  1975  		assert.Equal(t, nil, err)
  1976  
  1977  		txs = append(txs, tx)
  1978  
  1979  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1980  			t.Fatal(err)
  1981  		}
  1982  
  1983  		contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
  1984  
  1985  		reservoir.AddNonce()
  1986  	}
  1987  
  1988  	// transfer KLAY to fee payer
  1989  	{
  1990  		var txs types.Transactions
  1991  
  1992  		values := map[types.TxValueKeyType]interface{}{
  1993  			types.TxValueKeyNonce:    reservoir.GetNonce(),
  1994  			types.TxValueKeyFrom:     reservoir.GetAddr(),
  1995  			types.TxValueKeyTo:       feePayer.Addr,
  1996  			types.TxValueKeyAmount:   new(big.Int).Mul(big.NewInt(params.KLAY), big.NewInt(100000)),
  1997  			types.TxValueKeyGasLimit: gasLimit,
  1998  			types.TxValueKeyGasPrice: big.NewInt(25 * params.Ston),
  1999  		}
  2000  
  2001  		tx, err := types.NewTransactionWithMap(types.TxTypeValueTransfer, values)
  2002  		assert.Equal(t, nil, err)
  2003  
  2004  		err = tx.SignWithKeys(signer, reservoir.Keys)
  2005  		assert.Equal(t, nil, err)
  2006  
  2007  		txs = append(txs, tx)
  2008  
  2009  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  2010  			t.Fatal(err)
  2011  		}
  2012  		reservoir.AddNonce()
  2013  	}
  2014  
  2015  	// make TxPool to test validation in 'TxPool add' process
  2016  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
  2017  
  2018  	// state changing tx which will invalidate other txs when it is contained in a block.
  2019  	var txs types.Transactions
  2020  	{
  2021  		valueMap, _ := genMapForTxTypes(feePayer, feePayer, types.TxTypeAccountUpdate)
  2022  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, valueMap)
  2023  
  2024  		assert.Equal(t, nil, err)
  2025  
  2026  		err = tx.SignWithKeys(signer, feePayer.Keys)
  2027  		assert.Equal(t, nil, err)
  2028  
  2029  		txs = append(txs, tx)
  2030  
  2031  		err = txpool.AddRemote(tx)
  2032  		assert.Equal(t, nil, err)
  2033  		feePayer.AddNonce()
  2034  	}
  2035  
  2036  	// generate valid txs with all tx fee delegation types.
  2037  	for _, txType := range txTypes {
  2038  		to := reservoir
  2039  		if toBasicType(txType) == types.TxTypeSmartContractExecution {
  2040  			to = contract
  2041  		}
  2042  
  2043  		valueMap, _ := genMapForTxTypes(reservoir, to, txType)
  2044  		valueMap[types.TxValueKeyFeePayer] = feePayer.Addr
  2045  
  2046  		tx, err := types.NewTransactionWithMap(txType, valueMap)
  2047  		assert.Equal(t, nil, err)
  2048  
  2049  		err = tx.SignWithKeys(signer, reservoir.Keys)
  2050  		assert.Equal(t, nil, err)
  2051  
  2052  		tx.SignFeePayerWithKeys(signer, feePayer.Keys)
  2053  		assert.Equal(t, nil, err)
  2054  
  2055  		err = txpool.AddRemote(tx)
  2056  		assert.Equal(t, nil, err)
  2057  		reservoir.AddNonce()
  2058  	}
  2059  
  2060  	// check pending whether it contains all txs
  2061  	pendingLen, _ := txpool.Stats()
  2062  	assert.Equal(t, len(txTypes)+1, pendingLen)
  2063  
  2064  	// generate a block with a state changing tx
  2065  	if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  2066  		t.Fatal(err)
  2067  	}
  2068  
  2069  	// Wait 1 second until txpool.reset() is called.
  2070  	time.Sleep(1 * time.Second)
  2071  
  2072  	// check pending whether it contains zero tx
  2073  	pendingLen, _ = txpool.Stats()
  2074  	assert.Equal(t, 0, pendingLen)
  2075  }