nodeos_run_test.py 33.5 KB
Newer Older
1
#!/usr/bin/env python3
2

3
#from testUtils import Utils
4
import testUtils
5
from TestHelper import TestHelper
6

K
Kevin Heifner 已提交
7
import decimal
8
import re
9 10

###############################################################
11
# nodeos_run_test
12 13
# --dump-error-details <Upon error print etc/eosio/node_*/config.ini and var/lib/node_*/stderr.log to stdout>
# --keep-logs <Don't delete var/lib/node_* folders upon test completion>
14 15 16
###############################################################

Print=testUtils.Utils.Print
17
errorExit=testUtils.Utils.errorExit
18

19
from core_symbol import CORE_SYMBOL
20

21 22
def cmdError(name, cmdCode=0, exitNow=False):
    msg="FAILURE - %s%s" % (name, ("" if cmdCode == 0 else (" returned error code %d" % cmdCode)))
23 24 25 26 27
    if exitNow:
        errorExit(msg, True)
    else:
        Print(msg)

28 29
args = TestHelper.parse_args({"--host","--port","--prod-count","--defproducera_prvt_key","--defproducerb_prvt_key","--mongodb"
                              ,"--dump-error-details","--dont-launch","--keep-logs","-v","--leave-running","--only-bios","--clean-run"})
30 31
server=args.host
port=args.port
32
debug=args.v
33
enableMongo=args.mongodb
34 35
defproduceraPrvtKey=args.defproducera_prvt_key
defproducerbPrvtKey=args.defproducerb_prvt_key
36 37 38
dumpErrorDetails=args.dump_error_details
keepLogs=args.keep_logs
dontLaunch=args.dont_launch
39
dontKill=args.leave_running
40
prodCount=args.prod_count
41
onlyBios=args.only_bios
42
killAll=args.clean_run
43

44
testUtils.Utils.Debug=debug
45
localTest=True if server == TestHelper.LOCAL_HOST else False
46
cluster=testUtils.Cluster(walletd=True, enableMongo=enableMongo, defproduceraPrvtKey=defproduceraPrvtKey, defproducerbPrvtKey=defproducerbPrvtKey)
47
walletMgr=testUtils.WalletMgr(True)
48
testSuccessful=False
49 50
killEosInstances=not dontKill
killWallet=not dontKill
51

52 53 54
WalletdName="keosd"
ClientName="cleos"
# testUtils.Utils.setMongoSyncTime(50)
55

56 57
try:
    Print("BEGIN")
58 59
    Print("SERVER: %s" % (server))
    Print("PORT: %d" % (port))
60

61 62 63
    if enableMongo and not cluster.isMongodDbRunning():
        errorExit("MongoDb doesn't seem to be running.")

64
    walletMgr.killall(allInstances=killAll)
65 66
    walletMgr.cleanup()

67
    if localTest and not dontLaunch:
68
        cluster.killall(allInstances=killAll)
69
        cluster.cleanup()
70
        Print("Stand up cluster")
71
        if cluster.launch(prodCount=prodCount, onlyBios=onlyBios, dontKill=dontKill) is False:
72 73
            cmdError("launcher")
            errorExit("Failed to stand up eos cluster.")
74
    else:
75
        cluster.initializeNodes(defproduceraPrvtKey=defproduceraPrvtKey, defproducerbPrvtKey=defproducerbPrvtKey)
76 77
        killEosInstances=False

C
Ciju John 已提交
78 79 80
    Print("Validating system accounts after bootstrap")
    cluster.validateAccounts(None)

81 82 83 84
    accounts=testUtils.Cluster.createAccountKeys(3)
    if accounts is None:
        errorExit("FAILURE - create keys")
    testeraAccount=accounts[0]
85
    testeraAccount.name="testera11111"
86
    currencyAccount=accounts[1]
87
    currencyAccount.name="currency1111"
88
    exchangeAccount=accounts[2]
89
    exchangeAccount.name="exchange1111"
90 91 92 93 94 95 96

    PRV_KEY1=testeraAccount.ownerPrivateKey
    PUB_KEY1=testeraAccount.ownerPublicKey
    PRV_KEY2=currencyAccount.ownerPrivateKey
    PUB_KEY2=currencyAccount.ownerPublicKey
    PRV_KEY3=exchangeAccount.activePrivateKey
    PUB_KEY3=exchangeAccount.activePublicKey
97

98 99 100 101 102
    testeraAccount.activePrivateKey=currencyAccount.activePrivateKey=PRV_KEY3
    testeraAccount.activePublicKey=currencyAccount.activePublicKey=PUB_KEY3

    exchangeAccount.ownerPrivateKey=PRV_KEY2
    exchangeAccount.ownerPublicKey=PUB_KEY2
103

B
Brian Johnson 已提交
104
    Print("Stand up %s" % (WalletdName))
