Skip to content

Commit

Permalink
Merge branch 'master' into dependabot/pip/pycryptodome-3.18.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mvadari authored Jun 12, 2023
2 parents f35a380 + 383957a commit 5fd783b
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 40 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added:
- Added `submit_and_wait` to sign (if needed), autofill, submit a transaction and wait for its final outcome
- `submit` and `send_reliable_submission` now accept an optional boolean param `fail_hard` (if `True` halt the submission if it's not immediately validated)
- Added sidechain devnet support to faucet generation

### Changed:
- Allowed keypairs.sign to take a hex string in addition to bytes

### Fixed:
- Refactored `does_account_exist` and `get_balance` to avoid deprecated methods and use `ledger_index` parameter
- Fixed crashes in the SignerListSet validation
- Improved error messages in `send_reliable_submission`
- Better error handling in reliable submission

### Removed:
- RPCs and utils related to the old sidechain design
Expand Down
23 changes: 16 additions & 7 deletions tests/integration/sugar/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,6 @@ class TestSubmitAndWait(IntegrationTestCase):
globals(),
[
"xrpl.transaction.submit_and_wait",
"xrpl.account.get_next_valid_seq_number",
"xrpl.ledger.get_fee",
],
)
Expand All @@ -367,7 +366,6 @@ async def test_submit_and_wait_simple(self, client):
globals(),
[
"xrpl.transaction.submit_and_wait",
"xrpl.account.get_next_valid_seq_number",
"xrpl.ledger.get_fee",
],
)
Expand All @@ -390,7 +388,6 @@ async def test_submit_and_wait_payment(self, client):
[
"xrpl.transaction.autofill_and_sign",
"xrpl.transaction.submit_and_wait",
"xrpl.account.get_next_valid_seq_number",
"xrpl.ledger.get_fee",
],
)
Expand All @@ -416,9 +413,7 @@ async def test_submit_and_wait_signed(self, client):
[
"xrpl.transaction.autofill_and_sign",
"xrpl.transaction.submit_and_wait",
"xrpl.account.get_next_valid_seq_number",
"xrpl.ledger.get_fee",
"xrpl.core.binarycodec.main.encode",
],
)
async def test_submit_and_wait_blob(self, client):
Expand All @@ -443,18 +438,32 @@ async def test_submit_and_wait_blob(self, client):
globals(),
[
"xrpl.transaction.submit_and_wait",
"xrpl.account.get_next_valid_seq_number",
"xrpl.ledger.get_latest_validated_ledger_sequence",
],
)
async def test_submit_and_wait_last_ledger_expiration(self, client):
payment_transaction = Payment(
account=ACCOUNT,
last_ledger_sequence=await get_latest_validated_ledger_sequence(client),
fee="10",
amount="100",
destination=DESTINATION,
)
await accept_ledger_async(delay=1)
with self.assertRaises(XRPLReliableSubmissionException):
await submit_and_wait(payment_transaction, client, WALLET)

@test_async_and_sync(
globals(),
[
"xrpl.transaction.submit_and_wait",
],
)
async def test_submit_and_wait_tec_error(self, client):
payment_transaction = Payment(
account=ACCOUNT,
amount=xrp_to_drops(10**10), # tecINSUFFICIENT_FUNDS
destination=DESTINATION,
)
await accept_ledger_async(delay=1)
with self.assertRaises(XRPLReliableSubmissionException):
await submit_and_wait(payment_transaction, client, WALLET)
91 changes: 61 additions & 30 deletions tests/integration/sugar/test_wallet.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import asyncio
import time
from threading import Thread

from tests.integration.integration_test_case import IntegrationTestCase
from tests.integration.it_utils import submit_transaction_async, test_async_and_sync
from tests.integration.reusable_values import WALLET
from tests.integration.it_utils import submit_transaction_async
from xrpl.asyncio.clients import AsyncJsonRpcClient, AsyncWebsocketClient
from xrpl.asyncio.wallet import generate_faucet_wallet
from xrpl.clients import JsonRpcClient, WebsocketClient
from xrpl.core.addresscodec import classic_address_to_xaddress
from xrpl.models.requests import AccountInfo
from xrpl.models.transactions import Payment
from xrpl.wallet import generate_faucet_wallet as sync_generate_faucet_wallet
Expand Down Expand Up @@ -56,13 +56,34 @@ async def generate_faucet_wallet_and_fund_again(self, client, faucet_host=None):


