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

3 4 5 6
from testUtils import Utils
from Cluster import Cluster
from WalletMgr import WalletMgr
from Node import Node
7
from TestHelper import TestHelper
8

K
Kevin Heifner 已提交
9
import decimal
10
import re
11 12

###############################################################
13
# nodeos_run_test
14 15
# --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>
16 17
###############################################################

18 19
Print=Utils.Print
errorExit=Utils.errorExit
B
Brian Johnson 已提交
20
cmdError=Utils.cmdError
21
from core_symbol import CORE_SYMBOL
22

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

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

50 51
WalletdName="keosd"
ClientName="cleos"
C
Ciju John 已提交
52 53
timeout = .5 * 12 * 2 + 60 # time for finalization with 1 producer + 60 seconds padding
Utils.setIrreversibleTimeout(timeout)
54

55
try:
56
    TestHelper.printSystemInfo("BEGIN")
57 58
    Print("SERVER: %s" % (server))
    Print("PORT: %d" % (port))
59

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

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

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

77 78 79 80
    if sanityTest:
        testSuccessful=True
        exit(0)

C
Ciju John 已提交
81 82 83
    Print("Validating system accounts after bootstrap")
    cluster.validateAccounts(None)

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

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

101 102 103 104 105
    testeraAccount.activePrivateKey=currencyAccount.activePrivateKey=PRV_KEY3
    testeraAccount.activePublicKey=currencyAccount.activePublicKey=PUB_KEY3

    exchangeAccount.ownerPrivateKey=PRV_KEY2
    exchangeAccount.ownerPublicKey=PUB_KEY2
106

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

    testWalletName="test"
    Print("Creating wallet \"%s\"." % (testWalletName))
P
Paul Calabrese 已提交
116
    testWallet=walletMgr.create(testWalletName, [cluster.eosioAccount,cluster.defproduceraAccount,cluster.defproducerbAccount])
117

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
    defproduceraWalletName="defproducera"
    Print("Creating wallet \"%s\"." % (defproduceraWalletName))
    defproduceraWallet=walletMgr.create(defproduceraWalletName)
129

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

132 133
    defproduceraAccount=cluster.defproduceraAccount
    defproducerbAccount=cluster.defproducerbAccount
134

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

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

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

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

    Print("Unlocking wallet \"%s\"." % (testWallet.name))
    if not walletMgr.unlockWallet(testWallet):
157
        cmdError("%s wallet unlock" % (ClientName))
158 159 160 161 162 163 164 165 166
        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.")
167
    actualKeys=walletMgr.getKeys(testWallet)
168 169 170 171 172 173
    expectedkeys=[]
    for account in accounts:
        expectedkeys.append(account.ownerPrivateKey)
        expectedkeys.append(account.activePrivateKey)
    noMatch=list(set(expectedkeys) - set(actualKeys))
    if len(noMatch) > 0:
174
        errorExit("FAILURE - wallet keys did not include %s" % (noMatch), raw=True)
175 176 177

    Print("Locking all wallets.")
    if not walletMgr.lockAllWallets():
178
        cmdError("%s wallet lock_all" % (ClientName))
179 180
        errorExit("Failed to lock all wallets")

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

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

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

198 199
    node=cluster.getNode(0)

C
Ciju John 已提交
200 201 202
    Print("Validating accounts before user accounts creation")
    cluster.validateAccounts(None)

203 204
    # create accounts via eosio as otherwise a bid is needed 
    Print("Create new account %s via %s" % (testeraAccount.name, cluster.eosioAccount.name))
205
    transId=node.createInitializeAccount(testeraAccount, cluster.eosioAccount, stakedDeposit=0, waitForTransBlock=False, exitOnError=True)
206

207
    Print("Create new account %s via %s" % (currencyAccount.name, cluster.eosioAccount.name))
208
    transId=node.createInitializeAccount(currencyAccount, cluster.eosioAccount, stakedDeposit=5000, exitOnError=True)
C
Ciju John 已提交
209

210
    Print("Create new account %s via %s" % (exchangeAccount.name, cluster.eosioAccount.name))
211
    transId=node.createInitializeAccount(exchangeAccount, cluster.eosioAccount, waitForTransBlock=True, exitOnError=True)