105
    walletMgr.killall(allInstances=killAll)
106
    walletMgr.cleanup()
107
    if walletMgr.launch() is False:
108
        cmdError("%s" % (WalletdName))
109 110 111 112
        errorExit("Failed to stand up eos walletd.")

    testWalletName="test"
    Print("Creating wallet \"%s\"." % (testWalletName))
P
Paul Calabrese 已提交
113
    testWallet=walletMgr.create(testWalletName, [cluster.eosioAccount,cluster.defproduceraAccount,cluster.defproducerbAccount])
114 115 116 117
    if testWallet is None:
        cmdError("eos wallet create")
        errorExit("Failed to create wallet %s." % (testWalletName))

118 119
    Print("Wallet \"%s\" password=%s." % (testWalletName, testWallet.password.encode("utf-8")))

120 121 122
    for account in accounts:
        Print("Importing keys for account %s into wallet %s." % (account.name, testWallet.name))
        if not walletMgr.importKey(account, testWallet):
123
            cmdError("%s wallet import" % (ClientName))
124 125
            errorExit("Failed to import key for account %s" % (account.name))

126 127 128 129
    defproduceraWalletName="defproducera"
    Print("Creating wallet \"%s\"." % (defproduceraWalletName))
    defproduceraWallet=walletMgr.create(defproduceraWalletName)
    if defproduceraWallet is None:
130
        cmdError("eos wallet create")
131
        errorExit("Failed to create wallet %s." % (defproduceraWalletName))
132

133 134
    Print("Wallet \"%s\" password=%s." % (defproduceraWalletName, defproduceraWallet.password.encode("utf-8")))

135 136
    defproduceraAccount=cluster.defproduceraAccount
    defproducerbAccount=cluster.defproducerbAccount
137

138 139
    Print("Importing keys for account %s into wallet %s." % (defproduceraAccount.name, defproduceraWallet.name))
    if not walletMgr.importKey(defproduceraAccount, defproduceraWallet):
140
        cmdError("%s wallet import" % (ClientName))
141
        errorExit("Failed to import key for account %s" % (defproduceraAccount.name))
142 143 144

    Print("Locking wallet \"%s\"." % (testWallet.name))
    if not walletMgr.lockWallet(testWallet):
145
        cmdError("%s wallet lock" % (ClientName))
146 147 148 149
        errorExit("Failed to lock wallet %s" % (testWallet.name))

    Print("Unlocking wallet \"%s\"." % (testWallet.name))
    if not walletMgr.unlockWallet(testWallet):
150
        cmdError("%s wallet unlock" % (ClientName))
151 152 153 154
        errorExit("Failed to unlock wallet %s" % (testWallet.name))

    Print("Locking all wallets.")
    if not walletMgr.lockAllWallets():
155
        cmdError("%s wallet lock_all" % (ClientName))
156 157 158 159
        errorExit("Failed to lock all wallets")

    Print("Unlocking wallet \"%s\"." % (testWallet.name))
    if not walletMgr.unlockWallet(testWallet):
160
        cmdError("%s wallet unlock" % (ClientName))
161 162 163 164 165 166 167 168 169
        errorExit("Failed to unlock wallet %s" % (testWallet.name))

    Print("Getting open wallet list.")
    wallets=walletMgr.getOpenWallets()
    if len(wallets) == 0 or wallets[0] != testWallet.name or len(wallets) > 1:
        Print("FAILURE - wallet list did not include %s" % (testWallet.name))
        errorExit("Unexpected wallet list: %s" % (wallets))

    Print("Getting wallet keys.")
170
    actualKeys=walletMgr.getKeys(testWallet)
171 172 173 174 175 176
    expectedkeys=[]
    for account in accounts:
        expectedkeys.append(account.ownerPrivateKey)
        expectedkeys.append(account.activePrivateKey)
    noMatch=list(set(expectedkeys) - set(actualKeys))
    if len(noMatch) > 0:
177
        errorExit("FAILURE - wallet keys did not include %s" % (noMatch), raw=True)
178 179 180

    Print("Locking all wallets.")
    if not walletMgr.lockAllWallets():
181
        cmdError("%s wallet lock_all" % (ClientName))
182 183
        errorExit("Failed to lock all wallets")

184 185
    Print("Unlocking wallet \"%s\"." % (defproduceraWallet.name))
    if not walletMgr.unlockWallet(defproduceraWallet):
186
        cmdError("%s wallet unlock" % (ClientName))
187
        errorExit("Failed to unlock wallet %s" % (defproduceraWallet.name))
188 189 190

    Print("Unlocking wallet \"%s\"." % (testWallet.name))
    if not walletMgr.unlockWallet(testWallet):
191
        cmdError("%s wallet unlock" % (ClientName))
192 193 194
        errorExit("Failed to unlock wallet %s" % (testWallet.name))

    Print("Getting wallet keys.")
