github.com/klaytn/klaytn@v1.12.1/tests/apply_tx_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/big" 23 "os" 24 "reflect" 25 "runtime" 26 "runtime/pprof" 27 "strings" 28 "testing" 29 "time" 30 31 "github.com/klaytn/klaytn/blockchain/types" 32 "github.com/klaytn/klaytn/blockchain/types/accountkey" 33 "github.com/klaytn/klaytn/blockchain/vm" 34 "github.com/klaytn/klaytn/common" 35 "github.com/klaytn/klaytn/common/profile" 36 "github.com/klaytn/klaytn/crypto" 37 "github.com/klaytn/klaytn/log" 38 "github.com/klaytn/klaytn/params" 39 "github.com/stretchr/testify/assert" 40 ) 41 42 var benchName string 43 44 type genTx func(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction 45 46 // BenchmarkTxPerformanceCompatible compares performance between a legacy transaction and new transaction types. 47 // It compares the following: 48 // - legacy value transfer vs. new value transfer 49 // - legacy smart contract deploy vs. new smart contract deploy 50 func BenchmarkTxPerformanceCompatible(b *testing.B) { 51 testfns := []genTx{ 52 genLegacyValueTransfer, 53 genNewValueTransfer, 54 genLegacySmartContractDeploy, 55 genNewSmartContractDeploy, 56 } 57 58 for _, fn := range testfns { 59 fnname := getFunctionName(fn) 60 fnname = fnname[strings.LastIndex(fnname, ".")+1:] 61 if strings.Contains(fnname, "New") { 62 benchName = "New/" + strings.Split(fnname, "New")[1] 63 } else { 64 benchName = "Legacy/" + strings.Split(fnname, "Legacy")[1] 65 } 66 b.Run(benchName, func(b *testing.B) { 67 benchmarkTxPerformanceCompatible(b, fn) 68 }) 69 } 70 } 71 72 // BenchmarkTxPerformanceSmartContractExecution compares performance between a legacy transaction and new transaction types. 73 // This needs one more step "deploying a smart contract" compared to BenchmarkTxPerformanceCompatible. 74 // It compares the following: 75 // - legacy smart contract execution vs. new smart contract execution. 76 func BenchmarkTxPerformanceSmartContractExecution(b *testing.B) { 77 testfns := []genTx{ 78 genLegacySmartContractExecution, 79 genNewSmartContractExecution, 80 } 81 82 for _, fn := range testfns { 83 fnname := getFunctionName(fn) 84 fnname = fnname[strings.LastIndex(fnname, ".")+1:] 85 if strings.Contains(fnname, "New") { 86 benchName = "New/" + strings.Split(fnname, "New")[1] 87 } else { 88 benchName = "Legacy/" + strings.Split(fnname, "Legacy")[1] 89 } 90 b.Run(benchName, func(b *testing.B) { 91 benchmarkTxPerformanceSmartContractExecution(b, fn) 92 }) 93 } 94 } 95 96 // BenchmarkTxPerformanceNew measures performance of newly introduced transaction types. 97 // This requires one more step "account creation of a Klaytn account" compared to BenchmarkTxPerformanceCompatible. 98 func BenchmarkTxPerformanceNew(b *testing.B) { 99 testfns := []genTx{ 100 genNewAccountUpdateMultisig3, 101 genNewAccountUpdateRoleBasedSingle, 102 genNewAccountUpdateRoleBasedMultisig3, 103 genNewAccountUpdateAccountKeyPublic, 104 genNewFeeDelegatedValueTransfer, 105 genNewFeeDelegatedValueTransferWithRatio, 106 genNewCancel, 107 } 108 109 // sender account 110 sender, err := createDecoupledAccount("c64f2cd1196e2a1791365b00c4bc07ab8f047b73152e4617c6ed06ac221a4b0c", 111 common.HexToAddress("0x75c3098be5e4b63fbac05838daaee378dd48098d")) 112 assert.Equal(b, nil, err) 113 114 for _, fn := range testfns { 115 fnname := getFunctionName(fn) 116 fnname = fnname[strings.LastIndex(fnname, ".")+1:] 117 if strings.Contains(fnname, "New") { 118 benchName = "New/" + strings.Split(fnname, "New")[1] 119 } else { 120 benchName = "Legacy/" + strings.Split(fnname, "Legacy")[1] 121 } 122 b.Run(benchName, func(b *testing.B) { 123 sender.Nonce = 0 124 benchmarkTxPerformanceNew(b, fn, sender) 125 }) 126 } 127 } 128 129 func BenchmarkTxPerformanceNewMultisig(b *testing.B) { 130 testfns := []genTx{ 131 genNewAccountUpdateMultisig3, 132 genNewAccountUpdateRoleBasedSingle, 133 genNewAccountUpdateRoleBasedMultisig3, 134 genNewAccountUpdateAccountKeyPublic, 135 genNewFeeDelegatedValueTransfer, 136 genNewFeeDelegatedValueTransferWithRatio, 137 genNewCancel, 138 } 139 140 // sender account 141 sender, err := createMultisigAccount(uint(2), 142 []uint{1, 1, 1}, 143 []string{ 144 "bb113e82881499a7a361e8354a5b68f6c6885c7bcba09ea2b0891480396c322e", 145 "a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989", 146 "c32c471b732e2f56103e2f8e8cfd52792ef548f05f326e546a7d1fbf9d0419ec", 147 }, 148 common.HexToAddress("0xbbfa38050bf3167c887c086758f448ce067ea8ea")) 149 assert.Equal(b, nil, err) 150 151 for _, fn := range testfns { 152 fnname := getFunctionName(fn) 153 fnname = fnname[strings.LastIndex(fnname, ".")+1:] 154 if strings.Contains(fnname, "New") { 155 benchName = "New/" + strings.Split(fnname, "New")[1] 156 } else { 157 benchName = "Legacy/" + strings.Split(fnname, "Legacy")[1] 158 } 159 b.Run(benchName, func(b *testing.B) { 160 sender.Nonce = 0 161 benchmarkTxPerformanceNew(b, fn, sender) 162 }) 163 } 164 } 165 166 func BenchmarkTxPerformanceNewRoleBasedSingle(b *testing.B) { 167 testfns := []genTx{ 168 genNewAccountUpdateMultisig3, 169 genNewAccountUpdateRoleBasedSingle, 170 genNewAccountUpdateRoleBasedMultisig3, 171 genNewAccountUpdateAccountKeyPublic, 172 genNewFeeDelegatedValueTransfer, 173 genNewFeeDelegatedValueTransferWithRatio, 174 genNewCancel, 175 } 176 177 // sender account 178 k1, err := crypto.HexToECDSA("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab") 179 if err != nil { 180 panic(err) 181 } 182 pubkey := accountkey.NewAccountKeyPublicWithValue(&k1.PublicKey) 183 sender := &TestAccountType{ 184 Addr: common.HexToAddress("0x75c3098be5e4b63fbac05838daaee378dd48098d"), 185 Keys: []*ecdsa.PrivateKey{k1}, 186 Nonce: uint64(0), 187 AccKey: accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{pubkey, pubkey, pubkey}), 188 } 189 190 for _, fn := range testfns { 191 fnname := getFunctionName(fn) 192 fnname = fnname[strings.LastIndex(fnname, ".")+1:] 193 if strings.Contains(fnname, "New") { 194 benchName = "New/" + strings.Split(fnname, "New")[1] 195 } else { 196 benchName = "Legacy/" + strings.Split(fnname, "Legacy")[1] 197 } 198 b.Run(benchName, func(b *testing.B) { 199 sender.Nonce = 0 200 benchmarkTxPerformanceNew(b, fn, sender) 201 }) 202 } 203 } 204 205 func BenchmarkTxPerformanceNewRoleBasedMultisig3(b *testing.B) { 206 testfns := []genTx{ 207 genNewAccountUpdateMultisig3, 208 genNewAccountUpdateRoleBasedSingle, 209 genNewAccountUpdateRoleBasedMultisig3, 210 genNewAccountUpdateAccountKeyPublic, 211 genNewFeeDelegatedValueTransfer, 212 genNewFeeDelegatedValueTransferWithRatio, 213 genNewCancel, 214 } 215 216 // sender account 217 k1, err := crypto.HexToECDSA("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab") 218 if err != nil { 219 panic(err) 220 } 221 k2, err := crypto.HexToECDSA("c64f2cd1196e2a1791365b00c4bc07ab8f047b73152e4617c6ed06ac221a4b0c") 222 if err != nil { 223 panic(err) 224 } 225 k3, err := crypto.HexToECDSA("ed580f5bd71a2ee4dae5cb43e331b7d0318596e561e6add7844271ed94156b20") 226 if err != nil { 227 panic(err) 228 } 229 230 keys := accountkey.WeightedPublicKeys{ 231 accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&k1.PublicKey)), 232 accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&k2.PublicKey)), 233 accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&k3.PublicKey)), 234 } 235 threshold := uint(2) 236 pubkey := accountkey.NewAccountKeyWeightedMultiSigWithValues(threshold, keys) 237 sender := &TestAccountType{ 238 Addr: common.HexToAddress("0x75c3098be5e4b63fbac05838daaee378dd48098d"), 239 Keys: []*ecdsa.PrivateKey{k1, k2, k3}, 240 Nonce: uint64(0), 241 AccKey: accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{pubkey, pubkey, pubkey}), 242 } 243 244 for _, fn := range testfns { 245 fnname := getFunctionName(fn) 246 fnname = fnname[strings.LastIndex(fnname, ".")+1:] 247 if strings.Contains(fnname, "New") { 248 benchName = "New/" + strings.Split(fnname, "New")[1] 249 } else { 250 benchName = "Legacy/" + strings.Split(fnname, "Legacy")[1] 251 } 252 b.Run(benchName, func(b *testing.B) { 253 sender.Nonce = 0 254 benchmarkTxPerformanceNew(b, fn, sender) 255 }) 256 } 257 } 258 259 func benchmarkTxPerformanceCompatible(b *testing.B, genTx genTx) { 260 log.EnableLogForTest(log.LvlCrit, log.LvlTrace) 261 262 // Initialize blockchain 263 bcdata, err := NewBCData(6, 4) 264 if err != nil { 265 b.Fatal(err) 266 } 267 defer bcdata.Shutdown() 268 269 // Initialize address-balance map for verification 270 accountMap := NewAccountMap() 271 if err := accountMap.Initialize(bcdata); err != nil { 272 b.Fatal(err) 273 } 274 275 // reservoir account 276 reservoir := &TestAccountType{ 277 Addr: *bcdata.addrs[0], 278 Keys: []*ecdsa.PrivateKey{bcdata.privKeys[0]}, 279 Nonce: uint64(0), 280 } 281 282 // anonymous account 283 anon, err := createAnonymousAccount("ed580f5bd71a2ee4dae5cb43e331b7d0318596e561e6add7844271ed94156b20") 284 assert.Equal(b, nil, err) 285 286 if testing.Verbose() { 287 fmt.Println("reservoirAddr = ", reservoir.Addr.String()) 288 fmt.Println("anonAddr = ", anon.Addr.String()) 289 } 290 291 signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID) 292 293 // Prepare a next block header. 294 author := bcdata.addrs[0] 295 vmConfig := &vm.Config{ 296 JumpTable: vm.ConstantinopleInstructionSet, 297 } 298 parent := bcdata.bc.CurrentBlock() 299 num := parent.Number() 300 header := &types.Header{ 301 ParentHash: parent.Hash(), 302 Number: num.Add(num, common.Big1), 303 Extra: parent.Extra(), 304 Time: new(big.Int).Add(parent.Time(), common.Big1), 305 } 306 if err := bcdata.engine.Prepare(bcdata.bc, header); err != nil { 307 b.Fatal(err) 308 } 309 310 state, err := bcdata.bc.State() 311 assert.Equal(b, nil, err) 312 313 txs := make([]*types.Transaction, b.N) 314 315 // Generate transactions. 316 for i := 0; i < b.N; i++ { 317 tx := genTx(signer, reservoir, anon) 318 319 txs[i] = tx 320 321 reservoir.Nonce += 1 322 323 // execute this to cache ecrecover. 324 tx.AsMessageWithAccountKeyPicker(signer, state, header.Number.Uint64()) 325 } 326 327 if isProfileEnabled() { 328 fname := strings.Replace(benchName, "/", ".", -1) 329 f, err := os.Create(fname + ".cpu.out") 330 if err != nil { 331 panic(err) 332 } 333 pprof.StartCPUProfile(f) 334 defer pprof.StopCPUProfile() 335 } 336 b.ResetTimer() 337 // Execute ApplyTransaction to measure performance of the given transaction type. 338 for i := 0; i < b.N; i++ { 339 usedGas := uint64(0) 340 _, _, err = bcdata.bc.ApplyTransaction(bcdata.bc.Config(), author, state, header, txs[i], &usedGas, vmConfig) 341 assert.Equal(b, nil, err) 342 } 343 b.StopTimer() 344 } 345 346 func benchmarkTxPerformanceSmartContractExecution(b *testing.B, genTx genTx) { 347 log.EnableLogForTest(log.LvlCrit, log.LvlTrace) 348 prof := profile.NewProfiler() 349 350 // Initialize blockchain 351 start := time.Now() 352 bcdata, err := NewBCData(6, 4) 353 if err != nil { 354 b.Fatal(err) 355 } 356 prof.Profile("main_init_blockchain", time.Now().Sub(start)) 357 defer bcdata.Shutdown() 358 359 // Initialize address-balance map for verification 360 start = time.Now() 361 accountMap := NewAccountMap() 362 if err := accountMap.Initialize(bcdata); err != nil { 363 b.Fatal(err) 364 } 365 prof.Profile("main_init_accountMap", time.Now().Sub(start)) 366 367 // reservoir account 368 reservoir := &TestAccountType{ 369 Addr: *bcdata.addrs[0], 370 Keys: []*ecdsa.PrivateKey{bcdata.privKeys[0]}, 371 Nonce: uint64(0), 372 } 373 374 if testing.Verbose() { 375 fmt.Println("reservoirAddr = ", reservoir.Addr.String()) 376 } 377 378 contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989") 379 contract.Addr = common.Address{} 380 381 gasPrice := new(big.Int).SetUint64(0) 382 gasLimit := uint64(100000000000) 383 384 signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID) 385 386 // Deploy smart contract (reservoir -> contract) 387 { 388 var txs types.Transactions 389 390 code := "0x608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029" 391 amount := new(big.Int).SetUint64(0) 392 393 values := map[types.TxValueKeyType]interface{}{ 394 types.TxValueKeyNonce: reservoir.Nonce, 395 types.TxValueKeyFrom: reservoir.Addr, 396 types.TxValueKeyTo: (*common.Address)(nil), 397 types.TxValueKeyAmount: amount, 398 types.TxValueKeyGasLimit: gasLimit, 399 types.TxValueKeyGasPrice: gasPrice, 400 types.TxValueKeyHumanReadable: false, 401 types.TxValueKeyData: common.FromHex(code), 402 } 403 tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values) 404 assert.Equal(b, nil, err) 405 406 err = tx.SignWithKeys(signer, reservoir.Keys) 407 assert.Equal(b, nil, err) 408 409 txs = append(txs, tx) 410 411 if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil { 412 b.Fatal(err) 413 } 414 415 contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce) 416 417 reservoir.Nonce += 1 418 } 419 420 // Prepare a next block header. 421 author := bcdata.addrs[0] 422 vmConfig := &vm.Config{ 423 JumpTable: vm.ConstantinopleInstructionSet, 424 } 425 parent := bcdata.bc.CurrentBlock() 426 num := parent.Number() 427 header := &types.Header{ 428 ParentHash: parent.Hash(), 429 Number: num.Add(num, common.Big1), 430 Extra: parent.Extra(), 431 Time: new(big.Int).Add(parent.Time(), common.Big1), 432 } 433 if err := bcdata.engine.Prepare(bcdata.bc, header); err != nil { 434 b.Fatal(err) 435 } 436 437 state, err := bcdata.bc.State() 438 assert.Equal(b, nil, err) 439 440 txs := make([]*types.Transaction, b.N) 441 442 // Generate transactions. 443 for i := 0; i < b.N; i++ { 444 tx := genTx(signer, reservoir, contract) 445 446 txs[i] = tx 447 448 reservoir.Nonce += 1 449 450 tx.AsMessageWithAccountKeyPicker(signer, state, header.Number.Uint64()) 451 } 452 453 if isProfileEnabled() { 454 fname := strings.Replace(benchName, "/", ".", -1) 455 f, err := os.Create(fname + ".cpu.out") 456 if err != nil { 457 panic(err) 458 } 459 pprof.StartCPUProfile(f) 460 defer pprof.StopCPUProfile() 461 } 462 b.ResetTimer() 463 // Execute ApplyTransaction to measure performance of the given transaction type. 464 for i := 0; i < b.N; i++ { 465 usedGas := uint64(0) 466 _, _, err = bcdata.bc.ApplyTransaction(bcdata.bc.Config(), author, state, header, txs[i], &usedGas, vmConfig) 467 assert.Equal(b, nil, err) 468 } 469 b.StopTimer() 470 471 if testing.Verbose() { 472 prof.PrintProfileInfo() 473 } 474 } 475 476 func benchmarkTxPerformanceNew(b *testing.B, genTx genTx, sender *TestAccountType) { 477 log.EnableLogForTest(log.LvlCrit, log.LvlTrace) 478 prof := profile.NewProfiler() 479 480 // Initialize blockchain 481 bcdata, err := NewBCData(6, 4) 482 if err != nil { 483 b.Fatal(err) 484 } 485 defer bcdata.Shutdown() 486 487 // Initialize address-balance map for verification 488 accountMap := NewAccountMap() 489 if err := accountMap.Initialize(bcdata); err != nil { 490 b.Fatal(err) 491 } 492 493 // reservoir account 494 reservoir := &TestAccountType{ 495 Addr: *bcdata.addrs[0], 496 Keys: []*ecdsa.PrivateKey{bcdata.privKeys[0]}, 497 Nonce: uint64(0), 498 } 499 500 anon, err := createAnonymousAccount("ed580f5bd71a2ee4dae5cb43e331b7d0318596e561e6add7844271ed94156b20") 501 502 if testing.Verbose() { 503 fmt.Println("reservoirAddr = ", reservoir.Addr.String()) 504 fmt.Println("decoupledAddr = ", sender.Addr.String()) 505 fmt.Println("anonAddr = ", anon.Addr.String()) 506 } 507 508 signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID) 509 gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice) 510 511 // Create an account sender using TxTypeValueTransfer. 512 { 513 var txs types.Transactions 514 515 amount := new(big.Int).SetUint64(1000000000000) 516 values := map[types.TxValueKeyType]interface{}{ 517 types.TxValueKeyNonce: reservoir.Nonce, 518 types.TxValueKeyFrom: reservoir.Addr, 519 types.TxValueKeyTo: sender.Addr, 520 types.TxValueKeyAmount: amount, 521 types.TxValueKeyGasLimit: gasLimit, 522 types.TxValueKeyGasPrice: gasPrice, 523 } 524 tx, err := types.NewTransactionWithMap(types.TxTypeValueTransfer, values) 525 assert.Equal(b, nil, err) 526 527 err = tx.SignWithKeys(signer, reservoir.Keys) 528 assert.Equal(b, nil, err) 529 530 txs = append(txs, tx) 531 532 if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil { 533 b.Fatal(err) 534 } 535 reservoir.Nonce += 1 536 } 537 538 // Prepare a next block header. 539 author := bcdata.addrs[0] 540 vmConfig := &vm.Config{ 541 JumpTable: vm.ConstantinopleInstructionSet, 542 } 543 parent := bcdata.bc.CurrentBlock() 544 num := parent.Number() 545 header := &types.Header{ 546 ParentHash: parent.Hash(), 547 Number: num.Add(num, common.Big1), 548 Extra: parent.Extra(), 549 Time: new(big.Int).Add(parent.Time(), common.Big1), 550 } 551 if err := bcdata.engine.Prepare(bcdata.bc, header); err != nil { 552 b.Fatal(err) 553 } 554 555 state, err := bcdata.bc.State() 556 assert.Equal(b, nil, err) 557 558 txs := make([]*types.Transaction, b.N) 559 560 // Generate transactions. 561 for i := 0; i < b.N; i++ { 562 tx := genTx(signer, sender, anon) 563 564 txs[i] = tx 565 566 sender.Nonce += 1 567 568 tx.AsMessageWithAccountKeyPicker(signer, state, header.Number.Uint64()) 569 } 570 571 if isProfileEnabled() { 572 fname := strings.Replace(benchName, "/", ".", -1) 573 f, err := os.Create(fname + ".cpu.out") 574 if err != nil { 575 panic(err) 576 } 577 pprof.StartCPUProfile(f) 578 defer pprof.StopCPUProfile() 579 } 580 b.ResetTimer() 581 // Execute ApplyTransaction to measure performance of the given transaction type. 582 for i := 0; i < b.N; i++ { 583 usedGas := uint64(0) 584 _, _, err = bcdata.bc.ApplyTransaction(bcdata.bc.Config(), author, state, header, txs[i], &usedGas, vmConfig) 585 assert.Equal(b, nil, err) 586 } 587 b.StopTimer() 588 589 if testing.Verbose() { 590 prof.PrintProfileInfo() 591 } 592 } 593 594 func genLegacyValueTransfer(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 595 amount := big.NewInt(100) 596 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 597 tx := types.NewTransaction(from.Nonce, to.Addr, amount, gasLimit, gasPrice, []byte{}) 598 err := tx.SignWithKeys(signer, from.Keys) 599 if err != nil { 600 panic(err) 601 } 602 603 return tx 604 } 605 606 func genNewValueTransfer(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 607 amount := big.NewInt(100) 608 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 609 tx, err := types.NewTransactionWithMap(types.TxTypeValueTransfer, map[types.TxValueKeyType]interface{}{ 610 types.TxValueKeyNonce: from.Nonce, 611 types.TxValueKeyTo: to.Addr, 612 types.TxValueKeyAmount: amount, 613 types.TxValueKeyGasLimit: gasLimit, 614 types.TxValueKeyGasPrice: gasPrice, 615 types.TxValueKeyFrom: from.Addr, 616 }) 617 if err != nil { 618 panic(err) 619 } 620 621 err = tx.SignWithKeys(signer, from.Keys) 622 if err != nil { 623 panic(err) 624 } 625 626 return tx 627 } 628 629 func genLegacySmartContractDeploy(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 630 amount := big.NewInt(0) 631 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 632 data := common.Hex2Bytes("608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029") 633 tx := types.NewContractCreation(from.Nonce, amount, gasLimit, gasPrice, data) 634 err := tx.SignWithKeys(signer, from.Keys) 635 if err != nil { 636 panic(err) 637 } 638 639 return tx 640 } 641 642 func genNewSmartContractDeploy(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 643 amount := big.NewInt(0) 644 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 645 tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, map[types.TxValueKeyType]interface{}{ 646 types.TxValueKeyNonce: from.Nonce, 647 types.TxValueKeyAmount: amount, 648 types.TxValueKeyGasLimit: gasLimit, 649 types.TxValueKeyGasPrice: gasPrice, 650 types.TxValueKeyHumanReadable: false, 651 types.TxValueKeyTo: (*common.Address)(nil), 652 types.TxValueKeyCodeFormat: params.CodeFormatEVM, 653 types.TxValueKeyFrom: from.Addr, 654 // The binary below is a compiled binary of contracts/reward/contract/KlaytnReward.sol. 655 types.TxValueKeyData: common.Hex2Bytes("608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029"), 656 }) 657 if err != nil { 658 panic(err) 659 } 660 661 err = tx.SignWithKeys(signer, from.Keys) 662 if err != nil { 663 panic(err) 664 } 665 666 return tx 667 } 668 669 func genAccountKeyWeightedMultisig() (accountkey.AccountKey, []*ecdsa.PrivateKey) { 670 threshold := uint(2) 671 numKeys := 3 672 keys := make(accountkey.WeightedPublicKeys, numKeys) 673 prvKeys := make([]*ecdsa.PrivateKey, numKeys) 674 675 for i := 0; i < numKeys; i++ { 676 prvKeys[i], _ = crypto.GenerateKey() 677 keys[i] = accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&prvKeys[i].PublicKey)) 678 } 679 680 return accountkey.NewAccountKeyWeightedMultiSigWithValues(threshold, keys), prvKeys 681 } 682 683 func genNewAccountUpdateMultisig3(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 684 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 685 keys, prvKeys := genAccountKeyWeightedMultisig() 686 tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, map[types.TxValueKeyType]interface{}{ 687 types.TxValueKeyNonce: from.Nonce, 688 types.TxValueKeyGasLimit: gasLimit, 689 types.TxValueKeyGasPrice: gasPrice, 690 types.TxValueKeyFrom: from.Addr, 691 types.TxValueKeyHumanReadable: false, 692 types.TxValueKeyAccountKey: keys, 693 }) 694 if err != nil { 695 panic(err) 696 } 697 698 err = tx.SignWithKeys(signer, from.Keys) 699 if err != nil { 700 panic(err) 701 } 702 703 from.Keys = prvKeys 704 from.AccKey = keys 705 return tx 706 } 707 708 func genAccountKeyRoleBasedSingle() (accountkey.AccountKey, []*ecdsa.PrivateKey) { 709 k1, err := crypto.HexToECDSA("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab") 710 if err != nil { 711 panic(err) 712 } 713 txKey := accountkey.NewAccountKeyPublicWithValue(&k1.PublicKey) 714 715 return accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{txKey, txKey, txKey}), []*ecdsa.PrivateKey{k1} 716 } 717 718 func genNewAccountUpdateRoleBasedSingle(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 719 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 720 keys, prvKeys := genAccountKeyRoleBasedSingle() 721 tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, map[types.TxValueKeyType]interface{}{ 722 types.TxValueKeyNonce: from.Nonce, 723 types.TxValueKeyGasLimit: gasLimit, 724 types.TxValueKeyGasPrice: gasPrice, 725 types.TxValueKeyFrom: from.Addr, 726 types.TxValueKeyHumanReadable: false, 727 types.TxValueKeyAccountKey: keys, 728 }) 729 if err != nil { 730 panic(err) 731 } 732 733 err = tx.SignWithKeys(signer, from.Keys) 734 if err != nil { 735 panic(err) 736 } 737 738 from.Keys = prvKeys 739 from.AccKey = keys 740 return tx 741 } 742 743 func genAccountKeyRoleBasedMultisig3() (accountkey.AccountKey, []*ecdsa.PrivateKey) { 744 threshold := uint(2) 745 746 k1, err := crypto.HexToECDSA("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab") 747 if err != nil { 748 panic(err) 749 } 750 k2, err := crypto.HexToECDSA("c64f2cd1196e2a1791365b00c4bc07ab8f047b73152e4617c6ed06ac221a4b0c") 751 if err != nil { 752 panic(err) 753 } 754 k3, err := crypto.HexToECDSA("ed580f5bd71a2ee4dae5cb43e331b7d0318596e561e6add7844271ed94156b20") 755 if err != nil { 756 panic(err) 757 } 758 759 keys := accountkey.WeightedPublicKeys{ 760 accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&k1.PublicKey)), 761 accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&k2.PublicKey)), 762 accountkey.NewWeightedPublicKey(1, (*accountkey.PublicKeySerializable)(&k3.PublicKey)), 763 } 764 txKey := accountkey.NewAccountKeyWeightedMultiSigWithValues(threshold, keys) 765 766 return accountkey.NewAccountKeyRoleBasedWithValues(accountkey.AccountKeyRoleBased{txKey, txKey, txKey}), []*ecdsa.PrivateKey{k1, k2, k3} 767 } 768 769 func genNewAccountUpdateRoleBasedMultisig3(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 770 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 771 keys, prvKeys := genAccountKeyRoleBasedMultisig3() 772 tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, map[types.TxValueKeyType]interface{}{ 773 types.TxValueKeyNonce: from.Nonce, 774 types.TxValueKeyGasLimit: gasLimit, 775 types.TxValueKeyGasPrice: gasPrice, 776 types.TxValueKeyFrom: from.Addr, 777 types.TxValueKeyHumanReadable: false, 778 types.TxValueKeyAccountKey: keys, 779 }) 780 if err != nil { 781 panic(err) 782 } 783 784 err = tx.SignWithKeys(signer, from.Keys) 785 if err != nil { 786 panic(err) 787 } 788 789 from.Keys = prvKeys 790 from.AccKey = keys 791 return tx 792 } 793 794 func genNewFeeDelegatedValueTransfer(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 795 amount := big.NewInt(100) 796 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 797 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedValueTransfer, map[types.TxValueKeyType]interface{}{ 798 types.TxValueKeyNonce: from.Nonce, 799 types.TxValueKeyTo: to.Addr, 800 types.TxValueKeyAmount: amount, 801 types.TxValueKeyGasLimit: gasLimit, 802 types.TxValueKeyGasPrice: gasPrice, 803 types.TxValueKeyFrom: from.Addr, 804 types.TxValueKeyFeePayer: from.Addr, 805 }) 806 if err != nil { 807 panic(err) 808 } 809 810 err = tx.SignWithKeys(signer, from.Keys) 811 if err != nil { 812 panic(err) 813 } 814 815 err = tx.SignFeePayerWithKeys(signer, from.Keys) 816 if err != nil { 817 panic(err) 818 } 819 820 return tx 821 } 822 823 func genNewFeeDelegatedValueTransferWithRatio(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 824 amount := big.NewInt(100) 825 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 826 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedValueTransferWithRatio, map[types.TxValueKeyType]interface{}{ 827 types.TxValueKeyNonce: from.Nonce, 828 types.TxValueKeyTo: to.Addr, 829 types.TxValueKeyAmount: amount, 830 types.TxValueKeyGasLimit: gasLimit, 831 types.TxValueKeyGasPrice: gasPrice, 832 types.TxValueKeyFrom: from.Addr, 833 types.TxValueKeyFeePayer: from.Addr, 834 types.TxValueKeyFeeRatioOfFeePayer: types.FeeRatio(30), 835 }) 836 if err != nil { 837 panic(err) 838 } 839 840 err = tx.SignWithKeys(signer, from.Keys) 841 if err != nil { 842 panic(err) 843 } 844 845 err = tx.SignFeePayerWithKeys(signer, from.Keys) 846 if err != nil { 847 panic(err) 848 } 849 850 return tx 851 } 852 853 func genLegacySmartContractExecution(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 854 amount := big.NewInt(100) 855 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 856 data := common.Hex2Bytes("6353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2") 857 tx := types.NewTransaction(from.Nonce, to.Addr, amount, gasLimit, gasPrice, data) 858 err := tx.SignWithKeys(signer, from.Keys) 859 if err != nil { 860 panic(err) 861 } 862 863 return tx 864 } 865 866 func genNewSmartContractExecution(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 867 amount := big.NewInt(100) 868 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 869 tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractExecution, map[types.TxValueKeyType]interface{}{ 870 types.TxValueKeyNonce: from.Nonce, 871 types.TxValueKeyTo: to.Addr, 872 types.TxValueKeyAmount: amount, 873 types.TxValueKeyGasLimit: gasLimit, 874 types.TxValueKeyGasPrice: gasPrice, 875 types.TxValueKeyFrom: from.Addr, 876 // An abi-packed bytes calling "reward" of contracts/reward/contract/KlaytnReward.sol with an address "bc5951f055a85f41a3b62fd6f68ab7de76d299b2". 877 types.TxValueKeyData: common.Hex2Bytes("6353586b000000000000000000000000bc5951f055a85f41a3b62fd6f68ab7de76d299b2"), 878 }) 879 if err != nil { 880 panic(err) 881 } 882 883 err = tx.SignWithKeys(signer, from.Keys) 884 if err != nil { 885 panic(err) 886 } 887 888 return tx 889 } 890 891 func genNewAccountUpdateAccountKeyPublic(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 892 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 893 k, _ := crypto.GenerateKey() 894 tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, map[types.TxValueKeyType]interface{}{ 895 types.TxValueKeyNonce: from.Nonce, 896 types.TxValueKeyGasLimit: gasLimit, 897 types.TxValueKeyGasPrice: gasPrice, 898 types.TxValueKeyFrom: from.Addr, 899 types.TxValueKeyAccountKey: accountkey.NewAccountKeyPublicWithValue(&k.PublicKey), 900 }) 901 if err != nil { 902 panic(err) 903 } 904 905 err = tx.SignWithKeys(signer, from.Keys) 906 if err != nil { 907 panic(err) 908 } 909 910 from.Keys = []*ecdsa.PrivateKey{k} 911 from.AccKey = accountkey.NewAccountKeyPublicWithValue(&k.PublicKey) 912 913 return tx 914 } 915 916 func genNewCancel(signer types.Signer, from *TestAccountType, to *TestAccountType) *types.Transaction { 917 gasPrice := new(big.Int).SetUint64(25 * params.Ston) 918 tx, err := types.NewTransactionWithMap(types.TxTypeCancel, map[types.TxValueKeyType]interface{}{ 919 types.TxValueKeyNonce: from.Nonce, 920 types.TxValueKeyGasLimit: gasLimit, 921 types.TxValueKeyGasPrice: gasPrice, 922 types.TxValueKeyFrom: from.Addr, 923 }) 924 if err != nil { 925 panic(err) 926 } 927 928 err = tx.SignWithKeys(signer, from.Keys) 929 if err != nil { 930 panic(err) 931 } 932 933 return tx 934 } 935 936 func getFunctionName(i interface{}) string { 937 return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() 938 } 939 940 func isProfileEnabled() bool { 941 return os.Getenv("PROFILE") != "" 942 }