class TestWallet(IntegrationTestCase):
@test_async_and_sync(
globals(),
["xrpl.wallet.generate_faucet_wallet"],
num_retries=5,
use_testnet=True,
)
async def test_generate_faucet_wallet_rel_sub(self, client):
async def test_run_faucet_tests(self):
# run all the tests that start with `_test_` in parallel
def run_test(test_name):
with self.subTest(method=test_name):
method = getattr(self, test_name) # get the test with the given name
if asyncio.iscoroutinefunction(method): # is async
asyncio.run(method())
else: # is sync
method()

# get all the test methods starting with `_parallel_test_`
# (the ones to run in parallel)
test_methods = [
method for method in dir(self) if method.startswith("_parallel_test_")
]

# run all the tests in parallel
processes = []
for method in test_methods:
process = Thread(target=run_test, args=(method,))
process.start()
processes.append(process)
for process in processes:
process.join()

# ensure that the wallet creation has been validated and the account actually exists
async def _parallel_test_generate_faucet_wallet_rel_sub(self):
client = JsonRpcClient("https://s.devnet.rippletest.net:51234")
destination = await generate_faucet_wallet(client)
wallet = await generate_faucet_wallet(client)
# TODO: refactor so this actually waits for validation
Expand All @@ -78,51 +99,65 @@ async def test_generate_faucet_wallet_rel_sub(self, client):
)
self.assertTrue(response.is_successful())

async def test_generate_faucet_wallet_testnet_async_websockets(self):
async with AsyncWebsocketClient(
"wss://s.altnet.rippletest.net:51233"
) as client:
await generate_faucet_wallet_and_fund_again(self, client)
# Custom host tests

async def test_generate_faucet_wallet_custom_host_async_websockets(self):
async def _parallel_test_generate_faucet_wallet_custom_host_async_websockets(self):
async with AsyncWebsocketClient(
"wss://s.devnet.rippletest.net:51233/"
"wss://s.devnet.rippletest.net:51233"
) as client:
await generate_faucet_wallet_and_fund_again(
self, client, "faucet.devnet.rippletest.net"
)

async def test_generate_faucet_wallet_custom_host_async_json_rpc(self):
client = AsyncJsonRpcClient("https://s.devnet.rippletest.net:51234/")
async def _parallel_test_generate_faucet_wallet_custom_host_async_json_rpc(self):
client = AsyncJsonRpcClient("https://s.devnet.rippletest.net:51234")
await generate_faucet_wallet_and_fund_again(
self, client, "faucet.devnet.rippletest.net"
)

def test_generate_faucet_wallet_custom_host_sync_websockets(self):
with WebsocketClient("wss://s.devnet.rippletest.net:51233/") as client:
def _parallel_test_generate_faucet_wallet_custom_host_sync_websockets(self):
with WebsocketClient("wss://s.devnet.rippletest.net:51233") as client:
sync_generate_faucet_wallet_and_fund_again(
self, client, "faucet.devnet.rippletest.net"
)

def test_generate_faucet_wallet_custom_host_sync_json_rpc(self):
client = JsonRpcClient("https://s.devnet.rippletest.net:51234/")
def _parallel_test_generate_faucet_wallet_custom_host_sync_json_rpc(self):
client = JsonRpcClient("https://s.devnet.rippletest.net:51234")
sync_generate_faucet_wallet_and_fund_again(
self, client, "faucet.devnet.rippletest.net"
)

async def test_generate_faucet_wallet_devnet_async_websockets(self):
# Network tests

async def _parallel_test_generate_faucet_wallet_testnet_async_websockets(self):
async with AsyncWebsocketClient(
"wss://s.altnet.rippletest.net:51233"
) as client:
await generate_faucet_wallet_and_fund_again(self, client)

async def _parallel_test_generate_faucet_wallet_devnet_async_websockets(self):
async with AsyncWebsocketClient(
"wss://s.devnet.rippletest.net:51233"
) as client:
await generate_faucet_wallet_and_fund_again(self, client)