195
    actualKeys=walletMgr.getKeys(defproduceraWallet)
196
    expectedkeys=[defproduceraAccount.ownerPrivateKey]
197 198
    noMatch=list(set(expectedkeys) - set(actualKeys))
    if len(noMatch) > 0:
199
        errorExit("FAILURE - wallet keys did not include %s" % (noMatch), raw=True)
200

201 202 203 204
    node=cluster.getNode(0)
    if node is None:
        errorExit("Cluster in bad state, received None node")

C
Ciju John 已提交
205 206 207
    Print("Validating accounts before user accounts creation")
    cluster.validateAccounts(None)

208 209 210
    # create accounts via eosio as otherwise a bid is needed 
    Print("Create new account %s via %s" % (testeraAccount.name, cluster.eosioAccount.name))
    transId=node.createInitializeAccount(testeraAccount, cluster.eosioAccount, stakedDeposit=0, waitForTransBlock=False)
211
    if transId is None:
C
Ciju John 已提交
212
        cmdError("%s create account" % (testeraAccount.name))
213 214
        errorExit("Failed to create account %s" % (testeraAccount.name))

215 216
    Print("Create new account %s via %s" % (currencyAccount.name, cluster.eosioAccount.name))
    transId=node.createInitializeAccount(currencyAccount, cluster.eosioAccount, stakedDeposit=5000)
C
Ciju John 已提交
217 218 219 220
    if transId is None:
        cmdError("%s create account" % (ClientName))
        errorExit("Failed to create account %s" % (currencyAccount.name))

221 222
    Print("Create new account %s via %s" % (exchangeAccount.name, cluster.eosioAccount.name))
    transId=node.createInitializeAccount(exchangeAccount, cluster.eosioAccount, waitForTransBlock=True)
C
Ciju John 已提交
223 224 225 226 227 228 229 230
    if transId is None:
        cmdError("%s create account" % (ClientName))
        errorExit("Failed to create account %s" % (exchangeAccount.name))

    Print("Validating accounts after user accounts creation")
    accounts=[testeraAccount, currencyAccount, exchangeAccount]
    cluster.validateAccounts(accounts)

231 232 233 234
    Print("Verify account %s" % (testeraAccount))
    if not node.verifyAccount(testeraAccount):
        errorExit("FAILURE - account creation failed.", raw=True)

235
    transferAmount="97.5321 {0}".format(CORE_SYMBOL)
236 237
    Print("Transfer funds %s from account %s to %s" % (transferAmount, defproduceraAccount.name, testeraAccount.name))
    if node.transferFunds(defproduceraAccount, testeraAccount, transferAmount, "test transfer") is None:
238
        cmdError("%s transfer" % (ClientName))
239
        errorExit("Failed to transfer funds %d from account %s to %s" % (
240
            transferAmount, defproduceraAccount.name, testeraAccount.name))
241

242 243 244 245 246 247
    expectedAmount=transferAmount
    Print("Verify transfer, Expected: %s" % (expectedAmount))
    actualAmount=node.getAccountEosBalanceStr(testeraAccount.name)
    if expectedAmount != actualAmount:
        cmdError("FAILURE - transfer failed")
        errorExit("Transfer verification failed. Excepted %s, actual: %s" % (expectedAmount, actualAmount))
248

249
    transferAmount="0.0100 {0}".format(CORE_SYMBOL)
250
    Print("Force transfer funds %s from account %s to %s" % (
251 252
        transferAmount, defproduceraAccount.name, testeraAccount.name))
    if node.transferFunds(defproduceraAccount, testeraAccount, transferAmount, "test transfer", force=True) is None:
253
        cmdError("%s transfer" % (ClientName))
254
        errorExit("Failed to force transfer funds %d from account %s to %s" % (
255
            transferAmount, defproduceraAccount.name, testeraAccount.name))
256

257
    expectedAmount="97.5421 {0}".format(CORE_SYMBOL)
258 259 260 261 262
    Print("Verify transfer, Expected: %s" % (expectedAmount))
    actualAmount=node.getAccountEosBalanceStr(testeraAccount.name)
    if expectedAmount != actualAmount:
        cmdError("FAILURE - transfer failed")
        errorExit("Transfer verification failed. Excepted %s, actual: %s" % (expectedAmount, actualAmount))
263

C
Ciju John 已提交
264 265 266
    Print("Validating accounts after some user trasactions")
    accounts=[testeraAccount, currencyAccount, exchangeAccount]
    cluster.validateAccounts(accounts)
267 268 269

    Print("Locking all wallets.")
    if not walletMgr.lockAllWallets():
270
        cmdError("%s wallet lock_all" % (ClientName))
271 272 273 274
        errorExit("Failed to lock all wallets")

    Print("Unlocking wallet \"%s\"." % (testWallet.name))
    if not walletMgr.unlockWallet(testWallet):
