github.com/igggame/nebulas-go@v2.1.0+incompatible/nf/nvm/engine_inner_test.go (about) 1 package nvm 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "testing" 8 "time" 9 10 "github.com/nebulasio/go-nebulas/account" 11 "github.com/nebulasio/go-nebulas/consensus/dpos" 12 "github.com/nebulasio/go-nebulas/core" 13 "github.com/nebulasio/go-nebulas/crypto/keystore" 14 "github.com/nebulasio/go-nebulas/util" 15 "github.com/stretchr/testify/assert" 16 ) 17 18 type deployTx struct { 19 value int64 20 gasLimit int64 21 contract contract 22 } 23 24 type contract struct { 25 contractPath string 26 sourceType string 27 initArgs string 28 } 29 30 type call struct { 31 function string 32 args string 33 exceptArgs []string //[congractA,B,C, AccountA, B] 34 } 35 36 type SysEvent struct { 37 Hash string `json:"hash"` 38 Status int `json:"status"` 39 GasUsed string `json:"gas_used"` 40 Err string `json:"error"` 41 Result string `json:"execute_result"` 42 } 43 type InnerEvent struct { 44 From string `json:"from"` 45 To string `json:"to"` 46 Value int `json:"value"` 47 Error string `json:"error"` 48 } 49 50 func mockNeb(t *testing.T) core.Neblet { 51 am, err := account.NewManager(nil) 52 assert.Nil(t, err) 53 consensus := dpos.NewDpos() 54 nvm := NewNebulasVM() 55 neb := core.NewMockNeb(am, consensus, nvm) 56 return neb 57 } 58 59 func generateRandom(t *testing.T, neb core.Neblet, block *core.Block) { 60 ancestorHash, parentSeed, err := neb.BlockChain().GetInputForVRFSigner(block.ParentHash(), block.Height()) 61 assert.Nil(t, err) 62 63 proposer := block.WorldState().ConsensusRoot().Proposer 64 miner, err := core.AddressParseFromBytes(proposer) 65 assert.Nil(t, err) 66 67 // generate VRF hash,proof 68 vrfSeed, vrfProof, err := neb.AccountManager().GenerateRandomSeed(miner, ancestorHash, parentSeed) 69 assert.Nil(t, err) 70 block.SetRandomSeed(vrfSeed, vrfProof) 71 } 72 73 func unlockAccount(t *testing.T, neb core.Neblet) []*core.Address { 74 manager := neb.AccountManager() 75 dynasty := neb.Genesis().Consensus.Dpos.Dynasty 76 addrs := []*core.Address{} 77 for _, v := range dynasty { 78 addr, err := core.AddressParse(v) 79 assert.Nil(t, err) 80 assert.Nil(t, manager.Unlock(addr, []byte("passphrase"), keystore.YearUnlockDuration)) 81 addrs = append(addrs, addr) 82 } 83 //a, _ := core.AddressParse("n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE") 84 //assert.Nil(t, manager.Unlock(a, []byte("passphrase"), keystore.YearUnlockDuration)) 85 //b, _ := core.AddressParse("n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s") 86 //assert.Nil(t, manager.Unlock(b, []byte("passphrase"), keystore.YearUnlockDuration)) 87 //c, _ := core.AddressParse("n1H4MYms9F55ehcvygwWE71J8tJC4CRr2so") 88 //assert.Nil(t, manager.Unlock(c, []byte("passphrase"), keystore.YearUnlockDuration)) 89 //d, _ := core.AddressParse("n1JAy4X6KKLCNiTd7MWMRsVBjgdVq5WCCpf") 90 //assert.Nil(t, manager.Unlock(d, []byte("passphrase"), keystore.YearUnlockDuration)) 91 return addrs 92 } 93 94 func mintBlock(t *testing.T, neb core.Neblet, txs []*core.Transaction) { 95 mintBlockWithDuration(t, neb, txs, int64(1)) 96 } 97 98 func mintBlockWithDuration(t *testing.T, neb core.Neblet, txs []*core.Transaction, duration int64) { 99 tail := neb.BlockChain().TailBlock() 100 manager := neb.AccountManager() 101 elapsedSecond := dpos.BlockIntervalInMs / dpos.SecondInMs 102 consensusState, err := tail.WorldState().NextConsensusState(elapsedSecond) 103 assert.Nil(t, err) 104 105 coinbase, err := core.AddressParse(neb.Config().Chain.Coinbase) 106 assert.Nil(t, err) 107 block, err := core.NewBlock(neb.BlockChain().ChainID(), coinbase, tail) 108 assert.Nil(t, err) 109 block.WorldState().SetConsensusState(consensusState) 110 block.SetTimestamp(consensusState.TimeStamp()) 111 generateRandom(t, neb, block) 112 113 for _, tx := range txs { 114 assert.Nil(t, neb.BlockChain().TransactionPool().Push(tx)) 115 } 116 117 block.CollectTransactions((time.Now().Unix() + duration) * dpos.SecondInMs) 118 assert.Nil(t, block.Seal()) 119 err = manager.SignBlock(block.Miner(), block) 120 assert.Nil(t, err) 121 assert.Nil(t, neb.BlockChain().BlockPool().Push(block)) 122 assert.Equal(t, block.Hash(), neb.BlockChain().TailBlock().Hash()) 123 } 124 125 //block->a empty coinbase c . block->b deploy and accout is a and coinbase is c . block->c run js 126 func TestInnerTransactions(t *testing.T) { 127 tests := []struct { 128 name string 129 txs []deployTx 130 calls []call 131 }{ 132 { 133 "inner transaction", 134 []deployTx{{ 135 0, 200000, 136 contract{ 137 "./test/inner_call_tests/test_inner_transaction.js", 138 "js", 139 "", 140 }, 141 }, 142 { 143 0, 200000, 144 contract{ 145 "./test/inner_call_tests/bank_vault_inner_contract.js", 146 "js", 147 "", 148 }, 149 }, 150 { 151 0, 200000, 152 contract{ 153 "./test/inner_call_tests/bank_vault_final_contract.js", 154 "js", 155 "", 156 }, 157 }, 158 }, 159 []call{ 160 call{ 161 "save", 162 "[1]", 163 []string{"1", "3", "2", "4999999999999833225999994"}, 164 }, 165 }, 166 }, 167 } 168 169 core.NebCompatibility = core.NewCompatibilityLocal() 170 neb := mockNeb(t) 171 manager := neb.AccountManager() 172 173 addrs := unlockAccount(t, neb) 174 175 // mint height 2, inner contracts >= 3 176 mintBlock(t, neb, nil) 177 178 tt := tests[0] 179 for _, call := range tt.calls { 180 181 txs := []*core.Transaction{} 182 contracts := []*core.Address{} 183 for k, tx := range tt.txs { 184 data, err := ioutil.ReadFile(tx.contract.contractPath) 185 assert.Nil(t, err, "contract path read error") 186 source := string(data) 187 sourceType := "js" 188 argsDeploy := "" 189 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 190 payloadDeploy, _ := deploy.ToBytes() 191 192 value, _ := util.NewUint128FromInt(tx.value) 193 gasLimit, _ := util.NewUint128FromInt(tx.gasLimit) 194 from := addrs[0] 195 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 196 assert.Nil(t, err) 197 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 198 txs = append(txs, txDeploy) 199 200 contractAddr, err := txDeploy.GenerateContractAddress() 201 assert.Nil(t, err) 202 contracts = append(contracts, contractAddr) 203 } 204 //package contract txs 205 mintBlock(t, neb, txs) 206 207 for _, v := range contracts { 208 _, err := neb.BlockChain().TailBlock().CheckContract(v) 209 assert.Nil(t, err) 210 } 211 212 contractB := contracts[1] 213 contractC := contracts[2] 214 callPayload, _ := core.NewCallPayload(call.function, fmt.Sprintf("[\"%s\", \"%s\", 1]", contractB.String(), contractC.String())) 215 payloadCall, _ := callPayload.ToBytes() 216 value, _ := util.NewUint128FromInt(6) 217 gasLimit, _ := util.NewUint128FromInt(200000) 218 from := neb.BlockChain().TailBlock().Transactions()[0].From() 219 proxyContractAddress := contracts[0] 220 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 221 uint64(len(contracts)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 222 assert.Nil(t, err) 223 assert.Nil(t, manager.SignTransaction(txCall.From(), txCall)) 224 225 // package call tx 226 mintBlock(t, neb, []*core.Transaction{txCall}) 227 228 tail := neb.BlockChain().TailBlock() 229 events, err := tail.FetchEvents(txCall.Hash()) 230 assert.Nil(t, err) 231 for _, event := range events { 232 t.Logf("call tpoic: %s, data:%s", event.Topic, event.Data) 233 } 234 contractAddrA := contracts[0] 235 accountAAcc, err := tail.GetAccount(contractAddrA.Bytes()) 236 assert.Nil(t, err) 237 fmt.Printf("account :%v\n", accountAAcc) 238 assert.Equal(t, call.exceptArgs[0], accountAAcc.Balance().String()) 239 240 contractAddrB := contracts[1] 241 accountBAcc, err := tail.GetAccount(contractAddrB.Bytes()) 242 assert.Nil(t, err) 243 fmt.Printf("accountB :%v\n", accountBAcc) 244 assert.Equal(t, call.exceptArgs[1], accountBAcc.Balance().String()) 245 246 contractAddrC := contracts[2] 247 accountAccC, err := tail.GetAccount(contractAddrC.Bytes()) 248 assert.Nil(t, err) 249 fmt.Printf("accountC :%v\n", accountAccC) 250 assert.Equal(t, call.exceptArgs[2], accountAccC.Balance().String()) 251 252 aUser, err := tail.GetAccount(from.Bytes()) 253 assert.Equal(t, call.exceptArgs[3], aUser.Balance().String()) 254 fmt.Printf("from:%v\n", aUser) 255 256 } 257 } 258 259 func TestInnerTransactionsInMulitithCoroutine(t *testing.T) { 260 core.NebCompatibility = core.NewCompatibilityLocal() 261 core.PackedParallelNum = 2 262 tests := []struct { 263 name string 264 txs []deployTx 265 calls []call 266 paralleNum uint32 267 }{ 268 { 269 "inner transaction", 270 []deployTx{ 271 { 272 0, 200000, 273 contract{ 274 "./test/inner_call_tests/test_inner_transaction.js", 275 "js", 276 "", 277 }, 278 }, 279 { 280 0, 200000, 281 contract{ 282 "./test/inner_call_tests/bank_vault_inner_contract.js", 283 "js", 284 "", 285 }, 286 }, 287 { 288 0, 200000, 289 contract{ 290 "./test/inner_call_tests/bank_vault_final_contract.js", 291 "js", 292 "", 293 }, 294 }, 295 }, 296 []call{ 297 call{ 298 "save", 299 "[1]", 300 []string{"1", "3", "2", "4999999999999833224999994", "5000004280820166775000000"}, 301 }, 302 }, 303 4, 304 }, 305 } 306 neb := mockNeb(t) 307 manager := neb.AccountManager() 308 309 addrs := unlockAccount(t, neb) 310 311 // mint height 2, inner contracts >= 3 312 mintBlock(t, neb, nil) 313 314 tt := tests[0] 315 for _, call := range tt.calls { 316 317 txs := []*core.Transaction{} 318 var contractsAddr [][]string 319 // var nonce uint64 320 // t.Run(tt.name, func(t *testing.T) { 321 for i := uint32(0); i < tt.paralleNum; i++ { 322 // contractsAddr[i] = [] 323 var tmp []string 324 nonce := uint64(0) 325 for _, v := range tt.txs { 326 data, err := ioutil.ReadFile(v.contract.contractPath) 327 assert.Nil(t, err, "contract path read error") 328 source := string(data) 329 sourceType := "js" 330 argsDeploy := "" 331 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 332 payloadDeploy, _ := deploy.ToBytes() 333 334 value, _ := util.NewUint128FromInt(v.value) 335 gasLimit, _ := util.NewUint128FromInt(v.gasLimit) 336 // nonce := uint32(k+1)*(i+1) + 1 337 nonce++ 338 idx := int(i) % len(addrs) 339 from := addrs[idx] 340 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, nonce, core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 341 assert.Nil(t, err) 342 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 343 txs = append(txs, txDeploy) 344 345 contractAddr, err := txDeploy.GenerateContractAddress() 346 assert.Nil(t, err) 347 fmt.Printf("index;%v", i) 348 // if contractsAddr[i] = nil { 349 // contractsAddr[i] = "" 350 // } 351 // contractsAddr[i] = append(contractsAddr[i], contractAddr.String()) 352 tmp = append(tmp, contractAddr.String()) 353 // contractsAddr[i] 354 } 355 contractsAddr = append(contractsAddr, tmp) 356 } 357 // }) 358 359 // mint block for contracts 360 mintBlock(t, neb, txs) 361 362 txCalls := []*core.Transaction{} 363 for i := uint32(0); i < tt.paralleNum; i++ { 364 365 calleeContract := contractsAddr[i][1] 366 calleeContractAddr, _ := core.AddressParse(calleeContract) 367 _, err := neb.BlockChain().TailBlock().CheckContract(calleeContractAddr) 368 assert.Nil(t, err) 369 callToContract := contractsAddr[i][2] 370 callToContractAddr, _ := core.AddressParse(callToContract) 371 _, err = neb.BlockChain().TailBlock().CheckContract(callToContractAddr) 372 assert.Nil(t, err) 373 callPayload, _ := core.NewCallPayload(call.function, fmt.Sprintf("[\"%s\", \"%s\", 1]", calleeContract, callToContract)) 374 payloadCall, _ := callPayload.ToBytes() 375 value, _ := util.NewUint128FromInt(6) 376 gasLimit, _ := util.NewUint128FromInt(200000) 377 378 proxyContractAddress, err := core.AddressParse(contractsAddr[i][0]) 379 idx := int(i) % len(addrs) 380 from := addrs[idx] 381 account, err := neb.BlockChain().TailBlock().GetAccount(from.Bytes()) 382 assert.Nil(t, err) 383 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 384 account.Nonce()+1, core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 385 assert.Nil(t, err) 386 assert.Nil(t, manager.SignTransaction(from, txCall)) 387 // fmt.Printf("++tx:%v\n", txCall.JSONString()) 388 txCalls = append(txCalls, txCall) 389 // txCalls[i] = txCall 390 } 391 392 mintBlock(t, neb, txCalls) 393 394 // check 395 tail := neb.BlockChain().TailBlock() 396 for i := uint32(0); i < tt.paralleNum; i++ { 397 fmt.Printf("xxxxxxxxxxxx i:%v", i) 398 events, err := tail.FetchEvents(txCalls[i].Hash()) 399 assert.Nil(t, err) 400 for _, event := range events { 401 402 fmt.Println("==============", event.Data) 403 } 404 contractAddrA, err := core.AddressParse(contractsAddr[i][0]) 405 accountAAcc, err := tail.GetAccount(contractAddrA.Bytes()) 406 assert.Nil(t, err) 407 fmt.Printf("account :%v\n", accountAAcc) 408 assert.Equal(t, call.exceptArgs[0], accountAAcc.Balance().String()) 409 410 contractAddrB, err := core.AddressParse(contractsAddr[i][1]) 411 accountBAcc, err := tail.GetAccount(contractAddrB.Bytes()) 412 assert.Nil(t, err) 413 fmt.Printf("accountB :%v\n", accountBAcc) 414 assert.Equal(t, call.exceptArgs[1], accountBAcc.Balance().String()) 415 416 contractAddrC, err := core.AddressParse(contractsAddr[i][2]) 417 accountAccC, err := tail.GetAccount(contractAddrC.Bytes()) 418 assert.Nil(t, err) 419 fmt.Printf("accountC :%v\n", accountAccC) 420 assert.Equal(t, call.exceptArgs[2], accountAccC.Balance().String()) 421 422 aUser, err := tail.GetAccount(addrs[0].Bytes()) 423 // assert.Equal(t, call.exceptArgs[3], aUser.Balance().String()) 424 fmt.Printf("a:%v\n", aUser) 425 cUser, err := tail.GetAccount(addrs[2].Bytes()) 426 fmt.Printf("c:%v\n", cUser) 427 // assert.Equal(t, call.exceptArgs[4], cUser.Balance().String()) 428 429 // cUser, err := tail.GetAccount(c.Bytes()) 430 // fmt.Printf("c:%v\n", cUser) 431 432 // dUser, err := tail.GetAccount(d.Bytes()) 433 // fmt.Printf("d:%v\n", dUser) 434 // assert.Equal(t, txEvent.Status, 1) 435 } 436 437 } 438 } 439 440 func TestInnerTransactionsMaxMulit(t *testing.T) { 441 core.NebCompatibility = core.NewCompatibilityLocal() 442 tests := []struct { 443 name string 444 contracts []contract 445 call call 446 innerExpectedErr string 447 contractExpectedErr string 448 contractExpectedResult string 449 }{ 450 { 451 "deploy test_require_module.js", 452 []contract{ 453 contract{ 454 "./test/inner_call_tests/test_inner_transaction.js", 455 "js", 456 "", 457 }, 458 contract{ 459 "./test/inner_call_tests/bank_vault_inner_contract.js", 460 "js", 461 "", 462 }, 463 contract{ 464 "./test/inner_call_tests/bank_vault_final_contract.js", 465 "js", 466 "", 467 }, 468 }, 469 call{ 470 "saveToLoop", 471 "[1]", 472 []string{""}, 473 }, 474 "multi execution failed", 475 "Call: Inner Contract: out of limit nvm count", 476 "Inner Contract: out of limit nvm count", 477 }, 478 } 479 480 neb := mockNeb(t) 481 manager, err := account.NewManager(neb) 482 assert.Nil(t, err) 483 484 addrs := unlockAccount(t, neb) 485 from := addrs[0] 486 487 // mint height 2, inner contracts >= 3 488 mintBlock(t, neb, nil) 489 490 for _, tt := range tests { 491 492 txs := []*core.Transaction{} 493 contractsAddr := []string{} 494 // t.Run(tt.name, func(t *testing.T) { 495 for k, v := range tt.contracts { 496 data, err := ioutil.ReadFile(v.contractPath) 497 assert.Nil(t, err, "contract path read error") 498 source := string(data) 499 sourceType := "js" 500 argsDeploy := "" 501 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 502 payloadDeploy, _ := deploy.ToBytes() 503 504 value, _ := util.NewUint128FromInt(0) 505 gasLimit, _ := util.NewUint128FromInt(200000) 506 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 507 assert.Nil(t, err) 508 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 509 txs = append(txs, txDeploy) 510 511 contractAddr, err := txDeploy.GenerateContractAddress() 512 assert.Nil(t, err) 513 contractsAddr = append(contractsAddr, contractAddr.String()) 514 } 515 // }) 516 517 // mint for contract deploy 518 mintBlock(t, neb, txs) 519 520 for _, v := range contractsAddr { 521 contract, err := core.AddressParse(v) 522 assert.Nil(t, err) 523 _, err = neb.BlockChain().TailBlock().CheckContract(contract) 524 assert.Nil(t, err) 525 } 526 527 calleeContract := contractsAddr[0] 528 callToContract := contractsAddr[2] 529 callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", 1]", calleeContract, callToContract)) 530 payloadCall, _ := callPayload.ToBytes() 531 532 value, _ := util.NewUint128FromInt(6) 533 gasLimit, _ := util.NewUint128FromInt(2000000) 534 535 proxyContractAddress, err := core.AddressParse(contractsAddr[0]) 536 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 537 uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 538 assert.Nil(t, err) 539 assert.Nil(t, manager.SignTransaction(from, txCall)) 540 541 // mint for inner call 542 mintBlock(t, neb, []*core.Transaction{txCall}) 543 544 // check 545 tail := neb.BlockChain().TailBlock() 546 547 events, err := tail.FetchEvents(txCall.Hash()) 548 assert.Nil(t, err) 549 for _, event := range events { 550 fmt.Printf("topic:%v--event:%v\n", event.Topic, event.Data) 551 if event.Topic == "chain.transactionResult" { 552 var jEvent SysEvent 553 if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil { 554 assert.Equal(t, tt.contractExpectedErr, jEvent.Err) 555 assert.Equal(t, tt.contractExpectedResult, jEvent.Result) 556 } 557 } else { 558 var jEvent InnerEvent 559 if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil { 560 assert.Equal(t, tt.innerExpectedErr, jEvent.Error) 561 } 562 } 563 564 } 565 566 } 567 } 568 569 // optimized 570 func TestInnerTransactionsGasLimit(t *testing.T) { 571 core.NebCompatibility = core.NewCompatibilityLocal() 572 tests := []struct { 573 name string 574 contracts []contract 575 call call 576 expectedErr string 577 gasArr []int 578 gasExpectedErr []string 579 gasExpectedResult []string 580 }{ 581 { 582 "deploy test_require_module.js", 583 []contract{ 584 contract{ 585 "./test/inner_call_tests/test_inner_transaction.js", 586 "js", 587 "", 588 }, 589 contract{ 590 "./test/inner_call_tests/bank_vault_inner_contract.js", 591 "js", 592 "", 593 }, 594 contract{ 595 "./test/inner_call_tests/bank_vault_final_contract.js", 596 "js", 597 "", 598 }, 599 }, 600 call{ 601 "save", 602 "[1]", 603 []string{""}, 604 }, 605 "multi execution failed", 606 //96093 “” "\"\"" 607 //95269 insufficient gas "null" B+C执行完毕,代码回到A执行失败 608 //95105 insufficient gas "null" 609 //95092 insufficient gas "\"\"" C刚好最后一句代码gas limit 610 //94710 insufficient gas "null" 611 //94697 insufficient gas "null" 612 //57249 insufficient gas "null" 613 //57248 insufficient gas "null" 614 //53000 insufficient gas "null" 615 []int{20175, 20174, 53000, 57248, 57249, 94697, 94710, 95092, 95105, 95269, 96093}, 616 // []int{53000}, 617 //95093->95105, 94698->94710 618 //96093 “” "\"\"" 619 //95269 insufficient gas "null" B+C执行完毕,代码回到A执行失败 620 //95105 c刚好消费殆尽,代码回到B后gas不足. Call: inner transation err [insufficient gas] engine index:0 621 //95092 Inner Call: inner transation err [insufficient gas] engine index:1 622 //94710 Inner Call: inner transation err [insufficient gas] engine index:1","execute_result":"inner transation err [insufficient gas] engine index:1" 623 //94697 调用C的时候B消耗完毕 Inner Call: inner transation err [preparation inner nvm insufficient gas] engine index:1 624 //57249 Inner Call: inner transation err [insufficient gas] engine index:0 625 //57248 调用B的时候,A消耗完毕 Inner Call: inner transation err [preparation inner nvm insufficient gas] engine index:0 626 //53000 Inner Call: inner transation err [preparation inner nvm insufficient gas] engine index:0 627 //20174 out of gas limit "" 628 //20175 insufficient gas "null" 629 //20000 630 []string{"insufficient gas", "out of gas limit", 631 "insufficient gas", 632 "insufficient gas", 633 "insufficient gas", 634 "insufficient gas", 635 "insufficient gas", 636 "insufficient gas", 637 "insufficient gas", 638 "insufficient gas", 639 "", 640 }, 641 []string{"null", "", "Inner Contract: null", 642 "Inner Contract: null", 643 "Inner Contract: null", 644 "Inner Contract: null", 645 "Inner Contract: null", 646 "Inner Contract: \"\"", 647 "Inner Contract: null", 648 "null", 649 "\"\""}, 650 }, 651 } 652 653 neb := mockNeb(t) 654 manager, err := account.NewManager(neb) 655 assert.Nil(t, err) 656 657 addrs := unlockAccount(t, neb) 658 from := addrs[0] 659 660 // mint height 2, inner contracts >= 3 661 mintBlock(t, neb, nil) 662 663 for _, tt := range tests { 664 665 txs := []*core.Transaction{} 666 contractsAddr := []string{} 667 // t.Run(tt.name, func(t *testing.T) { 668 for k, v := range tt.contracts { 669 data, err := ioutil.ReadFile(v.contractPath) 670 assert.Nil(t, err, "contract path read error") 671 source := string(data) 672 sourceType := "js" 673 argsDeploy := "" 674 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 675 payloadDeploy, _ := deploy.ToBytes() 676 677 value, _ := util.NewUint128FromInt(0) 678 gasLimit, _ := util.NewUint128FromInt(200000) 679 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 680 assert.Nil(t, err) 681 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 682 txs = append(txs, txDeploy) 683 684 contractAddr, err := txDeploy.GenerateContractAddress() 685 assert.Nil(t, err) 686 contractsAddr = append(contractsAddr, contractAddr.String()) 687 } 688 // }) 689 690 // mint for contract deploy 691 mintBlock(t, neb, txs) 692 693 for _, v := range contractsAddr { 694 contract, err := core.AddressParse(v) 695 assert.Nil(t, err) 696 _, err = neb.BlockChain().TailBlock().CheckContract(contract) 697 assert.Nil(t, err) 698 } 699 700 proxyContractAddress, _ := core.AddressParse(contractsAddr[0]) 701 calleeContract := contractsAddr[1] 702 callToContract := contractsAddr[2] 703 704 callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", 1]", calleeContract, callToContract)) 705 payloadCall, _ := callPayload.ToBytes() 706 707 // call tx 708 for i := 0; i < len(tt.gasArr); i++ { 709 710 value, _ := util.NewUint128FromInt(6) 711 gasLimit, _ := util.NewUint128FromInt(int64(tt.gasArr[i])) 712 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 713 uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 714 assert.Nil(t, err) 715 assert.Nil(t, manager.SignTransaction(from, txCall)) 716 717 // mint for contract call 718 mintBlock(t, neb, []*core.Transaction{txCall}) 719 720 tail := neb.BlockChain().TailBlock() 721 events, err := tail.WorldState().FetchEvents(txCall.Hash()) 722 assert.Nil(t, err) 723 for _, tx := range tail.Transactions() { 724 // fmt.Println("=========>Tx", tx.Hash(), tx.GasLimit(), txCall.Hash()) 725 assert.Equal(t, tx.Hash(), txCall.Hash()) 726 } 727 for _, event := range events { 728 var jEvent SysEvent 729 if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil { 730 if jEvent.Hash != "" { 731 assert.Equal(t, tt.gasExpectedErr[i], jEvent.Err) 732 assert.Equal(t, tt.gasExpectedResult[i], jEvent.Result) 733 } 734 } 735 } 736 737 } 738 } 739 } 740 741 func TestInnerTransactionsMemLimit(t *testing.T) { 742 core.NebCompatibility = core.NewCompatibilityLocal() 743 tests := []struct { 744 name string 745 contracts []contract 746 call call 747 expectedErr string 748 memArr []int 749 memExpectedErr []string 750 memExpectedResult []string 751 }{ 752 { 753 "deploy test_require_module.js", 754 []contract{ 755 contract{ 756 "./test/inner_call_tests/test_inner_transaction.js", 757 "js", 758 "", 759 }, 760 contract{ 761 "./test/inner_call_tests/bank_vault_inner_contract.js", 762 "js", 763 "", 764 }, 765 contract{ 766 "./test/inner_call_tests/bank_vault_final_contract.js", 767 "js", 768 "", 769 }, 770 }, 771 call{ 772 "saveMem", 773 "[1]", 774 []string{""}, 775 }, 776 "multi execution failed", 777 []int{5 * 1024 * 1024, 10 * 1024 * 1024, 20 * 1024 * 1024, 40 * 1024 * 1024}, 778 // []int{40 * 1024 * 1024}, 779 []string{"", 780 "exceed memory limits", 781 "exceed memory limits", 782 "exceed memory limits"}, 783 []string{"\"\"", 784 "Inner Contract: null", "Inner Contract: null", "null", 785 }, 786 }, 787 } 788 789 neb := mockNeb(t) 790 manager, err := account.NewManager(neb) 791 assert.Nil(t, err) 792 793 addrs := unlockAccount(t, neb) 794 from := addrs[0] 795 796 // mint height 2, inner contracts >= 3 797 mintBlock(t, neb, nil) 798 799 for _, tt := range tests { 800 for i := 0; i < len(tt.memArr); i++ { 801 802 txs := []*core.Transaction{} 803 contractsAddr := []string{} 804 for k, v := range tt.contracts { 805 data, err := ioutil.ReadFile(v.contractPath) 806 assert.Nil(t, err, "contract path read error") 807 source := string(data) 808 sourceType := "js" 809 argsDeploy := "" 810 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 811 payloadDeploy, _ := deploy.ToBytes() 812 813 value, _ := util.NewUint128FromInt(0) 814 gasLimit, _ := util.NewUint128FromInt(200000) 815 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 816 assert.Nil(t, err) 817 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 818 txs = append(txs, txDeploy) 819 820 contractAddr, err := txDeploy.GenerateContractAddress() 821 assert.Nil(t, err) 822 contractsAddr = append(contractsAddr, contractAddr.String()) 823 } 824 825 // mint for contract deploy 826 mintBlock(t, neb, txs) 827 828 for _, v := range contractsAddr { 829 contract, err := core.AddressParse(v) 830 assert.Nil(t, err) 831 _, err = neb.BlockChain().TailBlock().CheckContract(contract) 832 assert.Nil(t, err) 833 } 834 835 calleeContract := contractsAddr[1] 836 callToContract := contractsAddr[2] 837 callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", \"%d\"]", calleeContract, callToContract, tt.memArr[i])) 838 payloadCall, _ := callPayload.ToBytes() 839 840 value, _ := util.NewUint128FromInt(6) 841 gasLimit, _ := util.NewUint128FromInt(5000000) 842 proxyContractAddress, err := core.AddressParse(contractsAddr[0]) 843 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 844 uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 845 assert.Nil(t, err) 846 assert.Nil(t, manager.SignTransaction(from, txCall)) 847 848 // mint for contract call 849 mintBlock(t, neb, []*core.Transaction{txCall}) 850 851 tail := neb.BlockChain().TailBlock() 852 events, err := tail.FetchEvents(txCall.Hash()) 853 for _, event := range events { 854 fmt.Printf("mem err:%v", event.Data) 855 var jEvent SysEvent 856 if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil { 857 if jEvent.Hash != "" { 858 assert.Equal(t, tt.memExpectedErr[i], jEvent.Err) 859 assert.Equal(t, tt.memExpectedResult[i], jEvent.Result) 860 } 861 } 862 863 } 864 } 865 } 866 } 867 868 func TestInnerTransactionsErr(t *testing.T) { 869 core.NebCompatibility = core.NewCompatibilityLocal() 870 tests := []struct { 871 name string 872 contracts []contract 873 call call 874 errFlagArr []uint32 875 expectedErrArr []string 876 expectedAccount [][]string 877 }{ 878 { 879 "deploy TestInnerTransactionsErr.js", 880 []contract{ 881 contract{ 882 "./test/inner_call_tests/test_inner_transaction.js", 883 "js", 884 "", 885 }, 886 contract{ 887 "./test/inner_call_tests/bank_vault_inner_contract.js", 888 "js", 889 "", 890 }, 891 contract{ 892 "./test/inner_call_tests/bank_vault_final_contract.js", 893 "js", 894 "", 895 }, 896 }, 897 call{ 898 "saveErr", 899 "[1]", 900 []string{""}, 901 }, 902 []uint32{0, 1, 2, 3}, 903 // []uint32{0}, 904 []string{"Call: saveErr in test_inner_transaction", 905 "Call: Inner Contract: saveErr in bank_vault_inner_contract", 906 "Call: Inner Contract: saveErr in bank_vault_contract", 907 "", 908 }, 909 [][]string{ 910 {"0", "0", "0", "4999999999999903290000000", "5000000000000000000000000", "5000004280820096710000000", "5000000000000000000000000"}, 911 {"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 912 {"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 913 {"1", "2", "3", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 914 }, 915 }, 916 } 917 918 for _, tt := range tests { 919 for i := 0; i < len(tt.errFlagArr); i++ { 920 921 neb := mockNeb(t) 922 manager, err := account.NewManager(neb) 923 assert.Nil(t, err) 924 925 addrs := unlockAccount(t, neb) 926 from := addrs[0] 927 928 // mint height 2, inner contracts >= 3 929 mintBlock(t, neb, nil) 930 931 txs := []*core.Transaction{} 932 contractsAddr := []string{} 933 for k, v := range tt.contracts { 934 data, err := ioutil.ReadFile(v.contractPath) 935 assert.Nil(t, err, "contract path read error") 936 source := string(data) 937 sourceType := "js" 938 argsDeploy := "" 939 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 940 payloadDeploy, _ := deploy.ToBytes() 941 942 value, _ := util.NewUint128FromInt(0) 943 gasLimit, _ := util.NewUint128FromInt(200000) 944 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 945 assert.Nil(t, err) 946 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 947 txs = append(txs, txDeploy) 948 949 contractAddr, err := txDeploy.GenerateContractAddress() 950 assert.Nil(t, err) 951 contractsAddr = append(contractsAddr, contractAddr.String()) 952 } 953 954 // mint for deploy contracts 955 mintBlock(t, neb, txs) 956 957 for _, v := range contractsAddr { 958 contract, err := core.AddressParse(v) 959 assert.Nil(t, err) 960 _, err = neb.BlockChain().TailBlock().CheckContract(contract) 961 assert.Nil(t, err) 962 } 963 964 calleeContract := contractsAddr[1] 965 callToContract := contractsAddr[2] 966 callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", \"%d\"]", calleeContract, callToContract, tt.errFlagArr[i])) 967 payloadCall, _ := callPayload.ToBytes() 968 969 value, _ := util.NewUint128FromInt(6) 970 gasLimit, _ := util.NewUint128FromInt(1000000) 971 proxyContractAddress, err := core.AddressParse(contractsAddr[0]) 972 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 973 uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 974 assert.Nil(t, err) 975 assert.Nil(t, manager.SignTransaction(from, txCall)) 976 977 // mint for contract call 978 mintBlock(t, neb, []*core.Transaction{txCall}) 979 980 tail := neb.BlockChain().TailBlock() 981 events, err := tail.FetchEvents(txCall.Hash()) 982 for _, event := range events { 983 fmt.Printf("event:%v\n", event.Data) 984 var jEvent SysEvent 985 if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil { 986 if jEvent.Hash != "" { 987 assert.Equal(t, tt.expectedErrArr[i], jEvent.Err) 988 } 989 } 990 991 } 992 //chech accout 993 contractAddrA, err := core.AddressParse(contractsAddr[0]) 994 accountAAcc, err := tail.GetAccount(contractAddrA.Bytes()) 995 assert.Nil(t, err) 996 // fmt.Printf("account :%v\n", accountAAcc) 997 assert.Equal(t, tt.expectedAccount[i][0], accountAAcc.Balance().String()) 998 999 contractAddrB, err := core.AddressParse(contractsAddr[1]) 1000 accountBAcc, err := tail.GetAccount(contractAddrB.Bytes()) 1001 assert.Nil(t, err) 1002 // fmt.Printf("accountB :%v\n", accountBAcc) 1003 assert.Equal(t, tt.expectedAccount[i][1], accountBAcc.Balance().String()) 1004 1005 contractAddrC, err := core.AddressParse(contractsAddr[2]) 1006 accountAccC, err := tail.GetAccount(contractAddrC.Bytes()) 1007 assert.Nil(t, err) 1008 fmt.Printf("accountC :%v\n", accountAccC) 1009 assert.Equal(t, tt.expectedAccount[i][2], accountAccC.Balance().String()) 1010 1011 aUser, err := tail.GetAccount(addrs[0].Bytes()) 1012 // assert.Equal(t, tt.expectedAccount[i][3], aUser.Balance().String()) 1013 fmt.Printf("aI:%v\n", aUser) 1014 bUser, err := tail.GetAccount(addrs[1].Bytes()) 1015 assert.Equal(t, tt.expectedAccount[i][4], bUser.Balance().String()) 1016 1017 cUser, err := tail.GetAccount(addrs[2].Bytes()) 1018 fmt.Printf("cI:%v\n", cUser) 1019 // assert.Equal(t, tt.expectedAccount[i][5], cUser.Balance().String()) 1020 1021 // fmt.Printf("b:%v\n", bUser) 1022 // assert.Equal(t, tt.expectedAccount[i][4], cUser.Balance().String()) 1023 dUser, err := tail.GetAccount(addrs[3].Bytes()) 1024 assert.Equal(t, tt.expectedAccount[i][6], dUser.Balance().String()) 1025 // fmt.Printf("d:%v\n", dUser) 1026 // assert.Equal(t, tt.expectedAccount[i][4], dUser.Balance().String()) 1027 } 1028 } 1029 } 1030 1031 func TestInnerTransactionsValue(t *testing.T) { 1032 core.NebCompatibility = core.NewCompatibilityLocal() 1033 tests := []struct { 1034 name string 1035 contracts []contract 1036 call call 1037 errValueArr []string 1038 expectedErrArr []string 1039 expectedAccount [][]string 1040 }{ 1041 { 1042 "deploy TestInnerTransactionsValue", 1043 []contract{ 1044 contract{ 1045 "./test/inner_call_tests/test_inner_transaction.js", 1046 "js", 1047 "", 1048 }, 1049 contract{ 1050 "./test/inner_call_tests/bank_vault_inner_contract.js", 1051 "js", 1052 "", 1053 }, 1054 contract{ 1055 "./test/inner_call_tests/bank_vault_final_contract.js", 1056 "js", 1057 "", 1058 }, 1059 }, 1060 call{ 1061 "saveValue", 1062 "[1]", 1063 []string{""}, 1064 }, 1065 []string{"-1", "340282366920938463463374607431768211455", "340282366920938463463374607431768211456", 1066 "1.1", "NaN", "undefined", "null", "infinity", "", "\"\""}, 1067 // []string{"0"}, 1068 []string{"Call: Inner Call: invalid value", 1069 "Call: Inner Contract: inner transfer failed", 1070 "Call: Inner Contract: uint128: overflow", 1071 "Call: Inner Call: invalid value", 1072 "Call: Inner Call: invalid value", 1073 "Call: BigNumber Error: new BigNumber() not a number: undefined", 1074 "Call: BigNumber Error: new BigNumber() not a number: null", 1075 "Call: BigNumber Error: new BigNumber() not a number: infinity", 1076 "", 1077 "invalid function of call payload", 1078 }, 1079 [][]string{ 1080 {"0", "0", "0", "4999999999999903290000000", "5000000000000000000000000", "5000004280820096710000000", "5000000000000000000000000"}, 1081 {"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 1082 {"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 1083 {"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 1084 {"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 1085 {"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 1086 {"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 1087 {"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 1088 {"6", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 1089 {"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"}, 1090 }, 1091 }, 1092 } 1093 for _, tt := range tests { 1094 for i := 0; i < len(tt.errValueArr); i++ { 1095 1096 neb := mockNeb(t) 1097 manager, err := account.NewManager(neb) 1098 assert.Nil(t, err) 1099 1100 addrs := unlockAccount(t, neb) 1101 from := addrs[0] 1102 1103 // mint height 2, inner contracts >= 3 1104 mintBlock(t, neb, nil) 1105 1106 txs := []*core.Transaction{} 1107 contractsAddr := []string{} 1108 for k, v := range tt.contracts { 1109 data, err := ioutil.ReadFile(v.contractPath) 1110 assert.Nil(t, err, "contract path read error") 1111 source := string(data) 1112 sourceType := "js" 1113 argsDeploy := "" 1114 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 1115 payloadDeploy, _ := deploy.ToBytes() 1116 1117 value, _ := util.NewUint128FromInt(0) 1118 gasLimit, _ := util.NewUint128FromInt(200000) 1119 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 1120 assert.Nil(t, err) 1121 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 1122 txs = append(txs, txDeploy) 1123 1124 contractAddr, err := txDeploy.GenerateContractAddress() 1125 assert.Nil(t, err) 1126 contractsAddr = append(contractsAddr, contractAddr.String()) 1127 } 1128 1129 // mint block for contract deploy 1130 mintBlock(t, neb, txs) 1131 1132 for _, v := range contractsAddr { 1133 contract, err := core.AddressParse(v) 1134 assert.Nil(t, err) 1135 _, err = neb.BlockChain().TailBlock().CheckContract(contract) 1136 assert.Nil(t, err) 1137 } 1138 1139 calleeContract := contractsAddr[1] 1140 callToContract := contractsAddr[2] 1141 callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", \"%s\"]", calleeContract, callToContract, tt.errValueArr[i])) 1142 payloadCall, _ := callPayload.ToBytes() 1143 1144 value, _ := util.NewUint128FromInt(6) 1145 gasLimit, _ := util.NewUint128FromInt(1000000) 1146 proxyContractAddress, err := core.AddressParse(contractsAddr[0]) 1147 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 1148 uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 1149 assert.Nil(t, err) 1150 assert.Nil(t, manager.SignTransaction(from, txCall)) 1151 1152 // mint for contract call 1153 mintBlock(t, neb, []*core.Transaction{txCall}) 1154 1155 tail := neb.BlockChain().TailBlock() 1156 events, err := tail.FetchEvents(txCall.Hash()) 1157 for _, event := range events { 1158 fmt.Printf("event:%v\n", event.Data) 1159 var jEvent SysEvent 1160 if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil { 1161 if jEvent.Hash != "" { 1162 assert.Equal(t, tt.expectedErrArr[i], jEvent.Err) 1163 } 1164 } 1165 1166 } 1167 //chech accout 1168 contractAddrA, err := core.AddressParse(contractsAddr[0]) 1169 accountAAcc, err := tail.GetAccount(contractAddrA.Bytes()) 1170 assert.Nil(t, err) 1171 // fmt.Printf("account :%v\n", accountAAcc) 1172 assert.Equal(t, tt.expectedAccount[i][0], accountAAcc.Balance().String()) 1173 1174 contractAddrB, err := core.AddressParse(contractsAddr[1]) 1175 accountBAcc, err := tail.GetAccount(contractAddrB.Bytes()) 1176 assert.Nil(t, err) 1177 // fmt.Printf("accountB :%v\n", accountBAcc) 1178 assert.Equal(t, tt.expectedAccount[i][1], accountBAcc.Balance().String()) 1179 1180 contractAddrC, err := core.AddressParse(contractsAddr[2]) 1181 accountAccC, err := tail.GetAccount(contractAddrC.Bytes()) 1182 assert.Nil(t, err) 1183 fmt.Printf("accountC :%v\n", accountAccC) 1184 assert.Equal(t, tt.expectedAccount[i][2], accountAccC.Balance().String()) 1185 1186 aUser, err := tail.GetAccount(addrs[0].Bytes()) 1187 // assert.Equal(t, tt.expectedAccount[i][3], aUser.Balance().String()) 1188 fmt.Printf("aI:%v\n", aUser) 1189 bUser, err := tail.GetAccount(addrs[1].Bytes()) 1190 assert.Equal(t, tt.expectedAccount[i][4], bUser.Balance().String()) 1191 1192 cUser, err := tail.GetAccount(addrs[2].Bytes()) 1193 fmt.Printf("cI:%v\n", cUser) 1194 // assert.Equal(t, tt.expectedAccount[i][5], cUser.Balance().String()) 1195 1196 // fmt.Printf("b:%v\n", bUser) 1197 // assert.Equal(t, tt.expectedAccount[i][4], cUser.Balance().String()) 1198 dUser, err := tail.GetAccount(addrs[3].Bytes()) 1199 assert.Equal(t, tt.expectedAccount[i][6], dUser.Balance().String()) 1200 // fmt.Printf("d:%v\n", dUser) 1201 // assert.Equal(t, tt.expectedAccount[i][4], dUser.Balance().String()) 1202 } 1203 } 1204 } 1205 1206 func TestGetContractErr(t *testing.T) { 1207 core.NebCompatibility = core.NewCompatibilityLocal() 1208 tests := []struct { 1209 name string 1210 contracts []contract 1211 calls []call 1212 }{ 1213 { 1214 "TestGetContractErr", 1215 []contract{ 1216 contract{ 1217 "./test/inner_call_tests/test_inner_transaction.js", 1218 "js", 1219 "", 1220 }, 1221 contract{ 1222 "./test/inner_call_tests/bank_vault_inner_contract.js", 1223 "js", 1224 "", 1225 }, 1226 }, 1227 []call{ 1228 call{ 1229 "getSource", 1230 "[1]", 1231 []string{"Call: Inner Call: no contract at this address"}, 1232 }, 1233 }, 1234 }, 1235 } 1236 1237 for _, tt := range tests { 1238 for i := 0; i < len(tt.calls); i++ { 1239 1240 neb := mockNeb(t) 1241 manager, err := account.NewManager(neb) 1242 assert.Nil(t, err) 1243 1244 addrs := unlockAccount(t, neb) 1245 from := addrs[0] 1246 1247 // mint height 2, inner contracts >= 3 1248 mintBlock(t, neb, nil) 1249 1250 txs := []*core.Transaction{} 1251 contractsAddr := []string{} 1252 for k, v := range tt.contracts { 1253 data, err := ioutil.ReadFile(v.contractPath) 1254 assert.Nil(t, err, "contract path read error") 1255 source := string(data) 1256 sourceType := "js" 1257 argsDeploy := "" 1258 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 1259 payloadDeploy, _ := deploy.ToBytes() 1260 1261 value, _ := util.NewUint128FromInt(0) 1262 gasLimit, _ := util.NewUint128FromInt(200000) 1263 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 1264 assert.Nil(t, err) 1265 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 1266 txs = append(txs, txDeploy) 1267 1268 contractAddr, err := txDeploy.GenerateContractAddress() 1269 assert.Nil(t, err) 1270 contractsAddr = append(contractsAddr, contractAddr.String()) 1271 } 1272 1273 // mint for contract deploy 1274 mintBlock(t, neb, txs) 1275 1276 for _, v := range contractsAddr { 1277 contract, err := core.AddressParse(v) 1278 assert.Nil(t, err) 1279 _, err = neb.BlockChain().TailBlock().CheckContract(contract) 1280 assert.Nil(t, err) 1281 } 1282 1283 calleeContract := "123456789" 1284 callToContract := "123456789" 1285 callPayload, _ := core.NewCallPayload(tt.calls[i].function, fmt.Sprintf("[\"%s\", \"%s\"]", calleeContract, callToContract)) 1286 payloadCall, _ := callPayload.ToBytes() 1287 1288 value, _ := util.NewUint128FromInt(6) 1289 gasLimit, _ := util.NewUint128FromInt(1000000) 1290 proxyContractAddress, err := core.AddressParse(contractsAddr[0]) 1291 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 1292 uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 1293 assert.Nil(t, err) 1294 assert.Nil(t, manager.SignTransaction(from, txCall)) 1295 1296 // mint for contract call 1297 mintBlock(t, neb, []*core.Transaction{txCall}) 1298 1299 tail := neb.BlockChain().TailBlock() 1300 events, err := tail.FetchEvents(txCall.Hash()) 1301 for _, event := range events { 1302 fmt.Printf("event:%v\n", events) 1303 var jEvent SysEvent 1304 if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil { 1305 if jEvent.Hash != "" { 1306 assert.Equal(t, tt.calls[i].exceptArgs[0], jEvent.Err) 1307 } 1308 fmt.Printf("event:%v\n", jEvent.Err) 1309 } 1310 1311 } 1312 } 1313 } 1314 } 1315 1316 func TestInnerTransactionsRand(t *testing.T) { 1317 core.NebCompatibility = core.NewCompatibilityLocal() 1318 tests := []struct { 1319 name string 1320 contracts []contract 1321 call call 1322 }{ 1323 { 1324 "test TestInnerTransactionsRand", 1325 []contract{ 1326 contract{ 1327 "./test/inner_call_tests/test_inner_transaction.js", 1328 "js", 1329 "", 1330 }, 1331 contract{ 1332 "./test/inner_call_tests/bank_vault_inner_contract.js", 1333 "js", 1334 "", 1335 }, 1336 contract{ 1337 "./test/inner_call_tests/bank_vault_final_contract.js", 1338 "js", 1339 "", 1340 }, 1341 }, 1342 call{ 1343 "getRandom", 1344 "[1]", 1345 []string{""}, 1346 }, 1347 }, 1348 } 1349 1350 for _, tt := range tests { 1351 // for i := 0; i < len(tt); i++ { 1352 1353 neb := mockNeb(t) 1354 manager, err := account.NewManager(neb) 1355 assert.Nil(t, err) 1356 1357 addrs := unlockAccount(t, neb) 1358 from := addrs[0] 1359 1360 // mint height 2, inner contracts >= 3 1361 mintBlock(t, neb, nil) 1362 1363 txs := []*core.Transaction{} 1364 contractsAddr := []string{} 1365 for k, v := range tt.contracts { 1366 data, err := ioutil.ReadFile(v.contractPath) 1367 assert.Nil(t, err, "contract path read error") 1368 source := string(data) 1369 sourceType := "js" 1370 argsDeploy := "" 1371 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 1372 payloadDeploy, _ := deploy.ToBytes() 1373 1374 value, _ := util.NewUint128FromInt(0) 1375 gasLimit, _ := util.NewUint128FromInt(200000) 1376 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 1377 assert.Nil(t, err) 1378 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 1379 txs = append(txs, txDeploy) 1380 1381 contractAddr, err := txDeploy.GenerateContractAddress() 1382 assert.Nil(t, err) 1383 contractsAddr = append(contractsAddr, contractAddr.String()) 1384 } 1385 1386 // mint for contract deploy 1387 mintBlock(t, neb, txs) 1388 1389 for _, v := range contractsAddr { 1390 contract, err := core.AddressParse(v) 1391 assert.Nil(t, err) 1392 _, err = neb.BlockChain().TailBlock().CheckContract(contract) 1393 assert.Nil(t, err) 1394 } 1395 1396 calleeContract := contractsAddr[1] 1397 callToContract := contractsAddr[2] 1398 callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\"]", calleeContract, callToContract)) 1399 payloadCall, _ := callPayload.ToBytes() 1400 1401 value, _ := util.NewUint128FromInt(6) 1402 gasLimit, _ := util.NewUint128FromInt(int64(100000)) 1403 proxyContractAddress, err := core.AddressParse(contractsAddr[0]) 1404 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 1405 uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 1406 assert.Nil(t, err) 1407 assert.Nil(t, manager.SignTransaction(from, txCall)) 1408 1409 // mint for contract call 1410 mintBlock(t, neb, []*core.Transaction{txCall}) 1411 1412 tail := neb.BlockChain().TailBlock() 1413 events, err := tail.FetchEvents(txCall.Hash()) 1414 for _, event := range events { 1415 1416 var jEvent SysEvent 1417 if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil { 1418 fmt.Printf("event:%v\n", event.Data) 1419 if jEvent.Hash != "" { 1420 assert.Equal(t, "", jEvent.Err) 1421 } 1422 } 1423 1424 } 1425 // } 1426 } 1427 } 1428 1429 func TestInnerTransactionsTimeOut(t *testing.T) { 1430 core.NebCompatibility = core.NewCompatibilityLocal() 1431 tests := []struct { 1432 name string 1433 contracts []contract 1434 call call 1435 errFlagArr []uint32 1436 expectedErrArr []string 1437 }{ 1438 { 1439 "deploy TestInnerTransactionsErr.js", 1440 []contract{ 1441 contract{ 1442 "./test/inner_call_tests/test_inner_transaction.js", 1443 "js", 1444 "", 1445 }, 1446 contract{ 1447 "./test/inner_call_tests/bank_vault_inner_contract.js", 1448 "js", 1449 "", 1450 }, 1451 contract{ 1452 "./test/inner_call_tests/bank_vault_final_contract.js", 1453 "js", 1454 "", 1455 }, 1456 }, 1457 call{ 1458 "saveTimeOut", 1459 "[1]", 1460 []string{""}, 1461 }, 1462 []uint32{0, 1, 2}, 1463 []string{"insufficient gas", 1464 "insufficient gas", 1465 "insufficient gas"}, 1466 }, 1467 } 1468 1469 for _, tt := range tests { 1470 for i := 0; i < len(tt.errFlagArr); i++ { 1471 1472 neb := mockNeb(t) 1473 manager, err := account.NewManager(neb) 1474 assert.Nil(t, err) 1475 1476 addrs := unlockAccount(t, neb) 1477 from := addrs[0] 1478 1479 // mint height 2, inner contracts >= 3 1480 mintBlock(t, neb, nil) 1481 1482 txs := []*core.Transaction{} 1483 contractsAddr := []string{} 1484 for k, v := range tt.contracts { 1485 data, err := ioutil.ReadFile(v.contractPath) 1486 assert.Nil(t, err, "contract path read error") 1487 source := string(data) 1488 sourceType := "js" 1489 argsDeploy := "" 1490 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 1491 payloadDeploy, _ := deploy.ToBytes() 1492 1493 value, _ := util.NewUint128FromInt(0) 1494 gasLimit, _ := util.NewUint128FromInt(5000000) 1495 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 1496 assert.Nil(t, err) 1497 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 1498 txs = append(txs, txDeploy) 1499 1500 contractAddr, err := txDeploy.GenerateContractAddress() 1501 assert.Nil(t, err) 1502 contractsAddr = append(contractsAddr, contractAddr.String()) 1503 } 1504 1505 // mint for contract deploy 1506 mintBlock(t, neb, txs) 1507 1508 for _, v := range contractsAddr { 1509 contract, err := core.AddressParse(v) 1510 assert.Nil(t, err) 1511 _, err = neb.BlockChain().TailBlock().CheckContract(contract) 1512 assert.Nil(t, err) 1513 } 1514 1515 calleeContract := contractsAddr[1] 1516 callToContract := contractsAddr[2] 1517 callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", \"%d\"]", calleeContract, callToContract, tt.errFlagArr[i])) 1518 payloadCall, _ := callPayload.ToBytes() 1519 1520 value, _ := util.NewUint128FromInt(6) 1521 gasLimit, _ := util.NewUint128FromInt(1000000) 1522 proxyContractAddress, err := core.AddressParse(contractsAddr[0]) 1523 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 1524 uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 1525 assert.Nil(t, err) 1526 assert.Nil(t, manager.SignTransaction(from, txCall)) 1527 1528 // mint for contract call 1529 mintBlock(t, neb, []*core.Transaction{txCall}) 1530 1531 tail := neb.BlockChain().TailBlock() 1532 events, err := tail.FetchEvents(txCall.Hash()) 1533 for _, event := range events { 1534 fmt.Printf("event:%v\n", event.Data) 1535 var jEvent SysEvent 1536 if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil { 1537 if jEvent.Hash != "" { 1538 assert.Equal(t, tt.expectedErrArr[i], jEvent.Err) 1539 } 1540 } 1541 1542 } 1543 } 1544 } 1545 } 1546 1547 func TestInnerTxInstructionCounter(t *testing.T) { 1548 core.NebCompatibility = core.NewCompatibilityLocal() 1549 tests := []struct { 1550 name string 1551 contracts []contract 1552 calls []call 1553 }{ 1554 { 1555 "deploy contracts", 1556 []contract{ 1557 contract{ 1558 "./test/instruction_counter_tests/inner_contract_callee.js", 1559 "js", 1560 "", 1561 }, 1562 contract{ 1563 "./test/instruction_counter_tests/inner_contract_caller.js", 1564 "js", 1565 "", 1566 }, 1567 }, 1568 []call{ 1569 call{ 1570 "callWhile", 1571 "", 1572 []string{"57296000000"}, // 57286000000 for instruction_counter.js v1.0.0 1573 }, 1574 }, 1575 }, 1576 } 1577 tt := tests[0] 1578 for _, call := range tt.calls { 1579 1580 neb := mockNeb(t) 1581 manager, err := account.NewManager(neb) 1582 assert.Nil(t, err) 1583 1584 addrs := unlockAccount(t, neb) 1585 from := addrs[0] 1586 1587 // mint height 2, inner contracts >= 3 1588 mintBlock(t, neb, nil) 1589 1590 txs := []*core.Transaction{} 1591 contractsAddr := []string{} 1592 1593 // t.Run(tt.name, func(t *testing.T) { 1594 for k, v := range tt.contracts { 1595 data, err := ioutil.ReadFile(v.contractPath) 1596 assert.Nil(t, err, "contract path read error") 1597 source := string(data) 1598 sourceType := "js" 1599 argsDeploy := "" 1600 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 1601 payloadDeploy, _ := deploy.ToBytes() 1602 1603 value, _ := util.NewUint128FromInt(0) 1604 gasLimit, _ := util.NewUint128FromInt(200000) 1605 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 1606 assert.Nil(t, err) 1607 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 1608 txs = append(txs, txDeploy) 1609 1610 contractAddr, err := txDeploy.GenerateContractAddress() 1611 assert.Nil(t, err) 1612 contractsAddr = append(contractsAddr, contractAddr.String()) 1613 } 1614 // }) 1615 1616 // mint for contract deploy 1617 mintBlock(t, neb, txs) 1618 1619 for _, v := range contractsAddr { 1620 contract, err := core.AddressParse(v) 1621 assert.Nil(t, err) 1622 _, err = neb.BlockChain().TailBlock().CheckContract(contract) 1623 assert.Nil(t, err) 1624 } 1625 1626 callPayload, _ := core.NewCallPayload(call.function, fmt.Sprintf("[\"%s\"]", contractsAddr[0])) 1627 payloadCall, _ := callPayload.ToBytes() 1628 1629 value, _ := util.NewUint128FromInt(0) 1630 gasLimit, _ := util.NewUint128FromInt(200000) 1631 1632 tail := neb.BlockChain().TailBlock() 1633 aUser, err := tail.GetAccount(from.Bytes()) 1634 balBefore := aUser.Balance() 1635 1636 proxyContractAddress, err := core.AddressParse(contractsAddr[1]) 1637 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 1638 uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 1639 assert.Nil(t, err) 1640 assert.Nil(t, manager.SignTransaction(from, txCall)) 1641 1642 // mint for contract call 1643 mintBlock(t, neb, []*core.Transaction{txCall}) 1644 1645 // // check 1646 tail = neb.BlockChain().TailBlock() 1647 events, err := tail.FetchEvents(txCall.Hash()) 1648 assert.Nil(t, err) 1649 for _, event := range events { 1650 fmt.Println("==============", event.Data) 1651 } 1652 1653 aUser, err = tail.GetAccount(from.Bytes()) 1654 assert.Nil(t, err) 1655 det, err := balBefore.Sub(aUser.Balance()) 1656 assert.Nil(t, err) 1657 // fmt.Println("from account balance change: ", det.String()) 1658 assert.Equal(t, call.exceptArgs[0], det.String()) 1659 fmt.Printf("aI:%v\n", aUser) 1660 } 1661 } 1662 1663 func TestMultiLibVersionCall(t *testing.T) { 1664 core.NebCompatibility = core.NewCompatibilityLocal() 1665 m := core.NebCompatibility.V8JSLibVersionHeightMap().Data 1666 m["1.1.0"] = 4 1667 m["1.0.5"] = 3 1668 defer func() { 1669 m["1.1.0"] = 3 1670 m["1.0.5"] = 2 1671 }() 1672 1673 tests := []struct { 1674 name string 1675 calls []call 1676 }{ 1677 { 1678 "call contracts", 1679 []call{ 1680 call{ 1681 "testInnerCall", 1682 "[\"%s\", \"undefined\"]", // in version before 1.1.0, typeof(Blockchain.Contract)=='undefined' 1683 []string{"\"\"", ""}, 1684 }, 1685 call{ 1686 "testRandom", 1687 // before 1.1.0 1688 // true -- Blockchain.block.seed is not empty 1689 // true -- Math.random.seed exists 1690 // 1691 // since 1.1.0 1692 // false -- Blockchain.block.seed is empty 1693 // false -- Math.random.seed not exist 1694 "[\"%s\", true, true, false, false]", 1695 []string{"\"\"", ""}, 1696 }, 1697 }, 1698 }, 1699 } 1700 tt := tests[0] 1701 1702 neb := mockNeb(t) 1703 manager, err := account.NewManager(neb) 1704 assert.Nil(t, err) 1705 1706 addrs := unlockAccount(t, neb) 1707 from := addrs[0] 1708 1709 // mint height 2, inner contracts >= 3 1710 mintBlock(t, neb, nil) 1711 1712 txs := []*core.Transaction{} 1713 contractsAddr := []string{} 1714 1715 data, err := ioutil.ReadFile("./test/inner_call_tests/callee.js") 1716 assert.Nil(t, err, "contract path read error") 1717 source := string(data) 1718 sourceType := "js" 1719 argsDeploy := "" 1720 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 1721 payloadDeploy, _ := deploy.ToBytes() 1722 1723 value, _ := util.NewUint128FromInt(0) 1724 gasLimit, _ := util.NewUint128FromInt(200000) 1725 txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 1726 assert.Nil(t, err) 1727 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 1728 txs = append(txs, txDeploy) 1729 1730 contractAddr, err := txDeploy.GenerateContractAddress() 1731 assert.Nil(t, err) 1732 contractsAddr = append(contractsAddr, contractAddr.String()) 1733 1734 // mint for contract deploy 1735 mintBlock(t, neb, txs) 1736 1737 data, err = ioutil.ReadFile("./test/inner_call_tests/caller.js") 1738 assert.Nil(t, err, "contract path read error") 1739 source = string(data) 1740 sourceType = "js" 1741 argsDeploy = "" 1742 deploy, _ = core.NewDeployPayload(source, sourceType, argsDeploy) 1743 payloadDeploy, _ = deploy.ToBytes() 1744 1745 txDeploy, err = core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(2), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 1746 assert.Nil(t, err) 1747 assert.Nil(t, manager.SignTransaction(from, txDeploy)) 1748 1749 contractAddr, err = txDeploy.GenerateContractAddress() 1750 assert.Nil(t, err) 1751 contractsAddr = append(contractsAddr, contractAddr.String()) 1752 1753 // mint for contract deploy 1754 mintBlock(t, neb, []*core.Transaction{txDeploy}) 1755 1756 for _, v := range contractsAddr { 1757 contract, err := core.AddressParse(v) 1758 assert.Nil(t, err) 1759 _, err = neb.BlockChain().TailBlock().CheckContract(contract) 1760 assert.Nil(t, err) 1761 } 1762 1763 for _, call := range tt.calls { 1764 callPayload, _ := core.NewCallPayload(call.function, fmt.Sprintf(call.args, contractsAddr[0])) 1765 payloadCall, _ := callPayload.ToBytes() 1766 1767 proxyContractAddress, err := core.AddressParse(contractsAddr[1]) 1768 txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value, 1769 uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) 1770 assert.Nil(t, err) 1771 assert.Nil(t, manager.SignTransaction(from, txCall)) 1772 1773 // mint for contract call 1774 mintBlock(t, neb, []*core.Transaction{txCall}) 1775 1776 tail := neb.BlockChain().TailBlock() 1777 events, err := tail.WorldState().FetchEvents(txCall.Hash()) 1778 assert.Nil(t, err) 1779 for _, event := range events { 1780 fmt.Println("==============", event.Data) 1781 1782 var jEvent SysEvent 1783 if event.Topic == core.TopicTransactionExecutionResult { 1784 if err = json.Unmarshal([]byte(event.Data), &jEvent); err == nil { 1785 assert.Equal(t, call.exceptArgs[0], jEvent.Result) 1786 assert.Equal(t, call.exceptArgs[1], jEvent.Err) 1787 } 1788 } 1789 } 1790 1791 } 1792 }