async def test_generate_faucet_wallet_amm_devnet_async_websockets(self):
async def _parallel_test_generate_faucet_wallet_amm_devnet_async_websockets(self):
async with AsyncWebsocketClient(
"wss://amm.devnet.rippletest.net:51233"
) as client:
await generate_faucet_wallet_and_fund_again(self, client)

async def test_generate_faucet_wallet_hooks_v3_testnet_async_websockets(self):
async def _parallel_test_generate_faucet_wallet_sidechain_devnet_async_websockets(
self,
):
async with AsyncWebsocketClient(
"wss://sidechain-net1.devnet.rippletest.net:51233"
) as client:
await generate_faucet_wallet_and_fund_again(self, client)

async def _parallel_test_generate_faucet_wallet_hooks_v3_testnet_async_websockets(
self,
):
async with AsyncWebsocketClient(
"wss://hooks-testnet-v3.xrpl-labs.com"
) as client:
Expand Down Expand Up @@ -178,7 +213,3 @@ async def test_fund_given_wallet_hooks_v3_testnet_async_websockets(self):
)
new_balance = int(new_result.result["account_data"]["Balance"])
self.assertTrue(new_balance > balance)

def test_wallet_get_xaddress(self):
expected = classic_address_to_xaddress(WALLET.classic_address, None, False)
self.assertEqual(WALLET.get_xaddress(), expected)
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@
_TEST_FAUCET_URL,
get_faucet_url,
)
from xrpl.core.addresscodec import classic_address_to_xaddress
from xrpl.wallet import Wallet


class TestWallet(TestCase):
def test_wallet_get_xaddress(self):
wallet = Wallet.create()
expected = classic_address_to_xaddress(wallet.classic_address, None, False)
self.assertEqual(wallet.get_xaddress(), expected)

def test_get_faucet_wallet_dev(self):
json_client_url = "https://s.devnet.rippletest.net:51234"
ws_client_url = "wss://s.devnet.rippletest.net/"
Expand Down
8 changes: 5 additions & 3 deletions xrpl/asyncio/transaction/reliable_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ async def _wait_for_final_transaction_outcome(
result = transaction_response.result
if "validated" in result and result["validated"]:
# result is in a validated ledger, outcome is final
return_code = result["meta"]["TransactionResult"]
if return_code != "tesSUCCESS":
raise XRPLReliableSubmissionException(f"Transaction failed: {return_code}")
return transaction_response

# outcome is not yet final
Expand Down Expand Up @@ -107,9 +110,8 @@ async def send_reliable_submission(
submit_response = await submit(transaction, client, fail_hard=fail_hard)
prelim_result = submit_response.result["engine_result"]
if prelim_result[0:3] == "tem":
raise XRPLReliableSubmissionException(
submit_response.result["engine_result_message"]
)
error_message = submit_response.result["engine_result_message"]
raise XRPLReliableSubmissionException(f"{prelim_result}: {error_message}")

return await _wait_for_final_transaction_outcome(
transaction_hash, client, prelim_result, transaction.last_ledger_sequence
Expand Down
10 changes: 10 additions & 0 deletions xrpl/asyncio/wallet/wallet_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
_HOOKS_V3_TEST_FAUCET_URL: Final[
str
] = "https://hooks-testnet-v3.xrpl-labs.com/accounts"
_SIDECHAIN_DEVNET_FAUCET_URL: Final[
str
] = "https://sidechain-faucet.devnet.rippletest.net/accounts"

_TIMEOUT_SECONDS: Final[int] = 40

Expand Down Expand Up @@ -116,6 +119,13 @@ def get_faucet_url(url: str, faucet_host: Optional[str] = None) -> str:
return _TEST_FAUCET_URL
if "amm" in url: # amm devnet
return _AMM_DEV_FAUCET_URL
if "sidechain-net1" in url: # sidechain devnet
return _SIDECHAIN_DEVNET_FAUCET_URL
elif "sidechain-net2" in url: # sidechain issuing chain devnet
raise XRPLFaucetException(
"Cannot fund an account on an issuing chain. Accounts must be created via "
"the bridge."
)
if "devnet" in url: # devnet
return _DEV_FAUCET_URL
raise XRPLFaucetException(
Expand Down

0 comments on commit 5fd783b

Please sign in to comment.