275
        cmdError("%s wallet unlock" % (ClientName))
276 277
        errorExit("Failed to unlock wallet %s" % (testWallet.name))

278
    transferAmount="97.5311 {0}".format(CORE_SYMBOL)
279
    Print("Transfer funds %s from account %s to %s" % (
280
        transferAmount, testeraAccount.name, currencyAccount.name))
281 282
    trans=node.transferFunds(testeraAccount, currencyAccount, transferAmount, "test transfer a->b")
    if trans is None:
283
        cmdError("%s transfer" % (ClientName))
284
        errorExit("Failed to transfer funds %d from account %s to %s" % (
C
Ciju John 已提交
285
            transferAmount, testeraAccount.name, currencyAccount.name))
286
    transId=testUtils.Node.getTransId(trans)
287

288
    expectedAmount="98.0311 {0}".format(CORE_SYMBOL) # 5000 initial deposit
289 290 291 292 293
    Print("Verify transfer, Expected: %s" % (expectedAmount))
    actualAmount=node.getAccountEosBalanceStr(currencyAccount.name)
    if expectedAmount != actualAmount:
        cmdError("FAILURE - transfer failed")
        errorExit("Transfer verification failed. Excepted %s, actual: %s" % (expectedAmount, actualAmount))
294

C
Ciju John 已提交
295 296 297 298 299
    Print("Validate last action for account %s" % (testeraAccount.name))
    actions=node.getActions(testeraAccount, -1, -1)
    assert(actions)
    try:
        assert(actions["actions"][0]["action_trace"]["act"]["name"] == "transfer")
300
    except (AssertionError, TypeError, KeyError) as _:
301
        Print("Last action validation failed. Actions: %s" % (actions))
C
Ciju John 已提交
302 303
        raise

304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
    # This API (get accounts) is no longer supported (Issue 2876)
    # expectedAccounts=[testeraAccount.name, currencyAccount.name, exchangeAccount.name]
    # Print("Get accounts by key %s, Expected: %s" % (PUB_KEY3, expectedAccounts))
    # actualAccounts=node.getAccountsArrByKey(PUB_KEY3)
    # if actualAccounts is None:
    #     cmdError("%s get accounts pub_key3" % (ClientName))
    #     errorExit("Failed to retrieve accounts by key %s" % (PUB_KEY3))
    # noMatch=list(set(expectedAccounts) - set(actualAccounts))
    # if len(noMatch) > 0:
    #     errorExit("FAILURE - Accounts lookup by key %s. Expected: %s, Actual: %s" % (
    #         PUB_KEY3, expectedAccounts, actualAccounts), raw=True)
    #
    # expectedAccounts=[testeraAccount.name]
    # Print("Get accounts by key %s, Expected: %s" % (PUB_KEY1, expectedAccounts))
    # actualAccounts=node.getAccountsArrByKey(PUB_KEY1)
    # if actualAccounts is None:
    #     cmdError("%s get accounts pub_key1" % (ClientName))
    #     errorExit("Failed to retrieve accounts by key %s" % (PUB_KEY1))
    # noMatch=list(set(expectedAccounts) - set(actualAccounts))
    # if len(noMatch) > 0:
    #     errorExit("FAILURE - Accounts lookup by key %s. Expected: %s, Actual: %s" % (
    #         PUB_KEY1, expectedAccounts, actualAccounts), raw=True)
326 327

    # This API (get servants) is no longer supported. (Issue 3160)
328
    # expectedServants=[testeraAccount.name, currencyAccount.name]
329 330
    # Print("Get %s servants, Expected: %s" % (defproduceraAccount.name, expectedServants))
    # actualServants=node.getServantsArr(defproduceraAccount.name)
331
    # if actualServants is None:
332 333
    #     cmdError("%s get servants testera11111" % (ClientName))
    #     errorExit("Failed to retrieve %s servants" % (defproduceraAccount.name))
334 335 336
    # noMatch=list(set(expectedAccounts) - set(actualAccounts))
    # if len(noMatch) > 0:
    #     errorExit("FAILURE - %s servants. Expected: %s, Actual: %s" % (
337
    #         defproduceraAccount.name, expectedServants, actualServants), raw=True)
338 339 340 341
    #
    # Print("Get %s servants, Expected: []" % (testeraAccount.name))
    # actualServants=node.getServantsArr(testeraAccount.name)
    # if actualServants is None:
342
    #     cmdError("%s get servants testera11111" % (ClientName))
343 344 345 346
    #     errorExit("Failed to retrieve %s servants" % (testeraAccount.name))
    # if len(actualServants) > 0:
    #     errorExit("FAILURE - %s servants. Expected: [], Actual: %s" % (
    #         testeraAccount.name, actualServants), raw=True)
347