C
Ciju John 已提交
212 213 214 215 216

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

217 218 219 220
    Print("Verify account %s" % (testeraAccount))
    if not node.verifyAccount(testeraAccount):
        errorExit("FAILURE - account creation failed.", raw=True)

221
    transferAmount="97.5321 {0}".format(CORE_SYMBOL)
222
    Print("Transfer funds %s from account %s to %s" % (transferAmount, defproduceraAccount.name, testeraAccount.name))
223
    node.transferFunds(defproduceraAccount, testeraAccount, transferAmount, "test transfer")
224

225 226 227 228 229 230
    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))
231

232
    transferAmount="0.0100 {0}".format(CORE_SYMBOL)
233
    Print("Force transfer funds %s from account %s to %s" % (
234
        transferAmount, defproduceraAccount.name, testeraAccount.name))
235
    node.transferFunds(defproduceraAccount, testeraAccount, transferAmount, "test transfer", force=True)
236

237
    expectedAmount="97.5421 {0}".format(CORE_SYMBOL)
238 239 240 241 242
    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))
243

C
Ciju John 已提交
244 245 246
    Print("Validating accounts after some user trasactions")
    accounts=[testeraAccount, currencyAccount, exchangeAccount]
    cluster.validateAccounts(accounts)
247 248 249

    Print("Locking all wallets.")
    if not walletMgr.lockAllWallets():
250
        cmdError("%s wallet lock_all" % (ClientName))
251 252 253 254
        errorExit("Failed to lock all wallets")

    Print("Unlocking wallet \"%s\"." % (testWallet.name))
    if not walletMgr.unlockWallet(testWallet):
255
        cmdError("%s wallet unlock" % (ClientName))
256 257
        errorExit("Failed to unlock wallet %s" % (testWallet.name))

258
    transferAmount="97.5311 {0}".format(CORE_SYMBOL)
259
    Print("Transfer funds %s from account %s to %s" % (
260
        transferAmount, testeraAccount.name, currencyAccount.name))
261
    trans=node.transferFunds(testeraAccount, currencyAccount, transferAmount, "test transfer a->b")
262
    transId=Node.getTransId(trans)
263

264
    expectedAmount="98.0311 {0}".format(CORE_SYMBOL) # 5000 initial deposit
265 266 267 268 269
    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))
270

C
Ciju John 已提交
271
    Print("Validate last action for account %s" % (testeraAccount.name))
272
    actions=node.getActions(testeraAccount, -1, -1, exitOnError=True)
C
Ciju John 已提交
273
    try:
C
Ciju John 已提交
274 275 276 277
        if not enableMongo:
            assert(actions["actions"][0]["action_trace"]["act"]["name"] == "transfer")
        else:
            assert(actions["name"] == "transfer")
278
    except (AssertionError, TypeError, KeyError) as _:
C
Ciju John 已提交
279
        Print("Action validation failed. Actions: %s" % (actions))
C
Ciju John 已提交
280 281
        raise

282
    node.waitForTransInBlock(transId)
283

B
Brian Johnson 已提交
284
    transaction=node.getTransaction(transId, exitOnError=True)
285

286 287
    typeVal=None
    amountVal=None
C
Ciju John 已提交
288
    key=""
289 290
    try:
        if not enableMongo:
C
Ciju John 已提交
291
            key="[traces][0][act][name]"
292
            typeVal=  transaction["traces"][0]["act"]["name"]
C
Ciju John 已提交
293
            key="[traces][0][act][data][quantity]"
294 295 296
            amountVal=transaction["traces"][0]["act"]["data"]["quantity"]
            amountVal=int(decimal.Decimal(amountVal.split()[0])*10000)
        else:
C
Ciju John 已提交
297 298 299 300
            key="[actions][0][name]"
            typeVal=  transaction["actions"][0]["name"]
            key="[actions][0][data][quantity]"
            amountVal=transaction["actions"][0]["data"]["quantity"]
301
            amountVal=int(decimal.Decimal(amountVal.split()[0])*10000)
C
Ciju John 已提交
302
    except (TypeError, KeyError) as e:
C
Ciju John 已提交
303
        Print("transaction%s not found. Transaction: %s" % (key, transaction))
