def _try_to_get_next_seq(address: str, client: Client) -> Optional[int]: try: return get_next_valid_seq_number(address, client) except XRPLRequestFailureException as e: if e.error == "actNotFound": # faucet gen has not fully gone through, try again return None else: # some other error raise
def generate_faucet_wallet(client: Client, debug: bool = False) -> Wallet: """ Generates a random wallet and funds it using the XRPL Testnet Faucet. Args: client: the network client used to make network calls. debug: Whether to print debug information as it creates the wallet. Returns: A Wallet on the testnet that contains some amount of XRP. Raises: XRPLFaucetException: if an address could not be funded with the faucet. """ timeout_seconds = 40 wallet = Wallet.create() address = wallet.classic_address # The faucet *can* be flakey... by printing info about this it's easier to # understand if tests are actually failing, or if it was just a faucet failure. if debug: print("Attempting to fund address {}".format(address)) # Balance prior to asking for more funds try: starting_balance = get_balance(address, client) except XRPLRequestFailureException: starting_balance = 0 # Ask the faucet to send funds to the given address post(url=FAUCET_URL, json={"destination": address}) # Wait for the faucet to fund our account or until timeout # Waits one second checks if balance has changed # If balance doesn't change it will attempt again until timeout_seconds for _ in range(timeout_seconds): sleep(1) try: current_balance = get_balance(address, client) except XRPLRequestFailureException: current_balance = 0 # If our current balance has changed, then return if starting_balance != current_balance: if debug: print("Faucet fund successful.") wallet.next_sequence_num = get_next_valid_seq_number( wallet.classic_address, client ) return wallet # Otherwise, timeout before balance updates raise XRPLFaucetException( "Unable to fund address with faucet after waiting {} seconds".format( timeout_seconds ) )
def _autofill_transaction(transaction: Transaction, client: Client) -> Transaction: transaction_json = transaction.to_dict() if "sequence" not in transaction_json: sequence = get_next_valid_seq_number(transaction_json["account"], client) transaction_json["sequence"] = sequence if "fee" not in transaction_json: transaction_json["fee"] = _calculate_fee_per_transaction_type( transaction, client ) if "last_ledger_sequence" not in transaction_json: ledger_sequence = get_latest_validated_ledger_sequence(client) transaction_json["last_ledger_sequence"] = ledger_sequence + _LEDGER_OFFSET return Transaction.from_dict(transaction_json)
def test_last_ledger_expiration(self): WALLET.next_sequence_num = get_next_valid_seq_number(ACCOUNT, JSON_RPC_CLIENT) payment_dict = { "account": ACCOUNT, "sequence": WALLET.next_sequence_num, "last_ledger_sequence": WALLET.next_sequence_num + 1, "fee": "10000", "amount": "100", "destination": DESTINATION, } payment_transaction = Payment.from_dict(payment_dict) with self.assertRaises(LastLedgerSequenceExpiredException): send_reliable_submission(payment_transaction, WALLET, JSON_RPC_CLIENT)
def test_simple(self): WALLET.next_sequence_num = get_next_valid_seq_number(ACCOUNT, JSON_RPC_CLIENT) account_set = AccountSet( account=ACCOUNT, fee=FEE, sequence=WALLET.next_sequence_num, set_flag=SET_FLAG, last_ledger_sequence=WALLET.next_sequence_num + 10, ) response = send_reliable_submission(account_set, WALLET, JSON_RPC_CLIENT) self.assertTrue(response.result["validated"]) self.assertEqual(response.result["meta"]["TransactionResult"], "tesSUCCESS") self.assertTrue(response.is_successful())
def test_reliable_submission_bad_transaction(self): WALLET.next_sequence_num = get_next_valid_seq_number(ACCOUNT, JSON_RPC_CLIENT) payment_dict = { "account": ACCOUNT, "last_ledger_sequence": WALLET.next_sequence_num + 20, "fee": "10", "amount": "100", "destination": DESTINATION, } payment_transaction = Payment.from_dict(payment_dict) signed_payment_transaction = safe_sign_transaction(payment_transaction, WALLET) with self.assertRaises(XRPLRequestFailureException): send_reliable_submission(signed_payment_transaction, JSON_RPC_CLIENT) WALLET.next_sequence_num -= 1
def test_reliable_submission_simple(self): WALLET.next_sequence_num = get_next_valid_seq_number(ACCOUNT, JSON_RPC_CLIENT) account_set = AccountSet( account=ACCOUNT, sequence=WALLET.next_sequence_num, set_flag=SET_FLAG, ) signed_account_set = safe_sign_and_autofill_transaction( account_set, WALLET, JSON_RPC_CLIENT ) response = send_reliable_submission(signed_account_set, JSON_RPC_CLIENT) self.assertTrue(response.result["validated"]) self.assertEqual(response.result["meta"]["TransactionResult"], "tesSUCCESS") self.assertTrue(response.is_successful()) WALLET.next_sequence_num += 1
def test_reliable_submission_last_ledger_expiration(self): WALLET.sequence = get_next_valid_seq_number(ACCOUNT, JSON_RPC_CLIENT) payment_dict = { "account": ACCOUNT, "sequence": WALLET.sequence, "last_ledger_sequence": WALLET.sequence + 1, "fee": "10000", "amount": "100", "destination": DESTINATION, } payment_transaction = Payment.from_dict(payment_dict) signed_payment_transaction = safe_sign_and_autofill_transaction( payment_transaction, WALLET, JSON_RPC_CLIENT) with self.assertRaises(XRPLReliableSubmissionException): send_reliable_submission(signed_payment_transaction, JSON_RPC_CLIENT) WALLET.sequence -= 1
def test_payment(self): WALLET.next_sequence_num = get_next_valid_seq_number(ACCOUNT, JSON_RPC_CLIENT) payment_dict = { "account": ACCOUNT, "sequence": WALLET.next_sequence_num, "last_ledger_sequence": WALLET.next_sequence_num + 10, "fee": "10000", "amount": "10", "destination": DESTINATION, } payment_transaction = Payment.from_dict(payment_dict) response = send_reliable_submission( payment_transaction, WALLET, JSON_RPC_CLIENT ) self.assertTrue(response.result["validated"]) self.assertEqual(response.result["meta"]["TransactionResult"], "tesSUCCESS") self.assertTrue(response.is_successful())
def test_reliable_submission_payment(self): WALLET.sequence = get_next_valid_seq_number(ACCOUNT, JSON_RPC_CLIENT) payment_dict = { "account": ACCOUNT, "sequence": WALLET.sequence, "amount": "10", "destination": DESTINATION, } payment_transaction = Payment.from_dict(payment_dict) signed_payment_transaction = safe_sign_and_autofill_transaction( payment_transaction, WALLET, JSON_RPC_CLIENT) response = send_reliable_submission(signed_payment_transaction, JSON_RPC_CLIENT) self.assertTrue(response.result["validated"]) self.assertEqual(response.result["meta"]["TransactionResult"], "tesSUCCESS") self.assertTrue(response.is_successful()) self.assertEqual(response.result["Fee"], get_fee(JSON_RPC_CLIENT)) WALLET.sequence += 1