348
    node.waitForTransInBlock(transId)
349

350 351 352 353
    transaction=None
    if not enableMongo:
        transaction=node.getTransaction(transId)
    else:
354
        transaction=node.getActionFromDb(transId)
355
    if transaction is None:
356
        cmdError("%s get transaction trans_id" % (ClientName))
357 358
        errorExit("Failed to retrieve transaction details %s" % (transId))

359 360
    typeVal=None
    amountVal=None
361 362 363 364 365 366 367 368 369 370
    assert(transaction)
    try:
        if not enableMongo:
            typeVal=  transaction["traces"][0]["act"]["name"]
            amountVal=transaction["traces"][0]["act"]["data"]["quantity"]
            amountVal=int(decimal.Decimal(amountVal.split()[0])*10000)
        else:
            typeVal=  transaction["name"]
            amountVal=transaction["data"]["quantity"]
            amountVal=int(decimal.Decimal(amountVal.split()[0])*10000)
C
Ciju John 已提交
371
    except (TypeError, KeyError) as e:
372 373
        Print("Transaction validation parsing failed. Transaction: %s" % (transaction))
        raise
374 375

    if typeVal != "transfer" or amountVal != 975311:
K
Kevin Heifner 已提交
376
        errorExit("FAILURE - get transaction trans_id failed: %s %s %s" % (transId, typeVal, amountVal), raw=True)
377

378 379
    Print("Currency Contract Tests")
    Print("verify no contract in place")
380 381 382
    Print("Get code hash for account %s" % (currencyAccount.name))
    codeHash=node.getAccountCodeHash(currencyAccount.name)
    if codeHash is None:
383
        cmdError("%s get code currency1111" % (ClientName))
384
        errorExit("Failed to get code hash for account %s" % (currencyAccount.name))
385 386
    hashNum=int(codeHash, 16)
    if hashNum != 0:
387
        errorExit("FAILURE - get code currency1111 failed", raw=True)
388

389 390 391
    contractDir="contracts/eosio.token"
    wastFile="contracts/eosio.token/eosio.token.wast"
    abiFile="contracts/eosio.token/eosio.token.abi"
392
    Print("Publish contract")
393
    trans=node.publishContract(currencyAccount.name, contractDir, wastFile, abiFile, waitForTransBlock=True)
394
    if trans is None:
395
        cmdError("%s set contract currency1111" % (ClientName))
396
        errorExit("Failed to publish contract.")
397

398 399 400 401
    if not enableMongo:
        Print("Get code hash for account %s" % (currencyAccount.name))
        codeHash=node.getAccountCodeHash(currencyAccount.name)
        if codeHash is None:
402
            cmdError("%s get code currency1111" % (ClientName))
403 404 405
            errorExit("Failed to get code hash for account %s" % (currencyAccount.name))
        hashNum=int(codeHash, 16)
        if hashNum == 0:
406
            errorExit("FAILURE - get code currency1111 failed", raw=True)
407 408 409 410
    else:
        Print("verify abi is set")
        account=node.getEosAccountFromDb(currencyAccount.name)
        abiName=account["abi"]["structs"][0]["name"]
411
        abiActionName=account["abi"]["actions"][0]["name"]
412 413
        abiType=account["abi"]["actions"][0]["type"]
        if abiName != "transfer" or abiActionName != "transfer" or abiType != "transfer":
414
            errorExit("FAILURE - get EOS account failed", raw=True)
415

416 417
    Print("push create action to currency1111 contract")
    contract="currency1111"
418
    action="create"
419 420
    data="{\"issuer\":\"currency1111\",\"maximum_supply\":\"100000.0000 CUR\",\"can_freeze\":\"0\",\"can_recall\":\"0\",\"can_whitelist\":\"0\"}"
    opts="--permission currency1111@active"
421
    trans=node.pushMessage(contract, action, data, opts)
422 423 424 425 426 427
    try:
        assert(trans)
        assert(trans[0])
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed push create action to currency1111 contract assertion. %s" % (trans))
        raise
428

429
    Print("push issue action to currency1111 contract")
430
    action="issue"
431 432
    data="{\"to\":\"currency1111\",\"quantity\":\"100000.0000 CUR\",\"memo\":\"issue\"}"
    opts="--permission currency1111@active"
433
    trans=node.pushMessage(contract, action, data, opts)
434 435 436 437 438 439
    try:
        assert(trans)
        assert(trans[0])
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed push issue action to currency1111 contract assertion. %s" % (trans))
        raise
440

441 442
    Print("Verify currency1111 contract has proper initial balance (via get table)")
    contract="currency1111"
443 444
    table="accounts"
    row0=node.getTableRow(contract, currencyAccount.name, table, 0)
445 446 447 448 449 450
    try:
        assert(row0)
        assert(row0["balance"] == "100000.0000 CUR")
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed get table row assertion. %s" % (row0))
        raise
