def run_test(self): tmpdir = self.options.tmpdir nodes = self.nodes nodes[0].extkeyimportmaster(nodes[0].mnemonic('new')['master']) nodes[1].extkeyimportmaster( 'abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb' ) address0 = nodes[0].getnewaddress() # Will be different each run address1 = nodes[1].getnewaddress() assert (address1 == 'pX9N6S76ZtA5BfsiJmqBbjaEgLMHpt58it') sx_addr0 = nodes[0].getnewstealthaddress() nodes[1].sendtypeto('rhom', 'rhom', [ { 'address': sx_addr0, 'amount': 20 }, ]) ro = nodes[0].smsglocalkeys() assert (len(ro['wallet_keys']) == 0) ro = nodes[0].smsgaddlocaladdress(address0) assert ('Receiving messages enabled for address' in ro['result']) ro = nodes[0].smsglocalkeys() assert (len(ro['wallet_keys']) == 1) ro = nodes[1].smsgaddaddress(address0, ro['wallet_keys'][0]['public_key']) assert (ro['result'] == 'Public key added to db.') text_1 = "['data':'test','value':1]" ro = nodes[1].smsgsend(address1, address0, text_1, True, 4, True) assert (ro['result'] == 'Not Sent.') assert (isclose(ro['fee'], 0.00086600)) ro = nodes[1].smsgsend(address1, address0, text_1, True, 4) assert (ro['result'] == 'Sent.') self.stakeBlocks(1, nStakeNode=1) for i in range(20): nodes[0].sendtypeto('rhom', 'anon', [ { 'address': sx_addr0, 'amount': 0.5 }, ]) self.waitForSmsgExchange(1, 1, 0) ro = nodes[0].smsginbox() assert (len(ro['messages']) == 1) assert (ro['messages'][0]['text'] == text_1) self.log.info('Test smsgimportprivkey and smsgdumpprivkey') test_privkey = '7pHSJFY1tNwi6d68UttGzB8YnXq2wFWrBVoadLv4Y6ekJD3L1iKs' address0_1 = 'pasdoMwEn35xQUXFvsChWAQjuG8rEKJQW9' nodes[0].smsgimportprivkey(test_privkey, 'smsg test key') assert (nodes[0].smsgdumpprivkey(address0_1) == test_privkey) text_2 = "['data':'test','value':2]" ro = nodes[0].smsglocalkeys() assert (len(ro['smsg_keys']) == 1) assert (ro['smsg_keys'][0]['address'] == address0_1) ro = nodes[1].smsgaddaddress(address0_1, ro['smsg_keys'][0]['public_key']) assert (ro['result'] == 'Public key added to db.') ro = nodes[1].smsgsend(address1, address0_1, text_2, True, 4) assert (ro['result'] == 'Sent.') self.stakeBlocks(1, nStakeNode=1) self.waitForSmsgExchange(2, 1, 0) ro = nodes[0].smsginbox() assert (len(ro['messages']) == 1) assert (ro['messages'][0]['text'] == text_2) nodes[0].encryptwallet('qwerty234') time.sleep(2) ro = nodes[0].getwalletinfo() assert (ro['encryptionstatus'] == 'Locked') localkeys0 = nodes[0].smsglocalkeys() assert (len(localkeys0['smsg_keys']) == 1) assert (len(localkeys0['wallet_keys']) == 1) assert (localkeys0['smsg_keys'][0]['address'] == address0_1) assert (localkeys0['wallet_keys'][0]['address'] == address0) text_3 = "['data':'test','value':3]" ro = nodes[0].smsglocalkeys() assert (len(ro['smsg_keys']) == 1) assert (ro['smsg_keys'][0]['address'] == address0_1) ro = nodes[1].smsgsend(address1, address0, 'Non paid msg') assert (ro['result'] == 'Sent.') ro = nodes[1].smsgsend(address1, address0_1, text_3, True, 4) assert (ro['result'] == 'Sent.') assert (len(ro['txid']) == 64) self.sync_all() self.stakeBlocks(1, nStakeNode=1) self.waitForSmsgExchange(4, 1, 0) msgid = ro['msgid'] for i in range(5): try: ro = nodes[1].smsg(msgid) assert (ro['location'] == 'outbox') break except Exception as e: time.sleep(1) assert (ro['text'] == text_3) assert (ro['from'] == address1) assert (ro['to'] == address0_1) ro = nodes[0].walletpassphrase("qwerty234", 300) ro = nodes[0].smsginbox() assert (len(ro['messages']) == 2) flat = self.dumpj(ro) assert ('Non paid msg' in flat) assert (text_3 in flat) ro = nodes[0].walletlock() ro = nodes[0].smsginbox("all") assert (len(ro['messages']) == 4) flat = self.dumpj(ro) assert (flat.count('Wallet is locked') == 2) ro = nodes[0].smsg(msgid) assert (ro['read'] == True) ro = nodes[0].smsg(msgid, {'setread': False}) assert (ro['read'] == False) ro = nodes[0].smsg(msgid, {'delete': True}) assert (ro['operation'] == 'Deleted') try: ro = nodes[0].smsg(msgid) assert (False), 'Read deleted msg.' except: pass ro = nodes[0].smsggetpubkey(address0_1) assert ( ro['publickey'] == 'h2UfzZxbhxQPcXDfYTBRGSC7GM77qrLjhtqcmfAnAia9') filepath = tmpdir + '/sendfile.txt' msg = b"msg in file\0after null sep" with open(filepath, 'wb', encoding=None) as fp: fp.write(msg) sendoptions = {'fromfile': True} ro = nodes[1].smsgsend(address1, address0_1, filepath, True, 4, False, sendoptions) assert (ro['result'] == 'Sent.') msgid = ro['msgid'] sendoptions = {'decodehex': True} ro = nodes[1].smsgsend(address1, address0_1, binascii.hexlify(msg).decode("utf-8"), True, 4, False, sendoptions) msgid2 = ro['msgid'] self.stakeBlocks(1, nStakeNode=1) for i in range(5): try: ro = nodes[1].smsg(msgid, {'encoding': 'hex'}) assert (ro['location'] == 'outbox') break except: time.sleep(1) assert (msg == bytes.fromhex(ro['hex'][:-2]) ) # Extra null byte gets tacked on for i in range(5): try: ro = nodes[1].smsg(msgid2, {'encoding': 'hex'}) assert (ro['location'] == 'outbox') break except: time.sleep(1) assert (msg == bytes.fromhex(ro['hex'][:-2])) assert (ro['daysretention'] == 4) ro = nodes[0].smsgoptions('list', True) assert (len(ro['options']) == 3) assert (len(ro['options'][0]['description']) > 0) ro = nodes[0].smsgoptions('set', 'newAddressAnon', 'false') assert ('newAddressAnon = false' in json.dumps(ro)) addr = nodes[0].getnewaddress('smsg test') pubkey = nodes[0].getaddressinfo(addr)['pubkey'] ro = nodes[1].smsgaddaddress(addr, pubkey) assert ('Public key added to db' in json.dumps(ro)) # Wait for sync i = 0 for i in range(10): ro = nodes[0].smsginbox('all') if len(ro['messages']) >= 5: break time.sleep(1) assert (i < 10) self.log.info('Test filtering') ro = nodes[0].smsginbox('all', "'vAlue':2") assert (len(ro['messages']) == 1) ro = nodes[1].smsgoutbox('all', "'vAlue':2") assert (len(ro['messages']) == 1) self.log.info('Test clear and rescan') ro = nodes[0].smsginbox('clear') assert ('Deleted 5 messages' in ro['result']) ro = nodes[0].walletpassphrase("qwerty234", 300) ro = nodes[0].smsgscanbuckets() assert ('Scan Buckets Completed' in ro['result']) ro = nodes[0].smsginbox('all') # Recover 5 + 1 dropped msg assert (len(ro['messages']) == 6) self.log.info('Test smsglocalkeys') addr = nodes[0].getnewaddress() ro = nodes[0].smsglocalkeys('recv', '+', addr) assert ('Address not found' in ro['result']) ro = nodes[0].smsglocalkeys('anon', '+', addr) assert ('Address not found' in ro['result']) ro = nodes[0].smsgaddlocaladdress(addr) assert ('Receiving messages enabled for address' in ro['result']) ro = nodes[0].smsglocalkeys('recv', '-', addr) assert ('Receive off' in ro['key']) assert (addr in ro['key']) ro = nodes[0].smsglocalkeys('anon', '-', addr) assert ('Anon off' in ro['key']) assert (addr in ro['key']) ro = nodes[0].smsglocalkeys('all') n = getIndexAtProperty(ro['wallet_keys'], 'address', addr) assert (ro['wallet_keys'][n]['receive'] == '0') assert (ro['wallet_keys'][n]['anon'] == '0') self.log.info('Test smsgpurge') ro = nodes[0].smsg(msgid, {'encoding': 'hex'}) assert (ro['msgid'] == msgid) nodes[0].smsgpurge(msgid) try: nodes[0].smsg(msgid, {'encoding': 'hex'}) assert (False), 'Purged message in inbox' except JSONRPCException as e: assert ('Unknown message id' in e.error['message']) ro = nodes[0].smsgbuckets() assert (int(ro['total']['numpurged']) == 1) # Sum all buckets num_messages = 0 num_active = 0 for b in ro['buckets']: num_messages += int(b['no. messages']) num_active += int(b['active messages']) assert (num_messages == num_active + 1) self.log.info('Test listunspent include_immature') without_immature = nodes[1].listunspent() with_immature = nodes[1].listunspent( query_options={'include_immature': True}) assert (len(with_immature) > len(without_immature)) self.log.info('Test encoding options') options = {'encoding': 'hex'} ro = nodes[0].smsginbox('all', '', options) assert (len(ro['messages']) == 5) for msg in ro['messages']: assert ('hex' in msg) options = {'encoding': 'text'} ro = nodes[0].smsginbox('all', '', options) assert (len(ro['messages']) == 5) for msg in ro['messages']: assert ('text' in msg) options = {'encoding': 'none'} ro = nodes[0].smsginbox('all', '', options) assert (len(ro['messages']) == 5) for msg in ro['messages']: assert ('text' not in msg) assert ('hex' not in msg) self.log.info('Test disablewallet') assert ('SMSG' in self.dumpj(nodes[2].getnetworkinfo()['localservicesnames'])) assert_raises_rpc_error(-32601, 'Method not found', nodes[2].getwalletinfo) for i in range(20): if nodes[0].smsgbuckets('total')['total']['messages'] != nodes[ 2].smsgbuckets('total')['total']['messages']: time.sleep(0.5) continue break assert (nodes[0].smsgbuckets('total')['total']['messages'] == nodes[2].smsgbuckets('total')['total']['messages']) self.log.info('Test smsggetinfo and smsgsetwallet') ro = nodes[0].smsggetinfo() assert (ro['enabled'] is True) assert (ro['active_wallet'] == '') assert_raises_rpc_error(-1, 'Wallet not found: "abc"', nodes[0].smsgsetwallet, 'abc') nodes[0].smsgsetwallet() ro = nodes[0].smsggetinfo() assert (ro['enabled'] is True) assert (ro['active_wallet'] == 'Not set.') nodes[0].createwallet('new_wallet') assert (len(nodes[0].listwallets()) == 2) nodes[0].smsgsetwallet('new_wallet') ro = nodes[0].smsggetinfo() assert (ro['enabled'] is True) assert (ro['active_wallet'] == 'new_wallet') nodes[0].smsgdisable() ro = nodes[0].smsggetinfo() assert (ro['enabled'] is False) nodes[0].smsgenable() ro = nodes[0].smsggetinfo() assert (ro['enabled'] is True) self.log.info('Test funding from RCT balance') nodes[1].smsginbox() # Clear inbox ro = nodes[1].smsgaddlocaladdress(address1) assert ('Receiving messages enabled for address' in ro['result']) msg = 'Test funding from RCT balance' sendoptions = {'fund_from_rct': True, 'rct_ring_size': 6} sent_msg = nodes[0].smsgsend(address0, address1, msg, True, 4, False, sendoptions) assert (sent_msg['result'] == 'Sent.') fund_tx = nodes[0].getrawtransaction(sent_msg['txid'], True) assert (fund_tx['vin'][0]['type'] == 'anon') ro = nodes[0].smsgoutbox('all', '', {'sending': True}) assert (ro['messages'][0]['msgid'] == sent_msg['msgid']) sync_mempools([nodes[0], nodes[1]]) self.stakeBlocks(1, nStakeNode=1) i = 0 for i in range(20): ro = nodes[1].smsginbox() if len(ro['messages']) > 0: break time.sleep(1) assert (i < 19) assert (msg == ro['messages'][0]['text']) ro = nodes[0].smsgoutbox('all', '', {'sending': True}) assert (len(ro['messages']) == 0)
def test_cttx(self): nodes = self.nodes # Test confidential transactions addrA_sx = nodes[0].getnewstealthaddress() # party A addrB_sx = nodes[1].getnewstealthaddress() # party B outputs = [ { 'address':addrA_sx, 'type':'blind', 'amount':100, }, { 'address':addrB_sx, 'type':'blind', 'amount':100, }, ] ro = nodes[0].createrawparttransaction([], outputs) ro = nodes[0].fundrawtransactionfrom('standard', ro['hex'], {}, ro['amounts']) rawtx = ro['hex'] ro = nodes[0].signrawtransactionwithwallet(rawtx) assert(ro['complete'] == True) ro = nodes[0].sendrawtransaction(ro['hex']) txnid = ro self.stakeBlocks(1) ro = nodes[0].getwalletinfo() assert(isclose(ro['blind_balance'], 100.0)) ro = nodes[0].filtertransactions() n = getIndexAtProperty(ro, 'txid', txnid) assert(n > -1) assert(isclose(ro[n]['amount'], -100.00203200)) ro = nodes[1].getwalletinfo() assert(isclose(ro['blind_balance'], 100.0)) ro = nodes[1].filtertransactions() n = getIndexAtProperty(ro, 'txid', txnid) assert(n > -1) assert(isclose(ro[n]['amount'], 100.0)) # Initiate A -> B # A has address (addrB_sx) of B amountA = 7.0 amountB = 7.0 secretA = os.urandom(32) secretAHash = sha256(secretA) lockTime = int(time.time()) + 10000 # future locktime destA = nodes[0].derivefromstealthaddress(addrA_sx) pkh0_0 = b58decode(destA['address'])[1:-4] ro = nodes[0].derivefromstealthaddress(addrA_sx, destA['ephemeral_pubkey']) privKeyA = ro['privatekey'] pubKeyA = ro['pubkey'] destB = nodes[0].derivefromstealthaddress(addrB_sx) pkh1_0 = b58decode(destB['address'])[1:-4] ro = nodes[1].derivefromstealthaddress(addrB_sx, destB['ephemeral_pubkey']) privKeyB = ro['privatekey'] pubKeyB = ro['pubkey'] scriptInitiate = CreateAtomicSwapScript(payTo=pkh1_0, refundTo=pkh0_0, lockTime=lockTime, secretHash=secretAHash) p2sh_initiate = script_to_p2sh_part(scriptInitiate) outputs = [ { 'address':p2sh_initiate, 'pubkey':destB['pubkey'], 'type':'blind', 'amount':amountA, }, ] ro = nodes[0].createrawparttransaction([], outputs) ro = nodes[0].fundrawtransactionfrom('blind', ro['hex'], {}, ro['amounts']) output_amounts_i = ro['output_amounts'] ro = nodes[0].signrawtransactionwithwallet(ro['hex']) assert(ro['complete'] == True) rawtx_i = ro['hex'] rawtx_i_refund = createRefundTxCT(nodes[0], rawtx_i, output_amounts_i, scriptInitiate, lockTime, privKeyA, pubKeyA, addrA_sx) ro = nodes[0].testmempoolaccept([rawtx_i_refund,]) print(ro) assert('non-final' in ro[0]['reject-reason']) txnid1 = nodes[0].sendrawtransaction(rawtx_i) self.stakeBlocks(1) # Party A sends B rawtx_i/txnid1, script and output_amounts_i # auditcontract # Party B extracts the secrethash and verifies the txn: ro = nodes[1].decoderawtransaction(rawtx_i) n = getOutputByAddr(ro, p2sh_initiate) valueCommitment = ro['vout'][n]['valueCommitment'] amount = output_amounts_i[str(n)]['value'] blind = output_amounts_i[str(n)]['blind'] assert(nodes[1].verifycommitment(valueCommitment, blind, amount)['result'] == True) # Participate B -> A # needs address and publickey from A, amount and secretAHash lockTimeP = int(time.time()) + 10000 # future locktime scriptParticipate = CreateAtomicSwapScript(payTo=pkh0_0, refundTo=pkh1_0, lockTime=lockTimeP, secretHash=secretAHash) p2sh_participate = script_to_p2sh_part(scriptParticipate) outputs = [ { 'address':p2sh_participate, 'pubkey':destA['pubkey'], 'type':'blind', 'amount':amountB, }, ] ro = nodes[1].createrawparttransaction([], outputs) ro = nodes[1].fundrawtransactionfrom('blind', ro['hex'], {}, ro['amounts']) output_amounts_p = ro['output_amounts'] ro = nodes[1].signrawtransactionwithwallet(ro['hex']) rawtx_p = ro['hex'] rawtx_p_refund = createRefundTxCT(nodes[1], rawtx_p, output_amounts_p, scriptParticipate, lockTime, privKeyB, pubKeyB, addrB_sx) ro = nodes[1].testmempoolaccept([rawtx_p_refund,]) assert('non-final' in ro[0]['reject-reason']) txnid_p = nodes[0].sendrawtransaction(rawtx_p) self.stakeBlocks(1) assert(txnid_p in nodes[0].getblock(nodes[0].getblockhash(nodes[0].getblockcount()))['tx']) # B sends output_amounts to A # Party A Redeem/Claim from participate txn # Party A spends the funds from the participate txn, and to do so must reveal secretA rawtxclaimA = createClaimTxCT(nodes[0], rawtx_p, output_amounts_p, scriptParticipate, secretA, privKeyA, pubKeyA, addrA_sx) txnidAClaim = nodes[0].sendrawtransaction(rawtxclaimA) # Party B claims from initiate txn # Get secret from txnidAClaim #ro = nodes[1].getrawtransaction(txnidAClaim, True) #print('ro', json.dumps(ro, indent=4, default=jsonDecimal)) rawtxclaimB = createClaimTxCT(nodes[1], rawtx_i, output_amounts_i, scriptInitiate, secretA, privKeyB, pubKeyB, addrB_sx) txnidBClaim = nodes[0].sendrawtransaction(rawtxclaimB) nodes[0].getmempoolentry(txnidAClaim) nodes[0].getmempoolentry(txnidBClaim) # Test Refund expired initiate tx secretA = os.urandom(32) secretAHash = sha256(secretA) lockTime = int(time.time()) - 100000 # past locktime amountA = 7.1 scriptInitiate = CreateAtomicSwapScript(payTo=pkh1_0, refundTo=pkh0_0, lockTime=lockTime, secretHash=secretAHash) p2sh_initiate = script_to_p2sh_part(scriptInitiate) outputs = [ { 'address':p2sh_initiate, 'pubkey':destB['pubkey'], 'type':'blind', 'amount':amountA, }, ] ro = nodes[0].createrawparttransaction([], outputs) ro = nodes[0].fundrawtransactionfrom('blind', ro['hex'], {}, ro['amounts']) r2 = nodes[0].verifyrawtransaction(ro['hex']) assert(r2['complete'] == False) output_amounts_i = ro['output_amounts'] ro = nodes[0].signrawtransactionwithwallet(ro['hex']) assert(ro['complete'] == True) rawtx_i = ro['hex'] r2 = nodes[0].verifyrawtransaction(rawtx_i) assert(r2['complete'] == True) rawtx_i_refund = createRefundTxCT(nodes[0], rawtx_i, output_amounts_i, scriptInitiate, lockTime, privKeyA, pubKeyA, addrA_sx) ro = nodes[0].testmempoolaccept([rawtx_i_refund,]) assert('missing-inputs' in ro[0]['reject-reason']) txnid1 = nodes[0].sendrawtransaction(rawtx_i) ro = nodes[0].getwalletinfo() assert(ro['unconfirmed_blind'] > 6.0 and ro['unconfirmed_blind'] < 7.0) txnidRefund = nodes[0].sendrawtransaction(rawtx_i_refund) nodes[0].getmempoolentry(txnidRefund) ro = nodes[0].getwalletinfo() assert(ro['unconfirmed_blind'] > 14.0 and ro['unconfirmed_blind'] < 14.1)
def run_test(self): # Check that rhombus has been built with USB device enabled config = configparser.ConfigParser() if not self.options.configfile: self.options.configfile = os.path.dirname(__file__) + "/../config.ini" config.read_file(open(self.options.configfile)) if not config["components"].getboolean("ENABLE_USBDEVICE"): raise SkipTest("rhombusd has not been built with usb device enabled.") nodes = self.nodes nodes[0].extkeyimportmaster('abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb') assert(nodes[0].getwalletinfo()['total_balance'] == 100000) ro = nodes[1].listdevices() assert(len(ro) == 1) assert(ro[0]['vendor'] == 'Debug') assert(ro[0]['product'] == 'Device') ro = nodes[1].getdeviceinfo() assert(ro['device'] == 'debug') ro = nodes[1].getdevicepublickey('0') assert(ro['address'] == 'praish9BVxVdhykpqBYEs6L65AQ7iKd9z1') assert(ro['path'] == "m/44'/1'/0'/0") ro = nodes[1].getdevicepublickey('0/1') assert(ro['address'] == 'peWvjy33QptC2Gz3ww7jTTLPjC2QJmifBR') assert(ro['path'] == "m/44'/1'/0'/0/1") ro = nodes[1].getdevicexpub("m/44'/1'/0'", "") assert(ro == 'pparszKXPyRegWYwPacdPduNPNEryRbZDCAiSyo8oZYSsbTjc6FLP4TCPEX58kAeCB6YW9cSdR6fsbpeWDBTgjbkYjXCoD9CNoFVefbkg3exzpQE') message = 'This is just a test message' sig = nodes[1].devicesignmessage('0/1', message) assert(True == nodes[1].verifymessage('peWvjy33QptC2Gz3ww7jTTLPjC2QJmifBR', sig, message)) ro = nodes[1].initaccountfromdevice('test_acc') assert(ro['extkey'] == 'pparszKXPyRegWYwPacdPduNPNEryRbZDCAiSyo8oZYSsbTjc6FLP4TCPEX58kAeCB6YW9cSdR6fsbpeWDBTgjbkYjXCoD9CNoFVefbkg3exzpQE') assert(ro['path'] == "m/44'/1'/0'") ro = nodes[1].extkey('list', 'true') assert(len(ro) == 1) assert(ro[0]['path'] == "m/44h/1h/0h") assert(ro[0]['epkey'] == 'pparszKXPyRegWYwPacdPduNPNEryRbZDCAiSyo8oZYSsbTjc6FLP4TCPEX58kAeCB6YW9cSdR6fsbpeWDBTgjbkYjXCoD9CNoFVefbkg3exzpQE') assert(ro[0]['label'] == 'test_acc') assert(ro[0]['hardware_device'] == '0xffff 0x0001') ro = nodes[1].extkey('account') n = getIndexAtProperty(ro['chains'], 'use_type', 'stealth_spend') assert(n > -1) assert(ro['chains'][n]['path'] == "m/0h/444445h") addr1_0 = nodes[1].getnewaddress('lbl1_0') ro = nodes[1].filteraddresses() assert(len(ro) == 1) assert(ro[0]['path'] == 'm/0/0') assert(ro[0]['owned'] == 'true') assert(ro[0]['label'] == 'lbl1_0') va_addr1_0 = nodes[1].getaddressinfo(addr1_0) assert(va_addr1_0['ismine'] == True) assert(va_addr1_0['iswatchonly'] == False) assert(va_addr1_0['isondevice'] == True) assert(va_addr1_0['path'] == 'm/0/0') try: nodes[1].getnewstealthaddress() raise AssertionError('Should have failed.') except JSONRPCException as e: pass extaddr1_0 = nodes[1].getnewextaddress() txnid0 = nodes[0].sendtoaddress(addr1_0, 6) txnid1 = nodes[0].sendtoaddress(extaddr1_0, 6) self.stakeBlocks(1) block_txns = nodes[0].getblock(nodes[0].getblockhash(nodes[0].getblockcount()))['tx'] assert(txnid0 in block_txns) assert(txnid1 in block_txns) ro = nodes[1].getwalletinfo() assert(isclose(ro['balance'], 12.0)) addr0_0 = nodes[0].getnewaddress() hexRaw = nodes[1].createrawtransaction([], {addr0_0:10}) hexFunded = nodes[1].fundrawtransaction(hexRaw)['hex'] txDecoded = nodes[1].decoderawtransaction(hexFunded) ro = nodes[1].devicesignrawtransaction(hexFunded) assert(ro['complete'] == True) txnid1 = nodes[1].sendrawtransaction(ro['hex']) self.sync_all() self.stakeBlocks(1) ro = nodes[1].devicesignrawtransaction(hexFunded) assert(ro['errors'][0]['error'] == 'Input not found or already spent') prevtxns = [] for vin in txDecoded['vin']: rtx = nodes[1].getrawtransaction(vin['txid'], True) prev_out = rtx['vout'][vin['vout']] prevtxns.append({'txid': vin['txid'], 'vout': vin['vout'], 'scriptPubKey': prev_out['scriptPubKey']['hex'], 'amount': prev_out['value']}) ro = nodes[1].devicesignrawtransaction(hexFunded, prevtxns, ['0/0', '2/0']) assert(ro['complete'] == True) ro = nodes[1].listunspent() assert(ro[0]['ondevice'] == True) txnid2 = nodes[1].sendtoaddress(addr0_0, 0.1) self.sync_all() nodes[0].syncwithvalidationinterfacequeue() assert(nodes[0].filtertransactions()[0]['txid'] == txnid2) hwsxaddr = nodes[1].devicegetnewstealthaddress() assert(hwsxaddr == 'tps1qqpdwu7gqjqz9s9wfek843akvkzvw0xq3tkzs93sj4ceq60cp54mvzgpqf4tp6d7h0nza2xe362am697dax24hcr33yxqwvq58l5cf6j6q5hkqqqgykgrc') hwsxaddr2 = nodes[1].devicegetnewstealthaddress('lbl2 4bits', '4', '0xaaaa', True) assert(hwsxaddr2 == 'tps1qqpewyspjp93axk82zahx5xfjyprpvypfgnp95n9aynxxw3w0qs63acpq0s5z2rwk0raczg8jszl9qy5stncud76ahr5etn9hqmp30e3e86w2qqypgh9sgv0') ro = nodes[1].getaddressinfo(hwsxaddr2) assert(ro['prefix_num_bits'] == 4) assert(ro['prefix_bitfield'] == '0x000a') assert(ro['isondevice'] == True) ro = nodes[1].liststealthaddresses() assert(len(ro[0]['Stealth Addresses']) == 2) ro = nodes[1].filteraddresses() assert(len(ro) == 3) txnid3 = nodes[0].sendtoaddress(hwsxaddr, 0.1, '', '', False, 'test msg') self.stakeBlocks(1) ro = nodes[1].listtransactions() assert(len(ro) == 5) assert('test msg' in self.dumpj(ro[4])) ro = nodes[1].listunspent() inputs = [] for output in ro: if output['txid'] == txnid3: inputs.append({'txid' : txnid3, 'vout' : output['vout']}) break assert(len(inputs) > 0) hexRaw = nodes[1].createrawtransaction(inputs, {addr0_0:0.09}) ro = nodes[1].devicesignrawtransaction(hexRaw) assert(ro['complete'] == True) # import privkey in node2 rootkey = nodes[2].extkeyaltversion('xparFdrwJK7K2nfYzrkEqAKr5EcJNdY4c6ZNoLFFx1pMXQSQpo5MAufjogrS17RkqsLAijZJaBDHhG3G7SuJjtsTmRRTEKZDzGMnVCeX59cQCiR') ro = nodes[2].extkey('import', rootkey, 'master key', True) ro = nodes[2].extkey('setmaster', ro['id']) assert(ro['result'] == 'Success.') ro = nodes[2].extkey('deriveaccount', 'test account') ro = nodes[2].extkey('setdefaultaccount', ro['account']) assert(ro['result'] == 'Success.') ro = nodes[1].extkey('account') n = getIndexAtProperty(ro['chains'], 'use_type', 'stealth_spend') assert(n > -1) assert(ro['chains'][n]['path'] == "m/0h/444445h") addrtest = nodes[2].getnewaddress() ro = nodes[1].getdevicepublickey('0/0') assert(addrtest == ro['address']) addrtest = nodes[2].getnewstealthaddress('', '0', '', True, True) assert(addrtest == hwsxaddr) addrtest2 = nodes[2].getnewstealthaddress('lbl2 4bits', '4', '0xaaaa', True, True) assert(addrtest2 == hwsxaddr2) extaddr2_0 = nodes[2].getnewextaddress() assert(extaddr1_0 == extaddr2_0) # Ensure account matches after node restarts account1 = nodes[1].extkey('account') self.restart_node(1) account1_r = nodes[1].extkey('account') assert(json.dumps(account1) == json.dumps(account1_r)) # Test for coverage assert(nodes[1].promptunlockdevice()['sent'] is True) assert(nodes[1].unlockdevice('123')['unlocked'] is True) assert_raises_rpc_error(-8, 'Neither a pin nor a passphraseword was provided.', nodes[1].unlockdevice) assert('complete' in nodes[1].devicebackup()) assert('complete' in nodes[1].deviceloadmnemonic())
def test_standardtx(self): nodes = self.nodes addrA_0 = nodes[0].getnewaddress() # party A addrB_0 = nodes[1].getnewaddress() # party B # Initiate A -> B # A has address (addrB_0) of B amountA = 5.0 amountB = 5.0 pkh0_0 = b58decode(addrA_0)[1:-4] pkh1_0 = b58decode(addrB_0)[1:-4] secretA = os.urandom(32) secretAHash = sha256(secretA) lockTime = int(time.time()) + 10000 # future locktime scriptInitiate = CreateAtomicSwapScript(payTo=pkh1_0, refundTo=pkh0_0, lockTime=lockTime, secretHash=secretAHash) p2sh_initiate = script_to_p2sh_part(scriptInitiate) rawtxInitiate = nodes[0].createrawtransaction([], {p2sh_initiate:amountA}) rawtxInitiate = nodes[0].fundrawtransaction(rawtxInitiate)['hex'] ro = nodes[0].signrawtransactionwithwallet(rawtxInitiate) assert(ro['complete'] == True) rawtxInitiate = ro['hex'] rawtx1refund = createRefundTx(nodes[0], rawtxInitiate, scriptInitiate, lockTime, addrA_0, addrA_0) nodes[0].sendrawtransaction(rawtxInitiate) self.stakeBlocks(1) ro = nodes[0].getblockchaininfo() assert(ro['mediantime'] < lockTime) try: txnidrefund = nodes[0].sendrawtransaction(rawtx1refund) assert(False) except JSONRPCException as e: assert('non-final' in e.error['message']) # Party A sends B rawtxInitiate/txnid1 and script # auditcontract # Party B extracts the secrethash and verifies the txn: assert(len(scriptInitiate) == 97) extractedSecretAHash = scriptInitiate[7:7+32] assert(extractedSecretAHash == secretAHash) tx1 = nodes[1].decoderawtransaction(rawtxInitiate) self.log.info("Verify txn " + tx1['txid']) # TODO # Participate B -> A # needs address from A, amount and secretAHash lockTimeP = int(time.time()) + 10000 # future locktime scriptParticipate = CreateAtomicSwapScript(payTo=pkh0_0, refundTo=pkh1_0, lockTime=lockTimeP, secretHash=secretAHash) p2sh_participate = script_to_p2sh_part(scriptParticipate) rawtx_p = nodes[1].createrawtransaction([], {p2sh_participate:amountB}) rawtx_p = nodes[1].fundrawtransaction(rawtx_p)['hex'] ro = nodes[1].signrawtransactionwithwallet(rawtx_p) assert(ro['complete'] == True) rawtx_p = ro['hex'] rawtxRefundP = createRefundTx(nodes[1], rawtx_p, scriptParticipate, lockTimeP, addrB_0, addrB_0) txnidParticipate = nodes[1].sendrawtransaction(rawtx_p) self.sync_all() self.stakeBlocks(1) assert(txnidParticipate in nodes[0].getblock(nodes[0].getblockhash(nodes[0].getblockcount()))['tx']) ro = nodes[0].getblockchaininfo() assert(ro['mediantime'] < lockTimeP) try: txnidrefund = nodes[1].sendrawtransaction(rawtxRefundP) assert(False) except JSONRPCException as e: assert('non-final' in e.error['message']) # auditcontract # Party A verifies the participate txn from B # Party A Redeem/Claim from participate txn # Party A spends the funds from the participate txn, and to do so must reveal secretA rawtxclaimA = createClaimTx(nodes[0], rawtx_p, scriptParticipate, secretA, addrA_0, addrA_0) txnidAClaim = nodes[0].sendrawtransaction(rawtxclaimA) # Party B Redeem/Claim from initiate txn # Get secret from txnidAClaim #ro = nodes[1].getrawtransaction(txnidAClaim, True) #print('ro', json.dumps(ro, indent=4, default=jsonDecimal)) rawtxclaimB = createClaimTx(nodes[1], rawtxInitiate, scriptInitiate, secretA, addrB_0, addrB_0) txnidBClaim = nodes[0].sendrawtransaction(rawtxclaimB) # send from staking node to avoid syncing self.stakeBlocks(1) last_block_txns = nodes[0].getblock(nodes[0].getblockhash(nodes[0].getblockcount()))['tx'] assert(txnidAClaim in last_block_txns) assert(txnidBClaim in last_block_txns) ftxB = nodes[1].filtertransactions() assert(ftxB[0]['confirmations'] == 1) assert(ftxB[0]['outputs'][0]['amount'] < 5.0 and ftxB[-1]['outputs'][0]['amount'] > 4.9) assert(isclose(ftxB[1]['outputs'][0]['amount'], -5.0)) # Test Refund expired initiate tx lockTime = int(time.time()) - 100000 # past locktime scriptInitiate2 = CreateAtomicSwapScript(payTo=pkh1_0, refundTo=pkh0_0, lockTime=lockTime, secretHash=secretAHash) p2sh_initiate = script_to_p2sh_part(scriptInitiate2) rawtxInitiate = nodes[0].createrawtransaction([], {p2sh_initiate:6.0}) rawtxInitiate = nodes[0].fundrawtransaction(rawtxInitiate)['hex'] ro = nodes[0].signrawtransactionwithwallet(rawtxInitiate) assert(ro['complete'] == True) rawtxInitiate = ro['hex'] rawtx2refund = createRefundTx(nodes[0], rawtxInitiate, scriptInitiate2, lockTime, addrA_0, addrA_0) txnid2 = nodes[0].sendrawtransaction(rawtxInitiate) self.stakeBlocks(1) ro = nodes[0].getblockchaininfo() assert(ro['mediantime'] > lockTime) txnidrefund = nodes[0].sendrawtransaction(rawtx2refund) ftxA = nodes[0].filtertransactions() n = getIndexAtProperty(ftxA, 'txid', txnidrefund) assert(n > -1) assert(ftxA[n]['outputs'][0]['amount'] > 5.9 and ftxA[n]['outputs'][0]['amount'] < 6.0)