github.com/igggame/nebulas-go@v2.1.0+incompatible/nebtestkit/cases/contract/contract.feature.random.test.js (about) 1 'use strict'; 2 3 var sleep = require('system-sleep'); 4 var FS = require('fs'); 5 var expect = require('chai').expect; 6 var BigNumber = require('bignumber.js'); 7 var HttpRequest = require('../../node-request'); 8 var TestnetConfig = require('../testnet_config'); 9 var Wallet = require('nebulas'); 10 11 var Account = Wallet.Account; 12 var Transaction = Wallet.Transaction; 13 var env = process.argv.splice(2)[1]; 14 var testnetConfig = new TestnetConfig(env); 15 var originSource = testnetConfig.sourceAccount; 16 var ChainID = testnetConfig.ChainId; 17 var coinbase = testnetConfig.coinbase; 18 var neb = new Wallet.Neb(); 19 neb.setRequest(new HttpRequest(testnetConfig.apiEndPoint)); 20 21 22 var deploy, from, contractAddr, source, fromState, coinState; 23 var caseIndex = 0, lastnonce = 0; 24 25 function prepareSource(done) { 26 console.log("originSource address: " + originSource.getAddressString()); 27 neb.api.getAccountState(originSource.getAddressString()).then(function (resp) { 28 console.log("prepare source account state:" + JSON.stringify(resp)); 29 var nonce = parseInt(resp.nonce); 30 31 source = Account.NewAccount(); 32 33 var tx = new Transaction(ChainID, originSource, source, neb.nasToBasic(1000), nonce + 1, "1000000", "200000"); 34 tx.signTransaction(); 35 36 console.log("cliam source tx:", tx.toString()); 37 38 return neb.api.sendRawTransaction(tx.toProtoString()); 39 }).then(function (resp) { 40 console.log("send Raw Tx:" + JSON.stringify(resp)); 41 expect(resp).to.be.have.property('txhash'); 42 checkTransaction(resp.txhash, 0, function (receipt) { 43 console.log("tx receipt : " + JSON.stringify(receipt)); 44 expect(receipt).to.be.have.property('status').equal(1); 45 46 done(); 47 }); 48 }).catch(function (err) { 49 done(err); 50 }); 51 } 52 53 function cliamTokens(accounts, values, done) { 54 for (var i = 0; i < accounts.length; i++) { 55 console.log("acc:"+accounts[i].getAddressString()+" value:"+values[i]); 56 sendTransaction(source, accounts[i], values[i], ++lastnonce); 57 sleep(30); 58 } 59 checkCliamTokens(done); 60 } 61 62 63 function sendTransaction(from, address, value, nonce) { 64 var transaction = new Transaction(ChainID, from, address, value, nonce, "1000000", "200000"); 65 transaction.signTransaction(); 66 var rawTx = transaction.toProtoString(); 67 neb.api.sendRawTransaction(rawTx).then(function (resp) { 68 console.log("send raw transaction resp:" + JSON.stringify(resp)); 69 }); 70 } 71 72 function checkCliamTokens(done) { 73 var intervalAccount = setInterval(function () { 74 neb.api.getAccountState(source.getAddressString()).then(function (resp) { 75 // console.log("master accountState resp:" + JSON.stringify(resp)); 76 var nonce = parseInt(resp.nonce); 77 console.log("check cliam tokens nonce:", lastnonce); 78 79 if (lastnonce <= nonce){ 80 console.log("cliam tokens success"); 81 clearInterval(intervalAccount); 82 done(); 83 } 84 }); 85 }, 2000); 86 } 87 88 function checkTransaction(txhash, retry, done){ 89 90 var maxRetry = 45; 91 92 // contract status and get contract_address 93 var interval = setTimeout(function () { 94 neb.api.getTransactionReceipt(txhash).then(function (resp) { 95 retry++; 96 97 console.log("check transaction status:" + resp.status); 98 if(resp.status && resp.status === 1) { 99 // clearInterval(interval); 100 101 if (resp.contract_address) { 102 console.log("deploy private key:" + deploy.getPrivateKeyString()); 103 console.log("deploy address:" + deploy.getAddressString()); 104 console.log("deploy contract address:" + resp.contract_address); 105 106 contractAddr = resp.contract_address; 107 } 108 109 done(resp); 110 } else if (resp.status && resp.status === 2) { 111 if (retry > maxRetry) { 112 console.log("check transaction time out"); 113 // clearInterval(interval); 114 done(resp); 115 } else { 116 checkTransaction(txhash, retry++, done); 117 } 118 } else { 119 // clearInterval(interval); 120 console.log("transaction execution failed"); 121 done(resp); 122 } 123 }).catch(function (err) { 124 retry++; 125 console.log("check transaction not found retry " + retry); 126 if (retry > maxRetry) { 127 console.log(JSON.stringify(err.error)); 128 // clearInterval(interval); 129 done(err); 130 } else { 131 checkTransaction(txhash, retry++, done); 132 } 133 }); 134 135 }, 2000); 136 } 137 138 139 function deployContract(done, caseGroup) { 140 console.log("start deploying contract: " + caseGroup.groupname); 141 142 neb.api.getAccountState(source.getAddressString()).then(function (resp) { 143 console.log("source account state:" + JSON.stringify(resp)); 144 145 var accounts = new Array(); 146 var values = new Array(); 147 deploy = Account.NewAccount(); 148 accounts.push(deploy); 149 values.push(neb.nasToBasic(1)); 150 151 from = Account.NewAccount(); 152 accounts.push(from); 153 var fromBalance = (typeof caseGroup.fromBalance === "undefined") ? neb.nasToBasic(1) : caseGroup.fromBalance; 154 values.push(fromBalance); 155 156 cliamTokens(accounts, values, () => { 157 try { 158 var source = FS.readFileSync("../../../nf/nvm/test/" + caseGroup.filename, "utf-8"); 159 var contract = { 160 "source": source, 161 "sourceType": caseGroup.type, 162 "args": "" 163 }; 164 165 var tx = new Transaction(testnetConfig.ChainId, deploy, deploy, "0", 1, "10000000", "2000000", contract); 166 tx.signTransaction(); 167 var rawTx = tx.toProtoString(); 168 169 // console.log("contract:" + rawTx); 170 neb.api.sendRawTransaction(rawTx).then(function (resp) { 171 console.log("deploy contract " + caseGroup.groupname + " return: " + JSON.stringify(resp)); 172 173 checkTransaction(resp.txhash, 0, (ret) => { 174 if (ret.status && ret.status === 1) { 175 done(); 176 } else { 177 done(ret); 178 } 179 }); 180 }); 181 } catch (err) { 182 done(err); 183 }; 184 }); 185 186 }).catch (err => done(err)); 187 } 188 189 function runTest(testInput, testExpect, done) { 190 var fromAcc = (typeof testInput.from === "undefined") ? from : testInput.from; 191 var to = (typeof testInput.to === "undefined") ? Account.fromAddress(contractAddr) : testInput.to; 192 193 var fromBalanceBefore, toBalanceBefore; 194 195 neb.api.getAccountState(to.getAddressString()).then(function (resp) { 196 console.log("contractAddr state before: " + JSON.stringify(resp)); 197 toBalanceBefore = resp.balance; 198 return neb.api.getAccountState(from.getAddressString()); 199 }).then(resp => { 200 fromState = resp; 201 fromBalanceBefore = resp.balanece; 202 console.log("from state before: ", JSON.stringify(resp)); 203 return neb.api.getAccountState(coinbase); 204 }).then(function (resp) { 205 console.log("coin state before: ", JSON.stringify(resp)); 206 coinState = resp; 207 208 var tx = new Transaction(ChainID, fromAcc, to, testInput.value, parseInt(fromState.nonce) + testInput.nonce, testInput.gasPrice, testInput.gasLimit, testInput.contract); 209 tx.from.address = fromAcc.address; 210 tx.to.address = to.address; 211 tx.gasPrice = new BigNumber(testInput.gasPrice); 212 tx.gasLimit = new BigNumber(testInput.gasLimit); 213 tx.signTransaction(); 214 console.log("binary tx raw before send: ", tx.toString()); 215 return neb.api.sendRawTransaction(tx.toProtoString()); 216 }).then(function (rawResp) { 217 console.log("send Raw Tx return:" + JSON.stringify(rawResp)); 218 expect(rawResp).to.be.have.property('txhash'); 219 220 checkTransaction(rawResp.txhash, 0, function (receipt) { 221 console.log("tx receipt : " + JSON.stringify(receipt)); 222 try { 223 expect(receipt).to.not.be.a('undefined'); 224 if (true === testExpect.canExcuteTx) { 225 expect(receipt).to.be.have.property('status').equal(1); 226 } else { 227 expect(receipt).to.be.have.property('status').equal(0); 228 } 229 230 neb.api.getAccountState(receipt.from).then(function (state) { 231 232 console.log("from state after: " + JSON.stringify(state)); 233 // expect(state.balance).to.equal(testExpect.fromBalanceAfterTx); 234 return neb.api.getAccountState(contractAddr); 235 }).then(function (state) { 236 237 console.log("contractAddr state after: " + JSON.stringify(state)); 238 var change = new BigNumber(state.balance).minus(new BigNumber(toBalanceBefore)); 239 // expect(change.toString()).to.equal(testExpect.toBalanceChange); 240 return neb.api.getAccountState(coinbase); 241 }).then(function (state) { 242 243 console.log("get coinbase account state before tx:" + JSON.stringify(coinState)); 244 console.log("get coinbase account state after tx:" + JSON.stringify(state)); 245 var reward = new BigNumber(state.balance).sub(coinState.balance); 246 reward = reward.mod(new BigNumber(1.42694).mul(new BigNumber(10).pow(18))); 247 // The transaction should be only 248 // expect(reward.toString()).to.equal(testExpect.transferReward); 249 console.log("coinbase reward: " + reward.toString()); 250 if (receipt.gasUsed) { 251 var txCost = new BigNumber(receipt.gasUsed).mul(receipt.gasPrice).toString(10); 252 // expect(txCost).to.equal(testExpect.transferReward); 253 console.log("tx cost gas: " + txCost.toString()); 254 } 255 256 return neb.api.getEventsByHash(receipt.hash); 257 }).then(function (events) { 258 for (var i = 0; i < events.events.length; i++) { 259 var event = events.events[i]; 260 //console.log("tx event:", JSON.stringify(event,null,'\t')); 261 console.log("tx event:", event.data); 262 if (event.topic === "chain.transactionResult") { 263 var result = JSON.parse(event.data); 264 expect(result.status).to.equal(testExpect.status); 265 266 if (testExpect.hasOwnProperty("eventErr")){ 267 console.log("Event error checked."); 268 expect(result.error).to.equal(testExpect.eventErr); 269 } 270 } 271 if (event.topic === "chain.contract.random") { 272 var result = JSON.parse(event.data); 273 expect(result.defaultSeedRandom1 == result.userSeedRandom).to.equal(testExpect.equalr1r2); 274 console.log("check equalr1r2 success"); 275 } 276 } 277 done(); 278 }).catch(function (err) { 279 console.log("exe tx err:", err); 280 done(err); 281 }); 282 } catch (err) { 283 console.log("submit tx err:", err.message); 284 done(err); 285 } 286 }); 287 }).catch(function (err) { 288 if (err.error && err.error.error && testExpect.eventErr) { 289 try { 290 expect(err.error.error).to.equal(testExpect.eventErr) 291 done(); 292 } catch (err) { 293 done(err); 294 } 295 return; 296 } 297 done(err); 298 }); 299 } 300 301 var testCaseGroups = []; 302 303 // NOTE: for version before 1.1.0 304 // var caseGroup = { 305 // "filename": "contract_date_and_random.js", 306 // "type": "js", 307 // "groupname": "case group 0: Math.random", 308 // "groupIndex": 0, 309 310 // cases: [ 311 // { 312 // "name": "0-1. test 'undefined user seed'", 313 // "testInput": { 314 // value: "0", 315 // nonce: 1, 316 // gasPrice: 1000000, 317 // gasLimit: 2000000, 318 // contract: { 319 // function: "testRandom", 320 // args: "" 321 // } 322 // }, 323 // "testExpect": { 324 // canExcuteTx: false, 325 // toBalanceChange: "0", 326 // status: 0, 327 // eventErr: "Call: Error: input seed must be a string" 328 // } 329 // }, 330 // { 331 // "name": "0-2. test 'empty user seed('')'", 332 // "testInput": { 333 // value: "0", 334 // nonce: 1, 335 // gasPrice: 1000000, 336 // gasLimit: 2000000, 337 // contract: { 338 // function: "testRandom", 339 // args: "[\"\"]" 340 // } 341 // }, 342 // "testExpect": { 343 // canExcuteTx: true, 344 // toBalanceChange: "0", 345 // status: 1, 346 // equalr1r2: false 347 // } 348 // }, 349 // { 350 // "name": "0-3. test 'set user seed('abc')'", 351 // "testInput": { 352 // value: "0", 353 // nonce: 1, 354 // gasPrice: 1000000, 355 // gasLimit: 2000000, 356 // contract: { 357 // function: "testRandom", 358 // args: "[\"abc\"]" 359 // } 360 // }, 361 // "testExpect": { 362 // canExcuteTx: true, 363 // toBalanceChange: "0", 364 // status: 1, 365 // equalr1r2: false 366 // } 367 // } 368 // ] 369 // }; 370 371 372 // NOTE: for v1.1.0 373 var caseGroup = { 374 "filename": "contract_date_and_random.js", 375 "type": "js", 376 "groupname": "case group 0: Math.random", 377 "groupIndex": 0, 378 379 cases: [ 380 { 381 "name": "0-1. test", 382 "testInput": { 383 value: "0", 384 nonce: 1, 385 gasPrice: 1000000, 386 gasLimit: 2000000, 387 contract: { 388 function: "testRandom1_1_0", 389 args: "" 390 } 391 }, 392 "testExpect": { 393 canExcuteTx: true, 394 toBalanceChange: "0", 395 status: 1, 396 equalr1r2: false 397 } 398 } 399 ] 400 }; 401 testCaseGroups.push(caseGroup); 402 403 describe('Contract Math.random test', () => { 404 405 before(done => prepareSource(done)); 406 407 for (var i = 0; i < testCaseGroups.length; i++) { 408 409 // if (i != 3) {continue;} // selectively run tests 410 411 let caseGroup = testCaseGroups[i]; 412 describe(caseGroup.groupname, () => { 413 before(done => { 414 deployContract(done, caseGroup); 415 caseIndex = 0; 416 }); 417 418 419 for (var j = 0; j < caseGroup.cases.length; j++) { 420 let testCase = caseGroup.cases[j]; 421 it(testCase.name, done => { 422 console.log("===> running case: " + JSON.stringify(testCase)); 423 runTest(testCase.testInput, testCase.testExpect, done); 424 }); 425 } 426 427 afterEach(() => { 428 caseIndex++; 429 console.log("case group: " + caseGroup.groupIndex + ", index: " + caseIndex); 430 }); 431 }); 432 } 433 });