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": '888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H' }) 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 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 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 store(self): print('Testing store') 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 self.remove_file('test1') assert self.file_exists('test1.keys') assert not self.file_exists('test1') wallet.store() assert self.file_exists('test1.keys') assert self.file_exists('test1') wallet.close_wallet() self.remove_wallet_files('test1')
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 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 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(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 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
class AddressValidationTest(): def run_test(self): self.create() self.check_bad_addresses() self.check_good_addresses() def create(self): print('Creating 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' address = '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' self.wallet = Wallet() # close the wallet if any, will throw if none is loaded try: self.wallet.close_wallet() except: pass res = self.wallet.restore_deterministic_wallet(seed = seed) assert res.address == address assert res.seed == seed def check_bad_addresses(self): print('Validating bad addresses') bad_addresses = ['', 'a', '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWD9', ' ', '@', '42ey'] for address in bad_addresses: res = self.wallet.validate_address(address, any_net_type = False) assert not res.valid res = self.wallet.validate_address(address, any_net_type = True) assert not res.valid def check_good_addresses(self): print('Validating good addresses') addresses = [ [ 'mainnet', '', '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' ], [ 'mainnet', '', '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW' ], [ 'testnet', '', '9ujeXrjzf7bfeK3KZdCqnYaMwZVFuXemPU8Ubw335rj2FN1CdMiWNyFV3ksEfMFvRp9L9qum5UxkP5rN9aLcPxbH1au4WAB' ], [ 'stagenet', '', '53teqCAESLxeJ1REzGMAat1ZeHvuajvDiXqboEocPaDRRmqWoVPzy46GLo866qRFjbNhfkNckyhST3WEvBviDwpUDd7DSzB' ], [ 'mainnet', 'i', '4BxSHvcgTwu25WooY4BVmgdcKwZu5EksVZSZkDd6ooxSVVqQ4ubxXkhLF6hEqtw96i9cf3cVfLw8UWe95bdDKfRQeYtPwLm1Jiw7AKt2LY' ], [ 'mainnet', 's', '8AsN91rznfkBGTY8psSNkJBg9SZgxxGGRUhGwRptBhgr5XSQ1XzmA9m8QAnoxydecSh5aLJXdrgXwTDMMZ1AuXsN1EX5Mtm' ], [ 'mainnet', 's', '86kKnBKFqzCLxtK1Jmx2BkNBDBSMDEVaRYMMyVbeURYDWs8uNGDZURKCA5yRcyMxHzPcmCf1q2fSdhQVcaKsFrtGRsdGfNk' ], [ 'testnet', 'i', 'AApMA1VuhiCaHzr5X2KXi2Zc9oJ3VaGjkfChxxpRpxkyKf1NetvbRbQTbFMrGkr85DjnEH7JsBaoUFsgKwZnmtnVWnoB8MDotCsLb7eWwz' ], [ 'testnet', 's', 'BdKg9udkvckC5T58a8Nmtb6BNsgRAxs7uA2D49sWNNX5HPW5Us6Wxu8QMXrnSx3xPBQQ2iu9kwEcRGAoiz6EPmcZKbF62GS' ], [ 'testnet', 's', 'BcFvPa3fT4gVt5QyRDe5Vv7VtUFao9ci8NFEy3r254KF7R1N2cNB5FYhGvrHbMStv4D6VDzZ5xtxeKV8vgEPMnDcNFuwZb9' ], [ 'stagenet', 'i', '5K8mwfjumVseCcQEjNbf59Um6R9NfVUNkHTLhhPCmNvgDLVS88YW5tScnm83rw9mfgYtchtDDTW5jEfMhygi27j1QYphX38hg6m4VMtN29' ], [ 'stagenet', 's', '73LhUiix4DVFMcKhsPRG51QmCsv8dYYbL6GcQoLwEEFvPvkVvc7BhebfA4pnEFF9Lq66hwvLqBvpHjTcqvpJMHmmNjPPBqa' ], [ 'stagenet', 's', '7A1Hr63MfgUa8pkWxueD5xBqhQczkusYiCMYMnJGcGmuQxa7aDBxN1G7iCuLCNB3VPeb2TW7U9FdxB27xKkWKfJ8VhUZthF' ], ] for any_net_type in [True, False]: for address in addresses: res = self.wallet.validate_address(address[2], any_net_type = any_net_type) if any_net_type or address[0] == 'mainnet': assert res.valid assert res.integrated == (address[1] == 'i') assert res.subaddress == (address[1] == 's') assert res.nettype == address[0] else: assert not res.valid
class GetOutputDistributionTest(): def run_test(self): self.reset() self.create() self.test_get_output_distribution() def reset(self): print('Resetting blockchain') daemon = Daemon() res = daemon.get_height() daemon.pop_blocks(res.height - 1) daemon.flush_txpool() def create(self): self.wallet = Wallet() # close the wallet if any, will throw if none is loaded try: self.wallet.close_wallet() except: pass res = self.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 test_get_output_distribution(self): print("Test get_output_distribution") daemon = Daemon() res = daemon.get_output_distribution([0], 0, 0) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 1 assert d.distribution[0] == 0 res = daemon.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1) res = daemon.get_output_distribution([0], 0, 0) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 2 assert d.distribution[0] == 0 assert d.distribution[1] == 1 res = daemon.pop_blocks(1) res = daemon.get_output_distribution([0], 0, 0) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 1 assert d.distribution[0] == 0 res = daemon.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 3) res = daemon.get_output_distribution([0], 0, 0, cumulative=True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 4 assert d.distribution[0] == 0 assert d.distribution[1] == 1 assert d.distribution[2] == 2 assert d.distribution[3] == 3 # extend res = daemon.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80) res = daemon.get_output_distribution([0], 0, 0, cumulative=True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 84 for h in range(len(d.distribution)): assert d.distribution[h] == h # pop and replace, this will do through the "trim and extend" path res = daemon.pop_blocks(2) self.wallet.refresh() dst = { 'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000 } self.wallet.transfer([dst]) res = daemon.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1) for step in range( 3 ): # the second will be cached, the third will also be cached, but we get it in non-cumulative mode res = daemon.get_output_distribution([0], 0, 0, cumulative=step < 3) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 83 for h in range(len(d.distribution)): assert d.distribution[h] == (h if step < 3 else 1) + ( 2 if h == len(d.distribution) - 1 else 0) # start at 0, end earlier res = daemon.get_output_distribution([0], 0, 40, cumulative=True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 41 for h in range(len(d.distribution)): assert d.distribution[h] == h # start after 0, end earlier res = daemon.get_output_distribution([0], 10, 20, cumulative=True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 9 assert d.binary == False assert len(d.distribution) == 11 for h in range(len(d.distribution)): assert d.distribution[h] == 10 + h # straddling up res = daemon.get_output_distribution([0], 15, 25, cumulative=True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 14 assert d.binary == False assert len(d.distribution) == 11 for h in range(len(d.distribution)): assert d.distribution[h] == 15 + h # straddling down res = daemon.get_output_distribution([0], 8, 18, cumulative=True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 7 assert d.binary == False assert len(d.distribution) == 11 for h in range(len(d.distribution)): assert d.distribution[h] == 8 + h # encompassing res = daemon.get_output_distribution([0], 5, 20, cumulative=True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 4 assert d.binary == False assert len(d.distribution) == 16 for h in range(len(d.distribution)): assert d.distribution[h] == 5 + h # single res = daemon.get_output_distribution([0], 2, 2, cumulative=True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 1 assert d.binary == False assert len(d.distribution) == 1 assert d.distribution[0] == 2 # a non existent amount res = daemon.get_output_distribution([1], 0, 0) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 1 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 83 for h in range(len(d.distribution)): assert d.distribution[h] == 0
class P2PTest(): def run_test(self): self.reset() self.create() self.mine(80) self.test_p2p_reorg() self.test_p2p_tx_propagation() def reset(self): print('Resetting blockchain') daemon = Daemon() res = daemon.get_height() daemon.pop_blocks(res.height - 1) daemon.flush_txpool() def create(self): print('Creating 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' self.wallet = Wallet(idx=4) # close the wallet if any, will throw if none is loaded try: self.wallet.close_wallet() except: pass res = self.wallet.restore_deterministic_wallet(seed=seed) def mine(self, blocks): assert blocks >= 1 print("Generating", blocks, 'blocks') daemon = Daemon(idx=2) # generate blocks res_generateblocks = daemon.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', blocks) def test_p2p_reorg(self): print('Testing P2P reorg') daemon2 = Daemon(idx=2) daemon3 = Daemon(idx=3) # give sync some time time.sleep(1) res = daemon2.get_info() height = res.height assert height > 0 top_block_hash = res.top_block_hash assert len(top_block_hash) == 64 res = daemon3.get_info() assert res.height == height assert res.top_block_hash == top_block_hash # disconnect daemons and mine separately on both daemon2.out_peers(0) daemon3.out_peers(0) res = daemon2.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 2) res = daemon3.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 3) res = daemon2.get_info() assert res.height == height + 2 daemon2_top_block_hash = res.top_block_hash assert daemon2_top_block_hash != top_block_hash res = daemon3.get_info() assert res.height == height + 3 daemon3_top_block_hash = res.top_block_hash assert daemon3_top_block_hash != top_block_hash assert daemon3_top_block_hash != daemon2_top_block_hash # reconnect, daemon2 will now switch to daemon3's chain daemon2.out_peers(8) daemon3.out_peers(8) time.sleep(10) res = daemon2.get_info() assert res.height == height + 3 assert res.top_block_hash == daemon3_top_block_hash # disconect, mine on daemon2 again more than daemon3 daemon2.out_peers(0) daemon3.out_peers(0) res = daemon2.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 3) res = daemon3.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 2) res = daemon2.get_info() assert res.height == height + 6 daemon2_top_block_hash = res.top_block_hash assert daemon2_top_block_hash != top_block_hash res = daemon3.get_info() assert res.height == height + 5 daemon3_top_block_hash = res.top_block_hash assert daemon3_top_block_hash != top_block_hash assert daemon3_top_block_hash != daemon2_top_block_hash # reconnect, daemon3 will now switch to daemon2's chain daemon2.out_peers(8) daemon3.out_peers(8) time.sleep(5) res = daemon3.get_info() assert res.height == height + 6 assert res.top_block_hash == daemon2_top_block_hash # disconnect and mine a lot on daemon3 daemon2.out_peers(0) daemon3.out_peers(0) res = daemon3.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 500) # reconnect and wait for sync daemon2.out_peers(8) daemon3.out_peers(8) loops = 100 while True: res2 = daemon2.get_info() res3 = daemon3.get_info() if res2.top_block_hash == res3.top_block_hash: break time.sleep(10) loops -= 1 assert loops >= 0 def test_p2p_tx_propagation(self): print('Testing P2P tx propagation') daemon2 = Daemon(idx=2) daemon3 = Daemon(idx=3) for daemon in [daemon2, daemon3]: res = daemon.get_transaction_pool_hashes() assert not 'tx_hashes' in res or len(res.tx_hashes) == 0 self.wallet.refresh() res = self.wallet.get_balance() dst = { 'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000 } res = self.wallet.transfer([dst]) assert len(res.tx_hash) == 32 * 2 txid = res.tx_hash time.sleep(5) for daemon in [daemon2, daemon3]: res = daemon.get_transaction_pool_hashes() assert len(res.tx_hashes) == 1 assert res.tx_hashes[0] == txid
class ColdSigningTest(): def run_test(self): self.reset() self.create(0) self.mine() self.transfer() def reset(self): print('Resetting blockchain') daemon = Daemon() res = daemon.get_height() daemon.pop_blocks(res.height - 1) daemon.flush_txpool() def create(self, idx): print('Creating hot and cold wallet') self.hot_wallet = Wallet(idx=0) # close the wallet if any, will throw if none is loaded try: self.hot_wallet.close_wallet() except: pass self.cold_wallet = Wallet(idx=1) # close the wallet if any, will throw if none is loaded try: self.cold_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 = self.cold_wallet.restore_deterministic_wallet(seed=seed) self.cold_wallet.set_daemon('127.0.0.1:11111', ssl_support="disabled") spend_key = self.cold_wallet.query_key("spend_key").key view_key = self.cold_wallet.query_key("view_key").key res = self.hot_wallet.generate_from_keys( viewkey=view_key, address= '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' ) ok = False try: res = self.hot_wallet.query_key("spend_key") except: ok = True assert ok ok = False try: self.hot_wallet.query_key("mnemonic") except: ok = True assert ok assert self.cold_wallet.query_key("view_key").key == view_key assert self.cold_wallet.get_address( ).address == self.hot_wallet.get_address().address def mine(self): print("Mining some blocks") daemon = Daemon() wallet = Wallet() daemon.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80) wallet.refresh() def transfer(self): daemon = Daemon() print("Creating transaction in hot wallet") dst = { 'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000 } self.hot_wallet.refresh() res = self.hot_wallet.export_outputs() self.cold_wallet.import_outputs(res.outputs_data_hex) res = self.cold_wallet.export_key_images(True) self.hot_wallet.import_key_images(res.signed_key_images, offset=res.offset) res = self.hot_wallet.transfer([dst], ring_size=11, get_tx_key=False) assert len(res.tx_hash) == 32 * 2 txid = res.tx_hash assert len(res.tx_key) == 0 assert res.amount > 0 amount = res.amount assert res.fee > 0 fee = res.fee assert len(res.tx_blob) == 0 assert len(res.tx_metadata) == 0 assert len(res.multisig_txset) == 0 assert len(res.unsigned_txset) > 0 unsigned_txset = res.unsigned_txset print('Signing transaction with cold wallet') res = self.cold_wallet.describe_transfer(unsigned_txset=unsigned_txset) assert len(res.desc) == 1 desc = res.desc[0] assert desc.amount_in >= amount + fee assert desc.amount_out == desc.amount_in - fee assert desc.ring_size == 11 assert desc.unlock_time == 0 assert desc.payment_id in ['', '0000000000000000'] assert desc.change_amount == desc.amount_in - 1000000000000 - fee assert desc.change_address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert desc.fee == fee assert len(desc.recipients) == 1 rec = desc.recipients[0] assert rec.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert rec.amount == 1000000000000 res = self.cold_wallet.sign_transfer(unsigned_txset) assert len(res.signed_txset) > 0 signed_txset = res.signed_txset assert len(res.tx_hash_list) == 1 txid = res.tx_hash_list[0] assert len(txid) == 64 print('Submitting transaction with hot wallet') res = self.hot_wallet.submit_transfer(signed_txset) assert len(res.tx_hash_list) > 0 assert res.tx_hash_list[0] == txid res = self.hot_wallet.get_transfers() assert len([ x for x in (res['pending'] if 'pending' in res else []) if x.txid == txid ]) == 1 assert len([ x for x in (res['out'] if 'out' in res else []) if x.txid == txid ]) == 0 daemon.generateblocks( '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1) self.hot_wallet.refresh() res = self.hot_wallet.get_transfers() assert len([ x for x in (res['pending'] if 'pending' in res else []) if x.txid == txid ]) == 0 assert len([ x for x in (res['out'] if 'out' in res else []) if x.txid == txid ]) == 1 res = self.hot_wallet.get_tx_key(txid) assert len( res.tx_key ) == 0 or res.tx_key == '01' + '0' * 62 # identity is used as placeholder res = self.cold_wallet.get_tx_key(txid) assert len(res.tx_key) == 64
class ColdSigningTest(): def run_test(self): self.reset() self.create(0) self.mine() self.transfer() def reset(self): print('Resetting blockchain') daemon = Daemon() daemon.pop_blocks(1000) daemon.flush_txpool() def create(self, idx): print('Creating hot and cold wallet') self.hot_wallet = Wallet(idx = 0) # close the wallet if any, will throw if none is loaded try: self.hot_wallet.close_wallet() except: pass self.cold_wallet = Wallet(idx = 1) # close the wallet if any, will throw if none is loaded try: self.cold_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 = self.cold_wallet.restore_deterministic_wallet(seed = seed) self.cold_wallet.set_daemon('127.0.0.1:11111', ssl_support = "disabled") spend_key = self.cold_wallet.query_key("spend_key").key view_key = self.cold_wallet.query_key("view_key").key res = self.hot_wallet.generate_from_keys(viewkey = view_key, address = '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm') ok = False try: res = self.hot_wallet.query_key("spend_key") except: ok = True assert ok ok = False try: self.hot_wallet.query_key("mnemonic") except: ok = True assert ok assert self.cold_wallet.query_key("view_key").key == view_key assert self.cold_wallet.get_address().address == self.hot_wallet.get_address().address def mine(self): print("Mining some blocks") daemon = Daemon() wallet = Wallet() daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80) wallet.refresh() def transfer(self): daemon = Daemon() print("Creating transaction in hot wallet") dst = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000} payment_id = '1234500000012345abcde00000abcdeff1234500000012345abcde00000abcde' self.hot_wallet.refresh() res = self.hot_wallet.export_outputs() self.cold_wallet.import_outputs(res.outputs_data_hex) res = self.cold_wallet.export_key_images(True) self.hot_wallet.import_key_images(res.signed_key_images, offset = res.offset) res = self.hot_wallet.transfer([dst], ring_size = 11, payment_id = payment_id, get_tx_key = False) assert len(res.tx_hash) == 32*2 txid = res.tx_hash assert len(res.tx_key) == 0 assert res.amount > 0 amount = res.amount assert res.fee > 0 fee = res.fee assert len(res.tx_blob) == 0 assert len(res.tx_metadata) == 0 assert len(res.multisig_txset) == 0 assert len(res.unsigned_txset) > 0 unsigned_txset = res.unsigned_txset print('Signing transaction with cold wallet') res = self.cold_wallet.describe_transfer(unsigned_txset = unsigned_txset) assert len(res.desc) == 1 desc = res.desc[0] assert desc.amount_in >= amount + fee assert desc.amount_out == desc.amount_in - fee assert desc.ring_size == 11 assert desc.unlock_time == 0 assert desc.payment_id == payment_id assert desc.change_amount == desc.amount_in - 1000000000000 - fee assert desc.change_address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert desc.fee == fee assert len(desc.recipients) == 1 rec = desc.recipients[0] assert rec.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm' assert rec.amount == 1000000000000 res = self.cold_wallet.sign_transfer(unsigned_txset) assert len(res.signed_txset) > 0 signed_txset = res.signed_txset assert len(res.tx_hash_list) == 1 txid = res.tx_hash_list[0] assert len(txid) == 64 print('Submitting transaction with hot wallet') res = self.hot_wallet.submit_transfer(signed_txset) assert len(res.tx_hash_list) > 0 assert res.tx_hash_list[0] == txid res = self.hot_wallet.get_transfers() assert len([x for x in (res['pending'] if 'pending' in res else []) if x.txid == txid]) == 1 assert len([x for x in (res['out'] if 'out' in res else []) if x.txid == txid]) == 0 daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1) self.hot_wallet.refresh() res = self.hot_wallet.get_transfers() assert len([x for x in (res['pending'] if 'pending' in res else []) if x.txid == txid]) == 0 assert len([x for x in (res['out'] if 'out' in res else []) if x.txid == txid]) == 1 res = self.hot_wallet.get_tx_key(txid) assert len(res.tx_key) == 0 or res.tx_key == '01' + '0' * 62 # identity is used as placeholder res = self.cold_wallet.get_tx_key(txid) assert len(res.tx_key) == 64
class GetOutputDistributionTest(): def run_test(self): self.reset() self.create() self.test_get_output_distribution() def reset(self): print('Resetting blockchain') daemon = Daemon() daemon.pop_blocks(1000) daemon.flush_txpool() def create(self): self.wallet = Wallet() # close the wallet if any, will throw if none is loaded try: self.wallet.close_wallet() except: pass res = self.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 test_get_output_distribution(self): print("Test get_output_distribution") daemon = Daemon() res = daemon.get_output_distribution([0], 0, 0) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 1 assert d.distribution[0] == 0 res = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1) res = daemon.get_output_distribution([0], 0, 0) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 2 assert d.distribution[0] == 0 assert d.distribution[1] == 1 res = daemon.pop_blocks(1) res = daemon.get_output_distribution([0], 0, 0) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 1 assert d.distribution[0] == 0 res = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 3) res = daemon.get_output_distribution([0], 0, 0, cumulative = True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 4 assert d.distribution[0] == 0 assert d.distribution[1] == 1 assert d.distribution[2] == 2 assert d.distribution[3] == 3 # extend res = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80) res = daemon.get_output_distribution([0], 0, 0, cumulative = True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 84 for h in range(len(d.distribution)): assert d.distribution[h] == h # pop and replace, this will do through the "trim and extend" path res = daemon.pop_blocks(2) self.wallet.refresh() dst = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000} self.wallet.transfer([dst]) res = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1) for step in range(3): # the second will be cached, the third will also be cached, but we get it in non-cumulative mode res = daemon.get_output_distribution([0], 0, 0, cumulative = step < 3) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 83 for h in range(len(d.distribution)): assert d.distribution[h] == (h if step < 3 else 1) + (2 if h == len(d.distribution) - 1 else 0) # start at 0, end earlier res = daemon.get_output_distribution([0], 0, 40, cumulative = True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 41 for h in range(len(d.distribution)): assert d.distribution[h] == h # start after 0, end earlier res = daemon.get_output_distribution([0], 10, 20, cumulative = True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 9 assert d.binary == False assert len(d.distribution) == 11 for h in range(len(d.distribution)): assert d.distribution[h] == 10 + h # straddling up res = daemon.get_output_distribution([0], 15, 25, cumulative = True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 14 assert d.binary == False assert len(d.distribution) == 11 for h in range(len(d.distribution)): assert d.distribution[h] == 15 + h # straddling down res = daemon.get_output_distribution([0], 8, 18, cumulative = True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 7 assert d.binary == False assert len(d.distribution) == 11 for h in range(len(d.distribution)): assert d.distribution[h] == 8 + h # encompassing res = daemon.get_output_distribution([0], 5, 20, cumulative = True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 4 assert d.binary == False assert len(d.distribution) == 16 for h in range(len(d.distribution)): assert d.distribution[h] == 5 + h # single res = daemon.get_output_distribution([0], 2, 2, cumulative = True) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 0 assert d.base == 1 assert d.binary == False assert len(d.distribution) == 1 assert d.distribution[0] == 2 # a non existent amount res = daemon.get_output_distribution([1], 0, 0) assert len(res.distributions) == 1 d = res.distributions[0] assert d.amount == 1 assert d.base == 0 assert d.binary == False assert len(d.distribution) == 83 for h in range(len(d.distribution)): assert d.distribution[h] == 0