304
        raise
305 306

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

309 310
    Print("Currency Contract Tests")
    Print("verify no contract in place")
311 312 313
    Print("Get code hash for account %s" % (currencyAccount.name))
    codeHash=node.getAccountCodeHash(currencyAccount.name)
    if codeHash is None:
314
        cmdError("%s get code currency1111" % (ClientName))
315
        errorExit("Failed to get code hash for account %s" % (currencyAccount.name))
316 317
    hashNum=int(codeHash, 16)
    if hashNum != 0:
318
        errorExit("FAILURE - get code currency1111 failed", raw=True)
319

320 321 322
    contractDir="contracts/eosio.token"
    wastFile="contracts/eosio.token/eosio.token.wast"
    abiFile="contracts/eosio.token/eosio.token.abi"
323
    Print("Publish contract")
324
    trans=node.publishContract(currencyAccount.name, contractDir, wastFile, abiFile, waitForTransBlock=True)
325
    if trans is None:
326
        cmdError("%s set contract currency1111" % (ClientName))
327
        errorExit("Failed to publish contract.")
328

329 330 331 332
    if not enableMongo:
        Print("Get code hash for account %s" % (currencyAccount.name))
        codeHash=node.getAccountCodeHash(currencyAccount.name)
        if codeHash is None:
333
            cmdError("%s get code currency1111" % (ClientName))
334 335 336
            errorExit("Failed to get code hash for account %s" % (currencyAccount.name))
        hashNum=int(codeHash, 16)
        if hashNum == 0:
337
            errorExit("FAILURE - get code currency1111 failed", raw=True)
338 339 340 341
    else:
        Print("verify abi is set")
        account=node.getEosAccountFromDb(currencyAccount.name)
        abiName=account["abi"]["structs"][0]["name"]
342
        abiActionName=account["abi"]["actions"][0]["name"]
343 344
        abiType=account["abi"]["actions"][0]["type"]
        if abiName != "transfer" or abiActionName != "transfer" or abiType != "transfer":
345
            errorExit("FAILURE - get EOS account failed", raw=True)
346

347 348
    Print("push create action to currency1111 contract")
    contract="currency1111"
349
    action="create"
350 351
    data="{\"issuer\":\"currency1111\",\"maximum_supply\":\"100000.0000 CUR\",\"can_freeze\":\"0\",\"can_recall\":\"0\",\"can_whitelist\":\"0\"}"
    opts="--permission currency1111@active"
352
    trans=node.pushMessage(contract, action, data, opts)
353 354 355 356 357 358
    try:
        assert(trans)
        assert(trans[0])
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed push create action to currency1111 contract assertion. %s" % (trans))
        raise
359

360
    Print("push issue action to currency1111 contract")
361
    action="issue"
362 363
    data="{\"to\":\"currency1111\",\"quantity\":\"100000.0000 CUR\",\"memo\":\"issue\"}"
    opts="--permission currency1111@active"
364
    trans=node.pushMessage(contract, action, data, opts)
365 366 367 368 369 370
    try:
        assert(trans)
        assert(trans[0])
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed push issue action to currency1111 contract assertion. %s" % (trans))
        raise
371

372 373
    Print("Verify currency1111 contract has proper initial balance (via get table)")
    contract="currency1111"
374 375
    table="accounts"
    row0=node.getTableRow(contract, currencyAccount.name, table, 0)
376 377 378 379 380 381
    try:
        assert(row0)
        assert(row0["balance"] == "100000.0000 CUR")
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed get table row assertion. %s" % (row0))
        raise
382

383
    Print("Verify currency1111 contract has proper initial balance (via get currency1111 balance)")
384
    amountStr=node.getTableAccountBalance("currency1111", currencyAccount.name)
385 386

    expected="100000.0000 CUR"
387
    actual=amountStr
388
    if actual != expected:
389
        errorExit("FAILURE - currency1111 balance check failed. Expected: %s, Recieved %s" % (expected, actual), raw=True)
390

391
    Print("Verify currency1111 contract has proper total supply of CUR (via get currency1111 stats)")
392
    res=node.getCurrencyStats(contract, "CUR", exitOnError=True)
