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 }