def create(self): print 'Creating wallet' wallet = Wallet() # close the wallet if any, will throw if none is loaded try: wallet.close_wallet() except: pass res = wallet.restore_deterministic_wallet( seed= 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted' )
def create_wallets(self): print('Creating wallets') seeds = [ 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted', 'peeled mixture ionic radar utopia puddle buying illness nuns gadget river spout cavernous bounced paradise drunk looking cottage jump tequila melting went winter adjust spout', ] self.wallet = [None, None] for i in range(2): self.wallet[i] = Wallet(idx = i) try: self.wallet[i].close_wallet() except: pass res = self.wallet[i].restore_deterministic_wallet(seed = seeds[i])
def create(self): print('Creating wallet') wallet = Wallet() # close the wallet if any, will throw if none is loaded try: wallet.close_wallet() except: pass seed = 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted' res = wallet.restore_deterministic_wallet(seed=seed) assert res.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert res.seed == seed
def run_test(self): daemon = Daemon() wallet = Wallet() destinations = wallet.make_uniform_destinations('44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A',1,3) self._test_speed_generateblocks(daemon=daemon, blocks=70) for i in range(1, 10): while wallet.get_balance().unlocked_balance == 0: print('Waiting for wallet to refresh...') sleep(1) self._test_speed_transfer_split(wallet=wallet) self._test_speed_generateblocks(daemon=daemon, blocks=10)
def create(self): print('Creating wallets') seeds = [ 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted', 'peeled mixture ionic radar utopia puddle buying illness nuns gadget river spout cavernous bounced paradise drunk looking cottage jump tequila melting went winter adjust spout', 'dilute gutter certain antics pamphlet macro enjoy left slid guarded bogeys upload nineteen bomb jubilee enhanced irritate turnip eggs swung jukebox loudly reduce sedan slid', ] self.wallet = [None] * len(seeds) for i in range(len(seeds)): self.wallet[i] = Wallet(idx = i) # close the wallet if any, will throw if none is loaded try: self.wallet[i].close_wallet() except: pass res = self.wallet[i].restore_deterministic_wallet(seed = seeds[i])
def create_txes(self, address, ntxes): print('Creating ' + str(ntxes) + ' transactions') daemon = Daemon() wallet = Wallet() dst = {'address': address, 'amount': 1000000000000} txes = {} for i in range(ntxes): res = wallet.transfer([dst], get_tx_hex=True) txes[res.tx_hash] = res return txes
def test_free_access(self): print('Testing free access') daemon = Daemon(idx=0) wallet = Wallet(idx=0) res = daemon.rpc_access_info(client = self.get_signature()) assert res.credits_per_hash_found == 0 assert res.diff == 0 assert res.credits == 0 res = daemon.get_info(client = self.get_signature()) assert res.credits == 0 # any nonce will do here res = daemon.rpc_access_submit_nonce(nonce = 0, cookie = 0, client = self.get_signature()) assert res.credits == 0
def create(self): print('Creating wallets') seeds = [ 'upbeat wade toenail italics maverick anybody eluded altitude tumbling emotion against okay inkling ankle karate stunning doing verification slid zinger cucumber blender dual extra wade verification', 'upbeat wade toenail italics maverick anybody eluded altitude tumbling emotion against okay inkling ankle karate stunning doing verification slid zinger cucumber blender dual extra wade verification', 'upbeat wade toenail italics maverick anybody eluded altitude tumbling emotion against okay inkling ankle karate stunning doing verification slid zinger cucumber blender dual extra wade verification', ] self.wallet = [None] * len(seeds) for i in range(len(seeds)): self.wallet[i] = Wallet(idx=i) # close the wallet if any, will throw if none is loaded try: self.wallet[i].close_wallet() except: pass res = self.wallet[i].restore_deterministic_wallet(seed=seeds[i])
def languages(self): print('Testing languages') wallet = Wallet() res = wallet.get_languages() assert 'English' in res.languages assert 'English' in res.languages_local assert 'Dutch' in res.languages assert 'Nederlands' in res.languages_local assert 'Japanese' in res.languages assert u'日本語' in res.languages_local try: wallet.close_wallet() except: pass languages = res.languages for language in languages: print('Creating ' + str(language) + ' wallet') wallet.create_wallet(filename = '', language = language) res = wallet.query_key('mnemonic') wallet.close_wallet()
def create(self): print 'Creating wallets' seeds = [ 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted', 'peeled mixture ionic radar utopia puddle buying illness nuns gadget river spout cavernous bounced paradise drunk looking cottage jump tequila melting went winter adjust spout', ] self.address = [ '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', ] self.wallet = [None, None] for i in range(2): self.wallet[i] = Wallet(idx = i) # close the wallet if any, will throw if none is loaded try: self.wallet[i].close_wallet() except: pass res = self.wallet[i].restore_deterministic_wallet(seed = seeds[i]) assert res.address == self.address[i] assert res.seed == seeds[i]
def attributes(self): print('Testing attributes') wallet = Wallet() ok = False try: res = wallet.get_attribute('foo') except: ok = True assert ok res = wallet.set_attribute('foo', 'bar') res = wallet.get_attribute('foo') assert res.value == 'bar' res = wallet.set_attribute('foo', 'いっしゅん') res = wallet.get_attribute('foo') assert res.value == u'いっしゅん' ok = False try: res = wallet.get_attribute('いちりゅう') except: ok = True assert ok res = wallet.set_attribute('いちりゅう', 'いっぽう') res = wallet.get_attribute('いちりゅう') assert res.value == u'いっぽう'
def change_password(self): print('Testing password change') wallet = Wallet() # close the wallet if any, will throw if none is loaded try: wallet.close_wallet() except: pass self.remove_wallet_files('test1') seed = 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted' res = wallet.restore_deterministic_wallet(seed=seed, filename='test1') assert res.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert res.seed == seed wallet.close_wallet() res = wallet.open_wallet('test1', password='') res = wallet.get_address() assert res.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' res = wallet.change_wallet_password(old_password='', new_password='******') wallet.close_wallet() ok = False try: res = wallet.open_wallet('test1', password='') except: ok = True assert ok res = wallet.open_wallet('test1', password='******') res = wallet.get_address() assert res.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' wallet.close_wallet() self.remove_wallet_files('test1')
def check(self): wallet = Wallet() print('Checking local address') res = wallet.make_integrated_address(payment_id = '0123456789abcdef') assert res.integrated_address == '4CMe2PUhs4J4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfSbLRB61BQVATzerHGj' assert res.payment_id == '0123456789abcdef' res = wallet.split_integrated_address(res.integrated_address) assert res.standard_address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert res.payment_id == '0123456789abcdef' print('Checking different address') res = wallet.make_integrated_address(standard_address = '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', payment_id = '1122334455667788') assert res.integrated_address == '4GYjoMG9Y2BBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCVSs1ZojwrDCGS5rUuo' assert res.payment_id == '1122334455667788' res = wallet.split_integrated_address(res.integrated_address) assert res.standard_address == '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK' assert res.payment_id == '1122334455667788' print('Checking bad payment id') fails = 0 try: wallet.make_integrated_address(standard_address = '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', payment_id = '11223344556677880') except: fails += 1 try: wallet.make_integrated_address(standard_address = '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', payment_id = '112233445566778') except: fails += 1 try: wallet.make_integrated_address(standard_address = '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', payment_id = '') except: fails += 1 try: wallet.make_integrated_address(standard_address = '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', payment_id = '112233445566778g') except: fails += 1 try: wallet.make_integrated_address(standard_address = '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', payment_id = '1122334455667788112233445566778811223344556677881122334455667788') except: fails += 1 assert fails == 5 print('Checking bad standard address') fails = 0 try: wallet.make_integrated_address(standard_address = '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerr', payment_id = '1122334455667788') except: fails += 1 try: wallet.make_integrated_address(standard_address = '4GYjoMG9Y2BBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCVSs1ZojwrDCGS5rUuo', payment_id = '1122334455667788') except: fails += 1 assert fails == 2
def run_test(self): self.reset() daemon = Daemon() wallet = Wallet() # close the wallet if any, will throw if none is loaded try: wallet.close_wallet() except: pass wallet.restore_deterministic_wallet('velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted') destinations = [] for i in range(3): destinations.append({"amount":1,"address":'44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A'}) self._test_speed_generateblocks(daemon=daemon, blocks=70) for i in range(1, 10): while wallet.get_balance().unlocked_balance == 0: print('Waiting for wallet to refresh...') sleep(1) self._test_speed_transfer_split(wallet=wallet) self._test_speed_generateblocks(daemon=daemon, blocks=10)
def open_close(self): print('Testing open/close') wallet = Wallet() res = wallet.get_address() assert res.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' wallet.close_wallet() ok = False try: res = wallet.get_address() except: ok = True assert ok wallet.restore_deterministic_wallet( seed= 'peeled mixture ionic radar utopia puddle buying illness nuns gadget river spout cavernous bounced paradise drunk looking cottage jump tequila melting went winter adjust spout' ) res = wallet.get_address() assert res.address == '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW' wallet.close_wallet() ok = False try: wallet.get_address() except: ok = True assert ok wallet.restore_deterministic_wallet( seed= 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted' ) res = wallet.get_address() assert res.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
def test_randomx(self): print("Test RandomX") daemon = Daemon() wallet = Wallet() res = daemon.get_height() daemon.pop_blocks(res.height - 1) daemon.flush_txpool() epoch = int(os.environ['SEEDHASH_EPOCH_BLOCKS']) lag = int(os.environ['SEEDHASH_EPOCH_LAG']) address = '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' # check we can generate blocks, and that the seed hash changes when expected res = daemon.getblocktemplate(address) first_seed_hash = res.seed_hash daemon.generateblocks(address, 1 + lag) res = daemon.mining_status() assert res.active == False assert res.pow_algorithm == 'RandomX' res = daemon.getblocktemplate(address) seed_hash = res.seed_hash t0 = time.time() daemon.generateblocks(address, epoch - 3) t0 = time.time() - t0 res = daemon.get_info() assert res.height == lag + epoch - 1 res = daemon.getblocktemplate(address) assert seed_hash == res.seed_hash t0 = time.time() daemon.generateblocks(address, 1) t0 = time.time() - t0 res = daemon.get_info() assert res.height == lag + epoch daemon.generateblocks(address, 1) res = daemon.getblocktemplate(address) assert seed_hash != res.seed_hash new_seed_hash = res.seed_hash t0 = time.time() daemon.generateblocks(address, epoch - 1) t0 = time.time() - t0 res = daemon.getblocktemplate(address) assert new_seed_hash == res.seed_hash daemon.generateblocks(address, 1) res = daemon.getblocktemplate(address) assert new_seed_hash != res.seed_hash new_seed_hash = res.seed_hash t0 = time.time() daemon.generateblocks(address, epoch - 1) t0 = time.time() - t0 res = daemon.getblocktemplate(address) assert new_seed_hash == res.seed_hash daemon.generateblocks(address, 1) res = daemon.getblocktemplate(address) assert new_seed_hash != res.seed_hash #print('First mining: ' + str(t0)) # pop all these blocks, and feed them again to monerod print('Recreating the chain') res = daemon.get_info() height = res.height assert height == lag + epoch * 3 + 1 block_hashes = [ x.hash for x in daemon.getblockheadersrange(0, height - 1).headers ] assert len(block_hashes) == height blocks = [] for i in range(len(block_hashes)): res = daemon.getblock(height=i) assert res.block_header.hash == block_hashes[i] blocks.append(res.blob) daemon.pop_blocks(height) res = daemon.get_info() assert res.height == 1 res = daemon.getblocktemplate(address) assert first_seed_hash == res.seed_hash t0 = time.time() for h in range(len(block_hashes)): res = daemon.submitblock(blocks[h]) t0 = time.time() - t0 res = daemon.get_info() assert height == res.height res = daemon.getblocktemplate(address) assert new_seed_hash != res.seed_hash res = daemon.pop_blocks(1) res = daemon.getblocktemplate(address) assert new_seed_hash == res.seed_hash #print('Submit: ' + str(t0)) # start mining from the genesis block again print('Mining from genesis block again') res = daemon.get_height() top_hash = res.hash res = daemon.getblockheaderbyheight(0) genesis_block_hash = res.block_header.hash t0 = time.time() daemon.generateblocks(address, height - 2, prev_block=genesis_block_hash) t0 = time.time() - t0 res = daemon.get_info() assert res.height == height - 1 assert res.top_block_hash == top_hash #print('Second mining: ' + str(t0)) # that one will cause a huge reorg print('Adding one to reorg') res = daemon.generateblocks(address, 1) assert len(res.blocks) == 1 new_top_hash = res.blocks[0] res = daemon.get_info() assert res.height == height assert res.top_block_hash == new_top_hash
def tags(self): print('Testing tags') wallet = Wallet() res = wallet.get_account_tags() assert not 'account_tags' in res or len(res.account_tags) == 0 ok = False try: res = wallet.get_accounts('tag') except: ok = True assert ok or not 'subaddress_accounts' in res or res.subaddress_accounts == 0 wallet.tag_accounts('tag0', [1]) res = wallet.get_account_tags() assert len(res.account_tags) == 1 assert res.account_tags[0].tag == 'tag0' assert res.account_tags[0].label == '' assert res.account_tags[0].accounts == [1] res = wallet.get_accounts('tag0') assert len(res.subaddress_accounts) == 1 assert res.subaddress_accounts[0].account_index == 1 assert res.subaddress_accounts[ 0].base_address == '82pP87g1Vkd3LUMssBCumk3MfyEsFqLAaGDf6oxddu61EgSFzt8gCwUD4tr3kp9TUfdPs2CnpD7xLZzyC1Ei9UsW3oyCWDf' assert res.subaddress_accounts[0].balance == 0 assert res.subaddress_accounts[0].unlocked_balance == 0 assert res.subaddress_accounts[0].label == 'idx1_new' assert res.subaddress_accounts[0].tag == 'tag0' wallet.untag_accounts([0]) res = wallet.get_account_tags() assert len(res.account_tags) == 1 assert res.account_tags[0].tag == 'tag0' assert res.account_tags[0].label == '' assert res.account_tags[0].accounts == [1] wallet.untag_accounts([1]) res = wallet.get_account_tags() assert not 'account_tags' in res or len(res.account_tags) == 0 wallet.tag_accounts('tag0', [0]) wallet.tag_accounts('tag1', [1]) res = wallet.get_account_tags() assert len(res.account_tags) == 2 x = [x for x in res.account_tags if x.tag == 'tag0'] assert len(x) == 1 assert x[0].tag == 'tag0' assert x[0].label == '' assert x[0].accounts == [0] x = [x for x in res.account_tags if x.tag == 'tag1'] assert len(x) == 1 assert x[0].tag == 'tag1' assert x[0].label == '' assert x[0].accounts == [1] wallet.tag_accounts('tagA', [0, 1]) res = wallet.get_account_tags() assert len(res.account_tags) == 1 assert res.account_tags[0].tag == 'tagA' assert res.account_tags[0].label == '' assert res.account_tags[0].accounts == [0, 1] wallet.tag_accounts('tagB', [1, 0]) res = wallet.get_account_tags() assert len(res.account_tags) == 1 assert res.account_tags[0].tag == 'tagB' assert res.account_tags[0].label == '' assert res.account_tags[0].accounts == [0, 1] wallet.set_account_tag_description('tagB', 'tag B') res = wallet.get_account_tags() assert len(res.account_tags) == 1 assert res.account_tags[0].tag == 'tagB' assert res.account_tags[0].label == 'tag B' assert res.account_tags[0].accounts == [0, 1] res = wallet.get_accounts('tagB') assert len(res.subaddress_accounts) == 2 subaddress_accounts = [] for x in res.subaddress_accounts: assert x.balance == 0 assert x.unlocked_balance == 0 subaddress_accounts.append( (x.account_index, x.base_address, x.label)) assert sorted(subaddress_accounts) == [ (0, '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'main'), (1, '82pP87g1Vkd3LUMssBCumk3MfyEsFqLAaGDf6oxddu61EgSFzt8gCwUD4tr3kp9TUfdPs2CnpD7xLZzyC1Ei9UsW3oyCWDf', 'idx1_new') ]
def create_subaddresses(self): print('Creating subaddresses') wallet = Wallet() res = wallet.create_account("idx1") assert res.account_index == 1, res assert res.address == '82pP87g1Vkd3LUMssBCumk3MfyEsFqLAaGDf6oxddu61EgSFzt8gCwUD4tr3kp9TUfdPs2CnpD7xLZzyC1Ei9UsW3oyCWDf', res res = wallet.create_account("idx2") assert res.account_index == 2, res assert res.address == '8Bdb75y2MhvbkvaBnG7vYP6DCNneLWcXqNmfPmyyDkavAUUgrHQEAhTNK3jEq69kGPDrd3i5inPivCwTvvA12eQ4SJk9iyy', res res = wallet.get_address(0, 0) assert res.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', res assert len(res.addresses) == 1 assert res.addresses[0].address_index == 0, res res = wallet.get_address(1, 0) assert res.address == '82pP87g1Vkd3LUMssBCumk3MfyEsFqLAaGDf6oxddu61EgSFzt8gCwUD4tr3kp9TUfdPs2CnpD7xLZzyC1Ei9UsW3oyCWDf', res assert len(res.addresses) == 1 assert res.addresses[0].label == 'idx1', res assert res.addresses[0].address_index == 0, res res = wallet.get_address(2, 0) assert res.address == '8Bdb75y2MhvbkvaBnG7vYP6DCNneLWcXqNmfPmyyDkavAUUgrHQEAhTNK3jEq69kGPDrd3i5inPivCwTvvA12eQ4SJk9iyy', res assert len(res.addresses) == 1 assert res.addresses[0].label == 'idx2', res assert res.addresses[0].address_index == 0, res res = wallet.create_address(0, "sub_0_1") res = wallet.create_address(1, "sub_1_1") res = wallet.create_address(1, "sub_1_2") res = wallet.get_address(0, [1]) assert len(res.addresses) == 1 assert res.addresses[ 0].address == '84QRUYawRNrU3NN1VpFRndSukeyEb3Xpv8qZjjsoJZnTYpDYceuUTpog13D7qPxpviS7J29bSgSkR11hFFoXWk2yNdsR9WF' assert res.addresses[0].label == 'sub_0_1' res = wallet.get_address(1, [1]) assert len(res.addresses) == 1 assert res.addresses[ 0].address == '87qyoPVaEcWikVBmG1TaP1KumZ3hB3Q5f4wZRjuppNdwYjWzs2RgbLYQgtpdu2YdoTT3EZhiUGaPJQt2FsykeFZbCtaGXU4' assert res.addresses[0].label == 'sub_1_1' res = wallet.get_address(1, [2]) assert len(res.addresses) == 1 assert res.addresses[ 0].address == '87KfgTZ8ER5D3Frefqnrqif11TjVsTPaTcp37kqqKMrdDRUhpJRczeR7KiBmSHF32UJLP3HHhKUDmEQyJrv2mV8yFDCq8eB' assert res.addresses[0].label == 'sub_1_2' res = wallet.get_address(1, [0, 1, 2]) assert len(res.addresses) == 3 assert res.addresses[ 0].address == '82pP87g1Vkd3LUMssBCumk3MfyEsFqLAaGDf6oxddu61EgSFzt8gCwUD4tr3kp9TUfdPs2CnpD7xLZzyC1Ei9UsW3oyCWDf' assert res.addresses[0].label == 'idx1' assert res.addresses[ 1].address == '87qyoPVaEcWikVBmG1TaP1KumZ3hB3Q5f4wZRjuppNdwYjWzs2RgbLYQgtpdu2YdoTT3EZhiUGaPJQt2FsykeFZbCtaGXU4' assert res.addresses[1].label == 'sub_1_1' assert res.addresses[ 2].address == '87KfgTZ8ER5D3Frefqnrqif11TjVsTPaTcp37kqqKMrdDRUhpJRczeR7KiBmSHF32UJLP3HHhKUDmEQyJrv2mV8yFDCq8eB' assert res.addresses[2].label == 'sub_1_2' res = wallet.label_address((1, 2), "sub_1_2_new") res = wallet.get_address(1, [2]) assert len(res.addresses) == 1 assert res.addresses[ 0].address == '87KfgTZ8ER5D3Frefqnrqif11TjVsTPaTcp37kqqKMrdDRUhpJRczeR7KiBmSHF32UJLP3HHhKUDmEQyJrv2mV8yFDCq8eB' assert res.addresses[0].label == 'sub_1_2_new' res = wallet.label_account(1, "idx1_new") res = wallet.get_address(1, [0]) assert len(res.addresses) == 1 assert res.addresses[ 0].address == '82pP87g1Vkd3LUMssBCumk3MfyEsFqLAaGDf6oxddu61EgSFzt8gCwUD4tr3kp9TUfdPs2CnpD7xLZzyC1Ei9UsW3oyCWDf' assert res.addresses[0].label == 'idx1_new' res = wallet.get_address_index( '87KfgTZ8ER5D3Frefqnrqif11TjVsTPaTcp37kqqKMrdDRUhpJRczeR7KiBmSHF32UJLP3HHhKUDmEQyJrv2mV8yFDCq8eB' ) assert res.index == {'major': 1, 'minor': 2} res = wallet.get_address_index( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' ) assert res.index == {'major': 0, 'minor': 0} res = wallet.get_address_index( '84QRUYawRNrU3NN1VpFRndSukeyEb3Xpv8qZjjsoJZnTYpDYceuUTpog13D7qPxpviS7J29bSgSkR11hFFoXWk2yNdsR9WF' ) assert res.index == {'major': 0, 'minor': 1} res = wallet.get_address_index( '82pP87g1Vkd3LUMssBCumk3MfyEsFqLAaGDf6oxddu61EgSFzt8gCwUD4tr3kp9TUfdPs2CnpD7xLZzyC1Ei9UsW3oyCWDf' ) assert res.index == {'major': 1, 'minor': 0} res = wallet.label_account(0, "main")
def test_access_payment(self): print('Testing access payment') daemon = Daemon(idx=1) wallet = Wallet(idx=3) # Try random nonces till we find one that's valid so we get a load of credits res = daemon.rpc_access_info(client=self.get_signature()) credits = res.credits cookie = res.cookie nonce = 0 while credits <= 100: nonce += 1 try: res = daemon.rpc_access_submit_nonce( nonce=nonce, cookie=cookie, client=self.get_signature()) break except: pass assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails res = daemon.rpc_access_info(client=self.get_signature()) credits = res.credits assert credits > 0 res = daemon.get_info(client=self.get_signature()) assert res.credits == credits - 1 credits = res.credits res = daemon.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 100) block_hashes = res.blocks # ask for 1 block -> 1 credit res = daemon.getblockheadersrange(0, 0, client=self.get_signature()) assert res.credits == credits - 1 credits = res.credits # ask for 100 blocks -> >1 credit res = daemon.getblockheadersrange(1, 100, client=self.get_signature()) assert res.credits < credits - 1 credits = res.credits # external users res = daemon.rpc_access_pay(payment=1, paying_for='foo', client=self.get_signature()) assert res.credits == credits - 1 res = daemon.rpc_access_pay(payment=4, paying_for='bar', client=self.get_signature()) assert res.credits == credits - 5 res = daemon.rpc_access_pay(payment=credits, paying_for='baz', client=self.get_signature()) assert "PAYMENT REQUIRED" in res.status res = daemon.rpc_access_pay(payment=2, paying_for='quux', client=self.get_signature()) assert res.credits == credits - 7 res = daemon.rpc_access_pay(payment=3, paying_for='bar', client=self.get_signature()) assert res.credits == credits - 10 # that should be rejected because its cost is massive ok = False try: res = daemon.get_output_histogram(amounts=[], client=self.get_signature()) except Exception as e: print('e: ' + str(e)) ok = "PAYMENT REQUIRED" in e.status assert ok or "PAYMENT REQUIRED" in res.status
def test_access_mining(self): print('Testing access mining') daemon = Daemon(idx=1) wallet = Wallet(idx=3) res = daemon.rpc_access_info(client=self.get_signature()) assert len(res.hashing_blob) > 39 assert res.height == 1 assert res.top_hash == '418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3' assert res.credits_per_hash_found == 5000 assert res.diff == 10 assert res.credits == 0 cookie = res.cookie # Try random nonces till we find one that's valid and one that's invalid nonce = 0 found_valid = 0 found_invalid = 0 last_credits = 0 loop_time = time.time() while found_valid == 0 or found_invalid == 0: nonce += 1 try: res = daemon.rpc_access_submit_nonce( nonce=nonce, cookie=cookie, client=self.get_signature()) found_valid += 1 assert res.credits == last_credits + 5000 except Exception as e: found_invalid += 1 res = daemon.rpc_access_info(client=self.get_signature()) cookie = res.cookie loop_time = time.time() assert res.credits < last_credits or res.credits == 0 assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails last_credits = res.credits if time.time() >= loop_time + 10: res = daemon.rpc_access_info(client=self.get_signature()) cookie = res.cookie loop_time = time.time() # we should now have 1 valid nonce, and a number of bad ones res = daemon.rpc_access_info(client=self.get_signature()) assert len(res.hashing_blob) > 39 assert res.height > 1 assert res.top_hash != '418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3' # here, any share matches network diff assert res.credits_per_hash_found == 5000 assert res.diff == 10 cookie = res.cookie res = daemon.rpc_access_data() assert len(res.entries) > 0 e = [x for x in res.entries if x['client'] == self.public_key] assert len(e) == 1 e = e[0] assert e.nonces_stale == 0 assert e.nonces_bad == found_invalid assert e.nonces_good == found_valid assert e.nonces_dupe == 0 # Try random nonces till we find one that's valid so we get a load of credits loop_time = time.time() while last_credits == 0: nonce += 1 try: res = daemon.rpc_access_submit_nonce( nonce=nonce, cookie=cookie, client=self.get_signature()) found_valid += 1 last_credits = res.credits break except: found_invalid += 1 assert nonce < 1000 # can't find a valid none -> the RPC probably fails if time.time() >= loop_time + 10: res = daemon.rpc_access_info(client=self.get_signature()) cookie = res.cookie loop_time = time.time() # we should now have at least 5000 res = daemon.rpc_access_info(client=self.get_signature()) assert res.credits == last_credits assert res.credits >= 5000 # last one was a valid nonce res = daemon.rpc_access_data() assert len(res.entries) > 0 e = [x for x in res.entries if x['client'] == self.public_key] assert len(e) == 1 e = e[0] assert e.nonces_stale == 0 assert e.nonces_bad == found_invalid assert e.nonces_good == found_valid assert e.nonces_dupe == 0 assert e.balance == 5000 assert e.credits_total >= 5000 # find a valid one, then check dupes aren't allowed res = daemon.rpc_access_info(client=self.get_signature()) cookie = res.cookie old_cookie = cookie # we keep that so can submit a stale later loop_time = time.time() while True: nonce += 1 try: res = daemon.rpc_access_submit_nonce( nonce=nonce, cookie=cookie, client=self.get_signature()) found_valid += 1 break except: found_invalid += 1 assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails if time.time() >= loop_time + 10: res = daemon.rpc_access_info(client=self.get_signature()) cookie = res.cookie loop_time = time.time() res = daemon.rpc_access_data() assert len(res.entries) > 0 e = [x for x in res.entries if x['client'] == self.public_key] assert len(e) == 1 e = e[0] assert e.nonces_stale == 0 assert e.nonces_bad == found_invalid assert e.nonces_good == found_valid assert e.nonces_dupe == 0 ok = False try: res = daemon.rpc_access_submit_nonce(nonce=nonce, cookie=cookie, client=self.get_signature()) except: ok = True assert ok res = daemon.rpc_access_data() assert len(res.entries) > 0 e = [x for x in res.entries if x['client'] == self.public_key] assert len(e) == 1 e = e[0] assert e.nonces_stale == 0 assert e.nonces_bad == found_invalid assert e.nonces_good == found_valid assert e.nonces_dupe == 1 # find stales without updating cookie, one within 5 seconds (accepted), one later (rejected) res = daemon.rpc_access_info(client=self.get_signature()) cookie = res.cookie # let the daemon update its timestamp, but use old cookie found_close_stale = 0 found_late_stale = 0 loop_time = time.time() while found_close_stale == 0 or found_late_stale == 0: nonce += 1 try: res = daemon.rpc_access_submit_nonce( nonce=nonce, cookie=cookie, client=self.get_signature()) found_close_stale += 1 found_valid += 1 time.sleep( 15 ) # now we've got an early stale, wait till they become late stales except Exception as e: #if e[0]['error']['code'] == -18: # stale if "'code': -18" in str( e ): # stale (ugly version, but also works with python 3) found_late_stale += 1 else: found_invalid += 1 assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails if time.time() >= loop_time + 10: res = daemon.rpc_access_info(client=self.get_signature()) # cookie = res.cookie # let the daemon update its timestamp, but use old cookie loop_time = time.time() res = daemon.rpc_access_data() assert len(res.entries) > 0 e = [x for x in res.entries if x['client'] == self.public_key] assert len(e) == 1 e = e[0] assert e.nonces_stale == found_late_stale # close stales are accepted, don't count here assert e.nonces_bad == found_invalid assert e.nonces_good == found_valid assert e.nonces_dupe == 1 # find very stale with old cookie (rejected) res = daemon.rpc_access_info(client=self.get_signature()) nonce += 1 ok = False try: res = daemon.rpc_access_submit_nonce(nonce=nonce, cookie=old_cookie, client=self.get_signature()) except: found_late_stale += 1 ok = True assert ok res = daemon.rpc_access_data() assert len(res.entries) > 0 e = [x for x in res.entries if x['client'] == self.public_key] assert len(e) == 1 e = e[0] assert e.nonces_stale == found_late_stale assert e.nonces_bad == found_invalid assert e.nonces_good == found_valid assert e.nonces_dupe == 1
def test_address_book(self): print('Testing address book') wallet = Wallet() # empty at start res = wallet.get_address_book() assert not 'entries' in res or (res.entries) == 0 ok = False try: wallet.get_address_book([0]) except: ok = True assert ok ok = False try: wallet.delete_address_book(0) except: ok = True assert ok ok = False try: wallet.edit_address_book(0, description='') except: ok = True assert ok # add one res = wallet.add_address_book( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', description='self') assert res.index == 0, res for get_all in [True, False]: res = wallet.get_address_book( ) if get_all else wallet.get_address_book([0]) assert len(res.entries) == 1 e = res.entries[0] assert e.index == 0 assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', e assert e.description == 'self' # add a duplicate res = wallet.add_address_book( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', description='self') assert res.index == 1 res = wallet.get_address_book() assert len(res.entries) == 2 assert res.entries[0].index == 0 assert res.entries[1].index == 1 assert res.entries[0].address == res.entries[1].address assert res.entries[0].description == res.entries[1].description e = res.entries[1] res = wallet.get_address_book([1]) assert len(res.entries) == 1 assert e == res.entries[0] # request (partially) out of range ok = False try: res = wallet.get_address_book[4, 2] except: ok = True assert ok ok = False try: res = wallet.get_address_book[0, 2] except: ok = True assert ok ok = False try: res = wallet.get_address_book[2, 0] except: ok = True assert ok # delete first res = wallet.delete_address_book(0) res = wallet.get_address_book() assert len(res.entries) == 1 assert res.entries[0].index == 0 assert res.entries[0].address == e.address assert res.entries[0].description == e.description # delete (new) first res = wallet.delete_address_book(0) res = wallet.get_address_book() assert not 'entries' in res or (res.entries) == 0 # add non-addresses errors = 0 try: wallet.add_address_book('', description='bad') except: errors += 1 try: wallet.add_address_book( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm ', description='bad') except: errors += 1 try: wallet.add_address_book( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDn', description='bad') except: errors += 1 try: wallet.add_address_book( '9ujeXrjzf7bfeK3KZdCqnYaMwZVFuXemPU8Ubw335rj2FN1CdMiWNyFV3ksEfMFvRp9L9qum5UxkP5rN9aLcPxbH1au4WAB', description='bad') except: errors += 1 try: wallet.add_address_book('*****@*****.**', description='bad') except: errors += 1 assert errors == 5 res = wallet.get_address_book() assert not 'entries' in res or len(res.entries) == 0 # openalias res = wallet.add_address_book('*****@*****.**', description='dev fund') assert res.index == 0 res = wallet.get_address_book() assert len(res.entries) == 1 e = res.entries[0] assert e.address == '44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A' assert e.description == 'dev fund' # UTF-8 res = wallet.add_address_book( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', description=u'あまやかす') assert res.index == 1 res = wallet.get_address_book([1]) assert len(res.entries) == 1 assert res.entries[0].description == u'あまやかす' e = res.entries[0] # duplicate request res = wallet.get_address_book([1, 1]) assert len(res.entries) == 2 assert res.entries[0] == e assert res.entries[1] == e # various address types res = wallet.make_integrated_address() integrated_address = res.integrated_address res = wallet.add_address_book(integrated_address) assert res.index == 2 res = wallet.add_address_book( '87KfgTZ8ER5D3Frefqnrqif11TjVsTPaTcp37kqqKMrdDRUhpJRczeR7KiBmSHF32UJLP3HHhKUDmEQyJrv2mV8yFDCq8eB' ) assert res.index == 3 # get them back res = wallet.get_address_book([0]) assert len(res.entries) == 1 assert res.entries[ 0].address == '44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A' assert res.entries[0].description == 'dev fund' res = wallet.get_address_book([1]) assert len(res.entries) == 1 assert res.entries[ 0].address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert res.entries[0].description == u'あまやかす' res = wallet.get_address_book([2]) assert len(res.entries) == 1 assert res.entries[0].address == integrated_address res = wallet.get_address_book([3]) assert len(res.entries) == 1 assert res.entries[ 0].address == '87KfgTZ8ER5D3Frefqnrqif11TjVsTPaTcp37kqqKMrdDRUhpJRczeR7KiBmSHF32UJLP3HHhKUDmEQyJrv2mV8yFDCq8eB' # edit res = wallet.get_address_book([1]) assert len(res.entries) == 1 e = res.entries[0] assert e.index == 1 assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert e.description == u'あまやかす' res = wallet.get_address_book([1]) assert len(res.entries) == 1 e = res.entries[0] assert e.index == 1 assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert e.description == u'あまやかす' res = wallet.edit_address_book(1, description='') res = wallet.get_address_book([1]) assert len(res.entries) == 1 e = res.entries[0] assert e.index == 1 assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert e.description == '' res = wallet.edit_address_book(1, description='えんしゅう') res = wallet.get_address_book([1]) assert len(res.entries) == 1 e = res.entries[0] assert e.index == 1 assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert e.description == u'えんしゅう' res = wallet.edit_address_book( 1, address= '44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A' ) res = wallet.get_address_book([1]) assert len(res.entries) == 1 e = res.entries[0] assert e.index == 1 assert e.address == '44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A' assert e.description == u'えんしゅう' ok = False try: res = wallet.edit_address_book(1, address='') except: ok = True assert ok ok = False try: res = wallet.edit_address_book(1, address='address') except: ok = True assert ok res = wallet.edit_address_book(1) res = wallet.get_address_book([1]) assert len(res.entries) == 1 assert e == res.entries[0] # empty wallet.delete_address_book(0) res = wallet.get_address_book( [0]) # entries above the deleted one collapse one slot up assert len(res.entries) == 1 assert res.entries[ 0].address == '44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A' assert res.entries[0].description == u'えんしゅう' wallet.delete_address_book(2) wallet.delete_address_book(0) wallet.delete_address_book(0) res = wallet.get_address_book() assert not 'entries' in res or len(res.entries) == 0
def __enter__(self): for i in range(4): Wallet(idx=i).auto_refresh(False)
def test_states(self): print('Testing multisig states') seeds = [ 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted', 'peeled mixture ionic radar utopia puddle buying illness nuns gadget river spout cavernous bounced paradise drunk looking cottage jump tequila melting went winter adjust spout', 'dilute gutter certain antics pamphlet macro enjoy left slid guarded bogeys upload nineteen bomb jubilee enhanced irritate turnip eggs swung jukebox loudly reduce sedan slid', ] info2of2 = [] wallet2of2 = [None, None] for i in range(2): wallet2of2[i] = Wallet(idx=i) try: wallet2of2[i].close_wallet() except: pass res = wallet2of2[i].restore_deterministic_wallet(seed=seeds[i]) res = wallet2of2[i].is_multisig() assert not res.multisig res = wallet2of2[i].prepare_multisig( enable_multisig_experimental=True) assert len(res.multisig_info) > 0 info2of2.append(res.multisig_info) kex_info = [] res = wallet2of2[0].make_multisig(info2of2, 2) kex_info.append(res.multisig_info) res = wallet2of2[1].make_multisig(info2of2, 2) kex_info.append(res.multisig_info) res = wallet2of2[0].exchange_multisig_keys(kex_info) res = wallet2of2[0].is_multisig() assert res.multisig assert res.ready ok = False try: res = wallet2of2[0].prepare_multisig( enable_multisig_experimental=True) except: ok = True assert ok ok = False try: res = wallet2of2[0].make_multisig(info2of2, 2) except: ok = True assert ok info2of3 = [] wallet2of3 = [None, None, None] for i in range(3): wallet2of3[i] = Wallet(idx=i) try: wallet2of3[i].close_wallet() except: pass res = wallet2of3[i].restore_deterministic_wallet(seed=seeds[i]) res = wallet2of3[i].is_multisig() assert not res.multisig res = wallet2of3[i].prepare_multisig( enable_multisig_experimental=True) assert len(res.multisig_info) > 0 info2of3.append(res.multisig_info) for i in range(3): ok = False try: res = wallet2of3[i].exchange_multisig_keys(info) except: ok = True assert ok res = wallet2of3[i].is_multisig() assert not res.multisig res = wallet2of3[1].make_multisig(info2of3, 2) res = wallet2of3[1].is_multisig() assert res.multisig assert not res.ready ok = False try: res = wallet2of3[1].prepare_multisig( enable_multisig_experimental=True) except: ok = True assert ok ok = False try: res = wallet2of3[1].make_multisig(info2of3[0:2], 2) except: ok = True assert ok
def check_txpool(self): daemon = Daemon() wallet = Wallet() res = daemon.get_info() height = res.height txpool_size = res.tx_pool_size self.check_empty_pool() txes = self.create_txes('46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 5) res = daemon.get_info() assert res.tx_pool_size == txpool_size + 5 txpool_size = res.tx_pool_size res = daemon.get_transaction_pool() assert len(res.transactions) == txpool_size total_bytes = 0 total_fee = 0 min_bytes = 99999999999999 max_bytes = 0 for txid in txes.keys(): x = [x for x in res.transactions if x.id_hash == txid] assert len(x) == 1 x = x[0] assert x.kept_by_block == False assert x.last_failed_id_hash == '0'*64 assert x.double_spend_seen == False assert x.weight >= x.blob_size assert x.blob_size * 2 == len(txes[txid].tx_blob) assert x.fee == txes[txid].fee assert x.tx_blob == txes[txid].tx_blob total_bytes += x.blob_size total_fee += x.fee min_bytes = min(min_bytes, x.blob_size) max_bytes = max(max_bytes, x.blob_size) res = daemon.get_transaction_pool_hashes() assert sorted(res.tx_hashes) == sorted(txes.keys()) res = daemon.get_transaction_pool_stats() assert res.pool_stats.bytes_total == total_bytes assert res.pool_stats.bytes_min == min_bytes assert res.pool_stats.bytes_max == max_bytes assert res.pool_stats.bytes_med >= min_bytes and res.pool_stats.bytes_med <= max_bytes assert res.pool_stats.fee_total == total_fee assert res.pool_stats.txs_total == len(txes) assert res.pool_stats.num_failing == 0 assert res.pool_stats.num_10m == 0 assert res.pool_stats.num_not_relayed == 0 assert res.pool_stats.num_double_spends == 0 print('Flushing 2 transactions') txes_keys = list(txes.keys()) daemon.flush_txpool([txes_keys[1], txes_keys[3]]) res = daemon.get_transaction_pool() assert len(res.transactions) == txpool_size - 2 assert len([x for x in res.transactions if x.id_hash == txes_keys[1]]) == 0 assert len([x for x in res.transactions if x.id_hash == txes_keys[3]]) == 0 new_keys = list(txes.keys()) new_keys.remove(txes_keys[1]) new_keys.remove(txes_keys[3]) res = daemon.get_transaction_pool_hashes() assert sorted(res.tx_hashes) == sorted(new_keys) res = daemon.get_transaction_pool() assert len(res.transactions) == len(new_keys) total_bytes = 0 total_fee = 0 min_bytes = 99999999999999 max_bytes = 0 for txid in new_keys: x = [x for x in res.transactions if x.id_hash == txid] assert len(x) == 1 x = x[0] assert x.kept_by_block == False assert x.last_failed_id_hash == '0'*64 assert x.double_spend_seen == False assert x.weight >= x.blob_size assert x.blob_size * 2 == len(txes[txid].tx_blob) assert x.fee == txes[txid].fee assert x.tx_blob == txes[txid].tx_blob total_bytes += x.blob_size total_fee += x.fee min_bytes = min(min_bytes, x.blob_size) max_bytes = max(max_bytes, x.blob_size) res = daemon.get_transaction_pool_stats() assert res.pool_stats.bytes_total == total_bytes assert res.pool_stats.bytes_min == min_bytes assert res.pool_stats.bytes_max == max_bytes assert res.pool_stats.bytes_med >= min_bytes and res.pool_stats.bytes_med <= max_bytes assert res.pool_stats.fee_total == total_fee assert res.pool_stats.txs_total == len(new_keys) assert res.pool_stats.num_failing == 0 assert res.pool_stats.num_10m == 0 assert res.pool_stats.num_not_relayed == 0 assert res.pool_stats.num_double_spends == 0 print('Flushing unknown transactions') unknown_txids = ['1'*64, '2'*64, '3'*64] daemon.flush_txpool(unknown_txids) res = daemon.get_transaction_pool() assert len(res.transactions) == txpool_size - 2 print('Mining transactions') daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1) res = daemon.get_transaction_pool() assert not 'transactions' in res or len(res.transactions) == txpool_size - 5 res = daemon.get_transaction_pool_hashes() assert not 'tx_hashes' in res or len(res.tx_hashes) == 0 self.check_empty_pool() print('Popping block') daemon.pop_blocks(1) res = daemon.get_transaction_pool_hashes() assert sorted(res.tx_hashes) == sorted(new_keys) res = daemon.get_transaction_pool() assert len(res.transactions) == txpool_size - 2 for txid in new_keys: x = [x for x in res.transactions if x.id_hash == txid] assert len(x) == 1 x = x[0] assert x.kept_by_block == True assert x.last_failed_id_hash == '0'*64 assert x.double_spend_seen == False assert x.weight >= x.blob_size assert x.blob_size * 2 == len(txes[txid].tx_blob) assert x.fee == txes[txid].fee assert x.tx_blob == txes[txid].tx_blob print('Checking relaying txes') res = daemon.get_transaction_pool_hashes() assert len(res.tx_hashes) > 0 txid = res.tx_hashes[0] daemon.relay_tx([txid]) res = daemon.get_transactions([txid]) assert len(res.txs) == 1 assert res.txs[0].tx_hash == txid assert res.txs[0].in_pool assert res.txs[0].relayed daemon.flush_txpool() self.check_empty_pool()
def mine(self, via_daemon): print("Test mining via " + ("daemon" if via_daemon else "wallet")) daemon = Daemon() wallet = Wallet() # check info/height/balance before generating blocks res_info = daemon.get_info() prev_height = res_info.height res_getbalance = wallet.get_balance() prev_balance = res_getbalance.balance res_status = daemon.mining_status() if via_daemon: res = daemon.start_mining('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', threads_count = 1) else: res = wallet.start_mining(threads_count = 1) res_status = daemon.mining_status() assert res_status.active == True assert res_status.threads_count == 1 assert res_status.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert res_status.is_background_mining_enabled == False assert res_status.block_reward >= 600000000000 # wait till we mined a few of them target_height = prev_height + 5 height = prev_height timeout = 60 # randomx is slow to init while height < target_height: seen_height = height for _ in range(timeout): time.sleep(1) height = daemon.get_info().height if height > seen_height: break else: assert False, 'Failed to mine successor to block %d (initial block = %d)' % (seen_height, prev_height) timeout = 5 if via_daemon: res = daemon.stop_mining() else: res = wallet.stop_mining() res_status = daemon.mining_status() assert res_status.active == False res_info = daemon.get_info() new_height = res_info.height wallet.refresh() res_getbalance = wallet.get_balance() balance = res_getbalance.balance assert balance >= prev_balance + (new_height - prev_height) * 600000000000 if via_daemon: res = daemon.start_mining('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', threads_count = 1, do_background_mining = True) else: res = wallet.start_mining(threads_count = 1, do_background_mining = True) res_status = daemon.mining_status() assert res_status.active == True assert res_status.threads_count == 1 assert res_status.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert res_status.is_background_mining_enabled == True assert res_status.block_reward >= 600000000000 # don't wait, might be a while if the machine is busy, which it probably is if via_daemon: res = daemon.stop_mining() else: res = wallet.stop_mining() res_status = daemon.mining_status() assert res_status.active == False
def check_txpool(self): daemon = Daemon() wallet = Wallet() res = daemon.get_info() height = res.height txpool_size = res.tx_pool_size txes = self.create_txes( '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 5) res = daemon.get_info() assert res.tx_pool_size == txpool_size + 5 txpool_size = res.tx_pool_size res = daemon.get_transaction_pool() assert len(res.transactions) == txpool_size for txid in txes.keys(): x = [x for x in res.transactions if x.id_hash == txid] assert len(x) == 1 x = x[0] assert x.kept_by_block == False assert x.last_failed_id_hash == '0' * 64 assert x.double_spend_seen == False assert x.weight >= x.blob_size assert x.blob_size * 2 == len(txes[txid].tx_blob) assert x.fee == txes[txid].fee assert x.tx_blob == txes[txid].tx_blob res = daemon.get_transaction_pool_hashes() assert sorted(res.tx_hashes) == sorted(txes.keys()) print('Flushing 2 transactions') txes_keys = list(txes.keys()) daemon.flush_txpool([txes_keys[1], txes_keys[3]]) res = daemon.get_transaction_pool() assert len(res.transactions) == txpool_size - 2 assert len([x for x in res.transactions if x.id_hash == txes_keys[1]]) == 0 assert len([x for x in res.transactions if x.id_hash == txes_keys[3]]) == 0 new_keys = list(txes.keys()) new_keys.remove(txes_keys[1]) new_keys.remove(txes_keys[3]) res = daemon.get_transaction_pool_hashes() assert sorted(res.tx_hashes) == sorted(new_keys) print('Flushing unknown transactions') unknown_txids = ['1' * 64, '2' * 64, '3' * 64] daemon.flush_txpool(unknown_txids) res = daemon.get_transaction_pool() assert len(res.transactions) == txpool_size - 2 print('Mining transactions') daemon.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1) res = daemon.get_transaction_pool() assert not 'transactions' in res or len( res.transactions) == txpool_size - 5 res = daemon.get_transaction_pool_hashes() assert not 'tx_hashes' in res or len(res.tx_hashes) == 0 print('Popping block') daemon.pop_blocks(1) res = daemon.get_transaction_pool_hashes() assert sorted(res.tx_hashes) == sorted(new_keys) res = daemon.get_transaction_pool() assert len(res.transactions) == txpool_size - 2 for txid in new_keys: x = [x for x in res.transactions if x.id_hash == txid] assert len(x) == 1 x = x[0] assert x.kept_by_block == True assert x.last_failed_id_hash == '0' * 64 assert x.double_spend_seen == False assert x.weight >= x.blob_size assert x.blob_size * 2 == len(txes[txid].tx_blob) assert x.fee == txes[txid].fee assert x.tx_blob == txes[txid].tx_blob
def create_multisig_wallets(self, M_threshold, N_total, expected_address): print('Creating ' + str(M_threshold) + '/' + str(N_total) + ' multisig wallet') seeds = [ 'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted', 'peeled mixture ionic radar utopia puddle buying illness nuns gadget river spout cavernous bounced paradise drunk looking cottage jump tequila melting went winter adjust spout', 'dilute gutter certain antics pamphlet macro enjoy left slid guarded bogeys upload nineteen bomb jubilee enhanced irritate turnip eggs swung jukebox loudly reduce sedan slid', 'waking gown buffet negative reorder speedy baffles hotel pliers dewdrop actress diplomat lymph emit ajar mailed kennel cynical jaunt justice weavers height teardrop toyed lymph', ] assert M_threshold <= N_total assert N_total <= len(seeds) self.wallet = [None] * N_total info = [] for i in range(N_total): self.wallet[i] = Wallet(idx=i) try: self.wallet[i].close_wallet() except: pass res = self.wallet[i].restore_deterministic_wallet(seed=seeds[i]) res = self.wallet[i].prepare_multisig() assert len(res.multisig_info) > 0 info.append(res.multisig_info) for i in range(N_total): res = self.wallet[i].is_multisig() assert res.multisig == False addresses = [] next_stage = [] for i in range(N_total): res = self.wallet[i].make_multisig(info, M_threshold) addresses.append(res.address) next_stage.append(res.multisig_info) for i in range(N_total): res = self.wallet[i].is_multisig() assert res.multisig == True assert res.ready == (M_threshold == N_total) assert res.threshold == M_threshold assert res.total == N_total while True: n_empty = 0 for i in range(len(next_stage)): if len(next_stage[i]) == 0: n_empty += 1 assert n_empty == 0 or n_empty == len(next_stage) if n_empty == len(next_stage): break info = next_stage next_stage = [] addresses = [] for i in range(N_total): res = self.wallet[i].exchange_multisig_keys(info) next_stage.append(res.multisig_info) addresses.append(res.address) for i in range(N_total): assert addresses[i] == expected_address self.wallet_address = expected_address for i in range(N_total): res = self.wallet[i].is_multisig() assert res.multisig == True assert res.ready == True assert res.threshold == M_threshold assert res.total == N_total
def mine(self, via_daemon): print("Test mining via " + ("daemon" if via_daemon else "wallet")) cores_init = multiprocessing.cpu_count() # RX init uses all cores cores_mine = 1 # Mining uses a parametric number of cores is_mining_measurent = 'MINING_NO_MEASUREMENT' not in os.environ if is_mining_measurent: # A dynamic calculation of the CPU power requested time_pi_single_cpu = self.measure_cpu_power_get_time(cores_mine) time_pi_all_cores = self.measure_cpu_power_get_time(cores_init) # This is the last measurement, since it takes very little time and can be placed timewise-closer to the mining itself. available_ram = self.get_available_ram( ) # So far no ideas how to use this var, other than printing it start = monotonic.monotonic() daemon = Daemon() wallet = Wallet() # check info/height/balance before generating blocks res_info = daemon.get_info() initial_height = res_info.height res_getbalance = wallet.get_balance() prev_balance = res_getbalance.balance res_status = daemon.mining_status() if via_daemon: res = daemon.start_mining( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', threads_count=1) else: res = wallet.start_mining(threads_count=cores_mine) res_status = daemon.mining_status() assert res_status.active == True assert res_status.threads_count == cores_mine assert res_status.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert res_status.is_background_mining_enabled == False assert res_status.block_reward >= 600000000000 # wait till we mined a few of them target_height = initial_height + 5 height = initial_height if not is_mining_measurent: timeout_init = 600 timeout_mine = 300 else: """ Randomx init has high variance on CI machines due to noisy neighbors, taking up resources in parallel (including by our own jobs). Mining is organized in the following scheme: 1) first loop's pass: RandomX init and mining 2) every next pass: only mining Pass 1) takes much more time than pass 2) Pass 1) uses all cores, pass 2) just one (currently) For the above reasons both passes need separate timeouts and adjustments. After the first pass, the timeout is being reset to a lower value. """ def calc_timeout(seconds_constant, time_pi, cores): """ The time it took to calculate pi under certain conditions is proportional to the time it will take to calculate the real job. The number of cores used decreases the time almost linearly. """ timeout = float(seconds_constant) * time_pi / float(cores) return timeout timeout_base_init = 60 # RX init needs more time timeout_base_mine = 20 timeout_init = calc_timeout(timeout_base_init, time_pi_all_cores, cores_init) timeout_mine = calc_timeout(timeout_base_mine, time_pi_single_cpu, cores_mine) msg_timeout_src = "adjusted for the currently available CPU power" if is_mining_measurent else "selected to have the default value" msg = "Timeout for {} {}, is {:.1f} s" self.print_mining_info( msg.format("init, ", msg_timeout_src, timeout_init)) self.print_mining_info( msg.format("mining,", msg_timeout_src, timeout_mine)) timeout = timeout_init rx_inited = False # Gets initialized in the first pass of the below loop while height < target_height: seen_height = height for _ in range(int(math.ceil(timeout))): time.sleep(1) seconds_passed = monotonic.monotonic() - start height = daemon.get_info().height if height > seen_height: break else: assert False, 'Failed to mine successor to block %d (initial block = %d) after %d s. RX initialized = %r' % ( seen_height, initial_height, round(seconds_passed), rx_inited) if not rx_inited: rx_inited = True timeout = timeout_mine # Resetting the timeout after first mined block and RX init self.print_time_taken(start, "RX init + mining 1st block") else: self.print_time_taken(start, "mining iteration") self.print_time_taken(start, "mining total") if via_daemon: res = daemon.stop_mining() else: res = wallet.stop_mining() res_status = daemon.mining_status() assert res_status.active == False res_info = daemon.get_info() new_height = res_info.height wallet.refresh() res_getbalance = wallet.get_balance() balance = res_getbalance.balance assert balance >= prev_balance + (new_height - initial_height) * 600000000000 if via_daemon: res = daemon.start_mining( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', threads_count=1, do_background_mining=True) else: res = wallet.start_mining(threads_count=1, do_background_mining=True) res_status = daemon.mining_status() assert res_status.active == True assert res_status.threads_count == 1 assert res_status.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert res_status.is_background_mining_enabled == True assert res_status.block_reward >= 600000000000 # don't wait, might be a while if the machine is busy, which it probably is if via_daemon: res = daemon.stop_mining() else: res = wallet.stop_mining() res_status = daemon.mining_status() assert res_status.active == False
def __exit__(self, exc_type, exc_value, traceback): for i in range(4): Wallet(idx=i).auto_refresh(True)
def test_coinevo_uri(self): print('Testing coinevo: URI') wallet = Wallet() utf8string = [u'えんしゅう', u'あまやかす'] quoted_utf8string = [ urllib_quote(x.encode('utf8')) for x in utf8string ] ok = False try: res = wallet.make_uri() except: ok = True assert ok ok = False try: res = wallet.make_uri(address='') except: ok = True assert ok ok = False try: res = wallet.make_uri(address='kjshdkj') except: ok = True assert ok for address in [ '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', '4BxSHvcgTwu25WooY4BVmgdcKwZu5EksVZSZkDd6ooxSVVqQ4ubxXkhLF6hEqtw96i9cf3cVfLw8UWe95bdDKfRQeYtPwLm1Jiw7AKt2LY', '8AsN91rznfkBGTY8psSNkJBg9SZgxxGGRUhGwRptBhgr5XSQ1XzmA9m8QAnoxydecSh5aLJXdrgXwTDMMZ1AuXsN1EX5Mtm' ]: res = wallet.make_uri(address=address) assert res.uri == 'coinevo:' + address res = wallet.parse_uri(res.uri) assert res.uri.address == address assert res.uri.payment_id == '' assert res.uri.amount == 0 assert res.uri.tx_description == '' assert res.uri.recipient_name == '' assert not 'unknown_parameters' in res or len( res.unknown_parameters) == 0 res = wallet.make_uri(address=address, amount=11000000000) assert res.uri == 'coinevo:' + address + '?tx_amount=0.011' or res.uri == 'coinevo:' + address + '?tx_amount=0.011000000000' res = wallet.parse_uri(res.uri) assert res.uri.address == address assert res.uri.payment_id == '' assert res.uri.amount == 11000000000 assert res.uri.tx_description == '' assert res.uri.recipient_name == '' assert not 'unknown_parameters' in res or len( res.unknown_parameters) == 0 address = '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' res = wallet.make_uri(address=address, tx_description=utf8string[0]) assert res.uri == 'coinevo:' + address + '?tx_description=' + quoted_utf8string[ 0] res = wallet.parse_uri(res.uri) assert res.uri.address == address assert res.uri.payment_id == '' assert res.uri.amount == 0 assert res.uri.tx_description == utf8string[0] assert res.uri.recipient_name == '' assert not 'unknown_parameters' in res or len( res.unknown_parameters) == 0 res = wallet.make_uri(address=address, recipient_name=utf8string[0]) assert res.uri == 'coinevo:' + address + '?recipient_name=' + quoted_utf8string[ 0] res = wallet.parse_uri(res.uri) assert res.uri.address == address assert res.uri.payment_id == '' assert res.uri.amount == 0 assert res.uri.tx_description == '' assert res.uri.recipient_name == utf8string[0] assert not 'unknown_parameters' in res or len( res.unknown_parameters) == 0 res = wallet.make_uri(address=address, recipient_name=utf8string[0], tx_description=utf8string[1]) assert res.uri == 'coinevo:' + address + '?recipient_name=' + quoted_utf8string[ 0] + '&tx_description=' + quoted_utf8string[1] res = wallet.parse_uri(res.uri) assert res.uri.address == address assert res.uri.payment_id == '' assert res.uri.amount == 0 assert res.uri.tx_description == utf8string[1] assert res.uri.recipient_name == utf8string[0] assert not 'unknown_parameters' in res or len( res.unknown_parameters) == 0 res = wallet.make_uri(address=address, recipient_name=utf8string[0], tx_description=utf8string[1], amount=1000000000000) assert res.uri == 'coinevo:' + address + '?tx_amount=1.000000000000&recipient_name=' + quoted_utf8string[ 0] + '&tx_description=' + quoted_utf8string[1] res = wallet.parse_uri(res.uri) assert res.uri.address == address assert res.uri.payment_id == '' assert res.uri.amount == 1000000000000 assert res.uri.tx_description == utf8string[1] assert res.uri.recipient_name == utf8string[0] assert not 'unknown_parameters' in res or len( res.unknown_parameters) == 0 res = wallet.make_uri(address=address, recipient_name=utf8string[0], tx_description=utf8string[1], amount=1000000000000, payment_id='1' * 64) assert res.uri == 'coinevo:' + address + '?tx_payment_id=' + '1' * 64 + '&tx_amount=1.000000000000&recipient_name=' + quoted_utf8string[ 0] + '&tx_description=' + quoted_utf8string[1] res = wallet.parse_uri(res.uri) assert res.uri.address == address assert res.uri.payment_id == '1' * 64 assert res.uri.amount == 1000000000000 assert res.uri.tx_description == utf8string[1] assert res.uri.recipient_name == utf8string[0] assert not 'unknown_parameters' in res or len( res.unknown_parameters) == 0 # spaces must be encoded as %20 res = wallet.make_uri(address=address, tx_description=' ' + utf8string[1] + ' ' + utf8string[0] + ' ', amount=1000000000000) assert res.uri == 'coinevo:' + address + '?tx_amount=1.000000000000&tx_description=%20' + quoted_utf8string[ 1] + '%20' + quoted_utf8string[0] + '%20' res = wallet.parse_uri(res.uri) assert res.uri.address == address assert res.uri.payment_id == '' assert res.uri.amount == 1000000000000 assert res.uri.tx_description == ' ' + utf8string[ 1] + ' ' + utf8string[0] + ' ' assert res.uri.recipient_name == '' assert not 'unknown_parameters' in res or len( res.unknown_parameters) == 0 # the example from the docs res = wallet.parse_uri( 'coinevo:46BeWrHpwXmHDpDEUmZBWZfoQpdc6HaERCNmx1pEYL2rAcuwufPN9rXHHtyUA4QVy66qeFQkn6sfK8aHYjA3jk3o1Bv16em?tx_amount=239.39014&tx_description=donation' ) assert res.uri.address == '46BeWrHpwXmHDpDEUmZBWZfoQpdc6HaERCNmx1pEYL2rAcuwufPN9rXHHtyUA4QVy66qeFQkn6sfK8aHYjA3jk3o1Bv16em' assert res.uri.amount == 239390140000000 assert res.uri.tx_description == 'donation' assert res.uri.recipient_name == '' assert res.uri.payment_id == '' assert not 'unknown_parameters' in res or len( res.unknown_parameters) == 0 # malformed/invalid for uri in [ '', ':', 'coinevo', 'notcoinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'COINEVO:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'COINEVO::42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'coinevo:', 'coinevo:badaddress', 'coinevo:tx_amount=10', 'coinevo:?tx_amount=10', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm?tx_amount=-1', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm?tx_amount=1e12', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm?tx_amount=+12', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm?tx_amount=1+2', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm?tx_amount=A', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm?tx_amount=0x2', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm?tx_amount=222222222222222222222', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDn?tx_amount=10', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm&', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm&tx_amount', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm&tx_amount=', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm&tx_amount=10=', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm&tx_amount=10=&', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm&tx_amount=10=&foo=bar', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm?tx_amount=10&tx_amount=20', 'coinevo:42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm?tx_payment_id=1111111111111111', 'coinevo:4BxSHvcgTwu25WooY4BVmgdcKwZu5EksVZSZkDd6ooxSVVqQ4ubxXkhLF6hEqtw96i9cf3cVfLw8UWe95bdDKfRQeYtPwLm1Jiw7AKt2LY?tx_payment_id=' + '1' * 64, 'coinevo:9ujeXrjzf7bfeK3KZdCqnYaMwZVFuXemPU8Ubw335rj2FN1CdMiWNyFV3ksEfMFvRp9L9qum5UxkP5rN9aLcPxbH1au4WAB', 'coinevo:5K8mwfjumVseCcQEjNbf59Um6R9NfVUNkHTLhhPCmNvgDLVS88YW5tScnm83rw9mfgYtchtDDTW5jEfMhygi27j1QYphX38hg6m4VMtN29', 'coinevo:7A1Hr63MfgUa8pkWxueD5xBqhQczkusYiCMYMnJGcGmuQxa7aDBxN1G7iCuLCNB3VPeb2TW7U9FdxB27xKkWKfJ8VhUZthF', ]: ok = False try: res = wallet.parse_uri(uri) except: ok = True assert ok, res # unknown parameters but otherwise valid res = wallet.parse_uri('coinevo:' + address + '?tx_amount=239.39014&foo=bar') assert res.uri.address == address assert res.uri.amount == 239390140000000 assert res.unknown_parameters == ['foo=bar'], res res = wallet.parse_uri('coinevo:' + address + '?tx_amount=239.39014&foo=bar&baz=quux') assert res.uri.address == address assert res.uri.amount == 239390140000000 assert res.unknown_parameters == ['foo=bar', 'baz=quux'], res res = wallet.parse_uri('coinevo:' + address + '?tx_amount=239.39014&%20=%20') assert res.uri.address == address assert res.uri.amount == 239390140000000 assert res.unknown_parameters == ['%20=%20'], res res = wallet.parse_uri('coinevo:' + address + '?tx_amount=239.39014&unknown=' + quoted_utf8string[0]) assert res.uri.address == address assert res.uri.amount == 239390140000000 assert res.unknown_parameters == [u'unknown=' + quoted_utf8string[0] ], res