393 394 395 396 397
    try:
        assert(res["CUR"]["supply"] == "100000.0000 CUR")
    except (AssertionError, KeyError) as _:
        Print("ERROR: Failed get currecy stats assertion. %s" % (res))
        raise
398

399 400 401
    dupRejected=False
    dupTransAmount=10
    totalTransfer=dupTransAmount
402
    contract="currency1111"
403
    action="transfer"
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
    for _ in range(5):
        Print("push transfer action to currency1111 contract")
        data="{\"from\":\"currency1111\",\"to\":\"defproducera\",\"quantity\":"
        data +="\"00.00%s CUR\",\"memo\":\"test\"}" % (dupTransAmount)
        opts="--permission currency1111@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=Node.getTransId(trans[1])

        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=Node.getTransId(transDuplicate[1])
            if transId != transDuplicateId:
                Print("%s push message currency1111 duplicate transfer incorrectly accepted, but they were generated with different transaction ids, this is a timing setup issue, trying again" % (ClientName))
                # add the transfer that wasn't supposed to work
                totalTransfer+=dupTransAmount
                dupTransAmount+=1
                # add the new first transfer that is expected to work
                totalTransfer+=dupTransAmount
                continue
            else:
                cmdError("%s push message currency1111 transfer, \norig: %s \ndup: %s" % (ClientName, trans, transDuplicate))
            errorExit("Failed to reject duplicate message for currency1111 contract")
430
        else:
431 432 433 434
            dupRejected=True
            break

    if not dupRejected:
435 436
        errorExit("Failed to reject duplicate message for currency1111 contract")

437
    Print("verify transaction exists")
438
    if not node.waitForTransInBlock(transId):
439
        cmdError("%s get transaction trans_id" % (ClientName))
440
        errorExit("Failed to verify push message transaction id.")
441

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

445
    expectedDefproduceraBalance="0.00%s CUR" % (totalTransfer)
446
    actual=amountStr
447 448
    if actual != expectedDefproduceraBalance:
        errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (expectedDefproduceraBalance, actual), raw=True)
449

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

452 453
    expExtension=100-totalTransfer
    expectedCurrency1111Balance="99999.99%s CUR" % (expExtension)
454
    actual=amountStr
455 456
    if actual != expectedCurrency1111Balance:
        errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (expectedCurrency1111Balance, actual), raw=True)
457

458 459 460 461 462
    amountStr=node.getCurrencyBalance("currency1111", currencyAccount.name, "CUR")
    try:
        assert(actual)
        assert(isinstance(actual, str))
        actual=amountStr.strip()
463
        assert(expectedCurrency1111Balance == actual)
464
    except (AssertionError, KeyError) as _:
465
        Print("ERROR: Failed get currecy balance assertion. (expected=<%s>, actual=<%s>)" % (expectedCurrency1111Balance, actual))
466 467
        raise

468 469 470
    Print("Test for block decoded packed transaction (issue 2932)")
    blockId=node.getBlockIdByTransId(transId)
    assert(blockId)
B
Brian Johnson 已提交
471 472
    block=node.getBlock(blockId, exitOnError=True)

473 474
    transactions=None
    try:
C
Ciju John 已提交
475 476 477 478
        if not enableMongo:
            transactions=block["transactions"]
        else:
            transactions=block["block"]["transactions"]
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
        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")
505
        assert(myTrans["actions"][0]["data"]["quantity"] == "0.00%s CUR" % (dupTransAmount))
506 507 508 509 510
        assert(myTrans["actions"][0]["data"]["memo"] == "test")
    except (AssertionError, TypeError, KeyError) as _:
        Print("FAILURE - Failed to parse block transaction. %s" % (myTrans))
        raise

511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
    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)

    actual=amountStr
531 532
    if actual != expectedDefproduceraBalance:
        errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (expectedDefproduceraBalance, actual), raw=True)
533 534 535 536

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

    actual=amountStr
537 538
    if actual != expectedCurrency1111Balance:
        errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (expectedCurrency1111Balance, actual), raw=True)
539 540 541 542 543

    Print("push another transfer action to currency1111 contract")
    contract="currency1111"
    action="transfer"
    data="{\"from\":\"defproducera\",\"to\":\"currency1111\",\"quantity\":"
