def dust_test(harness: Harness) -> None: # Wallet. wallet: Wallet = Wallet(harness.crypto, urandom(32)) # WatchWallet. watch: WatchWallet = WatchWallet( harness.crypto, harness.rpc, wallet.private_view_key, wallet.public_spend_key, harness.rpc.get_block_count() - 1, ) # Send to self. tx: bytes = harness.send(watch.new_address((0, 0)), ATOMIC_XMR) # Verify it via can_spend. spendable: Tuple[List[bytes], Dict[OutputIndex, OutputInfo]] = watch.can_spend( watch.rpc.get_transaction(tx)) assert not spendable[0] assert len(spendable[1]) == 1 assert list(spendable[1].keys())[0].tx_hash == tx assert spendable[1][list(spendable[1].keys())[0]].amount == ATOMIC_XMR # 'Send' back to the master wallet. with pytest.raises(BalanceError): watch.prepare_send( watch.new_address((0, 0)), (ATOMIC_XMR // 10) * 9, (ATOMIC_XMR // 10) - 1, minimum_input=(2 * ATOMIC_XMR), ) # Still call return_funds so the post-test functions can be run. harness.return_funds(wallet, watch, 0)
def XMR_address_test(monero_crypto: MoneroCrypto, constants: Dict[str, Any]): watch: WatchWallet = WatchWallet( monero_crypto, MoneroRPC("", -1), constants["PRIVATE_VIEW_KEY"], constants["PUBLIC_SPEND_KEY"], -1, ) address: Address = watch.new_address((0, 0)) assert address.network == monero_crypto.network_bytes[0] assert address.payment_id is None assert address.address == constants["XMR"]["ADDRESS"] assert address == Address.parse(monero_crypto, constants["XMR"]["ADDRESS"])
def reload_test(harness: Harness) -> None: # Now that we have a Wallet with a lot of history, reload the state. reloaded: WatchWallet = WatchWallet( harness.crypto, harness.rpc, harness.watch.private_view_key, harness.watch.public_spend_key, json.loads(json.dumps(harness.watch.save_state())), ) assert harness.watch.last_block == reloaded.last_block assert harness.watch.confirmation_queue == reloaded.confirmation_queue assert harness.watch.inputs == reloaded.inputs assert harness.watch.unique_factors == reloaded.unique_factors
def return_funds(self, test_wallet: Wallet, test_watch: WatchWallet, amount: int) -> None: """Return sent funds back to the master wallet.""" if amount != 0: context: Dict[str, Any] = test_watch.prepare_send( self.watch.new_address((0, 0)), amount - (ATOMIC_XMR // 10), (ATOMIC_XMR // 10) - 1, ) publishable: List[str] = test_wallet.sign( json.loads(json.dumps(context))) test_watch.finalize_send(True, context, publishable[1]) # Wait for the return TXs to unlock. self.wait_for_unlock() # Verify we can spend the returned funds. returned: Tuple[List[bytes], Dict[OutputIndex, OutputInfo]] = self.watch.can_spend( self.rpc.get_transaction( bytes.fromhex(publishable[0]))) assert not returned[0] assert len(returned[1]) == 1 assert list(returned[1].keys())[0].tx_hash == bytes.fromhex( publishable[0]) assert returned[1][list( returned[1].keys())[0]].amount == amount - (ATOMIC_XMR // 10) # Poll the blockchain. # This gets us the miner Transactions and change outputs. # Since inputs are stored as a Dict, this will not create duplicates. self.poll_blocks() # Verify inputs. self.verify_inputs()
def XMR_subaddress_address_test(monero_crypto: MoneroCrypto, constants: Dict[str, Any]): watch: WatchWallet = WatchWallet( monero_crypto, MoneroRPC("", -1), constants["PRIVATE_VIEW_KEY"], constants["PUBLIC_SPEND_KEY"], -1, ) for subaddress in constants["XMR"]["SUBADDRESSES"]: address: Address = watch.new_address(subaddress[0]) assert address.payment_id is None assert address.address == subaddress[1] assert address.address == subaddress[1] assert address == Address.parse(monero_crypto, subaddress[1])
def TRTL_integrated_address_test(turtlecoin_crypto: TurtlecoinCrypto, constants: Dict[str, Any]): watch: WatchWallet = WatchWallet( turtlecoin_crypto, TurtlecoinRPC("", -1), constants["PRIVATE_VIEW_KEY"], constants["PUBLIC_SPEND_KEY"], -1, ) address: Address = watch.new_address(constants["TRTL"]["PAYMENT_ID"]) assert address.network == turtlecoin_crypto.network_bytes[1] assert address.payment_id == constants["TRTL"]["PAYMENT_ID"] assert address.address == constants["TRTL"]["INTEGRATED_ADDRESS"] assert address == Address.parse(turtlecoin_crypto, constants["TRTL"]["INTEGRATED_ADDRESS"])
def TRTL_address_test(turtlecoin_crypto: TurtlecoinCrypto, constants: Dict[str, Any]): watch: WatchWallet = WatchWallet( turtlecoin_crypto, TurtlecoinRPC("", -1), constants["PRIVATE_VIEW_KEY"], constants["PUBLIC_SPEND_KEY"], -1, ) address: Address = watch.new_address(b"") assert address.network == turtlecoin_crypto.network_bytes[0] assert address.payment_id is None assert address.address == constants["TRTL"]["ADDRESS"] assert address == Address.parse(turtlecoin_crypto, constants["TRTL"]["ADDRESS"])
def integrated_address_test( harness: Harness, monero_payment_id_crypto: MoneroPaymentIDCrypto) -> None: # Override the oldest TXO. monero_payment_id_crypto.oldest_txo_property = 1 # Wallet. wallet: Wallet = Wallet(monero_payment_id_crypto, urandom(32)) # WatchWallet. watch: WatchWallet = WatchWallet( monero_payment_id_crypto, harness.rpc, wallet.private_view_key, wallet.public_spend_key, harness.rpc.get_block_count() - 1, ) # Send to random payment IDs. payment_IDs: List[bytes] = [urandom(8)] amounts: List[int] = [] txs: List[bytes] = [] for i in range(10): amounts.append(randint(ATOMIC_XMR, 40 * ATOMIC_XMR)) txs.append( harness.send(watch.new_address(payment_IDs[-1]), amounts[-1])) payment_IDs.append(urandom(8)) del payment_IDs[-1] # Verify them via can_spend. for t in range(len(txs)): # Verify them via can_spend. for t in range(len(txs)): spendable: Tuple[List[bytes], Dict[OutputIndex, OutputInfo]] = watch.can_spend( watch.rpc.get_transaction(txs[t])) assert len(spendable[0]) == 1 assert spendable[0][0] == payment_IDs[t] assert len(spendable[1]) == 1 assert list(spendable[1].keys())[0].tx_hash == txs[t] assert spendable[1][list( spendable[1].keys())[0]].amount == amounts[t] # Send back to the master wallet. harness.return_funds(wallet, watch, sum(amounts))
def XMR_integrated_address_test( monero_payment_id_crypto: MoneroCrypto, constants: Dict[str, Any] ): watch: WatchWallet = WatchWallet( monero_payment_id_crypto, MoneroRPC("", -1), constants["PRIVATE_VIEW_KEY"], constants["PUBLIC_SPEND_KEY"], -1, ) address: Address = watch.new_address(constants["XMR"]["PAYMENT_ID"]) assert address.network == monero_payment_id_crypto.network_bytes[1] assert address.payment_id == constants["XMR"]["PAYMENT_ID"] assert address.address == constants["XMR"]["INTEGRATED_ADDRESS"] assert address == Address.parse( monero_payment_id_crypto, constants["XMR"]["INTEGRATED_ADDRESS"] )
def XMR_key_generation(monero_crypto: MoneroCrypto, constants: Dict[str, Any]): wallet: Wallet = Wallet(monero_crypto, constants["PRIVATE_SPEND_KEY"]) watch: WatchWallet = WatchWallet( monero_crypto, MoneroRPC("", -1), wallet.private_view_key, wallet.public_spend_key, -1, ) assert wallet.private_spend_key == constants["PRIVATE_SPEND_KEY"] assert wallet.public_spend_key == constants["PUBLIC_SPEND_KEY"] assert watch.public_spend_key == constants["PUBLIC_SPEND_KEY"] assert wallet.private_view_key == constants["PRIVATE_VIEW_KEY"] assert wallet.public_view_key == constants["PUBLIC_VIEW_KEY"] assert watch.private_view_key == constants["PRIVATE_VIEW_KEY"] assert watch.public_view_key == constants["PUBLIC_VIEW_KEY"]
def TRTL_key_generation(turtlecoin_crypto: TurtlecoinCrypto, constants: Dict[str, Any]): wallet: Wallet = Wallet(turtlecoin_crypto, constants["PRIVATE_SPEND_KEY"]) watch: WatchWallet = WatchWallet( turtlecoin_crypto, TurtlecoinRPC("", -1), wallet.private_view_key, wallet.public_spend_key, -1, ) assert wallet.private_spend_key == constants["PRIVATE_SPEND_KEY"] assert wallet.public_spend_key == constants["PUBLIC_SPEND_KEY"] assert watch.public_spend_key == constants["PUBLIC_SPEND_KEY"] assert wallet.private_view_key == constants["PRIVATE_VIEW_KEY"] assert wallet.public_view_key == constants["PUBLIC_VIEW_KEY"] assert watch.private_view_key == constants["PRIVATE_VIEW_KEY"] assert watch.public_view_key == constants["PUBLIC_VIEW_KEY"]
def __init__(self): """Construct a new test environment.""" self.rpc: RPC = MoneroRPC("127.0.0.1", 18081) self.crypto: MoneroCrypto = MoneroCrypto() self.crypto.oldest_txo_property = 1 key: bytes = urandom(32) self.wallet: Wallet = Wallet(self.crypto, key) self.watch: WatchWallet = WatchWallet( self.crypto, self.rpc, self.wallet.private_view_key, self.wallet.public_spend_key, 1, ) self.inputs: Dict[OutputIndex, OutputInfo] = {} self.rpc.generate_blocks(100, self.watch.new_address((0, 0)).address)
def rebuild_test(harness: Harness) -> None: # Test rebuilding the state. reloaded = WatchWallet( harness.crypto, harness.rpc, harness.wallet.private_view_key, harness.wallet.public_spend_key, 1, ) reloaded.poll_blocks() reloaded.rebuild_input_states( json.loads( json.dumps( harness.wallet.generate_key_images( json.loads(json.dumps(reloaded.save_state()["inputs"])))))) assert harness.watch.last_block == reloaded.last_block assert harness.watch.confirmation_queue == reloaded.confirmation_queue assert harness.watch.inputs == reloaded.inputs assert harness.watch.unique_factors == reloaded.unique_factors
def subaddress_test(harness: Harness) -> None: # Wallet. wallet: Wallet = Wallet(harness.crypto, urandom(32)) # WatchWallet. watch: WatchWallet = WatchWallet( harness.crypto, harness.rpc, wallet.private_view_key, wallet.public_spend_key, harness.rpc.get_block_count() - 1, ) # Send to random indexes (with the first index being the root index). indexes: List[Tuple[int, int]] = [(0, 0)] amounts: List[int] = [] txs: List[bytes] = [] for _ in range(10): amounts.append(randint(ATOMIC_XMR, 40 * ATOMIC_XMR)) txs.append(harness.send(watch.new_address(indexes[-1]), amounts[-1])) indexes.append((randint(0, 300), randint(0, 300))) del indexes[-1] # Verify them via can_spend. for t in range(len(txs)): spendable: Tuple[List[bytes], Dict[OutputIndex, OutputInfo]] = watch.can_spend( watch.rpc.get_transaction(txs[t])) assert not spendable[0] assert len(spendable[1]) == 1 assert list(spendable[1].keys())[0].tx_hash == txs[t] assert spendable[1][list(spendable[1].keys())[0]].amount == amounts[t] # Send back to the master wallet. harness.return_funds(wallet, watch, sum(amounts))
def multiple_Rs_test(harness: Harness) -> None: # Wallet. wallet: Wallet = Wallet(harness.crypto, urandom(32)) # WatchWallet. watch: WatchWallet = WatchWallet( harness.crypto, harness.rpc, wallet.private_view_key, wallet.public_spend_key, harness.rpc.get_block_count() - 1, ) # Test multiple Rs. indexes: List[Tuple[int, int]] = [(0, 0)] amounts: List[int] = [] txs: List[bytes] = [] for _ in range(5): indexes.append((randint(0, 300), randint(0, 300))) amounts.append(randint(ATOMIC_XMR, 40 * ATOMIC_XMR)) txs.append(harness.send(watch.new_address(indexes[-1]), amounts[-1])) # Get the Transaction. tx: Transaction = watch.rpc.get_transaction(txs[-1]) # Add multiple other Rs to the Transaction. for _ in range(3): tx.Rs.append(public_from_secret(Hs(urandom(32)))) # Check the other Rs had no affect. spendable: Tuple[List[bytes], Dict[OutputIndex, OutputInfo]] = watch.can_spend(tx) assert not spendable[0] assert len(spendable[1]) == 1 assert list(spendable[1].keys())[0].tx_hash == txs[-1] assert spendable[1][list(spendable[1].keys())[0]].amount == amounts[-1] # Test multiple identical Rs. for _ in range(5): # Send to a random index. indexes.append((randint(0, 300), randint(0, 300))) amounts.append(randint(ATOMIC_XMR, 5 * ATOMIC_XMR)) txs.append(harness.send(watch.new_address(indexes[-1]), amounts[-1])) # Manually get the Transaction's JSON. tx_json: Dict[str, Any] = json.loads( watch.rpc.rpc_request( "get_transactions", { "txs_hashes": [txs[-1].hex()], "decode_as_json": True }, )["txs"][0]["as_json"]) # Create a Transaction from it. tx: Transaction = Transaction(txs[-1], tx_json) # Get a duplicate list of Rs. Rs: List[bytes] = tx.Rs * 2 # Use the Rs and tx to craft a new extra in tx_json. extra: bytes = bytes([0x01]) + Rs[0] # Add the other Rs. extra += bytes([0x04]) + to_var_int(len(Rs) - 1) for R in Rs[1:]: extra += R # Store it in tx_json. tx_json["extra"] = [] for b in range(len(extra)): tx_json["extra"].append(extra[b]) # Parse the modified JSON. modified_tx: Transaction = Transaction(txs[-1], tx_json) # Check the duplicate Rs were stripped. assert tx.Rs == modified_tx.Rs spendable: Tuple[List[bytes], Dict[OutputIndex, OutputInfo]] = watch.can_spend(tx) assert not spendable[0] assert len(spendable[1]) == 1 assert list(spendable[1].keys())[0].tx_hash == txs[-1] assert spendable[1][list(spendable[1].keys())[0]].amount == amounts[-1] # Send back to the master wallet. harness.return_funds(wallet, watch, sum(amounts))
# Crypto. crypto: MoneroCrypto = MoneroCrypto(False) # RPC. rpc: MoneroRPC = MoneroRPC("127.0.0.1", 28081) # Wallet. wallet: Wallet = Wallet(crypto, key) print("The private spend key is " + wallet.private_spend_key.hex() + ".") print("The private view key is " + wallet.private_view_key.hex() + ".") # WatchWallet. watch: WatchWallet = WatchWallet( crypto, rpc, wallet.private_view_key, wallet.public_spend_key, rpc.get_block_count() - 1, ) print("Please specify what account index to use. ") account: int = int(input()) print("Please specify what address index to use. ") address: int = int(input()) last: int = rpc.get_block_count() print("Please deposit to " + watch.new_address((account, address)).address + ".") spendable: Tuple[List[bytes], Dict[OutputIndex, OutputInfo]] available: int = 0