github.com/klaytn/klaytn@v1.12.1/tests/account_keytype_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  	"fmt"
    22  	"math"
    23  	"math/big"
    24  	"strconv"
    25  	"strings"
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/klaytn/klaytn/accounts/abi"
    30  	"github.com/klaytn/klaytn/blockchain"
    31  	"github.com/klaytn/klaytn/blockchain/types"
    32  	"github.com/klaytn/klaytn/blockchain/types/accountkey"
    33  	"github.com/klaytn/klaytn/common"
    34  	"github.com/klaytn/klaytn/common/profile"
    35  	"github.com/klaytn/klaytn/crypto"
    36  	"github.com/klaytn/klaytn/kerrors"
    37  	"github.com/klaytn/klaytn/log"
    38  	"github.com/klaytn/klaytn/params"
    39  	"github.com/stretchr/testify/assert"
    40  )
    41  
    42  // createDefaultAccount creates a default account with a specific account key type.
    43  func createDefaultAccount(accountKeyType accountkey.AccountKeyType) (*TestAccountType, error) {
    44  	var err error
    45  
    46  	// prepare  keys
    47  	keys := genTestKeys(3)
    48  	weights := []uint{1, 1, 1}
    49  	weightedKeys := make(accountkey.WeightedPublicKeys, 3)
    50  	threshold := uint(2)
    51  
    52  	for i := range keys {
    53  		weightedKeys[i] = accountkey.NewWeightedPublicKey(weights[i], (*accountkey.PublicKeySerializable)(&keys[i].PublicKey))
    54  	}
    55  
    56  	// a role-based key
    57  	roleAccKey := accountkey.AccountKeyRoleBased{
    58  		accountkey.NewAccountKeyPublicWithValue(&keys[accountkey.RoleTransaction].PublicKey),
    59  		accountkey.NewAccountKeyPublicWithValue(&keys[accountkey.RoleAccountUpdate].PublicKey),
    60  		accountkey.NewAccountKeyPublicWithValue(&keys[accountkey.RoleFeePayer].PublicKey),
    61  	}
    62  
    63  	// default account setting
    64  	account := &TestAccountType{
    65  		Addr:   crypto.PubkeyToAddress(keys[0].PublicKey), // default
    66  		Keys:   []*ecdsa.PrivateKey{keys[0]},              // default
    67  		Nonce:  uint64(0),                                 // default
    68  		AccKey: nil,
    69  	}
    70  
    71  	// set an account key and a private key
    72  	switch accountKeyType {
    73  	case accountkey.AccountKeyTypeNil:
    74  		account.AccKey, err = accountkey.NewAccountKey(accountKeyType)
    75  	case accountkey.AccountKeyTypeLegacy:
    76  		account.AccKey, err = accountkey.NewAccountKey(accountKeyType)
    77  	case accountkey.AccountKeyTypePublic:
    78  		account.AccKey = accountkey.NewAccountKeyPublicWithValue(&keys[0].PublicKey)
    79  	case accountkey.AccountKeyTypeFail:
    80  		account.AccKey, err = accountkey.NewAccountKey(accountKeyType)
    81  	case accountkey.AccountKeyTypeWeightedMultiSig:
    82  		account.Keys = keys
    83  		account.AccKey = accountkey.NewAccountKeyWeightedMultiSigWithValues(threshold, weightedKeys)
    84  	case accountkey.AccountKeyTypeRoleBased:
    85  		account.Keys = keys
    86  		account.AccKey = accountkey.NewAccountKeyRoleBasedWithValues(roleAccKey)
    87  	default:
    88  		return nil, kerrors.ErrDifferentAccountKeyType
    89  	}
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	return account, err
    95  }
    96  
    97  // generateDefaultTx returns a Tx with default values of txTypes.
    98  // If txType is a kind of account update, it will return an account to update.
    99  // Otherwise, it will return (tx, nil, nil).
   100  // For contract execution Txs, TxValueKeyTo value is set to "contract" as a default.
   101  // The address "contact" should exist before calling this function.
   102  func generateDefaultTx(sender *TestAccountType, recipient *TestAccountType, txType types.TxType, contractAddr common.Address) (*types.Transaction, *TestAccountType, error) {
   103  	gasPrice := new(big.Int).SetUint64(25 * params.Ston)
   104  
   105  	// For Dynamic fee tx.
   106  	gasTipCap := new(big.Int).SetUint64(25 * params.Ston)
   107  	gasFeeCap := new(big.Int).SetUint64(25 * params.Ston)
   108  
   109  	gasLimit := uint64(10000000)
   110  	amount := new(big.Int).SetUint64(1)
   111  
   112  	// generate a new account for account creation/update Txs or contract deploy Txs
   113  	senderAccType := accountkey.AccountKeyTypeLegacy
   114  	if sender.AccKey != nil {
   115  		senderAccType = sender.AccKey.Type()
   116  	}
   117  	newAcc, err := createDefaultAccount(senderAccType)
   118  	if err != nil {
   119  		return nil, nil, err
   120  	}
   121  
   122  	// Smart contract data for TxTypeSmartContractDeploy, TxTypeSmartContractExecution Txs
   123  	var code string
   124  	var abiStr string
   125  
   126  	if isCompilerAvailable() {
   127  		filename := string("../contracts/reward/contract/KlaytnReward.sol")
   128  		codes, abistrings := compileSolidity(filename)
   129  		code = codes[0]
   130  		abiStr = abistrings[0]
   131  	} else {
   132  		// Falling back to use compiled code.
   133  		code = "0x608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029"
   134  		abiStr = `[{"constant":true,"inputs":[],"name":"totalAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"receiver","type":"address"}],"name":"reward","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"safeWithdrawal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"}]`
   135  	}
   136  
   137  	abii, err := abi.JSON(strings.NewReader(string(abiStr)))
   138  	if err != nil {
   139  		return nil, nil, err
   140  	}
   141  
   142  	dataABI, err := abii.Pack("reward", recipient.Addr)
   143  	if err != nil {
   144  		return nil, nil, err
   145  	}
   146  
   147  	// generate a legacy tx
   148  	if txType == types.TxTypeLegacyTransaction {
   149  		tx := types.NewTransaction(sender.Nonce, recipient.Addr, amount, gasLimit, gasPrice, []byte{})
   150  		return tx, nil, nil
   151  	}
   152  
   153  	// Default valuesMap setting
   154  	amountZero := new(big.Int).SetUint64(0)
   155  	ratio := types.FeeRatio(30)
   156  	dataMemo := []byte("hello")
   157  	dataAnchor := []byte{0x11, 0x22}
   158  	dataCode := common.FromHex(code)
   159  	values := map[types.TxValueKeyType]interface{}{}
   160  
   161  	switch txType {
   162  	case types.TxTypeValueTransfer:
   163  		values[types.TxValueKeyNonce] = sender.Nonce
   164  		values[types.TxValueKeyFrom] = sender.Addr
   165  		values[types.TxValueKeyTo] = recipient.Addr
   166  		values[types.TxValueKeyAmount] = amount
   167  		values[types.TxValueKeyGasLimit] = gasLimit
   168  		values[types.TxValueKeyGasPrice] = gasPrice
   169  	case types.TxTypeFeeDelegatedValueTransfer:
   170  		values[types.TxValueKeyNonce] = sender.Nonce
   171  		values[types.TxValueKeyFrom] = sender.Addr
   172  		values[types.TxValueKeyTo] = recipient.Addr
   173  		values[types.TxValueKeyAmount] = amount
   174  		values[types.TxValueKeyGasLimit] = gasLimit
   175  		values[types.TxValueKeyGasPrice] = gasPrice
   176  		values[types.TxValueKeyFeePayer] = recipient.Addr
   177  	case types.TxTypeFeeDelegatedValueTransferWithRatio:
   178  		values[types.TxValueKeyNonce] = sender.Nonce
   179  		values[types.TxValueKeyFrom] = sender.Addr
   180  		values[types.TxValueKeyTo] = recipient.Addr
   181  		values[types.TxValueKeyAmount] = amount
   182  		values[types.TxValueKeyGasLimit] = gasLimit
   183  		values[types.TxValueKeyGasPrice] = gasPrice
   184  		values[types.TxValueKeyFeePayer] = recipient.Addr
   185  		values[types.TxValueKeyFeeRatioOfFeePayer] = ratio
   186  	case types.TxTypeValueTransferMemo:
   187  		values[types.TxValueKeyNonce] = sender.Nonce
   188  		values[types.TxValueKeyFrom] = sender.Addr
   189  		values[types.TxValueKeyTo] = recipient.Addr
   190  		values[types.TxValueKeyAmount] = amount
   191  		values[types.TxValueKeyGasLimit] = gasLimit
   192  		values[types.TxValueKeyGasPrice] = gasPrice
   193  		values[types.TxValueKeyData] = dataMemo
   194  	case types.TxTypeFeeDelegatedValueTransferMemo:
   195  		values[types.TxValueKeyNonce] = sender.Nonce
   196  		values[types.TxValueKeyFrom] = sender.Addr
   197  		values[types.TxValueKeyTo] = recipient.Addr
   198  		values[types.TxValueKeyAmount] = amount
   199  		values[types.TxValueKeyGasLimit] = gasLimit
   200  		values[types.TxValueKeyGasPrice] = gasPrice
   201  		values[types.TxValueKeyData] = dataMemo
   202  		values[types.TxValueKeyFeePayer] = recipient.Addr
   203  	case types.TxTypeFeeDelegatedValueTransferMemoWithRatio:
   204  		values[types.TxValueKeyNonce] = sender.Nonce
   205  		values[types.TxValueKeyFrom] = sender.Addr
   206  		values[types.TxValueKeyTo] = recipient.Addr
   207  		values[types.TxValueKeyAmount] = amount
   208  		values[types.TxValueKeyGasLimit] = gasLimit
   209  		values[types.TxValueKeyGasPrice] = gasPrice
   210  		values[types.TxValueKeyData] = dataMemo
   211  		values[types.TxValueKeyFeePayer] = recipient.Addr
   212  		values[types.TxValueKeyFeeRatioOfFeePayer] = ratio
   213  	case types.TxTypeAccountUpdate:
   214  		values[types.TxValueKeyNonce] = sender.Nonce
   215  		values[types.TxValueKeyFrom] = sender.Addr
   216  		values[types.TxValueKeyGasLimit] = gasLimit
   217  		values[types.TxValueKeyGasPrice] = gasPrice
   218  		values[types.TxValueKeyAccountKey] = newAcc.AccKey
   219  	case types.TxTypeFeeDelegatedAccountUpdate:
   220  		values[types.TxValueKeyNonce] = sender.Nonce
   221  		values[types.TxValueKeyFrom] = sender.Addr
   222  		values[types.TxValueKeyGasLimit] = gasLimit
   223  		values[types.TxValueKeyGasPrice] = gasPrice
   224  		values[types.TxValueKeyAccountKey] = newAcc.AccKey
   225  		values[types.TxValueKeyFeePayer] = recipient.Addr
   226  	case types.TxTypeFeeDelegatedAccountUpdateWithRatio:
   227  		values[types.TxValueKeyNonce] = sender.Nonce
   228  		values[types.TxValueKeyFrom] = sender.Addr
   229  		values[types.TxValueKeyGasLimit] = gasLimit
   230  		values[types.TxValueKeyGasPrice] = gasPrice
   231  		values[types.TxValueKeyAccountKey] = newAcc.AccKey
   232  		values[types.TxValueKeyFeePayer] = recipient.Addr
   233  		values[types.TxValueKeyFeeRatioOfFeePayer] = ratio
   234  	case types.TxTypeSmartContractDeploy:
   235  		values[types.TxValueKeyNonce] = sender.Nonce
   236  		values[types.TxValueKeyFrom] = sender.Addr
   237  		values[types.TxValueKeyTo] = (*common.Address)(nil)
   238  		values[types.TxValueKeyAmount] = amountZero
   239  		values[types.TxValueKeyGasLimit] = gasLimit
   240  		values[types.TxValueKeyGasPrice] = amountZero
   241  		values[types.TxValueKeyData] = dataCode
   242  		values[types.TxValueKeyHumanReadable] = false
   243  		values[types.TxValueKeyCodeFormat] = params.CodeFormatEVM
   244  	case types.TxTypeFeeDelegatedSmartContractDeploy:
   245  		values[types.TxValueKeyNonce] = sender.Nonce
   246  		values[types.TxValueKeyFrom] = sender.Addr
   247  		values[types.TxValueKeyTo] = (*common.Address)(nil)
   248  		values[types.TxValueKeyAmount] = amountZero
   249  		values[types.TxValueKeyGasLimit] = gasLimit
   250  		values[types.TxValueKeyGasPrice] = amountZero
   251  		values[types.TxValueKeyData] = dataCode
   252  		values[types.TxValueKeyHumanReadable] = false
   253  		values[types.TxValueKeyFeePayer] = recipient.Addr
   254  		values[types.TxValueKeyCodeFormat] = params.CodeFormatEVM
   255  	case types.TxTypeFeeDelegatedSmartContractDeployWithRatio:
   256  		values[types.TxValueKeyNonce] = sender.Nonce
   257  		values[types.TxValueKeyFrom] = sender.Addr
   258  		values[types.TxValueKeyTo] = (*common.Address)(nil)
   259  		values[types.TxValueKeyAmount] = amountZero
   260  		values[types.TxValueKeyGasLimit] = gasLimit
   261  		values[types.TxValueKeyGasPrice] = amountZero
   262  		values[types.TxValueKeyData] = dataCode
   263  		values[types.TxValueKeyHumanReadable] = false
   264  		values[types.TxValueKeyFeePayer] = recipient.Addr
   265  		values[types.TxValueKeyFeeRatioOfFeePayer] = ratio
   266  		values[types.TxValueKeyCodeFormat] = params.CodeFormatEVM
   267  	case types.TxTypeSmartContractExecution:
   268  		values[types.TxValueKeyNonce] = sender.Nonce
   269  		values[types.TxValueKeyFrom] = sender.Addr
   270  		values[types.TxValueKeyTo] = contractAddr
   271  		values[types.TxValueKeyAmount] = amountZero
   272  		values[types.TxValueKeyGasLimit] = gasLimit
   273  		values[types.TxValueKeyGasPrice] = amountZero
   274  		values[types.TxValueKeyData] = dataABI
   275  	case types.TxTypeFeeDelegatedSmartContractExecution:
   276  		values[types.TxValueKeyNonce] = sender.Nonce
   277  		values[types.TxValueKeyFrom] = sender.Addr
   278  		values[types.TxValueKeyTo] = contractAddr
   279  		values[types.TxValueKeyAmount] = amountZero
   280  		values[types.TxValueKeyGasLimit] = gasLimit
   281  		values[types.TxValueKeyGasPrice] = amountZero
   282  		values[types.TxValueKeyData] = dataABI
   283  		values[types.TxValueKeyFeePayer] = recipient.Addr
   284  	case types.TxTypeFeeDelegatedSmartContractExecutionWithRatio:
   285  		values[types.TxValueKeyNonce] = sender.Nonce
   286  		values[types.TxValueKeyFrom] = sender.Addr
   287  		values[types.TxValueKeyTo] = contractAddr
   288  		values[types.TxValueKeyAmount] = amountZero
   289  		values[types.TxValueKeyGasLimit] = gasLimit
   290  		values[types.TxValueKeyGasPrice] = amountZero
   291  		values[types.TxValueKeyData] = dataABI
   292  		values[types.TxValueKeyFeePayer] = recipient.Addr
   293  		values[types.TxValueKeyFeeRatioOfFeePayer] = ratio
   294  	case types.TxTypeCancel:
   295  		values[types.TxValueKeyNonce] = sender.Nonce
   296  		values[types.TxValueKeyFrom] = sender.Addr
   297  		values[types.TxValueKeyGasLimit] = gasLimit
   298  		values[types.TxValueKeyGasPrice] = gasPrice
   299  	case types.TxTypeFeeDelegatedCancel:
   300  		values[types.TxValueKeyNonce] = sender.Nonce
   301  		values[types.TxValueKeyFrom] = sender.Addr
   302  		values[types.TxValueKeyGasLimit] = gasLimit
   303  		values[types.TxValueKeyGasPrice] = gasPrice
   304  		values[types.TxValueKeyFeePayer] = recipient.Addr
   305  	case types.TxTypeFeeDelegatedCancelWithRatio:
   306  		values[types.TxValueKeyNonce] = sender.Nonce
   307  		values[types.TxValueKeyFrom] = sender.Addr
   308  		values[types.TxValueKeyGasLimit] = gasLimit
   309  		values[types.TxValueKeyGasPrice] = gasPrice
   310  		values[types.TxValueKeyFeePayer] = recipient.Addr
   311  		values[types.TxValueKeyFeeRatioOfFeePayer] = ratio
   312  	case types.TxTypeChainDataAnchoring:
   313  		values[types.TxValueKeyNonce] = sender.Nonce
   314  		values[types.TxValueKeyFrom] = sender.Addr
   315  		values[types.TxValueKeyGasLimit] = gasLimit
   316  		values[types.TxValueKeyGasPrice] = gasPrice
   317  		values[types.TxValueKeyAnchoredData] = dataAnchor
   318  	case types.TxTypeFeeDelegatedChainDataAnchoring:
   319  		values[types.TxValueKeyNonce] = sender.Nonce
   320  		values[types.TxValueKeyFrom] = sender.Addr
   321  		values[types.TxValueKeyGasLimit] = gasLimit
   322  		values[types.TxValueKeyGasPrice] = gasPrice
   323  		values[types.TxValueKeyAnchoredData] = dataAnchor
   324  		values[types.TxValueKeyFeePayer] = recipient.Addr
   325  	case types.TxTypeFeeDelegatedChainDataAnchoringWithRatio:
   326  		values[types.TxValueKeyNonce] = sender.Nonce
   327  		values[types.TxValueKeyFrom] = sender.Addr
   328  		values[types.TxValueKeyGasLimit] = gasLimit
   329  		values[types.TxValueKeyGasPrice] = gasPrice
   330  		values[types.TxValueKeyAnchoredData] = dataAnchor
   331  		values[types.TxValueKeyFeePayer] = recipient.Addr
   332  		values[types.TxValueKeyFeeRatioOfFeePayer] = ratio
   333  	case types.TxTypeEthereumAccessList:
   334  		values[types.TxValueKeyNonce] = sender.Nonce
   335  		values[types.TxValueKeyTo] = &recipient.Addr
   336  		values[types.TxValueKeyAmount] = amount
   337  		values[types.TxValueKeyGasLimit] = gasLimit
   338  		values[types.TxValueKeyGasPrice] = gasPrice
   339  		values[types.TxValueKeyChainID] = big.NewInt(1)
   340  		values[types.TxValueKeyData] = dataCode
   341  		values[types.TxValueKeyAccessList] = types.AccessList{}
   342  	case types.TxTypeEthereumDynamicFee:
   343  		values[types.TxValueKeyNonce] = sender.Nonce
   344  		values[types.TxValueKeyTo] = &recipient.Addr
   345  		values[types.TxValueKeyAmount] = amount
   346  		values[types.TxValueKeyGasLimit] = gasLimit
   347  		values[types.TxValueKeyGasFeeCap] = gasFeeCap
   348  		values[types.TxValueKeyGasTipCap] = gasTipCap
   349  		values[types.TxValueKeyChainID] = big.NewInt(1)
   350  		values[types.TxValueKeyData] = dataCode
   351  		values[types.TxValueKeyAccessList] = types.AccessList{}
   352  	}
   353  
   354  	tx, err := types.NewTransactionWithMap(txType, values)
   355  	if err != nil {
   356  		return nil, nil, err
   357  	}
   358  
   359  	// the function returns an updated sender account for account update Txs
   360  	if txType.IsAccountUpdate() {
   361  		// For the account having a legacy key, its private key will not be updated since it is coupled with its address.
   362  		if newAcc.AccKey.Type().IsLegacyAccountKey() {
   363  			newAcc.Keys = sender.Keys
   364  		}
   365  		newAcc.Addr = sender.Addr
   366  		newAcc.Nonce = sender.Nonce
   367  		return tx, newAcc, err
   368  	}
   369  
   370  	return tx, nil, err
   371  }
   372  
   373  // expectedTestResultForDefaultTx returns expected validity of tx which generated from (accountKeyType, txType) pair.
   374  func expectedTestResultForDefaultTx(accountKeyType accountkey.AccountKeyType, txType types.TxType) error {
   375  	switch accountKeyType {
   376  	// case accountkey.AccountKeyTypeNil:                     // not supported type
   377  	case accountkey.AccountKeyTypeFail:
   378  		if txType.IsAccountUpdate() {
   379  			return kerrors.ErrAccountKeyFailNotUpdatable
   380  		}
   381  		return types.ErrSender(types.ErrInvalidAccountKey)
   382  	}
   383  	return nil
   384  }
   385  
   386  func signTxWithVariousKeyTypes(signer types.Signer, tx *types.Transaction, sender *TestAccountType) (*types.Transaction, error) {
   387  	var err error
   388  	txType := tx.Type()
   389  	accKeyType := sender.AccKey.Type()
   390  
   391  	if accKeyType == accountkey.AccountKeyTypeWeightedMultiSig {
   392  		if txType.IsLegacyTransaction() {
   393  			err = tx.SignWithKeys(signer, []*ecdsa.PrivateKey{sender.Keys[0]})
   394  		} else {
   395  			err = tx.SignWithKeys(signer, sender.Keys)
   396  		}
   397  	} else if accKeyType == accountkey.AccountKeyTypeRoleBased {
   398  		if txType.IsAccountUpdate() {
   399  			err = tx.SignWithKeys(signer, []*ecdsa.PrivateKey{sender.Keys[accountkey.RoleAccountUpdate]})
   400  		} else {
   401  			err = tx.SignWithKeys(signer, []*ecdsa.PrivateKey{sender.Keys[accountkey.RoleTransaction]})
   402  		}
   403  	} else {
   404  		err = tx.SignWithKeys(signer, sender.Keys)
   405  	}
   406  	return tx, err
   407  }
   408  
   409  // TestDefaultTxsWithDefaultAccountKey tests most of transactions types with most of account key types.
   410  // The test creates a default account for each account key type, and generates default Tx for each Tx type.
   411  // AccountKeyTypeNil is excluded because it cannot be used for account creation.
   412  func TestDefaultTxsWithDefaultAccountKey(t *testing.T) {
   413  	gasPrice := new(big.Int).SetUint64(25 * params.Ston)
   414  	gasLimit := uint64(100000000)
   415  
   416  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   417  	prof := profile.NewProfiler()
   418  
   419  	// Initialize blockchain
   420  	start := time.Now()
   421  	bcdata, err := NewBCData(6, 4)
   422  	if err != nil {
   423  		t.Fatal(err)
   424  	}
   425  	bcdata.bc.Config().IstanbulCompatibleBlock = big.NewInt(0)
   426  	bcdata.bc.Config().LondonCompatibleBlock = big.NewInt(0)
   427  	bcdata.bc.Config().EthTxTypeCompatibleBlock = big.NewInt(0)
   428  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
   429  	defer bcdata.Shutdown()
   430  
   431  	// Initialize address-balance map for verification
   432  	start = time.Now()
   433  	accountMap := NewAccountMap()
   434  	if err := accountMap.Initialize(bcdata); err != nil {
   435  		t.Fatal(err)
   436  	}
   437  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
   438  
   439  	// reservoir account
   440  	reservoir := &TestAccountType{
   441  		Addr:  *bcdata.addrs[0],
   442  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   443  		Nonce: uint64(0),
   444  	}
   445  
   446  	// smart contact account
   447  	contractAddr := common.Address{}
   448  
   449  	// smart contract code
   450  	var code string
   451  
   452  	if isCompilerAvailable() {
   453  		filename := string("../contracts/reward/contract/KlaytnReward.sol")
   454  		codes, _ := compileSolidity(filename)
   455  		code = codes[0]
   456  	} else {
   457  		// Falling back to use compiled code.
   458  		code = "0x608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029"
   459  	}
   460  
   461  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
   462  
   463  	// create a smart contract account for contract execution test
   464  	{
   465  		var txs types.Transactions
   466  
   467  		amount := new(big.Int).SetUint64(0)
   468  		values := map[types.TxValueKeyType]interface{}{
   469  			types.TxValueKeyNonce:         reservoir.Nonce,
   470  			types.TxValueKeyFrom:          reservoir.Addr,
   471  			types.TxValueKeyTo:            (*common.Address)(nil),
   472  			types.TxValueKeyAmount:        amount,
   473  			types.TxValueKeyGasLimit:      uint64(50 * uint64(params.Ston)),
   474  			types.TxValueKeyGasPrice:      gasPrice,
   475  			types.TxValueKeyHumanReadable: false,
   476  			types.TxValueKeyData:          common.FromHex(code),
   477  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
   478  		}
   479  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
   480  		assert.Equal(t, nil, err)
   481  
   482  		err = tx.SignWithKeys(signer, reservoir.Keys)
   483  		assert.Equal(t, nil, err)
   484  
   485  		txs = append(txs, tx)
   486  
   487  		err = bcdata.GenABlockWithTransactions(accountMap, txs, prof)
   488  		assert.Equal(t, nil, err)
   489  
   490  		contractAddr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
   491  
   492  		reservoir.Nonce += 1
   493  	}
   494  	// select account key types to be tested
   495  	accountKeyTypes := []accountkey.AccountKeyType{
   496  		// accountkey.AccountKeyTypeNil, // not supported type
   497  		accountkey.AccountKeyTypeLegacy,
   498  		accountkey.AccountKeyTypePublic,
   499  		accountkey.AccountKeyTypeFail,
   500  		accountkey.AccountKeyTypeWeightedMultiSig,
   501  		accountkey.AccountKeyTypeRoleBased,
   502  	}
   503  
   504  	txTypes := []types.TxType{}
   505  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
   506  		if i == types.TxTypeKlaytnLast {
   507  			i = types.TxTypeEthereumAccessList
   508  		}
   509  
   510  		_, err := types.NewTxInternalData(i)
   511  		if err == nil {
   512  			txTypes = append(txTypes, i)
   513  		}
   514  	}
   515  
   516  	// tests for all accountKeyTypes
   517  	for _, accountKeyType := range accountKeyTypes {
   518  		// a sender account
   519  		sender, err := createDefaultAccount(accountKeyType)
   520  		assert.Equal(t, nil, err)
   521  
   522  		// senderLegacy provides a coupled (address, key pair) will be used by sender
   523  		senderLegacy, err := createAnonymousAccount(getRandomPrivateKeyString(t))
   524  		assert.Equal(t, nil, err)
   525  
   526  		// assign senderLegacy address to sender
   527  		sender.Addr = senderLegacy.Addr
   528  
   529  		if testing.Verbose() {
   530  			fmt.Println("reservoirAddr = ", reservoir.Addr.String())
   531  			fmt.Println("senderAddr = ", sender.Addr.String())
   532  		}
   533  
   534  		// send KLAY to sender
   535  		{
   536  			var txs types.Transactions
   537  
   538  			amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
   539  			tx := types.NewTransaction(reservoir.GetNonce(),
   540  				sender.Addr, amount, gasLimit, gasPrice, []byte{})
   541  
   542  			err := tx.SignWithKeys(signer, reservoir.Keys)
   543  			assert.Equal(t, nil, err)
   544  			txs = append(txs, tx)
   545  
   546  			if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   547  				t.Fatal(err)
   548  			}
   549  			reservoir.AddNonce()
   550  		}
   551  
   552  		if senderLegacy.AccKey.Type() != accountKeyType {
   553  			// update sender's account key
   554  			{
   555  				var txs types.Transactions
   556  
   557  				values := map[types.TxValueKeyType]interface{}{
   558  					types.TxValueKeyNonce:      sender.Nonce,
   559  					types.TxValueKeyFrom:       sender.Addr,
   560  					types.TxValueKeyGasLimit:   gasLimit,
   561  					types.TxValueKeyGasPrice:   gasPrice,
   562  					types.TxValueKeyAccountKey: sender.AccKey,
   563  				}
   564  				tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
   565  				assert.Equal(t, nil, err)
   566  
   567  				err = tx.SignWithKeys(signer, senderLegacy.Keys)
   568  				assert.Equal(t, nil, err)
   569  
   570  				txs = append(txs, tx)
   571  
   572  				if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   573  					t.Fatal(err)
   574  				}
   575  				sender.AddNonce()
   576  			}
   577  		} else {
   578  			sender.Keys = senderLegacy.Keys
   579  		}
   580  
   581  		// tests for all txTypes
   582  		for _, txType := range txTypes {
   583  			// skip if tx type is legacy transaction and sender is not legacy.
   584  			if (txType.IsLegacyTransaction() || txType.IsEthTypedTransaction()) &&
   585  				!sender.AccKey.Type().IsLegacyAccountKey() {
   586  				continue
   587  			}
   588  
   589  			if testing.Verbose() {
   590  				fmt.Println("Testing... accountKeyType: ", accountKeyType, ", txType: ", txType)
   591  			}
   592  
   593  			// generate a default transaction
   594  			tx, _, err := generateDefaultTx(sender, reservoir, txType, contractAddr)
   595  			assert.Equal(t, nil, err)
   596  
   597  			// sign a tx
   598  			tx, err = signTxWithVariousKeyTypes(signer, tx, sender)
   599  			assert.Equal(t, nil, err)
   600  
   601  			if txType.IsFeeDelegatedTransaction() {
   602  				err = tx.SignFeePayerWithKeys(signer, reservoir.Keys)
   603  				assert.Equal(t, nil, err)
   604  			}
   605  
   606  			expectedError := expectedTestResultForDefaultTx(accountKeyType, txType)
   607  
   608  			receipt, err := applyTransaction(t, bcdata, tx)
   609  			assert.Equal(t, expectedError, err)
   610  
   611  			if err == nil {
   612  				assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
   613  			}
   614  		}
   615  	}
   616  	if testing.Verbose() {
   617  		prof.PrintProfileInfo()
   618  	}
   619  }
   620  
   621  // TestAccountUpdateMultiSigKeyMaxKey tests multiSig key update with maximum private keys.
   622  // A multiSig account supports maximum 10 different private keys.
   623  // Update an account key to a multiSig key with 11 different private keys (more than 10 -> failed)
   624  func TestAccountUpdateMultiSigKeyMaxKey(t *testing.T) {
   625  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   626  	prof := profile.NewProfiler()
   627  
   628  	// Initialize blockchain
   629  	start := time.Now()
   630  	bcdata, err := NewBCData(6, 4)
   631  	if err != nil {
   632  		t.Fatal(err)
   633  	}
   634  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
   635  	defer bcdata.Shutdown()
   636  
   637  	// Initialize address-balance map for verification
   638  	start = time.Now()
   639  	accountMap := NewAccountMap()
   640  	if err := accountMap.Initialize(bcdata); err != nil {
   641  		t.Fatal(err)
   642  	}
   643  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
   644  
   645  	// reservoir account
   646  	reservoir := &TestAccountType{
   647  		Addr:  *bcdata.addrs[0],
   648  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   649  		Nonce: uint64(0),
   650  	}
   651  
   652  	// anonymous account
   653  	anon, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594389999")
   654  	assert.Equal(t, nil, err)
   655  
   656  	// multisig setting
   657  	threshold := uint(10)
   658  	weights := []uint{1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 1}
   659  	multisigAddr := common.HexToAddress("0xbbfa38050bf3167c887c086758f448ce067ea8ea")
   660  	prvKeys := []string{
   661  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380000",
   662  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380001",
   663  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380002",
   664  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380003",
   665  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380004",
   666  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380005",
   667  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380006",
   668  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594300007",
   669  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594300008",
   670  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594300009",
   671  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594300010",
   672  	}
   673  
   674  	// multi-sig account
   675  	multisig, err := createMultisigAccount(threshold, weights, prvKeys, multisigAddr)
   676  	assert.Equal(t, nil, err)
   677  
   678  	if testing.Verbose() {
   679  		fmt.Println("reservoirAddr = ", reservoir.Addr.String())
   680  		fmt.Println("multisigAddr = ", multisig.Addr.String())
   681  	}
   682  
   683  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
   684  	gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice)
   685  
   686  	// Transfer (reservoir -> anon) using a legacy transaction.
   687  	{
   688  		var txs types.Transactions
   689  
   690  		amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
   691  		tx := types.NewTransaction(reservoir.Nonce,
   692  			anon.Addr, amount, gasLimit, gasPrice, []byte{})
   693  
   694  		err := tx.SignWithKeys(signer, reservoir.Keys)
   695  		assert.Equal(t, nil, err)
   696  		txs = append(txs, tx)
   697  
   698  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   699  			t.Fatal(err)
   700  		}
   701  		reservoir.Nonce += 1
   702  	}
   703  
   704  	// make TxPool to test validation in 'TxPool add' process
   705  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
   706  
   707  	// update key to a multiSig account with 11 different private keys (more than 10 -> failed)
   708  	{
   709  		values := map[types.TxValueKeyType]interface{}{
   710  			types.TxValueKeyNonce:      anon.Nonce,
   711  			types.TxValueKeyFrom:       anon.Addr,
   712  			types.TxValueKeyGasLimit:   gasLimit,
   713  			types.TxValueKeyGasPrice:   gasPrice,
   714  			types.TxValueKeyAccountKey: multisig.AccKey,
   715  		}
   716  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
   717  		assert.Equal(t, nil, err)
   718  
   719  		err = tx.SignWithKeys(signer, anon.Keys)
   720  		assert.Equal(t, nil, err)
   721  
   722  		// For tx pool validation test
   723  		{
   724  			err = txpool.AddRemote(tx)
   725  			assert.Equal(t, kerrors.ErrMaxKeysExceed, err)
   726  		}
   727  
   728  		// For block tx validation test
   729  		{
   730  			receipt, err := applyTransaction(t, bcdata, tx)
   731  			assert.Equal(t, kerrors.ErrMaxKeysExceed, err)
   732  			assert.Equal(t, (*types.Receipt)(nil), receipt)
   733  		}
   734  
   735  		anon.Nonce += 1
   736  	}
   737  
   738  	if testing.Verbose() {
   739  		prof.PrintProfileInfo()
   740  	}
   741  }
   742  
   743  // TestAccountUpdateMultiSigKeyBigThreshold tests multiSig key update with abnormal threshold.
   744  // When a multisig key is updated, a threshold value should be less or equal to the total weight of private keys.
   745  // If not, the account cannot creates any valid signatures.
   746  // The test update an account key to a multisig key with a threshold (10) and the total weight (6). (failed case)
   747  func TestAccountUpdateMultiSigKeyBigThreshold(t *testing.T) {
   748  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   749  	prof := profile.NewProfiler()
   750  
   751  	// Initialize blockchain
   752  	start := time.Now()
   753  	bcdata, err := NewBCData(6, 4)
   754  	if err != nil {
   755  		t.Fatal(err)
   756  	}
   757  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
   758  	defer bcdata.Shutdown()
   759  
   760  	// Initialize address-balance map for verification
   761  	start = time.Now()
   762  	accountMap := NewAccountMap()
   763  	if err := accountMap.Initialize(bcdata); err != nil {
   764  		t.Fatal(err)
   765  	}
   766  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
   767  
   768  	// reservoir account
   769  	reservoir := &TestAccountType{
   770  		Addr:  *bcdata.addrs[0],
   771  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   772  		Nonce: uint64(0),
   773  	}
   774  
   775  	// anonymous account
   776  	anon, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594389999")
   777  	assert.Equal(t, nil, err)
   778  
   779  	// multisig setting
   780  	threshold := uint(10)
   781  	weights := []uint{1, 2, 3}
   782  	multisigAddr := common.HexToAddress("0xbbfa38050bf3167c887c086758f448ce067ea8ea")
   783  	prvKeys := []string{
   784  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380000",
   785  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380001",
   786  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380002",
   787  	}
   788  
   789  	// multi-sig account
   790  	multisig, err := createMultisigAccount(threshold, weights, prvKeys, multisigAddr)
   791  
   792  	if testing.Verbose() {
   793  		fmt.Println("reservoirAddr = ", reservoir.Addr.String())
   794  		fmt.Println("multisigAddr = ", multisig.Addr.String())
   795  	}
   796  
   797  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
   798  	gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice)
   799  
   800  	// Transfer (reservoir -> anon) using a legacy transaction.
   801  	{
   802  		var txs types.Transactions
   803  
   804  		amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
   805  		tx := types.NewTransaction(reservoir.Nonce,
   806  			anon.Addr, amount, gasLimit, gasPrice, []byte{})
   807  
   808  		err := tx.SignWithKeys(signer, reservoir.Keys)
   809  		assert.Equal(t, nil, err)
   810  		txs = append(txs, tx)
   811  
   812  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   813  			t.Fatal(err)
   814  		}
   815  		reservoir.Nonce += 1
   816  	}
   817  
   818  	// make TxPool to test validation in 'TxPool add' process
   819  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
   820  
   821  	// update key to a multisig key with a threshold (10) and the total weight (6). (failed case)
   822  	{
   823  		values := map[types.TxValueKeyType]interface{}{
   824  			types.TxValueKeyNonce:      anon.Nonce,
   825  			types.TxValueKeyFrom:       anon.Addr,
   826  			types.TxValueKeyGasLimit:   gasLimit,
   827  			types.TxValueKeyGasPrice:   gasPrice,
   828  			types.TxValueKeyAccountKey: multisig.AccKey,
   829  		}
   830  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
   831  		assert.Equal(t, nil, err)
   832  
   833  		err = tx.SignWithKeys(signer, anon.Keys)
   834  		assert.Equal(t, nil, err)
   835  
   836  		// For tx pool validation test
   837  		{
   838  			err = txpool.AddRemote(tx)
   839  			assert.Equal(t, kerrors.ErrUnsatisfiableThreshold, err)
   840  		}
   841  
   842  		// For block tx validation test
   843  		{
   844  			receipt, err := applyTransaction(t, bcdata, tx)
   845  			assert.Equal(t, (*types.Receipt)(nil), receipt)
   846  			assert.Equal(t, kerrors.ErrUnsatisfiableThreshold, err)
   847  		}
   848  	}
   849  
   850  	if testing.Verbose() {
   851  		prof.PrintProfileInfo()
   852  	}
   853  }
   854  
   855  // TestAccountUpdateMultiSigKeyDupPrvKeys tests multiSig key update with duplicated private keys.
   856  // A multisig key consists of  all different private keys, therefore account update with duplicated private keys should be failed.
   857  // The test supposed the case when two same private keys are used in creation processes.
   858  func TestAccountUpdateMultiSigKeyDupPrvKeys(t *testing.T) {
   859  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   860  	prof := profile.NewProfiler()
   861  
   862  	// Initialize blockchain
   863  	start := time.Now()
   864  	bcdata, err := NewBCData(6, 4)
   865  	if err != nil {
   866  		t.Fatal(err)
   867  	}
   868  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
   869  	defer bcdata.Shutdown()
   870  
   871  	// Initialize address-balance map for verification
   872  	start = time.Now()
   873  	accountMap := NewAccountMap()
   874  	if err := accountMap.Initialize(bcdata); err != nil {
   875  		t.Fatal(err)
   876  	}
   877  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
   878  
   879  	// reservoir account
   880  	reservoir := &TestAccountType{
   881  		Addr:  *bcdata.addrs[0],
   882  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   883  		Nonce: uint64(0),
   884  	}
   885  
   886  	// anonymous account
   887  	anon, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594389999")
   888  	assert.Equal(t, nil, err)
   889  
   890  	// the case when two same private keys are used in creation processes.
   891  	threshold := uint(2)
   892  	weights := []uint{1, 1, 2}
   893  	multisigAddr := common.HexToAddress("0xbbfa38050bf3167c887c086758f448ce067ea8ea")
   894  	prvKeys := []string{
   895  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380000",
   896  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380001",
   897  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380001",
   898  	}
   899  
   900  	// multi-sig account
   901  	multisig, err := createMultisigAccount(threshold, weights, prvKeys, multisigAddr)
   902  	assert.Equal(t, nil, err)
   903  
   904  	if testing.Verbose() {
   905  		fmt.Println("reservoirAddr = ", reservoir.Addr.String())
   906  	}
   907  
   908  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
   909  	gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice)
   910  
   911  	// 1. Transfer (reservoir -> anon) using a legacy transaction.
   912  	{
   913  		var txs types.Transactions
   914  
   915  		amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
   916  		tx := types.NewTransaction(reservoir.Nonce,
   917  			anon.Addr, amount, gasLimit, gasPrice, []byte{})
   918  
   919  		err := tx.SignWithKeys(signer, reservoir.Keys)
   920  		assert.Equal(t, nil, err)
   921  		txs = append(txs, tx)
   922  
   923  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   924  			t.Fatal(err)
   925  		}
   926  		reservoir.Nonce += 1
   927  	}
   928  
   929  	// make TxPool to test validation in 'TxPool add' process
   930  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
   931  
   932  	// 2. Update to a multisig key which has two same private keys.
   933  	{
   934  		values := map[types.TxValueKeyType]interface{}{
   935  			types.TxValueKeyNonce:      anon.Nonce,
   936  			types.TxValueKeyFrom:       anon.Addr,
   937  			types.TxValueKeyGasLimit:   gasLimit,
   938  			types.TxValueKeyGasPrice:   gasPrice,
   939  			types.TxValueKeyAccountKey: multisig.AccKey,
   940  		}
   941  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
   942  		assert.Equal(t, nil, err)
   943  
   944  		err = tx.SignWithKeys(signer, anon.Keys)
   945  		assert.Equal(t, nil, err)
   946  
   947  		// For tx pool validation test
   948  		{
   949  			err = txpool.AddRemote(tx)
   950  			assert.Equal(t, kerrors.ErrDuplicatedKey, err)
   951  		}
   952  
   953  		// For block tx validation test
   954  		{
   955  			receipt, err := applyTransaction(t, bcdata, tx)
   956  			assert.Equal(t, (*types.Receipt)(nil), receipt)
   957  			assert.Equal(t, kerrors.ErrDuplicatedKey, err)
   958  		}
   959  	}
   960  
   961  	if testing.Verbose() {
   962  		prof.PrintProfileInfo()
   963  	}
   964  }
   965  
   966  // TestAccountUpdateMultiSigKeyWeightOverflow tests multiSig key update with weight overflow.
   967  // If the sum of weights is overflowed, the test should fail.
   968  func TestAccountUpdateMultiSigKeyWeightOverflow(t *testing.T) {
   969  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
   970  	prof := profile.NewProfiler()
   971  
   972  	// Initialize blockchain
   973  	start := time.Now()
   974  	bcdata, err := NewBCData(6, 4)
   975  	if err != nil {
   976  		t.Fatal(err)
   977  	}
   978  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
   979  	defer bcdata.Shutdown()
   980  
   981  	// Initialize address-balance map for verification
   982  	start = time.Now()
   983  	accountMap := NewAccountMap()
   984  	if err := accountMap.Initialize(bcdata); err != nil {
   985  		t.Fatal(err)
   986  	}
   987  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
   988  
   989  	// reservoir account
   990  	reservoir := &TestAccountType{
   991  		Addr:  *bcdata.addrs[0],
   992  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
   993  		Nonce: uint64(0),
   994  	}
   995  
   996  	// Simply check & set the maximum value of uint
   997  	MAX := uint(math.MaxUint32)
   998  	if strconv.IntSize == 64 {
   999  		MAX = math.MaxUint64
  1000  	}
  1001  
  1002  	// anonymous account
  1003  	anon, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594389999")
  1004  	assert.Equal(t, nil, err)
  1005  
  1006  	// multisig setting
  1007  	threshold := uint(MAX)
  1008  	weights := []uint{MAX / 2, MAX / 2, MAX / 2}
  1009  	multisigAddr := common.HexToAddress("0xbbfa38050bf3167c887c086758f448ce067ea8ea")
  1010  	prvKeys := []string{
  1011  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380000",
  1012  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380001",
  1013  		"a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae594380002",
  1014  	}
  1015  
  1016  	// multi-sig account
  1017  	multisig, err := createMultisigAccount(threshold, weights, prvKeys, multisigAddr)
  1018  	assert.Equal(t, nil, err)
  1019  
  1020  	if testing.Verbose() {
  1021  		fmt.Println("reservoirAddr = ", reservoir.Addr.String())
  1022  	}
  1023  
  1024  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  1025  	gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice)
  1026  
  1027  	// 1. Transfer (reservoir -> anon) using a legacy transaction.
  1028  	{
  1029  		var txs types.Transactions
  1030  
  1031  		amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
  1032  		tx := types.NewTransaction(reservoir.Nonce,
  1033  			anon.Addr, amount, gasLimit, gasPrice, []byte{})
  1034  
  1035  		err := tx.SignWithKeys(signer, reservoir.Keys)
  1036  		assert.Equal(t, nil, err)
  1037  		txs = append(txs, tx)
  1038  
  1039  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1040  			t.Fatal(err)
  1041  		}
  1042  		reservoir.Nonce += 1
  1043  	}
  1044  
  1045  	// make TxPool to test validation in 'TxPool add' process
  1046  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
  1047  
  1048  	// 2. update toc a multisig key with a threshold, uint(MAX), and the total weight, uint(MAX/2)*3. (failed case)
  1049  	{
  1050  		values := map[types.TxValueKeyType]interface{}{
  1051  			types.TxValueKeyNonce:      anon.Nonce,
  1052  			types.TxValueKeyFrom:       anon.Addr,
  1053  			types.TxValueKeyGasLimit:   gasLimit,
  1054  			types.TxValueKeyGasPrice:   gasPrice,
  1055  			types.TxValueKeyAccountKey: multisig.AccKey,
  1056  		}
  1057  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1058  		assert.Equal(t, nil, err)
  1059  
  1060  		err = tx.SignWithKeys(signer, anon.Keys)
  1061  		assert.Equal(t, nil, err)
  1062  
  1063  		// For tx pool validation test
  1064  		{
  1065  			err = txpool.AddRemote(tx)
  1066  			assert.Equal(t, kerrors.ErrWeightedSumOverflow, err)
  1067  		}
  1068  
  1069  		// For block tx validation test
  1070  		{
  1071  			receipt, err := applyTransaction(t, bcdata, tx)
  1072  			assert.Equal(t, (*types.Receipt)(nil), receipt)
  1073  			assert.Equal(t, kerrors.ErrWeightedSumOverflow, err)
  1074  		}
  1075  	}
  1076  
  1077  	if testing.Verbose() {
  1078  		prof.PrintProfileInfo()
  1079  	}
  1080  }
  1081  
  1082  // TestAccountUpdateRoleBasedKeyInvalidNumKey tests account update with a RoleBased key which contains invalid number of sub-keys.
  1083  // A RoleBased key can contain 1 ~ 3 sub-keys, otherwise it will fail to the account creation.
  1084  // 1. try to create an account with a RoleBased key which contains 4 sub-keys.
  1085  // 2. try to create an account with a RoleBased key which contains 0 sub-key.
  1086  func TestAccountUpdateRoleBasedKeyInvalidNumKey(t *testing.T) {
  1087  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1088  	prof := profile.NewProfiler()
  1089  
  1090  	// Initialize blockchain
  1091  	start := time.Now()
  1092  	bcdata, err := NewBCData(6, 4)
  1093  	if err != nil {
  1094  		t.Fatal(err)
  1095  	}
  1096  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
  1097  	defer bcdata.Shutdown()
  1098  
  1099  	// Initialize address-balance map for verification
  1100  	start = time.Now()
  1101  	accountMap := NewAccountMap()
  1102  	if err := accountMap.Initialize(bcdata); err != nil {
  1103  		t.Fatal(err)
  1104  	}
  1105  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
  1106  
  1107  	// reservoir account
  1108  	reservoir := &TestAccountType{
  1109  		Addr:  *bcdata.addrs[0],
  1110  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
  1111  		Nonce: uint64(0),
  1112  	}
  1113  
  1114  	// anonymous account
  1115  	anon, err := createAnonymousAccount("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab")
  1116  	assert.Equal(t, nil, err)
  1117  
  1118  	if testing.Verbose() {
  1119  		fmt.Println("reservoirAddr = ", reservoir.Addr.String())
  1120  		fmt.Println("anonAddr = ", anon.Addr.String())
  1121  	}
  1122  
  1123  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  1124  	gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice)
  1125  
  1126  	// 1. Transfer (reservoir -> anon) using a legacy transaction.
  1127  	{
  1128  		var txs types.Transactions
  1129  
  1130  		amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
  1131  		tx := types.NewTransaction(reservoir.Nonce,
  1132  			anon.Addr, amount, gasLimit, gasPrice, []byte{})
  1133  
  1134  		err := tx.SignWithKeys(signer, reservoir.Keys)
  1135  		assert.Equal(t, nil, err)
  1136  		txs = append(txs, tx)
  1137  
  1138  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1139  			t.Fatal(err)
  1140  		}
  1141  		reservoir.Nonce += 1
  1142  	}
  1143  
  1144  	// make TxPool to test validation in 'TxPool add' process
  1145  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
  1146  
  1147  	// 2. update to a RoleBased key which contains 4 sub-keys.
  1148  	{
  1149  		keys := genTestKeys(4)
  1150  		roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  1151  			accountkey.NewAccountKeyPublicWithValue(&keys[0].PublicKey),
  1152  			accountkey.NewAccountKeyPublicWithValue(&keys[1].PublicKey),
  1153  			accountkey.NewAccountKeyPublicWithValue(&keys[2].PublicKey),
  1154  			accountkey.NewAccountKeyPublicWithValue(&keys[3].PublicKey),
  1155  		})
  1156  
  1157  		values := map[types.TxValueKeyType]interface{}{
  1158  			types.TxValueKeyNonce:      anon.Nonce,
  1159  			types.TxValueKeyFrom:       anon.Addr,
  1160  			types.TxValueKeyGasLimit:   gasLimit,
  1161  			types.TxValueKeyGasPrice:   gasPrice,
  1162  			types.TxValueKeyAccountKey: roleKey,
  1163  		}
  1164  
  1165  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1166  		assert.Equal(t, nil, err)
  1167  
  1168  		err = tx.SignWithKeys(signer, anon.Keys)
  1169  		assert.Equal(t, nil, err)
  1170  
  1171  		// For tx pool validation test
  1172  		{
  1173  			err = txpool.AddRemote(tx)
  1174  			assert.Equal(t, kerrors.ErrLengthTooLong, err)
  1175  		}
  1176  
  1177  		// For block tx validation test
  1178  		{
  1179  			receipt, err := applyTransaction(t, bcdata, tx)
  1180  			assert.Equal(t, (*types.Receipt)(nil), receipt)
  1181  			assert.Equal(t, kerrors.ErrLengthTooLong, err)
  1182  		}
  1183  	}
  1184  
  1185  	// 2. update to a RoleBased key which contains 0 sub-key.
  1186  	{
  1187  		roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{})
  1188  
  1189  		values := map[types.TxValueKeyType]interface{}{
  1190  			types.TxValueKeyNonce:      anon.Nonce,
  1191  			types.TxValueKeyFrom:       anon.Addr,
  1192  			types.TxValueKeyGasLimit:   gasLimit,
  1193  			types.TxValueKeyGasPrice:   gasPrice,
  1194  			types.TxValueKeyAccountKey: roleKey,
  1195  		}
  1196  
  1197  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1198  		assert.Equal(t, nil, err)
  1199  
  1200  		err = tx.SignWithKeys(signer, anon.Keys)
  1201  		assert.Equal(t, nil, err)
  1202  
  1203  		// For tx pool validation test
  1204  		{
  1205  			err = txpool.AddRemote(tx)
  1206  			assert.Equal(t, kerrors.ErrZeroLength, err)
  1207  		}
  1208  
  1209  		// For block tx validation test
  1210  		{
  1211  			receipt, err := applyTransaction(t, bcdata, tx)
  1212  			assert.Equal(t, (*types.Receipt)(nil), receipt)
  1213  			assert.Equal(t, kerrors.ErrZeroLength, err)
  1214  		}
  1215  	}
  1216  
  1217  	if testing.Verbose() {
  1218  		prof.PrintProfileInfo()
  1219  	}
  1220  }
  1221  
  1222  // TestAccountUpdateRoleBasedKeyInvalidTypeKey tests account key update with a RoleBased key contains types of sub-keys.
  1223  // As a sub-key type, a RoleBased key can have AccountKeyFail keys but not AccountKeyNil keys.
  1224  // 1. a RoleBased key contains an AccountKeyNil type sub-key as a first sub-key. (fail)
  1225  // 2. a RoleBased key contains an AccountKeyNil type sub-key as a second sub-key. (fail)
  1226  // 3. a RoleBased key contains an AccountKeyNil type sub-key as a third sub-key. (fail)
  1227  // 4. a RoleBased key contains an AccountKeyFail type sub-key as a first sub-key. (success)
  1228  // 5. a RoleBased key contains an AccountKeyFail type sub-key as a second sub-key. (success)
  1229  // 6. a RoleBased key contains an AccountKeyFail type sub-key as a third sub-key. (success)
  1230  func TestAccountUpdateRoleBasedKeyInvalidTypeKey(t *testing.T) {
  1231  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1232  	prof := profile.NewProfiler()
  1233  
  1234  	// Initialize blockchain
  1235  	start := time.Now()
  1236  	bcdata, err := NewBCData(6, 4)
  1237  	if err != nil {
  1238  		t.Fatal(err)
  1239  	}
  1240  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
  1241  	defer bcdata.Shutdown()
  1242  
  1243  	// Initialize address-balance map for verification
  1244  	start = time.Now()
  1245  	accountMap := NewAccountMap()
  1246  	if err := accountMap.Initialize(bcdata); err != nil {
  1247  		t.Fatal(err)
  1248  	}
  1249  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
  1250  
  1251  	// reservoir account
  1252  	reservoir := &TestAccountType{
  1253  		Addr:  *bcdata.addrs[0],
  1254  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
  1255  		Nonce: uint64(0),
  1256  	}
  1257  
  1258  	// anonymous account
  1259  	anon, err := createAnonymousAccount("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab")
  1260  	assert.Equal(t, nil, err)
  1261  
  1262  	if testing.Verbose() {
  1263  		fmt.Println("reservoirAddr = ", reservoir.Addr.String())
  1264  		fmt.Println("anonAddr = ", anon.Addr.String())
  1265  	}
  1266  
  1267  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  1268  	gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice)
  1269  	keys := genTestKeys(2)
  1270  
  1271  	// 0. Transfer (reservoir -> anon) using a legacy transaction.
  1272  	{
  1273  		var txs types.Transactions
  1274  
  1275  		amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
  1276  		tx := types.NewTransaction(reservoir.Nonce,
  1277  			anon.Addr, amount, gasLimit, gasPrice, []byte{})
  1278  
  1279  		err := tx.SignWithKeys(signer, reservoir.Keys)
  1280  		assert.Equal(t, nil, err)
  1281  		txs = append(txs, tx)
  1282  
  1283  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1284  			t.Fatal(err)
  1285  		}
  1286  		reservoir.Nonce += 1
  1287  	}
  1288  
  1289  	// make TxPool to test validation in 'TxPool add' process
  1290  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
  1291  
  1292  	// 1. a RoleBased key contains an AccountKeyNil type sub-key as a first sub-key. (fail)
  1293  	{
  1294  		roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  1295  			accountkey.NewAccountKeyNil(),
  1296  			accountkey.NewAccountKeyPublicWithValue(&keys[0].PublicKey),
  1297  			accountkey.NewAccountKeyPublicWithValue(&keys[1].PublicKey),
  1298  		})
  1299  
  1300  		values := map[types.TxValueKeyType]interface{}{
  1301  			types.TxValueKeyNonce:      anon.Nonce,
  1302  			types.TxValueKeyFrom:       anon.Addr,
  1303  			types.TxValueKeyGasLimit:   gasLimit,
  1304  			types.TxValueKeyGasPrice:   gasPrice,
  1305  			types.TxValueKeyAccountKey: roleKey,
  1306  		}
  1307  
  1308  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1309  		assert.Equal(t, nil, err)
  1310  
  1311  		err = tx.SignWithKeys(signer, anon.Keys)
  1312  		assert.Equal(t, nil, err)
  1313  
  1314  		// For tx pool validation test
  1315  		{
  1316  			err = txpool.AddRemote(tx)
  1317  			assert.Equal(t, kerrors.ErrAccountKeyNilUninitializable, err)
  1318  		}
  1319  
  1320  		// For block tx validation test
  1321  		{
  1322  			receipt, err := applyTransaction(t, bcdata, tx)
  1323  			assert.Equal(t, (*types.Receipt)(nil), receipt)
  1324  			assert.Equal(t, kerrors.ErrAccountKeyNilUninitializable, err)
  1325  		}
  1326  	}
  1327  
  1328  	// 2. a RoleBased key contains an AccountKeyNil type sub-key as a second sub-key. (fail)
  1329  	{
  1330  		roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  1331  			accountkey.NewAccountKeyPublicWithValue(&keys[0].PublicKey),
  1332  			accountkey.NewAccountKeyNil(),
  1333  			accountkey.NewAccountKeyPublicWithValue(&keys[1].PublicKey),
  1334  		})
  1335  
  1336  		values := map[types.TxValueKeyType]interface{}{
  1337  			types.TxValueKeyNonce:      anon.Nonce,
  1338  			types.TxValueKeyFrom:       anon.Addr,
  1339  			types.TxValueKeyGasLimit:   gasLimit,
  1340  			types.TxValueKeyGasPrice:   gasPrice,
  1341  			types.TxValueKeyAccountKey: roleKey,
  1342  		}
  1343  
  1344  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1345  		assert.Equal(t, nil, err)
  1346  
  1347  		err = tx.SignWithKeys(signer, anon.Keys)
  1348  		assert.Equal(t, nil, err)
  1349  
  1350  		// For tx pool validation test
  1351  		{
  1352  			err = txpool.AddRemote(tx)
  1353  			assert.Equal(t, kerrors.ErrAccountKeyNilUninitializable, err)
  1354  		}
  1355  
  1356  		// For block tx validation test
  1357  		{
  1358  			receipt, err := applyTransaction(t, bcdata, tx)
  1359  			assert.Equal(t, (*types.Receipt)(nil), receipt)
  1360  			assert.Equal(t, kerrors.ErrAccountKeyNilUninitializable, err)
  1361  		}
  1362  	}
  1363  
  1364  	// 3. a RoleBased key contains an AccountKeyNil type sub-key as a third sub-key. (fail)
  1365  	{
  1366  		roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  1367  			accountkey.NewAccountKeyPublicWithValue(&keys[0].PublicKey),
  1368  			accountkey.NewAccountKeyPublicWithValue(&keys[1].PublicKey),
  1369  			accountkey.NewAccountKeyNil(),
  1370  		})
  1371  
  1372  		values := map[types.TxValueKeyType]interface{}{
  1373  			types.TxValueKeyNonce:      anon.Nonce,
  1374  			types.TxValueKeyFrom:       anon.Addr,
  1375  			types.TxValueKeyGasLimit:   gasLimit,
  1376  			types.TxValueKeyGasPrice:   gasPrice,
  1377  			types.TxValueKeyAccountKey: roleKey,
  1378  		}
  1379  
  1380  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1381  		assert.Equal(t, nil, err)
  1382  
  1383  		err = tx.SignWithKeys(signer, anon.Keys)
  1384  		assert.Equal(t, nil, err)
  1385  
  1386  		// For tx pool validation test
  1387  		{
  1388  			err = txpool.AddRemote(tx)
  1389  			assert.Equal(t, kerrors.ErrAccountKeyNilUninitializable, err)
  1390  		}
  1391  
  1392  		// For block tx validation test
  1393  		{
  1394  			receipt, err := applyTransaction(t, bcdata, tx)
  1395  			assert.Equal(t, (*types.Receipt)(nil), receipt)
  1396  			assert.Equal(t, kerrors.ErrAccountKeyNilUninitializable, err)
  1397  		}
  1398  	}
  1399  
  1400  	// 4. a RoleBased key contains an AccountKeyFail type sub-key as a first sub-key. (success)
  1401  	{
  1402  		roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  1403  			accountkey.NewAccountKeyFail(),
  1404  			accountkey.NewAccountKeyPublicWithValue(&keys[0].PublicKey),
  1405  			accountkey.NewAccountKeyPublicWithValue(&keys[1].PublicKey),
  1406  		})
  1407  
  1408  		values := map[types.TxValueKeyType]interface{}{
  1409  			types.TxValueKeyNonce:      anon.Nonce,
  1410  			types.TxValueKeyFrom:       anon.Addr,
  1411  			types.TxValueKeyGasLimit:   gasLimit,
  1412  			types.TxValueKeyGasPrice:   gasPrice,
  1413  			types.TxValueKeyAccountKey: roleKey,
  1414  		}
  1415  
  1416  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1417  		assert.Equal(t, nil, err)
  1418  
  1419  		err = tx.SignWithKeys(signer, anon.Keys)
  1420  		assert.Equal(t, nil, err)
  1421  
  1422  		receipt, err := applyTransaction(t, bcdata, tx)
  1423  		assert.Equal(t, nil, err)
  1424  		assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
  1425  	}
  1426  
  1427  	// 5. a RoleBased key contains an AccountKeyFail type sub-key as a second sub-key. (success)
  1428  	{
  1429  		roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  1430  			accountkey.NewAccountKeyPublicWithValue(&keys[0].PublicKey),
  1431  			accountkey.NewAccountKeyFail(),
  1432  			accountkey.NewAccountKeyPublicWithValue(&keys[1].PublicKey),
  1433  		})
  1434  
  1435  		values := map[types.TxValueKeyType]interface{}{
  1436  			types.TxValueKeyNonce:      anon.Nonce,
  1437  			types.TxValueKeyFrom:       anon.Addr,
  1438  			types.TxValueKeyGasLimit:   gasLimit,
  1439  			types.TxValueKeyGasPrice:   gasPrice,
  1440  			types.TxValueKeyAccountKey: roleKey,
  1441  		}
  1442  
  1443  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1444  		assert.Equal(t, nil, err)
  1445  
  1446  		err = tx.SignWithKeys(signer, anon.Keys)
  1447  		assert.Equal(t, nil, err)
  1448  
  1449  		receipt, err := applyTransaction(t, bcdata, tx)
  1450  		assert.Equal(t, nil, err)
  1451  		assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
  1452  	}
  1453  
  1454  	// 6. a RoleBased key contains an AccountKeyFail type sub-key as a third sub-key. (success)
  1455  	{
  1456  		roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  1457  			accountkey.NewAccountKeyPublicWithValue(&keys[0].PublicKey),
  1458  			accountkey.NewAccountKeyPublicWithValue(&keys[1].PublicKey),
  1459  			accountkey.NewAccountKeyFail(),
  1460  		})
  1461  
  1462  		values := map[types.TxValueKeyType]interface{}{
  1463  			types.TxValueKeyNonce:      anon.Nonce,
  1464  			types.TxValueKeyFrom:       anon.Addr,
  1465  			types.TxValueKeyGasLimit:   gasLimit,
  1466  			types.TxValueKeyGasPrice:   gasPrice,
  1467  			types.TxValueKeyAccountKey: roleKey,
  1468  		}
  1469  
  1470  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1471  		assert.Equal(t, nil, err)
  1472  
  1473  		err = tx.SignWithKeys(signer, anon.Keys)
  1474  		assert.Equal(t, nil, err)
  1475  
  1476  		receipt, err := applyTransaction(t, bcdata, tx)
  1477  		assert.Equal(t, nil, err)
  1478  		assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
  1479  	}
  1480  
  1481  	if testing.Verbose() {
  1482  		prof.PrintProfileInfo()
  1483  	}
  1484  }
  1485  
  1486  // TestAccountUpdateWithRoleBasedKey tests account update with a roleBased key.
  1487  // A roleBased key contains three types of sub-keys, and only RoleAccountUpdate key is used for update.
  1488  // Other sub-keys are not used for the account update.
  1489  // 0. create an account and update its key to a roleBased key.
  1490  // 1. try to update the account with a RoleTransaction key. (fail)
  1491  // 2. try to update the account with a RoleFeePayer key. (fail)
  1492  // 3. try to update the account with a RoleAccountUpdate key. (success)
  1493  func TestAccountUpdateRoleBasedKey(t *testing.T) {
  1494  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1495  	prof := profile.NewProfiler()
  1496  
  1497  	// Initialize blockchain
  1498  	start := time.Now()
  1499  	bcdata, err := NewBCData(6, 4)
  1500  	if err != nil {
  1501  		t.Fatal(err)
  1502  	}
  1503  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
  1504  	defer bcdata.Shutdown()
  1505  
  1506  	// Initialize address-balance map for verification
  1507  	start = time.Now()
  1508  	accountMap := NewAccountMap()
  1509  	if err := accountMap.Initialize(bcdata); err != nil {
  1510  		t.Fatal(err)
  1511  	}
  1512  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
  1513  
  1514  	// reservoir account
  1515  	reservoir := &TestAccountType{
  1516  		Addr:  *bcdata.addrs[0],
  1517  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
  1518  		Nonce: uint64(0),
  1519  	}
  1520  
  1521  	// anonymous account
  1522  	anon, err := createAnonymousAccount("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab")
  1523  	assert.Equal(t, nil, err)
  1524  
  1525  	// generate a roleBased key
  1526  	keys := genTestKeys(3)
  1527  	roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  1528  		accountkey.NewAccountKeyPublicWithValue(&keys[0].PublicKey),
  1529  		accountkey.NewAccountKeyPublicWithValue(&keys[1].PublicKey),
  1530  		accountkey.NewAccountKeyPublicWithValue(&keys[2].PublicKey),
  1531  	})
  1532  
  1533  	if testing.Verbose() {
  1534  		fmt.Println("reservoirAddr = ", reservoir.Addr.String())
  1535  		fmt.Println("anonAddr = ", anon.Addr.String())
  1536  	}
  1537  
  1538  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  1539  	gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice)
  1540  
  1541  	// Transfer (reservoir -> anon) using a legacy transaction.
  1542  	{
  1543  		var txs types.Transactions
  1544  
  1545  		amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
  1546  		tx := types.NewTransaction(reservoir.Nonce,
  1547  			anon.Addr, amount, gasLimit, gasPrice, []byte{})
  1548  
  1549  		err := tx.SignWithKeys(signer, reservoir.Keys)
  1550  		assert.Equal(t, nil, err)
  1551  		txs = append(txs, tx)
  1552  
  1553  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1554  			t.Fatal(err)
  1555  		}
  1556  		reservoir.Nonce += 1
  1557  	}
  1558  
  1559  	// update the account with a roleBased key.
  1560  	{
  1561  		var txs types.Transactions
  1562  		values := map[types.TxValueKeyType]interface{}{
  1563  			types.TxValueKeyNonce:      anon.Nonce,
  1564  			types.TxValueKeyFrom:       anon.Addr,
  1565  			types.TxValueKeyGasLimit:   gasLimit,
  1566  			types.TxValueKeyGasPrice:   gasPrice,
  1567  			types.TxValueKeyAccountKey: roleKey,
  1568  		}
  1569  
  1570  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1571  		assert.Equal(t, nil, err)
  1572  		txs = append(txs, tx)
  1573  
  1574  		err = tx.SignWithKeys(signer, anon.Keys)
  1575  		assert.Equal(t, nil, err)
  1576  
  1577  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1578  			t.Fatal(err)
  1579  		}
  1580  
  1581  		anon.Nonce += 1
  1582  	}
  1583  
  1584  	// make TxPool to test validation in 'TxPool add' process
  1585  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
  1586  
  1587  	// 1. try to update the account with a RoleTransaction key. (fail)
  1588  	{
  1589  		values := map[types.TxValueKeyType]interface{}{
  1590  			types.TxValueKeyNonce:      anon.Nonce,
  1591  			types.TxValueKeyFrom:       anon.Addr,
  1592  			types.TxValueKeyGasLimit:   gasLimit,
  1593  			types.TxValueKeyGasPrice:   gasPrice,
  1594  			types.TxValueKeyAccountKey: roleKey,
  1595  		}
  1596  
  1597  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1598  		assert.Equal(t, nil, err)
  1599  
  1600  		err = tx.SignWithKeys(signer, []*ecdsa.PrivateKey{keys[accountkey.RoleTransaction]})
  1601  		assert.Equal(t, nil, err)
  1602  
  1603  		// For tx pool validation test
  1604  		{
  1605  			err = txpool.AddRemote(tx)
  1606  			assert.Equal(t, types.ErrSender(types.ErrInvalidAccountKey), err)
  1607  		}
  1608  
  1609  		// For block tx validation test
  1610  		{
  1611  			receipt, err := applyTransaction(t, bcdata, tx)
  1612  			assert.Equal(t, (*types.Receipt)(nil), receipt)
  1613  			assert.Equal(t, types.ErrSender(types.ErrInvalidAccountKey), err)
  1614  		}
  1615  	}
  1616  
  1617  	// 2. try to update the account with a RoleFeePayer key. (fail)
  1618  	{
  1619  		values := map[types.TxValueKeyType]interface{}{
  1620  			types.TxValueKeyNonce:      anon.Nonce,
  1621  			types.TxValueKeyFrom:       anon.Addr,
  1622  			types.TxValueKeyGasLimit:   gasLimit,
  1623  			types.TxValueKeyGasPrice:   gasPrice,
  1624  			types.TxValueKeyAccountKey: roleKey,
  1625  		}
  1626  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1627  		assert.Equal(t, nil, err)
  1628  
  1629  		err = tx.SignWithKeys(signer, []*ecdsa.PrivateKey{keys[accountkey.RoleFeePayer]})
  1630  		assert.Equal(t, nil, err)
  1631  
  1632  		// For tx pool validation test
  1633  		{
  1634  			err = txpool.AddRemote(tx)
  1635  			assert.Equal(t, types.ErrSender(types.ErrInvalidAccountKey), err)
  1636  		}
  1637  
  1638  		// For block tx validation test
  1639  		{
  1640  			receipt, err := applyTransaction(t, bcdata, tx)
  1641  			assert.Equal(t, (*types.Receipt)(nil), receipt)
  1642  			assert.Equal(t, types.ErrSender(types.ErrInvalidAccountKey), err)
  1643  		}
  1644  	}
  1645  
  1646  	// 3. try to update the account with a RoleAccountUpdate key. (success)
  1647  	{
  1648  		var txs types.Transactions
  1649  		values := map[types.TxValueKeyType]interface{}{
  1650  			types.TxValueKeyNonce:      anon.Nonce,
  1651  			types.TxValueKeyFrom:       anon.Addr,
  1652  			types.TxValueKeyGasLimit:   gasLimit,
  1653  			types.TxValueKeyGasPrice:   gasPrice,
  1654  			types.TxValueKeyAccountKey: roleKey,
  1655  		}
  1656  
  1657  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1658  		assert.Equal(t, nil, err)
  1659  		txs = append(txs, tx)
  1660  
  1661  		err = tx.SignWithKeys(signer, []*ecdsa.PrivateKey{keys[accountkey.RoleAccountUpdate]})
  1662  		assert.Equal(t, nil, err)
  1663  
  1664  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1665  			t.Fatal(err)
  1666  		}
  1667  
  1668  		anon.Nonce += 1
  1669  	}
  1670  
  1671  	if testing.Verbose() {
  1672  		prof.PrintProfileInfo()
  1673  	}
  1674  }
  1675  
  1676  // TestAccountUpdateRoleBasedKeyNested tests account update with a nested RoleBasedKey.
  1677  // Nested RoleBasedKey is not allowed in Klaytn.
  1678  // 1. Create an account with a RoleBasedKey.
  1679  // 2. Update an accountKey with a nested RoleBasedKey
  1680  func TestAccountUpdateRoleBasedKeyNested(t *testing.T) {
  1681  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1682  	prof := profile.NewProfiler()
  1683  
  1684  	// Initialize blockchain
  1685  	start := time.Now()
  1686  	bcdata, err := NewBCData(6, 4)
  1687  	if err != nil {
  1688  		t.Fatal(err)
  1689  	}
  1690  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
  1691  	defer bcdata.Shutdown()
  1692  
  1693  	// Initialize address-balance map for verification
  1694  	start = time.Now()
  1695  	accountMap := NewAccountMap()
  1696  	if err := accountMap.Initialize(bcdata); err != nil {
  1697  		t.Fatal(err)
  1698  	}
  1699  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
  1700  
  1701  	// reservoir account
  1702  	reservoir := &TestAccountType{
  1703  		Addr:  *bcdata.addrs[0],
  1704  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
  1705  		Nonce: uint64(0),
  1706  	}
  1707  
  1708  	// anonymous account
  1709  	anon, err := createAnonymousAccount("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab")
  1710  	assert.Equal(t, nil, err)
  1711  
  1712  	// roleBasedKeys and a nested roleBasedKey
  1713  	roleKey, err := createDefaultAccount(accountkey.AccountKeyTypeRoleBased)
  1714  	assert.Equal(t, nil, err)
  1715  
  1716  	nestedAccKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  1717  		roleKey.AccKey,
  1718  	})
  1719  
  1720  	if testing.Verbose() {
  1721  		fmt.Println("reservoirAddr = ", reservoir.Addr.String())
  1722  		fmt.Println("roleAddr = ", roleKey.Addr.String())
  1723  	}
  1724  
  1725  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  1726  	gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice)
  1727  
  1728  	// transfer (reservoir -> anon) using a legacy transaction.
  1729  	{
  1730  		var txs types.Transactions
  1731  
  1732  		amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
  1733  		tx := types.NewTransaction(reservoir.Nonce,
  1734  			anon.Addr, amount, gasLimit, gasPrice, []byte{})
  1735  
  1736  		err := tx.SignWithKeys(signer, reservoir.Keys)
  1737  		assert.Equal(t, nil, err)
  1738  		txs = append(txs, tx)
  1739  
  1740  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1741  			t.Fatal(err)
  1742  		}
  1743  		reservoir.Nonce += 1
  1744  	}
  1745  
  1746  	// update the account with a roleBased key.
  1747  	{
  1748  		var txs types.Transactions
  1749  		values := map[types.TxValueKeyType]interface{}{
  1750  			types.TxValueKeyNonce:      anon.Nonce,
  1751  			types.TxValueKeyFrom:       anon.Addr,
  1752  			types.TxValueKeyGasLimit:   gasLimit,
  1753  			types.TxValueKeyGasPrice:   gasPrice,
  1754  			types.TxValueKeyAccountKey: roleKey.AccKey,
  1755  		}
  1756  
  1757  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1758  		assert.Equal(t, nil, err)
  1759  		txs = append(txs, tx)
  1760  
  1761  		err = tx.SignWithKeys(signer, anon.Keys)
  1762  		assert.Equal(t, nil, err)
  1763  
  1764  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1765  			t.Fatal(err)
  1766  		}
  1767  
  1768  		anon.Nonce += 1
  1769  	}
  1770  
  1771  	// make TxPool to test validation in 'TxPool add' process
  1772  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
  1773  
  1774  	// 2. Update an accountKey with a nested RoleBasedKey.
  1775  	{
  1776  		values := map[types.TxValueKeyType]interface{}{
  1777  			types.TxValueKeyNonce:      anon.Nonce,
  1778  			types.TxValueKeyFrom:       anon.Addr,
  1779  			types.TxValueKeyGasLimit:   gasLimit,
  1780  			types.TxValueKeyGasPrice:   gasPrice,
  1781  			types.TxValueKeyAccountKey: nestedAccKey,
  1782  		}
  1783  
  1784  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1785  		assert.Equal(t, nil, err)
  1786  
  1787  		err = tx.SignWithKeys(signer, []*ecdsa.PrivateKey{roleKey.Keys[accountkey.RoleAccountUpdate]})
  1788  		assert.Equal(t, nil, err)
  1789  
  1790  		// For tx pool validation test
  1791  		{
  1792  			err = txpool.AddRemote(tx)
  1793  			assert.Equal(t, kerrors.ErrNestedCompositeType, err)
  1794  		}
  1795  
  1796  		// For block tx validation test
  1797  		{
  1798  			receipt, err := applyTransaction(t, bcdata, tx)
  1799  			assert.Equal(t, (*types.Receipt)(nil), receipt)
  1800  			assert.Equal(t, kerrors.ErrNestedCompositeType, err)
  1801  		}
  1802  	}
  1803  
  1804  	if testing.Verbose() {
  1805  		prof.PrintProfileInfo()
  1806  	}
  1807  }
  1808  
  1809  // TestRoleBasedKeySendTx tests signing transactions with a role-based key.
  1810  // A role-based key contains three types of sub-keys: RoleTransaction, RoleAccountUpdate, RoleFeePayer.
  1811  // Only RoleTransaction can generate valid signature as a sender except account update txs.
  1812  // RoleAccountUpdate can generate valid signature for account update txs.
  1813  func TestRoleBasedKeySendTx(t *testing.T) {
  1814  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  1815  	prof := profile.NewProfiler()
  1816  
  1817  	// Initialize blockchain
  1818  	start := time.Now()
  1819  	bcdata, err := NewBCData(6, 4)
  1820  	if err != nil {
  1821  		t.Fatal(err)
  1822  	}
  1823  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
  1824  	defer bcdata.Shutdown()
  1825  
  1826  	gasPrice := new(big.Int).SetUint64(25 * params.Ston)
  1827  
  1828  	// Initialize address-balance map for verification
  1829  	start = time.Now()
  1830  	accountMap := NewAccountMap()
  1831  	if err := accountMap.Initialize(bcdata); err != nil {
  1832  		t.Fatal(err)
  1833  	}
  1834  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
  1835  
  1836  	// reservoir account
  1837  	reservoir := &TestAccountType{
  1838  		Addr:  *bcdata.addrs[0],
  1839  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
  1840  		Nonce: uint64(0),
  1841  	}
  1842  
  1843  	// main account with a role-based key
  1844  	roleBased, err := createAnonymousAccount("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab")
  1845  	assert.Equal(t, nil, err)
  1846  
  1847  	// smart contract account
  1848  	contractAddr := common.Address{}
  1849  
  1850  	// generate a role-based key
  1851  	prvKeys := genTestKeys(3)
  1852  	roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  1853  		accountkey.NewAccountKeyPublicWithValue(&prvKeys[0].PublicKey),
  1854  		accountkey.NewAccountKeyPublicWithValue(&prvKeys[1].PublicKey),
  1855  		accountkey.NewAccountKeyPublicWithValue(&prvKeys[2].PublicKey),
  1856  	})
  1857  
  1858  	if testing.Verbose() {
  1859  		fmt.Println("reservoirAddr = ", reservoir.Addr.String())
  1860  		fmt.Println("roleBasedAddr = ", roleBased.Addr.String())
  1861  	}
  1862  
  1863  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  1864  
  1865  	txTypes := []types.TxType{}
  1866  	for i := types.TxTypeLegacyTransaction; i < types.TxTypeEthereumLast; i++ {
  1867  		if i == types.TxTypeKlaytnLast {
  1868  			i = types.TxTypeEthereumAccessList
  1869  		}
  1870  
  1871  		if i.IsLegacyTransaction() || i.IsEthTypedTransaction() {
  1872  			continue // accounts with role-based key cannot send the legacy tx and ethereum typed tx.
  1873  		}
  1874  		_, err := types.NewTxInternalData(i)
  1875  		if err == nil {
  1876  			txTypes = append(txTypes, i)
  1877  		}
  1878  	}
  1879  
  1880  	// deploy a contract to test smart contract execution.
  1881  	{
  1882  		var txs types.Transactions
  1883  		valueMap, _ := genMapForTxTypes(reservoir, reservoir, types.TxTypeSmartContractDeploy)
  1884  		valueMap[types.TxValueKeyTo] = (*common.Address)(nil)
  1885  
  1886  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, valueMap)
  1887  		assert.Equal(t, nil, err)
  1888  
  1889  		err = tx.SignWithKeys(signer, reservoir.Keys)
  1890  		assert.Equal(t, nil, err)
  1891  
  1892  		txs = append(txs, tx)
  1893  
  1894  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1895  			t.Fatal(err)
  1896  		}
  1897  
  1898  		contractAddr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
  1899  		reservoir.Nonce += 1
  1900  	}
  1901  
  1902  	// transfer (reservoir -> roleBased) using a legacy transaction.
  1903  	{
  1904  		var txs types.Transactions
  1905  
  1906  		amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
  1907  		tx := types.NewTransaction(reservoir.Nonce,
  1908  			roleBased.Addr, amount, gasLimit, gasPrice, []byte{})
  1909  
  1910  		err := tx.SignWithKeys(signer, reservoir.Keys)
  1911  		assert.Equal(t, nil, err)
  1912  		txs = append(txs, tx)
  1913  
  1914  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1915  			t.Fatal(err)
  1916  		}
  1917  		reservoir.Nonce += 1
  1918  	}
  1919  
  1920  	// update to an roleBased account with a role-based key.
  1921  	{
  1922  		var txs types.Transactions
  1923  
  1924  		values := map[types.TxValueKeyType]interface{}{
  1925  			types.TxValueKeyNonce:      roleBased.Nonce,
  1926  			types.TxValueKeyFrom:       roleBased.Addr,
  1927  			types.TxValueKeyGasLimit:   gasLimit,
  1928  			types.TxValueKeyGasPrice:   gasPrice,
  1929  			types.TxValueKeyAccountKey: roleKey,
  1930  		}
  1931  
  1932  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  1933  		assert.Equal(t, nil, err)
  1934  
  1935  		err = tx.SignWithKeys(signer, roleBased.Keys)
  1936  		assert.Equal(t, nil, err)
  1937  
  1938  		txs = append(txs, tx)
  1939  
  1940  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  1941  			t.Fatal(err)
  1942  		}
  1943  		roleBased.Nonce += 1
  1944  	}
  1945  
  1946  	// make TxPool to test validation in 'TxPool add' process
  1947  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
  1948  
  1949  	// test fee delegation txs for each role of role-based key.
  1950  	// only RoleFeePayer type can generate valid signature as a fee payer.
  1951  	for keyType, key := range prvKeys {
  1952  		for _, txType := range txTypes {
  1953  			valueMap, _ := genMapForTxTypes(roleBased, reservoir, txType)
  1954  			valueMap[types.TxValueKeyGasLimit] = uint64(1000000)
  1955  
  1956  			if txType.IsFeeDelegatedTransaction() {
  1957  				valueMap[types.TxValueKeyFeePayer] = reservoir.Addr
  1958  			}
  1959  
  1960  			// Currently, test VM is not working properly when the GasPrice is not 0.
  1961  			basicType := toBasicType(txType)
  1962  			if keyType == int(accountkey.RoleTransaction) {
  1963  				if basicType == types.TxTypeSmartContractDeploy || basicType == types.TxTypeSmartContractExecution {
  1964  					valueMap[types.TxValueKeyGasPrice] = new(big.Int).SetUint64(0)
  1965  				}
  1966  			}
  1967  
  1968  			if basicType == types.TxTypeSmartContractExecution {
  1969  				valueMap[types.TxValueKeyTo] = contractAddr
  1970  			}
  1971  
  1972  			tx, err := types.NewTransactionWithMap(txType, valueMap)
  1973  			assert.Equal(t, nil, err)
  1974  
  1975  			err = tx.SignWithKeys(signer, []*ecdsa.PrivateKey{key})
  1976  			assert.Equal(t, nil, err)
  1977  
  1978  			if txType.IsFeeDelegatedTransaction() {
  1979  				err = tx.SignFeePayerWithKeys(signer, reservoir.Keys)
  1980  				assert.Equal(t, nil, err)
  1981  			}
  1982  
  1983  			// Only RoleTransaction can generate valid signature as a sender except account update txs.
  1984  			// RoleAccountUpdate can generate valid signature for account update txs.
  1985  			if keyType == int(accountkey.RoleAccountUpdate) && txType.IsAccountUpdate() ||
  1986  				keyType == int(accountkey.RoleTransaction) && !txType.IsAccountUpdate() {
  1987  				// Do not make a block since account update tx can change sender's keys.
  1988  				receipt, err := applyTransaction(t, bcdata, tx)
  1989  				assert.Equal(t, nil, err)
  1990  				assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
  1991  			} else {
  1992  				// For tx pool validation test
  1993  				{
  1994  					err = txpool.AddRemote(tx)
  1995  					assert.Equal(t, types.ErrSender(types.ErrInvalidAccountKey), err)
  1996  				}
  1997  
  1998  				// For block tx validation test
  1999  				{
  2000  					receipt, err := applyTransaction(t, bcdata, tx)
  2001  					assert.Equal(t, types.ErrSender(types.ErrInvalidAccountKey), err)
  2002  					assert.Equal(t, (*types.Receipt)(nil), receipt)
  2003  				}
  2004  			}
  2005  		}
  2006  	}
  2007  
  2008  	if testing.Verbose() {
  2009  		prof.PrintProfileInfo()
  2010  	}
  2011  }
  2012  
  2013  // TestRoleBasedKeyFeeDelegation tests fee delegation with a role-based key.
  2014  // A role-based key contains three types of sub-keys: RoleTransaction, RoleAccountUpdate, RoleFeePayer.
  2015  // Only RoleFeePayer can sign txs as a fee payer.
  2016  func TestRoleBasedKeyFeeDelegation(t *testing.T) {
  2017  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  2018  	prof := profile.NewProfiler()
  2019  
  2020  	// Initialize blockchain
  2021  	start := time.Now()
  2022  	bcdata, err := NewBCData(6, 4)
  2023  	if err != nil {
  2024  		t.Fatal(err)
  2025  	}
  2026  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
  2027  	defer bcdata.Shutdown()
  2028  
  2029  	gasPrice := new(big.Int).SetUint64(25 * params.Ston)
  2030  
  2031  	// Initialize address-balance map for verification
  2032  	start = time.Now()
  2033  	accountMap := NewAccountMap()
  2034  	if err := accountMap.Initialize(bcdata); err != nil {
  2035  		t.Fatal(err)
  2036  	}
  2037  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
  2038  
  2039  	// reservoir account
  2040  	reservoir := &TestAccountType{
  2041  		Addr:  *bcdata.addrs[0],
  2042  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
  2043  		Nonce: uint64(0),
  2044  	}
  2045  
  2046  	// main account with a role-based key
  2047  	roleBased, err := createAnonymousAccount("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab")
  2048  	assert.Equal(t, nil, err)
  2049  
  2050  	// smart contract account
  2051  	contractAddr := common.Address{}
  2052  
  2053  	// generate a role-based key
  2054  	prvKeys := genTestKeys(3)
  2055  	roleKey := accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{
  2056  		accountkey.NewAccountKeyPublicWithValue(&prvKeys[0].PublicKey),
  2057  		accountkey.NewAccountKeyPublicWithValue(&prvKeys[1].PublicKey),
  2058  		accountkey.NewAccountKeyPublicWithValue(&prvKeys[2].PublicKey),
  2059  	})
  2060  
  2061  	if testing.Verbose() {
  2062  		fmt.Println("reservoirAddr = ", reservoir.Addr.String())
  2063  		fmt.Println("roleBasedAddr = ", roleBased.Addr.String())
  2064  	}
  2065  
  2066  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  2067  
  2068  	feeTxTypes := []types.TxType{
  2069  		types.TxTypeFeeDelegatedValueTransfer,
  2070  		types.TxTypeFeeDelegatedValueTransferMemo,
  2071  		types.TxTypeFeeDelegatedSmartContractDeploy,
  2072  		types.TxTypeFeeDelegatedSmartContractExecution,
  2073  		types.TxTypeFeeDelegatedAccountUpdate,
  2074  		types.TxTypeFeeDelegatedCancel,
  2075  
  2076  		types.TxTypeFeeDelegatedValueTransferWithRatio,
  2077  		types.TxTypeFeeDelegatedValueTransferMemoWithRatio,
  2078  		types.TxTypeFeeDelegatedSmartContractDeployWithRatio,
  2079  		types.TxTypeFeeDelegatedSmartContractExecutionWithRatio,
  2080  		types.TxTypeFeeDelegatedAccountUpdateWithRatio,
  2081  		types.TxTypeFeeDelegatedCancelWithRatio,
  2082  	}
  2083  
  2084  	// deploy a contract to test smart contract execution.
  2085  	{
  2086  		var txs types.Transactions
  2087  		valueMap, _ := genMapForTxTypes(reservoir, reservoir, types.TxTypeSmartContractDeploy)
  2088  		valueMap[types.TxValueKeyTo] = (*common.Address)(nil)
  2089  
  2090  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, valueMap)
  2091  		assert.Equal(t, nil, err)
  2092  
  2093  		err = tx.SignWithKeys(signer, reservoir.Keys)
  2094  		assert.Equal(t, nil, err)
  2095  
  2096  		txs = append(txs, tx)
  2097  
  2098  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  2099  			t.Fatal(err)
  2100  		}
  2101  
  2102  		contractAddr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
  2103  
  2104  		reservoir.Nonce += 1
  2105  	}
  2106  
  2107  	// transfer (reservoir -> roleBased) using a legacy transaction.
  2108  	{
  2109  		var txs types.Transactions
  2110  
  2111  		amount := new(big.Int).Mul(big.NewInt(3000), new(big.Int).SetUint64(params.KLAY))
  2112  		tx := types.NewTransaction(reservoir.Nonce,
  2113  			roleBased.Addr, amount, gasLimit, gasPrice, []byte{})
  2114  
  2115  		err := tx.SignWithKeys(signer, reservoir.Keys)
  2116  		assert.Equal(t, nil, err)
  2117  		txs = append(txs, tx)
  2118  
  2119  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  2120  			t.Fatal(err)
  2121  		}
  2122  		reservoir.Nonce += 1
  2123  	}
  2124  
  2125  	// update to an roleBased account with a role-based key.
  2126  	{
  2127  		var txs types.Transactions
  2128  
  2129  		values := map[types.TxValueKeyType]interface{}{
  2130  			types.TxValueKeyNonce:      roleBased.Nonce,
  2131  			types.TxValueKeyFrom:       roleBased.Addr,
  2132  			types.TxValueKeyGasLimit:   gasLimit,
  2133  			types.TxValueKeyGasPrice:   gasPrice,
  2134  			types.TxValueKeyAccountKey: roleKey,
  2135  		}
  2136  
  2137  		tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values)
  2138  		assert.Equal(t, nil, err)
  2139  
  2140  		err = tx.SignWithKeys(signer, roleBased.Keys)
  2141  		assert.Equal(t, nil, err)
  2142  
  2143  		txs = append(txs, tx)
  2144  
  2145  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  2146  			t.Fatal(err)
  2147  		}
  2148  		roleBased.Nonce += 1
  2149  	}
  2150  
  2151  	// make TxPool to test validation in 'TxPool add' process
  2152  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
  2153  
  2154  	// test fee delegation txs for each role of role-based key.
  2155  	// only RoleFeePayer type can generate valid signature as a fee payer.
  2156  	for keyType, key := range prvKeys {
  2157  		for _, txType := range feeTxTypes {
  2158  			valueMap, _ := genMapForTxTypes(reservoir, reservoir, txType)
  2159  			valueMap[types.TxValueKeyFeePayer] = roleBased.GetAddr()
  2160  			valueMap[types.TxValueKeyGasLimit] = uint64(1000000)
  2161  
  2162  			// Currently, test VM is not working properly when the GasPrice is not 0.
  2163  			basicType := toBasicType(txType)
  2164  			if keyType == int(accountkey.RoleFeePayer) {
  2165  				if basicType == types.TxTypeSmartContractDeploy || basicType == types.TxTypeSmartContractExecution {
  2166  					valueMap[types.TxValueKeyGasPrice] = new(big.Int).SetUint64(0)
  2167  				}
  2168  			}
  2169  
  2170  			if basicType == types.TxTypeSmartContractExecution {
  2171  				valueMap[types.TxValueKeyTo] = contractAddr
  2172  			}
  2173  
  2174  			tx, err := types.NewTransactionWithMap(txType, valueMap)
  2175  			assert.Equal(t, nil, err)
  2176  
  2177  			err = tx.SignWithKeys(signer, reservoir.Keys)
  2178  			assert.Equal(t, nil, err)
  2179  
  2180  			err = tx.SignFeePayerWithKeys(signer, []*ecdsa.PrivateKey{key})
  2181  			assert.Equal(t, nil, err)
  2182  
  2183  			if keyType == int(accountkey.RoleFeePayer) {
  2184  				// Do not make a block since account update tx can change sender's keys.
  2185  				receipt, err := applyTransaction(t, bcdata, tx)
  2186  				assert.Equal(t, nil, err)
  2187  				assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
  2188  			} else {
  2189  				// For tx pool validation test
  2190  				{
  2191  					err = txpool.AddRemote(tx)
  2192  					assert.Equal(t, types.ErrFeePayer(types.ErrInvalidAccountKey), err)
  2193  				}
  2194  
  2195  				// For block tx validation test
  2196  				{
  2197  					receipt, err := applyTransaction(t, bcdata, tx)
  2198  					assert.Equal(t, types.ErrFeePayer(types.ErrInvalidAccountKey), err)
  2199  					assert.Equal(t, (*types.Receipt)(nil), receipt)
  2200  				}
  2201  			}
  2202  		}
  2203  	}
  2204  
  2205  	if testing.Verbose() {
  2206  		prof.PrintProfileInfo()
  2207  	}
  2208  }
  2209  
  2210  func TestAccountKeyUpdateLegacyToPublic(t *testing.T) {
  2211  	gasPrice := new(big.Int).SetUint64(25 * params.Ston)
  2212  	gasLimit := uint64(1000000)
  2213  
  2214  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
  2215  	prof := profile.NewProfiler()
  2216  
  2217  	// Initialize blockchain
  2218  	start := time.Now()
  2219  	bcdata, err := NewBCData(6, 4)
  2220  	if err != nil {
  2221  		t.Fatal(err)
  2222  	}
  2223  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
  2224  	defer bcdata.Shutdown()
  2225  
  2226  	// Initialize address-balance map for verification
  2227  	start = time.Now()
  2228  	accountMap := NewAccountMap()
  2229  	if err := accountMap.Initialize(bcdata); err != nil {
  2230  		t.Fatal(err)
  2231  	}
  2232  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
  2233  
  2234  	var txs types.Transactions
  2235  
  2236  	// make TxPool to test validation in 'TxPool add' process
  2237  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
  2238  
  2239  	{
  2240  		addr := *bcdata.addrs[1]
  2241  		feepayer := *bcdata.addrs[0]
  2242  		acckey := accountkey.NewAccountKeyWeightedMultiSigWithValues(1,
  2243  			accountkey.WeightedPublicKeys{
  2244  				accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&bcdata.privKeys[1].PublicKey)),
  2245  				accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&bcdata.privKeys[2].PublicKey)),
  2246  			})
  2247  
  2248  		values := map[types.TxValueKeyType]interface{}{
  2249  			types.TxValueKeyNonce:      uint64(0),
  2250  			types.TxValueKeyFrom:       addr,
  2251  			types.TxValueKeyGasLimit:   gasLimit,
  2252  			types.TxValueKeyGasPrice:   gasPrice,
  2253  			types.TxValueKeyAccountKey: acckey,
  2254  			types.TxValueKeyFeePayer:   feepayer,
  2255  		}
  2256  		tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedAccountUpdate, values)
  2257  		assert.Equal(t, nil, err)
  2258  
  2259  		err = tx.SignWithKeys(signer, []*ecdsa.PrivateKey{bcdata.privKeys[1]})
  2260  		assert.Equal(t, nil, err)
  2261  
  2262  		err = tx.SignFeePayerWithKeys(signer, []*ecdsa.PrivateKey{bcdata.privKeys[0]})
  2263  		assert.Equal(t, nil, err)
  2264  
  2265  		txs = append(txs, tx)
  2266  	}
  2267  	{
  2268  		addr := *bcdata.addrs[1]
  2269  		feepayer := *bcdata.addrs[0]
  2270  		acckey := accountkey.NewAccountKeyWeightedMultiSigWithValues(1,
  2271  			accountkey.WeightedPublicKeys{
  2272  				accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&bcdata.privKeys[1].PublicKey)),
  2273  				accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&bcdata.privKeys[3].PublicKey)),
  2274  			})
  2275  
  2276  		values := map[types.TxValueKeyType]interface{}{
  2277  			types.TxValueKeyNonce:      uint64(1),
  2278  			types.TxValueKeyFrom:       addr,
  2279  			types.TxValueKeyGasLimit:   gasLimit,
  2280  			types.TxValueKeyGasPrice:   gasPrice,
  2281  			types.TxValueKeyAccountKey: acckey,
  2282  			types.TxValueKeyFeePayer:   feepayer,
  2283  		}
  2284  		tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedAccountUpdate, values)
  2285  		assert.Equal(t, nil, err)
  2286  
  2287  		err = tx.SignWithKeys(signer, []*ecdsa.PrivateKey{bcdata.privKeys[1]})
  2288  		assert.Equal(t, nil, err)
  2289  
  2290  		err = tx.SignFeePayerWithKeys(signer, []*ecdsa.PrivateKey{bcdata.privKeys[0]})
  2291  		assert.Equal(t, nil, err)
  2292  
  2293  		txs = append(txs, tx)
  2294  	}
  2295  	if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
  2296  		t.Fatal(err)
  2297  	}
  2298  
  2299  	// select account key types to be tested
  2300  	if testing.Verbose() {
  2301  		prof.PrintProfileInfo()
  2302  	}
  2303  }