def global_freezing(self): self.log.info("Testing global freezing...") n0, n1 = self.nodes[0], self.nodes[1] base_asset_name = "FROZEN_GLOBAL" asset_name = f"${base_asset_name}" qty = 10000 verifier = "true" address = n0.getnewaddress() spl_change_address = n0.getnewaddress() n0.issue(base_asset_name) n0.generate(1) n0.issuerestrictedasset(asset_name, qty, verifier, address) n0.generate(1) # pre-freeze validation assert_does_not_contain(asset_name, n0.listglobalrestrictions()) assert not n0.checkglobalrestriction(asset_name) assert_equal(10000, n0.listassetbalancesbyaddress(address)[asset_name]) change_address = n0.getnewaddress() n0.transferfromaddress(asset_name, address, 1000, n1.getnewaddress(), "", "", "", change_address) n0.generate(1) self.sync_all() assert_equal(9000, n0.listassetbalancesbyaddress(change_address)[asset_name]) assert_equal(1000, n1.listmyassets()[asset_name]) address = change_address # assets have moved assert_raises_rpc_error(None, "Invalid Splendid change address", n0.freezerestrictedasset, asset_name, "garbagechangeaddress") n0.freezerestrictedasset(asset_name, spl_change_address) # Can only freeze once! assert_raises_rpc_error(-26, "Freezing transaction already in mempool", n0.freezerestrictedasset, asset_name, spl_change_address) n0.generate(1) assert_raises_rpc_error(None, "global-freeze-when-already-frozen", n0.freezerestrictedasset, asset_name, spl_change_address) # post-freeze validation assert_contains(asset_name, n0.listglobalrestrictions()) assert n0.checkglobalrestriction(asset_name) assert_raises_rpc_error(-8, "restricted asset has been globally frozen", n0.transferfromaddress, asset_name, address, 1000, n1.getnewaddress()) assert_raises_rpc_error(None, "Invalid Splendid change address", n0.unfreezerestrictedasset, asset_name, "garbagechangeaddress") n0.unfreezerestrictedasset(asset_name, spl_change_address) # Can only un-freeze once! assert_raises_rpc_error(-26, "Unfreezing transaction already in mempool", n0.unfreezerestrictedasset, asset_name, spl_change_address) n0.generate(1) assert_raises_rpc_error(None, "global-unfreeze-when-not-frozen", n0.unfreezerestrictedasset, asset_name, spl_change_address) # post-unfreeze validation assert_does_not_contain(asset_name, n0.listglobalrestrictions()) assert not n0.checkglobalrestriction(asset_name) assert_equal(9000, n0.listassetbalancesbyaddress(address)[asset_name]) change_address = n0.getnewaddress() n0.transferfromaddress(asset_name, address, 1000, n1.getnewaddress(), "", "", "", change_address) n0.generate(1) self.sync_all() assert_equal(8000, n0.listassetbalancesbyaddress(change_address)[asset_name]) assert_equal(2000, n1.listmyassets()[asset_name])
def issue_invalid(self): self.log.info("Trying some invalid calls...") n0, n1 = self.nodes[0], self.nodes[1] n1.generate(10) self.sync_all() root = gen_root_asset_name() asset_name = gen_unique_asset_name(root) # no root assert_raises_rpc_error(-32600, f"Wallet doesn't have asset: {root}!", n0.issue, asset_name) # don't own root n0.sendtoaddress(n1.getnewaddress(), 501) n0.generate(1) self.sync_all() n1.issue(root) n1.generate(1) self.sync_all() assert_contains(root, n0.listassets()) assert_raises_rpc_error(-32600, f"Wallet doesn't have asset: {root}!", n0.issue, asset_name) n1.transfer(f"{root}!", 1, n0.getnewaddress()) n1.generate(1) self.sync_all() # bad qty assert_raises_rpc_error( -8, "Invalid parameters for issuing a unique asset.", n0.issue, asset_name, 2) # bad units assert_raises_rpc_error( -8, "Invalid parameters for issuing a unique asset.", n0.issue, asset_name, 1, "", "", 1) # reissuable assert_raises_rpc_error( -8, "Invalid parameters for issuing a unique asset.", n0.issue, asset_name, 1, "", "", 0, True) # already exists n0.issue(asset_name) n0.generate(1) self.sync_all() assert_raises_rpc_error( -8, f"Invalid parameter: asset_name '{asset_name}' has already been used", n0.issue, asset_name)
def issue_unique_test(self): self.log.info("Testing issueunique RPC...") n0, n1 = self.nodes[0], self.nodes[1] n0.sendtoaddress(n1.getnewaddress(), 501) root = gen_root_asset_name() n0.issue(asset_name=root) asset_tags = ["first", "second"] ipfs_hashes = ["QmWWQSuPMS6aXCbZKpEjPHPUZN2NjB3YrhJTHsV4X3vb2t" ] * len(asset_tags) n0.issueunique(root, asset_tags, ipfs_hashes) block_hash = n0.generate(1)[0] asset_name = "" for tag in asset_tags: asset_name = f"{root}#{tag}" assert_equal(1, n0.listmyassets()[asset_name]) assert_equal( 1, n0.listassets(asset_name, True)[asset_name]['has_ipfs']) assert_equal( ipfs_hashes[0], n0.listassets(asset_name, True)[asset_name]['ipfs_hash']) # invalidate n0.invalidateblock(block_hash) assert (root in n0.listmyassets()) assert_does_not_contain_key( asset_name, n0.listmyassets(asset="*", verbose=False, count=100000, start=0, confs=1)) # reconsider n0.reconsiderblock(block_hash) assert_contains(root, n0.listmyassets()) assert_contains(asset_name, n0.listmyassets()) # root doesn't exist missing_asset = "VAPOUR" assert_raises_rpc_error( -32600, f"Wallet doesn't have asset: {missing_asset}!", n0.issueunique, missing_asset, asset_tags) # don't own root n1.issue(missing_asset) n1.generate(1) self.sync_all() assert_contains(missing_asset, n0.listassets()) assert_raises_rpc_error( -32600, f"Wallet doesn't have asset: {missing_asset}!", n0.issueunique, missing_asset, asset_tags)
def freezing(self): self.log.info("Testing freezing...") n0, n1 = self.nodes[0], self.nodes[1] base_asset_name = "FROZEN_TM" asset_name = f"${base_asset_name}" qty = 11000 verifier = "true" address = n0.getnewaddress() safe_address = n0.getnewaddress() spl_change_address = n0.getnewaddress() n0.issue(base_asset_name) n0.generate(1) n0.issuerestrictedasset(asset_name, qty, verifier, address) n0.generate(1) # squirrel some away change_address = n0.getnewaddress() n0.transferfromaddress(asset_name, address, 1000, safe_address, "", "", "", change_address) n0.generate(1) address = change_address # pre-freezing verification assert_does_not_contain(asset_name, n0.listaddressrestrictions(address)) assert not n0.checkaddressrestriction(address, address) assert_equal(10000, n0.listassetbalancesbyaddress(address)[asset_name]) # Isolate this test from other freezing on n0... def viewmyrestrictedaddresses(): return list(filter(lambda x: asset_name == x['Asset Name'], n0.viewmyrestrictedaddresses())) # viewmyrestrictedaddresses assert_equal(0, len(viewmyrestrictedaddresses())) change_address = n0.getnewaddress() n0.transferfromaddress(asset_name, address, 1000, n1.getnewaddress(), "", "", "", change_address) n0.generate(1) self.sync_all() assert_equal(9000, n0.listassetbalancesbyaddress(change_address)[asset_name]) assert_equal(1000, n1.listmyassets()[asset_name]) address = change_address # assets have moved assert_raises_rpc_error(None, "Invalid Splendid address", n0.freezeaddress, asset_name, "garbageaddress") assert_raises_rpc_error(None, "Invalid Splendid change address", n0.freezeaddress, asset_name, address, "garbagechangeaddress") n0.freezeaddress(asset_name, address, spl_change_address) n0.generate(1) assert_raises_rpc_error(-32600, "freeze-address-when-already-frozen", n0.freezeaddress, asset_name, address, spl_change_address) # post-freezing verification assert_contains(asset_name, n0.listaddressrestrictions(address)) assert n0.checkaddressrestriction(address, asset_name) # viewmyrestrictedaddresses restrictions = viewmyrestrictedaddresses() assert_equal(1, len(restrictions)) r = restrictions[0] assert_equal(address, r['Address']) assert_equal(asset_name, r['Asset Name']) assert_happening(r['Restricted']) assert_raises_rpc_error(-8, "No asset outpoints are selected from the given address", n0.transferfromaddress, asset_name, address, 1000, n1.getnewaddress()) assert_raises_rpc_error(None, "Invalid Splendid address", n0.unfreezeaddress, asset_name, "garbageaddress") assert_raises_rpc_error(None, "Invalid Splendid change address", n0.unfreezeaddress, asset_name, address, "garbagechangeaddress") n0.unfreezeaddress(asset_name, address, spl_change_address) n0.generate(1) assert_raises_rpc_error(-32600, "unfreeze-address-when-not-frozen", n0.unfreezeaddress, asset_name, address, spl_change_address) # post-unfreezing verification assert_does_not_contain(asset_name, n0.listaddressrestrictions(address)) assert not n0.checkaddressrestriction(address, asset_name) assert_equal(9000, n0.listassetbalancesbyaddress(address)[asset_name]) # viewmyrestrictedaddresses restrictions = viewmyrestrictedaddresses() assert_equal(1, len(restrictions)) r = restrictions[0] assert_equal(address, r['Address']) assert_equal(asset_name, r['Asset Name']) assert_happening(r['Derestricted']) change_address = n0.getnewaddress() n0.transferfromaddress(asset_name, address, 1000, n1.getnewaddress(), "", "", "", change_address) n0.generate(1) self.sync_all() assert_equal(8000, n0.listassetbalancesbyaddress(change_address)[asset_name]) assert_equal(2000, n1.listmyassets()[asset_name])
def tagging(self): self.log.info("Testing tagging...") n0 = self.nodes[0] tag = "#TAG" address = n0.getnewaddress() change_address = n0.getnewaddress() n0.issuequalifierasset(tag) n0.generate(1) base_asset_name = "TAG_RESTRICTED" asset_name = f"${base_asset_name}" qty = 1000 verifier = tag issue_address = n0.getnewaddress() n0.issue(base_asset_name) assert_raises_rpc_error(-8, "bad-txns-null-verifier-address-failed-verification", n0.issuerestrictedasset, asset_name, qty, verifier, issue_address) # Isolate this test from other tagging on n0... def viewmytaggedaddresses(): return list(filter(lambda x: tag == x['Tag Name'], n0.viewmytaggedaddresses())) assert_equal(0, len(viewmytaggedaddresses())) n0.addtagtoaddress(tag, issue_address, change_address) n0.generate(1) n0.issuerestrictedasset(asset_name, qty, verifier, issue_address) n0.generate(1) # pre-tagging verification assert_does_not_contain(address, n0.listaddressesfortag(tag)) assert_does_not_contain(tag, n0.listtagsforaddress(address)) assert not n0.checkaddresstag(address, tag) # viewmytaggedaddresses tagged = viewmytaggedaddresses() assert_equal(1, len(tagged)) t1 = tagged[0] assert_equal(issue_address, t1['Address']) assert_equal(tag, t1['Tag Name']) assert_contains_key('Assigned', t1) assert_happening(t1['Assigned']) assert_raises_rpc_error(-8, "bad-txns-null-verifier-address-failed-verification", n0.transfer, asset_name, 100, address) # special case: make sure transfer fails if change address(es) are verified even though to address isn't spl_change_address = n0.getnewaddress() asset_change_address = n0.getnewaddress() n0.addtagtoaddress(tag, spl_change_address) n0.addtagtoaddress(tag, asset_change_address) n0.generate(1) assert_raises_rpc_error(-8, "bad-txns-null-verifier-address-failed-verification", n0.transfer, asset_name, 100, address, "", 0, spl_change_address, asset_change_address) n0.removetagfromaddress(tag, spl_change_address) n0.removetagfromaddress(tag, asset_change_address) n0.generate(1) ## assert_raises_rpc_error(None, "Invalid Splendid address", n0.addtagtoaddress, tag, "garbageaddress") assert_raises_rpc_error(None, "Invalid Splendid change address", n0.addtagtoaddress, tag, address, "garbagechangeaddress") n0.addtagtoaddress(tag, address, change_address) n0.generate(1) assert_raises_rpc_error(-32600, "add-qualifier-when-already-assigned", n0.addtagtoaddress, tag, address, change_address) # post-tagging verification assert_contains(address, n0.listaddressesfortag(tag)) assert_contains(tag, n0.listtagsforaddress(address)) assert n0.checkaddresstag(address, tag) # viewmytaggedaddresses tagged = viewmytaggedaddresses() assert_equal(4, len(tagged)) assert_contains(issue_address, list(map(lambda x: x['Address'], tagged))) assert_contains(address, list(map(lambda x: x['Address'], tagged))) for t in tagged: assert_equal(tag, t['Tag Name']) if 'Assigned' in t: assert_happening(t['Assigned']) else: assert_happening(t['Removed']) # special case: make sure transfer fails if the asset change address isn't verified (even if the spl change address is) spl_change_address = n0.getnewaddress() asset_change_address = n0.getnewaddress() assert_raises_rpc_error(-20, "bad-txns-null-verifier-address-failed-verification", n0.transfer, asset_name, 100, address, "", 0, spl_change_address, asset_change_address) n0.addtagtoaddress(tag, spl_change_address) n0.generate(1) assert_raises_rpc_error(-20, "bad-txns-null-verifier-address-failed-verification", n0.transfer, asset_name, 100, address, "", 0, spl_change_address, asset_change_address) n0.removetagfromaddress(tag, spl_change_address) n0.generate(1) # do the transfer already! txid = n0.transfer(asset_name, 100, address) n0.generate(1) assert_equal(64, len(txid[0])) assert_equal(100, n0.listassetbalancesbyaddress(address)[asset_name]) # do another transfer with specified, tagged asset change address asset_change_address = n0.getnewaddress() n0.addtagtoaddress(tag, asset_change_address) n0.generate(1) txid = n0.transfer(asset_name, 1, issue_address, "", 0, "", asset_change_address) n0.generate(1) assert_equal(64, len(txid[0])) assert (n0.listassetbalancesbyaddress(asset_change_address)[asset_name] > 0) assert_raises_rpc_error(None, "Invalid Splendid address", n0.removetagfromaddress, tag, "garbageaddress") assert_raises_rpc_error(None, "Invalid Splendid change address", n0.removetagfromaddress, tag, address, "garbagechangeaddress") n0.removetagfromaddress(tag, address, change_address) n0.generate(1) assert_raises_rpc_error(-32600, "removing-qualifier-when-not-assigned", n0.removetagfromaddress, tag, address, change_address) # TODO: test without specifying change address when there are no valid change addresses (all untagged) # post-untagging verification assert_does_not_contain(address, n0.listaddressesfortag(tag)) assert_does_not_contain(tag, n0.listtagsforaddress(address)) assert not n0.checkaddresstag(address, tag) # viewmytaggedaddresses tagged = viewmytaggedaddresses() assert_equal(6, len(tagged)) # includes removed assert_contains(issue_address, list(map(lambda x: x['Address'], tagged))) assert_contains(address, list(map(lambda x: x['Address'], tagged))) for t in tagged: assert_equal(tag, t['Tag Name']) if issue_address == t['Address']: assert_happening(t['Assigned']) if address == t['Address']: assert_happening(t['Removed']) assert_raises_rpc_error(-8, "bad-txns-null-verifier-address-failed-verification", n0.transfer, asset_name, 100, address)
def run_test(self): nodes = self.nodes # BIP39 list should contain 2048 words assert_equal(len(bip39_english), 2048) # Node 0 has 12 words and a passphrase self.log.info("Testing BIP-44 Word-Lists and passphrases") assert_equal(len(nodes[0].getmywords()['word_list'].split(' ')), 12) # Contains 12 words assert_equal(nodes[0].getmywords()['word_list'], MNEMONIC_0) # Word list matches assert_equal(nodes[0].getmywords()['passphrase'], MNEMONIC_PASS_0) # Passphrase matches # Node 1 has 12 words but no passphrase assert_equal(len(nodes[1].getmywords()['word_list'].split(' ')), 12) # Contains 12 words assert_equal(nodes[1].getmywords()['word_list'], MNEMONIC_1) # Word list matches assert_does_not_contain(str(nodes[1].getmywords()), 'passphrase') # Passphrase does not exist # Node 2 was not created with specific 12 words (using random-auto-generated), and a passphrase assert_equal(len(nodes[2].getmywords()['word_list'].split(' ')), 12) # Contains 12 words assert(nodes[2].getmywords()['word_list'] != nodes[3].getmywords()['word_list']) # auto-generated word-lists should not match assert_equal(nodes[2].getmywords()['passphrase'], MNEMONIC_PASS_2) # Node 3 was not created with specific 12 words (using random-auto-generated), and no passphrase assert_equal(len(nodes[3].getmywords()['word_list'].split(' ')), 12) # Contains 12 words assert_does_not_contain(str(nodes[3].getmywords()), 'passphrase') # Passphrase does not exist # Nodes 4 & 5 are not BIP44 and should not have 12-words or passphrase assert_raises_rpc_error(-4, "Wallet doesn't have 12 words.", nodes[4].getmywords) assert_raises_rpc_error(-4, "Wallet doesn't have 12 words.", nodes[5].getmywords) # Cannot change from a non-BIP44 to a BIP44 wallet self.log.info("Testing that BIP-44 wallets are intransigent") self.stop_node(4) self.stop_node(5) self.start_node(4, extra_args=['-bip44=1', '-mnemonicpassphrase=test4']) self.start_node(5, extra_args=['-bip44=1', '-mnemonic=' + MNEMONIC_0, '-mnemonicpassphrase=' + MNEMONIC_PASS_0]) assert_raises_rpc_error(-4, "Wallet doesn't have 12 words.", nodes[4].getmywords) assert_raises_rpc_error(-4, "Wallet doesn't have 12 words.", nodes[5].getmywords) # Try to add a passphrase to an existing bip44 wallet (should not add passphrase) self.stop_node(3) self.start_node(3, extra_args=['-mnemonicpassphrase=test3']) assert_does_not_contain(str(nodes[3].getmywords()), 'passphrase') # Passphrase does not exist # Cannot change an already created bip44 wallet to a non-bip44 wallet word_list_3 = nodes[3].getmywords()['word_list'] self.stop_node(3) self.start_node(3, extra_args=['-bip44=0']) assert_equal(nodes[3].getmywords()['word_list'], word_list_3) # Word list matches # All 4 bip44 enabled wallets word-lists are in the bip39 word-list self.log.info("Testing that BIP-44 wallets words are valid") word_list_0 = MNEMONIC_0.split(' ') word_list_1 = MNEMONIC_1.split(' ') word_list_2 = nodes[2].getmywords()['word_list'].split(' ') word_list_3 = word_list_3.split(' ') for i in range(0, 12): assert_contains(word_list_0[i], bip39_english) assert_contains(word_list_1[i], bip39_english) assert_contains(word_list_2[i], bip39_english) assert_contains(word_list_3[i], bip39_english) # None of the words should be text-readable in the log files self.log.info("Testing that BIP-44 words aren't text readable") mnemonic_2 = nodes[2].getmywords()['word_list'] mnemonic_3 = nodes[3].getmywords()['word_list'] self.stop_nodes() with open(os.path.join(self.options.tmpdir+"/node0/regtest/", "debug.log"), 'r', encoding='utf8') as f: assert_does_not_contain(MNEMONIC_0, f.read()) with open(os.path.join(self.options.tmpdir+"/node1/regtest/", "debug.log"), 'r', encoding='utf8') as f: assert_does_not_contain(MNEMONIC_1, f.read()) with open(os.path.join(self.options.tmpdir+"/node2/regtest/", "debug.log"), 'r', encoding='utf8') as f: assert_does_not_contain(mnemonic_2, f.read()) with open(os.path.join(self.options.tmpdir+"/node3/regtest/", "debug.log"), 'r', encoding='utf8') as f: assert_does_not_contain(mnemonic_3, f.read()) # But words are readable in a non-encrypted wallet with open(os.path.join(self.options.tmpdir+"/node0/regtest/", "wallet.dat"), 'rb') as f: assert_contains(MNEMONIC_0, str(f.read())) with open(os.path.join(self.options.tmpdir+"/node1/regtest/", "wallet.dat"), 'rb') as f: assert_contains(MNEMONIC_1, str(f.read())) with open(os.path.join(self.options.tmpdir+"/node2/regtest/", "wallet.dat"), 'rb') as f: assert_contains(mnemonic_2, str(f.read())) with open(os.path.join(self.options.tmpdir+"/node3/regtest/", "wallet.dat"), 'rb') as f: assert_contains(mnemonic_3, str(f.read())) # After encryption the words are no longer readable self.log.info("Testing that BIP-44 wallet encryption") self.start_nodes() nodes[0].node_encrypt_wallet("password0") nodes[1].node_encrypt_wallet("password1") nodes[2].node_encrypt_wallet("password2") nodes[3].node_encrypt_wallet("password3") self.stop_nodes() # But words are not readable in an encrypted wallet with open(os.path.join(self.options.tmpdir+"/node0/regtest/", "wallet.dat"), 'rb') as f: assert_does_not_contain(MNEMONIC_0, str(f.read())) with open(os.path.join(self.options.tmpdir+"/node1/regtest/", "wallet.dat"), 'rb') as f: assert_does_not_contain(MNEMONIC_1, str(f.read())) with open(os.path.join(self.options.tmpdir+"/node2/regtest/", "wallet.dat"), 'rb') as f: assert_does_not_contain(mnemonic_2, str(f.read())) with open(os.path.join(self.options.tmpdir+"/node3/regtest/", "wallet.dat"), 'rb') as f: assert_does_not_contain(mnemonic_3, str(f.read())) # But the words are still available using getmywords after entering the passphrase self.start_nodes() assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first.", nodes[0].getmywords) nodes[0].walletpassphrase("password0", 48) assert_equal(nodes[0].getmywords()['word_list'], MNEMONIC_0) # Word list matches # Words can also be retrieved from the dumpwallet command nodes[0].dumpwallet(os.path.join(self.options.tmpdir+"/node0/regtest/", "dump_wallet_0.txt")) with open(os.path.join(self.options.tmpdir+"/node0/regtest/", "dump_wallet_0.txt"), 'r') as f: assert_contains(MNEMONIC_0, str(f.read()))
def run_test(self): """Main test logic""" # prepare node = self.nodes[0] node2 = self.nodes[1] node.generate(nblocks=2) # make some coins self.sync_all() # publish contract = generate_contract(self.options.tmpdir) result = node.publishcontract(contract) contract_id = result['contractaddress'] sender = result['senderaddress'] call_contract = caller_factory(self, contract_id, sender) # call # no coins assert_contains(call_contract(PAYABLE, amount=10000000), "Insufficient funds") # # 非法的入参 for amount in [10000000000, -1, 0, Decimal("0.00000009").quantize(Decimal("0.000000"))]: call_contract(PAYABLE, amount=amount) # 非法sender for sender_addr in [sender + "x", contract_id]: assert_contains(caller_factory(self, contract_id, sender_addr)(PAYABLE), "Invalid sender address") # # 合约不存在 assert_contains(caller_factory(self, "2PPWpHssgXjA8yEgfd3Vo36Hhx1eimbGCcP", sender)(PAYABLE), "GetContractInfo fail") # # 地址错误 for addr in [contract_id + 'x', sender]: caller_factory(self, addr, sender)(PAYABLE) # 函数不存在 if not SKIP: assert_contains(call_contract("payable2"), "can not find function") # send不能被裸调用 # bug被修复前,暂时跳过 if not SKIP: assert_contains(call_contract("send",sender,0),'can not call lua internal function directly') assert_contains(call_contract("rpcSendTest"), 'can not call lua internal function directly') # when not commit transaction, make sure contract tx is not in mempool if not SKIP: mempool = node.getrawmempool() node.callcontract(False, 1, contract_id, sender, PAYABLE) assert mempool == node.getrawmempool() # recharge to contract txid = call_contract(PAYABLE,amount = 1000)['txid'] sync_mempools(self.nodes) assert txid in node.getrawmempool() assert txid in node2.getrawmempool() assert_equal(node.getbalanceof(contract_id), 0) #合约的余额只会在一定的确认数之后才可以查看,在内存池中是不生效的 node.generate(nblocks=1) self.sync_all() assert txid not in node.getrawmempool() assert txid not in node2.getrawmempool() assert_equal(node.getbalanceof(contract_id), 1000) # 确认合约余额 # doubleSpendTest self.test_double_spend(mineblock=False) self.test_double_spend() call_contract("doubleSpendTest", node.getnewaddress(),throw_exception = True) # cmsgpackTest if not SKIP: assert_contains(call_contract("cmsgpackTest", node.getnewaddress(), 0), 'cmsgpack => sc >= LUACMSGPACK_MAX_NESTING') self.sync_all() # # tailLoopTest call_contract("tailLoopTest", 896) # v452,594 is the limit assert_contains(call_contract("tailLoopTest", 897), "run out of limit instruction") # # tailLoopTest2 call_contract("tailLoopTest2", 11) assert_contains(call_contract("tailLoopTest2", 12), "Too many args in lua function") # # unpackTest assert_contains(call_contract("unpackTest"), "too many results to unpack") # localFuncTest if not SKIP: assert_contains(call_contract("localFuncTest"), "can not find function") # longReturnTest if not SKIP: c = generate_contract(self.options.tmpdir, err_type="long_string_return") addre = node.publishcontract(c)['contractaddress'] node.callcontract(True,1,addre,sender,'longReturnTest') # contractDataTest call_contract("contractDataTest") assert_equal(call_contract("get", "size")['return'][0], 127) # make sure node1 mempool is empty node.generate(nblocks=2) assert_equal([], node.getrawmempool()) # sendCoinTest # send to mgc address new_address = node.getnewaddress() txid = call_contract("sendCoinTest", new_address, 1)['txid'] assert txid in node.getrawmempool() call_contract("sendCoinTest", new_address, "1e-3") assert_contains(call_contract("sendCoinTest", new_address, 2 ** 31 - 1), "not enough amount ") assert_contains(call_contract("sendCoinTest", new_address, 0.1), "JSON integer out of range") assert_contains(call_contract("sendCoinTest", new_address, 0), "SendCoins => amount(0) out of range") assert_contains(call_contract("sendCoinTest", new_address, -1), "SendCoins => amount(-100000000) out of range") # send all balance tmp_id = node.publishcontract(contract)["contractaddress"] tmp_caller = caller_factory(self, tmp_id, sender) tmp_caller(PAYABLE, amount=Decimal("1")) tmp_txid = tmp_caller("sendCoinTest", new_address, 1, amount=Decimal("0"),throw_exception = True)['txid'] # 利用节点2挖矿,确保节点1的交易可以打包的块 self.sync_all() node2.generate(nblocks=2) # 这里需要挖2个,因为send的输出需要达到成熟度才可以使用 self.sync_all() # make sure two transactions not in mempool # if assert failed it should be bug here assert txid not in node.getrawmempool() assert tmp_txid not in node.getrawmempool() self.sync_all() assert_equal(node.getbalanceof(tmp_id), 0) assert_equal(node.getbalanceof(new_address), 2) assert_equal(node2.getbalanceof(new_address), 2) assert_equal(node2.getbalanceof(tmp_id), 0) assert_contains(tmp_caller("sendCoinTest", new_address, 1), "not enough amount ") # send to contract tmp_id = node.publishcontract(contract)["contractaddress"] assert_contains(call_contract("sendCoinTest", tmp_id, 100), "Invalid destination address") node.generate(nblocks=1) # batchSendTest # 12个参数是上限,除去内部调用之后,实际能用的就只有7个参数位,并且不支持数组 for to in range(4): to_list = [node.getnewaddress() for i in range(7)] call_contract("addWithdrawList", *to_list) call_contract("batchSendTest") node.generate(nblocks=2) for addr in to_list: assert_equal(node.getbalanceof(addr), 1) # updateContractTest call_contract("updateContract", "self", "weigun") assert_equal(call_contract("get", "self")['return'][0], "weigun") node.generate(1) assert_equal([],node.getrawmempool()) # make sure mempool is empty # cycleSelfTest self.log.info("begin cycleSelfTest") if not SKIP: for i in range(100): call_contract("cycleSelf",throw_exception = False) call_contract("updateContract", "this", "",throw_exception = False) if i % 5 == 0: # print("generate block at :",i) node.generate(1) node.generate(1) # assert_equal([], node.getrawmempool()) # make sure mempool is empty # maxContractCallTest call_contract("maxContractCallTest", 15) # 15 is the limit assert_contains(call_contract("maxContractCallTest", 16), "run out of limit instruction") # callOtherContractTest # cycle call # step1 create contracts ca_id = contract_id cb_id = node.publishcontract(contract)["contractaddress"] cc_id = node.publishcontract(contract)["contractaddress"] caller_b = caller_factory(self, cb_id, sender) node.generate(nblocks=1) # step2 a->b->c->a(send will be call in last a) new_address = node.getnewaddress() if not SKIP: call_contract(CYCLE_CALL, cb_id, CYCLE_CALL, cc_id, CYCLE_CALL, ca_id, "sendCoinTest", new_address,throw_exception = True) node.generate(nblocks=1) assert_equal(node.getbalanceof(new_address), 1) # step3 a->b->c->b,modify PersistentData if not SKIP: caller_b("contractDataTest") # after called,size should be 127 assert_equal(caller_b("get", "size")['return'][0], 127) call_contract(CYCLE_CALL, cb_id, CYCLE_CALL, cc_id, CYCLE_CALL, cb_id, "reentrancyTest", new_address,throw_exception = True) # after called,size should be 127,because of replace dump call_contract(CYCLE_CALL, cb_id, CYCLE_CALL, cc_id, CYCLE_CALL, cb_id, "contractDataTest", new_address,throw_exception = True) # after called,size should be 127,because of replace dump node.generate(nblocks=1) assert_equal(caller_b("get", "size")['return'][0], 127) # lots of dust vin in contract's send transaction # TODO:maybe need to set payfee param in magnachaind if not SKIP: cd_id = node.publishcontract(contract)["contractaddress"] caller_d = caller_factory(self, cd_id, sender) for i in range(2000): caller_d(PAYABLE, amount=Decimal("1"),throw_exception = True) if i % 30 == 0: node.generate(nblocks=1) new_address = node.getnewaddress() caller_d("sendCoinTest", new_address, 1900, amount=Decimal("0")) node.generate(nblocks=2) assert_equal(node.getbalanceof(new_address), 1900) # dust change vout in send # node.sendtoaddress(new_sender,2) if not SKIP: tmp_id = node.publishcontract(contract)['contractaddress'] caller_tmp = caller_factory(self, tmp_id, sender) senders = [node.getnewaddress() for i in range(101)] i = 0 for _ in senders: # 充值101次,每次1个MGC caller_tmp(PAYABLE, amount=1,throw_exception = True) if i % 30 == 0: node.generate(1) i += 1 node.generate(2) assert_equal(node.getbalanceof(tmp_id), 101) i = 0 for to in senders: # 向每个地址发送cell - 999(最小单位),cell = 100000000。这里应该有101个微交易的找零 assert_equal(isinstance(caller_tmp("dustChangeTest", to, amount=Decimal("0"),throw_exception = True), dict), True) if i % 30 == 0: node.generate(1) i += 1 node.generate(nblocks=2) assert_equal(node.getbalanceof(tmp_id) * COIN, 101 * COIN - (COIN - 999 ) * 101) #因为lua没有浮点数,所以小数部分会截断掉 bal = node.getbalanceof(tmp_id) print(bal) tmp_sender = node.getnewaddress() assert_equal(isinstance(caller_tmp("sendCoinTest2", tmp_sender,amount=Decimal("0"),throw_exception = True), dict), True) # 组合所有微交易的找零,应该足够0.001个MGC的 node.generate(nblocks=2) assert_equal(node.getbalanceof(tmp_sender), Decimal("0.001")) assert_equal(node.getbalanceof(tmp_id), bal - Decimal("0.001")) # reentrancyTest last_id = node.publishcontract(contract)['contractaddress'] caller_last = caller_factory(self, last_id, sender) if not SKIP: caller_last("reentrancyTest") node.generate(nblocks=1) assert_equal(caller_last("get", "this")['return'], []) # 疲劳测试 if not SKIP: to_list = [node.getnewaddress() for i in range(1000)] for i,to in enumerate(to_list): caller_last(PAYABLE, amount=10) caller_last(CYCLE_CALL, last_id, "contractDataTest",amount=0) caller_last(CYCLE_CALL, last_id, "dustChangeTest",to,amount=0) caller_last(CYCLE_CALL, last_id, "addWithdrawList",to,amount=0) # caller_last(CYCLE_CALL, last_id, "batchSendTest",amount=0) if random.randint(1,100) > 70: node.generate(nblocks=1) else: if i % 30 == 0: node.generate(nblocks=1)
def test_messaging(self): self.log.info("Testing messaging!") n0, n1 = self.nodes[0], self.nodes[1] spam_name = "SPAM" asset_name = "MESSAGING" owner_name = "MESSAGING!" channel_one = "MESSAGING~ONE" channel_two = "MESSAGING~TWO" ipfs_hash = "QmZPGfJojdTzaqCWJu2m3krark38X1rqEHBo4SjeqHKB26" # need ownership before channels can be created assert_raises_rpc_error(-32600, "Wallet doesn't have asset: " + owner_name, n0.issue, channel_one) n0.issue(asset_name, 100) n0.issue(channel_one) n0.issue(channel_two) n0.issue(spam_name, 100) n0.generate(1) self.sync_all() # you're auto-subscribed to your own channels n0_channels = n0.viewallmessagechannels() assert_contains(owner_name, n0_channels) assert_contains(channel_one, n0_channels) assert_contains(channel_two, n0_channels) # n1 subscribes to owner and channel one assert_equal([], n1.viewallmessagechannels()) n1.subscribetochannel(owner_name) n1.subscribetochannel(channel_one) n1_channels = n1.viewallmessagechannels() assert_contains(owner_name, n1_channels) assert_contains(channel_one, n1_channels) assert_does_not_contain(channel_two, n1_channels) # n0 sends a message on owner n0.sendmessage(owner_name, ipfs_hash) n0.generate(1) self.sync_all() # n1 views then clears messages n1_messages = n1.viewallmessages() assert_equal(1, len(n1_messages)) message = n1_messages[0] assert_contains_pair("Asset Name", owner_name, message) assert_contains_pair("Message", ipfs_hash, message) n1.clearmessages() n1_messages = n1.viewallmessages() assert_equal(0, len(n1_messages)) # n0 sends more messages on channels one and two n0.sendmessage(channel_one, ipfs_hash) n0.sendmessage(channel_two, ipfs_hash) n0.generate(1) self.sync_all() # n1 views then clears messages n1_messages = n1.viewallmessages() assert_equal(1, len(n1_messages)) message = n1_messages[0] assert_contains_pair("Asset Name", channel_one, message) assert_contains_pair("Message", ipfs_hash, message) n1.clearmessages() n1_messages = n1.viewallmessages() assert_equal(0, len(n1_messages)) # n1 unsubscribes n1.unsubscribefromchannel(owner_name) n1.unsubscribefromchannel(channel_one) assert_equal(0, len(n1.viewallmessagechannels())) # auto-subscribe / spam protection (first address use only) addr1 = n1.getnewaddress() n0.transfer(asset_name, 10, addr1) n0.generate(1) self.sync_all() n0.transfer(spam_name, 10, addr1) n1_channels = n1.viewallmessagechannels() assert_equal(1, len(n1_channels)) assert_contains(owner_name, n1_channels) assert_does_not_contain(spam_name, n1_channels) n1.unsubscribefromchannel(owner_name) # pre-existing messages (don't see w/o rescan) assert_equal(0, len(n1.viewallmessages())) n0.sendmessage(channel_two, ipfs_hash) n0.generate(1) self.sync_all() assert_equal(0, len(n1.viewallmessages())) n1.subscribetochannel(channel_two) assert_equal(0, len(n1.viewallmessages())) n0.sendmessage(channel_two, ipfs_hash) n0.generate(1) self.sync_all() assert_equal(1, len(n1.viewallmessages())) assert_contains_pair("Asset Name", channel_two, n1.viewallmessages()[0]) n1.clearmessages() n1.unsubscribefromchannel(channel_two)