451

452
    Print("Verify currency1111 contract has proper initial balance (via get currency1111 balance)")
453
    amountStr=node.getTableAccountBalance("currency1111", currencyAccount.name)
454 455

    expected="100000.0000 CUR"
456
    actual=amountStr
457
    if actual != expected:
458
        errorExit("FAILURE - currency1111 balance check failed. Expected: %s, Recieved %s" % (expected, actual), raw=True)
459

460 461 462 463 464 465 466 467
    Print("Verify currency1111 contract has proper total supply of CUR (via get currency1111 stats)")
    res=node.getCurrencyStats(contract, "CUR")
    try:
        assert(res)
        assert(res["CUR"]["supply"] == "100000.0000 CUR")
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed get currecy stats assertion. %s" % (res))
        raise
468

469 470
    Print("push transfer action to currency1111 contract")
    contract="currency1111"
471
    action="transfer"
472
    data="{\"from\":\"currency1111\",\"to\":\"defproducera\",\"quantity\":"
473
    data +="\"00.0050 CUR\",\"memo\":\"test\"}"
474
    opts="--permission currency1111@active"
475
    trans=node.pushMessage(contract, action, data, opts)
476
    if trans is None or not trans[0]:
477 478
        cmdError("%s push message currency1111 transfer" % (ClientName))
        errorExit("Failed to push message to currency1111 contract")
479
    transId=testUtils.Node.getTransId(trans[1])
480

481 482 483 484
    Print("push duplicate transfer action to currency1111 contract")
    transDuplicate=node.pushMessage(contract, action, data, opts, True)
    if transDuplicate is not None and transDuplicate[0]:
        transDuplicateId=testUtils.Node.getTransId(transDuplicate[1])
485 486
        if transId != transDuplicateId:
            cmdError("%s push message currency1111 duplicate transfer incorrectly accepted, but they were generated with different transaction ids, it is likely a timing issue, report if problem persists, \norig: %s \ndup: %s" % (ClientName, trans, transDuplicate))
487 488 489 490
        else:
            cmdError("%s push message currency1111 transfer, \norig: %s \ndup: %s" % (ClientName, trans, transDuplicate))
        errorExit("Failed to reject duplicate message for currency1111 contract")

491
    Print("verify transaction exists")
492
    if not node.waitForTransInBlock(transId):
493
        cmdError("%s get transaction trans_id" % (ClientName))
494
        errorExit("Failed to verify push message transaction id.")
495

496
    Print("read current contract balance")
497
    amountStr=node.getTableAccountBalance("currency1111", defproduceraAccount.name)
498 499

    expected="0.0050 CUR"
500
    actual=amountStr
501
    if actual != expected:
502
        errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (str(expected), str(actual)), raw=True)
503

504
    amountStr=node.getTableAccountBalance("currency1111", currencyAccount.name)
505 506

    expected="99999.9950 CUR"
507
    actual=amountStr
508
    if actual != expected:
509
        errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (str(expected), str(actual)), raw=True)
510

511 512 513 514 515 516 517 518 519 520
    amountStr=node.getCurrencyBalance("currency1111", currencyAccount.name, "CUR")
    try:
        assert(actual)
        assert(isinstance(actual, str))
        actual=amountStr.strip()
        assert(expected == actual)
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed get currecy balance assertion. (expected=<%s>, actual=<%s>)" % (str(expected), str(actual)))
        raise

521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
    Print("Test for block decoded packed transaction (issue 2932)")
    blockId=node.getBlockIdByTransId(transId)
    assert(blockId)
    block=node.getBlock(blockId)
    assert(block)
    transactions=None
    try:
        transactions=block["transactions"]
        assert(transactions)
    except (AssertionError, TypeError, KeyError) as _:
        Print("FAILURE - Failed to parse block. %s" % (block))
        raise

    myTrans=None
    for trans in transactions:
        assert(trans)
        try:
            myTransId=trans["trx"]["id"]
            if transId == myTransId:
                myTrans=trans["trx"]["transaction"]
                assert(myTrans)
                break
        except (AssertionError, TypeError, KeyError) as _:
            Print("FAILURE - Failed to parse block transactions. %s" % (trans))
            raise

    assert(myTrans)
    try:
        assert(myTrans["actions"][0]["name"] == "transfer")
        assert(myTrans["actions"][0]["account"] == "currency1111")
        assert(myTrans["actions"][0]["authorization"][0]["actor"] == "currency1111")
        assert(myTrans["actions"][0]["authorization"][0]["permission"] == "active")
        assert(myTrans["actions"][0]["data"]["from"] == "currency1111")
        assert(myTrans["actions"][0]["data"]["to"] == "defproducera")
        assert(myTrans["actions"][0]["data"]["quantity"] == "0.0050 CUR")
        assert(myTrans["actions"][0]["data"]["memo"] == "test")
    except (AssertionError, TypeError, KeyError) as _:
        Print("FAILURE - Failed to parse block transaction. %s" % (myTrans))
        raise