544
    data +="\"00.00%s CUR\",\"memo\":\"test\"}" % (totalTransfer)
545 546 547 548 549
    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")
550
    transId=Node.getTransId(trans[1])
551 552 553 554 555 556 557 558 559 560 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

    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))

602

603 604 605
    Print("Exchange Contract Tests")
    Print("upload exchange contract")

606
    contractDir="contracts/exchange"
607 608 609
    wastFile="contracts/exchange/exchange.wast"
    abiFile="contracts/exchange/exchange.abi"
    Print("Publish exchange contract")
610
    trans=node.publishContract(exchangeAccount.name, contractDir, wastFile, abiFile, waitForTransBlock=True)
611 612 613
    if trans is None:
        cmdError("%s set contract exchange" % (ClientName))
        errorExit("Failed to publish contract.")
614

615
    contractDir="contracts/simpledb"
616 617
    wastFile="contracts/simpledb/simpledb.wast"
    abiFile="contracts/simpledb/simpledb.abi"
618 619
    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))
620
    retMap=node.publishContract("simpledb", contractDir, wastFile, abiFile, shouldFail=True)
621 622 623 624 625
    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:
626
        Print("Test successful, %s returned error code: %d" % (ClientName, retMap["returncode"]))
627 628

    Print("set permission")
629
    code="currency1111"
630 631
    pType="transfer"
    requirement="active"
632
    trans=node.setPermission(testeraAccount.name, code, pType, requirement, waitForTransBlock=True, exitOnError=True)
633

634 635
    Print("remove permission")
    requirement="null"
636
    trans=node.setPermission(testeraAccount.name, code, pType, requirement, waitForTransBlock=True, exitOnError=True)
637

638 639
    Print("Locking all wallets.")
    if not walletMgr.lockAllWallets():
640
        cmdError("%s wallet lock_all" % (ClientName))
641 642
        errorExit("Failed to lock all wallets")

643 644 645 646
    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))
647

648
    Print("Get account defproducera")
B
Brian Johnson 已提交
649
    account=node.getEosAccount(defproduceraAccount.name, exitOnError=True)
650

C
Ciju John 已提交
651 652 653 654 655
    Print("Unlocking wallet \"%s\"." % (defproduceraWallet.name))
    if not walletMgr.unlockWallet(testWallet):
        cmdError("%s wallet unlock test" % (ClientName))
        errorExit("Failed to unlock wallet %s" % (testWallet.name))

656 657 658 659 660

    Print("Get head block num.")
    currentBlockNum=node.getHeadBlockNum()
    Print("CurrentBlockNum: %d" % (currentBlockNum))
    Print("Request blocks 1-%d" % (currentBlockNum))
C
Ciju John 已提交
661 662 663 664
    start=1
    if enableMongo:
        start=2 # block 1 (genesis block) is not signaled to the plugins, so not available in DB
    for blockNum in range(start, currentBlockNum+1):
B
Brian Johnson 已提交
665
        block=node.getBlock(blockNum, silentErrors=False, exitOnError=True)
666 667 668

        if enableMongo:
            blockId=block["block_id"]
669
            block2=node.getBlockByIdMdb(blockId)
670 671 672
            if block2 is None:
                errorExit("mongo get block by id %s" % blockId)

C
Ciju John 已提交
673
    Print("Request invalid block numbered %d. This will generate an expected error message." % (currentBlockNum+1000))
C
Ciju John 已提交
674
    block=node.getBlock(currentBlockNum+1000, silentErrors=True)
675 676 677 678 679 680 681
    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')
682
        errFileName="var/lib/node_00/stderr.txt"
683
        assertionsFound=False
684 685 686
        with open(errFileName) as errFile:
            for line in errFile:
                if p.search(line):
687 688 689 690 691 692 693
                    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")
694

C
Ciju John 已提交
695 696 697 698
    Print("Validating accounts at end of test")
    accounts=[testeraAccount, currencyAccount, exchangeAccount]
    cluster.validateAccounts(accounts)

699 700
    testSuccessful=True
finally:
701
    TestHelper.shutdown(cluster, walletMgr, testSuccessful, killEosInstances, killWallet, keepLogs, killAll, dumpErrorDetails)
702

703
exit(0)