561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
    Print("Unlocking wallet \"%s\"." % (defproduceraWallet.name))
    if not walletMgr.unlockWallet(defproduceraWallet):
        cmdError("%s wallet unlock" % (ClientName))
        errorExit("Failed to unlock wallet %s" % (defproduceraWallet.name))

    Print("push transfer action to currency1111 contract that would go negative")
    contract="currency1111"
    action="transfer"
    data="{\"from\":\"defproducera\",\"to\":\"currency1111\",\"quantity\":"
    data +="\"00.0051 CUR\",\"memo\":\"test\"}"
    opts="--permission defproducera@active"
    trans=node.pushMessage(contract, action, data, opts, True)
    if trans is None or trans[0]:
        cmdError("%s push message currency1111 transfer should have failed" % (ClientName))
        errorExit("Failed to reject invalid transfer message to currency1111 contract")

    Print("read current contract balance")
    amountStr=node.getTableAccountBalance("currency1111", defproduceraAccount.name)

    expected="0.0050 CUR"
    actual=amountStr
    if actual != expected:
        errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (str(expected), str(actual)), raw=True)

    amountStr=node.getTableAccountBalance("currency1111", currencyAccount.name)

    expected="99999.9950 CUR"
    actual=amountStr
    if actual != expected:
        errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (str(expected), str(actual)), raw=True)

    Print("push another transfer action to currency1111 contract")
    contract="currency1111"
    action="transfer"
    data="{\"from\":\"defproducera\",\"to\":\"currency1111\",\"quantity\":"
    data +="\"00.0050 CUR\",\"memo\":\"test\"}"
    opts="--permission defproducera@active"
    trans=node.pushMessage(contract, action, data, opts)
    if trans is None or not trans[0]:
        cmdError("%s push message currency1111 transfer" % (ClientName))
        errorExit("Failed to push message to currency1111 contract")
    transId=testUtils.Node.getTransId(trans[1])

    Print("read current contract balance")
    amountStr=node.getCurrencyBalance("currency1111", defproduceraAccount.name, "CUR")
    expected="0.0000 CUR"
    try:
        actual=amountStr.strip()
        assert(expected == actual or not actual)
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed get currecy balance assertion. (expected=<%s>, actual=<%s>)" % (str(expected), str(actual)))
        raise

    amountStr=node.getTableAccountBalance("currency1111", currencyAccount.name)

    expected="100000.0000 CUR"
    actual=amountStr
    if actual != expected:
        errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (str(expected), str(actual)), raw=True)

    Print("push transfer action to currency1111 contract that would go negative")
    contract="currency1111"
    action="transfer"
    data="{\"from\":\"defproducera\",\"to\":\"currency1111\",\"quantity\":"
    data +="\"00.0025 CUR\",\"memo\":\"test\"}"
    opts="--permission defproducera@active"
    trans=node.pushMessage(contract, action, data, opts, True)
    if trans is None or trans[0]:
        cmdError("%s push message currency1111 transfer should have failed" % (ClientName))
        errorExit("Failed to reject invalid transfer message to currency1111 contract")

    Print("read current contract balance")
    amountStr=node.getCurrencyBalance("currency1111", defproduceraAccount.name, "CUR")
    expected="0.0000 CUR"
    try:
        actual=amountStr.strip()
        assert(expected == actual or not actual)
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed get currecy balance assertion. (expected=<%s>, actual=<%s>)" % (str(expected), str(actual)))
        raise

    amountStr=node.getTableAccountBalance("currency1111", currencyAccount.name)

    expected="100000.0000 CUR"
    actual=amountStr
    if actual != expected:
        errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (str(expected), str(actual)), raw=True)

    Print("Locking wallet \"%s\"." % (defproduceraWallet.name))
    if not walletMgr.lockWallet(defproduceraWallet):
        cmdError("%s wallet lock" % (ClientName))
        errorExit("Failed to lock wallet %s" % (defproduceraWallet.name))

654

655 656 657
    Print("Exchange Contract Tests")
    Print("upload exchange contract")

658
    contractDir="contracts/exchange"
659 660 661
    wastFile="contracts/exchange/exchange.wast"
    abiFile="contracts/exchange/exchange.abi"
    Print("Publish exchange contract")
662
    trans=node.publishContract(exchangeAccount.name, contractDir, wastFile, abiFile, waitForTransBlock=True)
663 664 665
    if trans is None:
        cmdError("%s set contract exchange" % (ClientName))
        errorExit("Failed to publish contract.")
666

667
    contractDir="contracts/simpledb"
668 669
    wastFile="contracts/simpledb/simpledb.wast"
    abiFile="contracts/simpledb/simpledb.abi"
670 671
    Print("Setting simpledb contract without simpledb account was causing core dump in %s." % (ClientName))
    Print("Verify %s generates an error, but does not core dump." % (ClientName))
672
    retMap=node.publishContract("simpledb", contractDir, wastFile, abiFile, shouldFail=True)
673 674 675 676 677
    if retMap is None:
        errorExit("Failed to publish, but should have returned a details map")
    if retMap["returncode"] == 0 or retMap["returncode"] == 139: # 139 SIGSEGV
        errorExit("FAILURE - set contract exchange failed", raw=True)
    else:
678
        Print("Test successful, %s returned error code: %d" % (ClientName, retMap["returncode"]))
679 680

    Print("set permission")
681
    code="currency1111"
682 683 684 685
    pType="transfer"
    requirement="active"
    trans=node.setPermission(testeraAccount.name, code, pType, requirement, waitForTransBlock=True)
    if trans is None:
686
        cmdError("%s set action permission set" % (ClientName))
687 688
        errorExit("Failed to set permission")

689 690 691 692 693 694
    Print("remove permission")
    requirement="null"
    trans=node.setPermission(testeraAccount.name, code, pType, requirement, waitForTransBlock=True)
    if trans is None:
        cmdError("%s set action permission set" % (ClientName))
        errorExit("Failed to remove permission")
695

696 697
    Print("Locking all wallets.")
    if not walletMgr.lockAllWallets():
698
        cmdError("%s wallet lock_all" % (ClientName))
699 700
        errorExit("Failed to lock all wallets")

701 702 703 704
    Print("Unlocking wallet \"%s\"." % (defproduceraWallet.name))
    if not walletMgr.unlockWallet(defproduceraWallet):
        cmdError("%s wallet unlock defproducera" % (ClientName))
        errorExit("Failed to unlock wallet %s" % (defproduceraWallet.name))
705

706 707
    Print("Get account defproducera")
    account=node.getEosAccount(defproduceraAccount.name)
708
    if account is None:
709
        cmdError("%s get account" % (ClientName))
710
        errorExit("Failed to get account %s" % (defproduceraAccount.name))
711 712 713 714 715 716 717 718 719 720 721

    #
    # Proxy
    #
    # not implemented

    Print("Get head block num.")
    currentBlockNum=node.getHeadBlockNum()
    Print("CurrentBlockNum: %d" % (currentBlockNum))
    Print("Request blocks 1-%d" % (currentBlockNum))
    for blockNum in range(1, currentBlockNum+1):
722
        block=node.getBlock(blockNum, retry=False, silentErrors=False)
723
        if block is None:
K
Kevin Heifner 已提交
724 725
            cmdError("%s get block" % (ClientName))
            errorExit("get block by num %d" % blockNum)
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740

        if enableMongo:
            blockId=block["block_id"]
            block2=node.getBlockById(blockId, retry=False)
            if block2 is None:
                errorExit("mongo get block by id %s" % blockId)

            # TBD: getTransByBlockId() needs to handle multiple returned transactions
            # trans=node.getTransByBlockId(blockId, retry=False)
            # if trans is not None:
            #     transId=testUtils.Node.getTransId(trans)
            #     trans2=node.getMessageFromDb(transId)
            #     if trans2 is None:
            #         errorExit("mongo get messages by transaction id %s" % (transId))

741

C
Ciju John 已提交
742
    Print("Request invalid block numbered %d. This will generate an expected error message." % (currentBlockNum+1000))
743
    block=node.getBlock(currentBlockNum+1000, silentErrors=True, retry=False)
744 745 746 747 748 749 750
    if block is not None:
        errorExit("ERROR: Received block where not expected")
    else:
        Print("Success: No such block found")

    if localTest:
        p = re.compile('Assert')
751
        errFileName="var/lib/node_00/stderr.txt"
752
        assertionsFound=False
753 754 755
        with open(errFileName) as errFile:
            for line in errFile:
                if p.search(line):
756 757 758 759 760 761 762
                    assertionsFound=True

        if assertionsFound:
            # Too many assertion logs, hard to validate how many are genuine. Make this a warning
            #  for now, hopefully the logs will get cleaned up in future.
            Print("WARNING: Asserts in var/lib/node_00/stderr.txt")
            #errorExit("FAILURE - Assert in var/lib/node_00/stderr.txt")
763

C
Ciju John 已提交
764 765 766 767
    Print("Validating accounts at end of test")
    accounts=[testeraAccount, currencyAccount, exchangeAccount]
    cluster.validateAccounts(accounts)

768 769
    testSuccessful=True
finally:
770
    TestHelper.shutdown(cluster, walletMgr, testSuccessful, killEosInstances, killWallet, keepLogs, killAll, dumpErrorDetails)
771

772
exit(0)