Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add submit and wait for transaction submission #528

Merged
merged 43 commits into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
d8e364c
add submit and wait
pdp2121 Feb 21, 2023
6d1ed3e
add tests and fix errors
pdp2121 Feb 22, 2023
328d9c9
fix snippets
pdp2121 Feb 24, 2023
d5c7419
support signed tx
pdp2121 Mar 2, 2023
f4c4176
Merge branch 'master' into add-submit-and-wait
pdp2121 Mar 2, 2023
022ead1
fix is_signed
pdp2121 Mar 2, 2023
5d4a0e0
update docs
pdp2121 Mar 3, 2023
e5132d3
add missing variable
pdp2121 Mar 3, 2023
5b0bb76
support blob
pdp2121 Mar 8, 2023
9276025
fix optional
pdp2121 Mar 8, 2023
bd399eb
increase ledger accept delay
pdp2121 Mar 9, 2023
214e298
Update snippets/multisign.py
pdp2121 Mar 20, 2023
5997c46
Update snippets/reliable_transaction_submission.py
pdp2121 Mar 20, 2023
7644c13
small updates
pdp2121 Mar 20, 2023
1141a8e
small doc fix
pdp2121 Mar 20, 2023
b08c19d
add positional args
pdp2121 Mar 20, 2023
6772a82
Merge branch 'master' into add-submit-and-wait
pdp2121 Mar 20, 2023
bf82159
Update snippets/multisign.py
pdp2121 Mar 22, 2023
0570613
test remove from dict
pdp2121 Mar 31, 2023
5a705f8
Merge branch 'add-submit-and-wait' of https://github.com/pdp2121/xrpl…
pdp2121 Mar 31, 2023
da1ac1c
Update xrpl/asyncio/transaction/reliable_submission.py
pdp2121 Mar 31, 2023
fe79767
remove predefined sequence
pdp2121 Mar 31, 2023
81125ee
Merge branch 'add-submit-and-wait' of https://github.com/pdp2121/xrpl…
pdp2121 Mar 31, 2023
ce51eec
Merge branch 'XRPLF:master' into add-submit-and-wait
pdp2121 Mar 31, 2023
05f20b0
add fail hard param
pdp2121 Mar 31, 2023
2b44c4b
fix for multisign
pdp2121 Mar 31, 2023
9634e8b
move is_signed to tx
pdp2121 Apr 11, 2023
7e6ef17
add changelog
pdp2121 Apr 11, 2023
8148a62
Merge branch 'master' into add-submit-and-wait
pdp2121 Apr 11, 2023
ef66a49
update changelog in unreleased
pdp2121 Apr 12, 2023
ec73e5f
Merge branch 'master' into add-submit-and-wait
pdp2121 Apr 12, 2023
3e15002
Update CHANGELOG.md
pdp2121 May 5, 2023
4d4f210
fix multisign condition
pdp2121 May 5, 2023
0c3ae7d
Merge branch 'add-submit-and-wait' of https://github.com/pdp2121/xrpl…
pdp2121 May 5, 2023
072ea83
Update xrpl/asyncio/transaction/reliable_submission.py
pdp2121 May 5, 2023
f5af074
docs fix for wallet variable
pdp2121 May 8, 2023
20ae956
Merge branch 'add-submit-and-wait' of https://github.com/pdp2121/xrpl…
pdp2121 May 8, 2023
d42e070
update fail hard docstring
pdp2121 May 9, 2023
f3f4dff
modify and add tests to is_signed
pdp2121 May 10, 2023
95bbf32
add blob methods
pdp2121 May 10, 2023
b067da2
Merge branch 'master' into add-submit-and-wait
pdp2121 May 10, 2023
51201c2
update comments
pdp2121 May 11, 2023
73d50e6
Merge branch 'add-submit-and-wait' of https://github.com/pdp2121/xrpl…
pdp2121 May 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions snippets/multisign.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@
from xrpl.clients import JsonRpcClient
from xrpl.models.requests import SubmitMultisigned
from xrpl.models.transactions import AccountSet, SignerEntry, SignerListSet
from xrpl.transaction import (
autofill,
autofill_and_sign,
multisign,
send_reliable_submission,
sign,
)
from xrpl.transaction import autofill, multisign, sign, submit_and_wait
from xrpl.utils import str_to_hex
from xrpl.wallet import generate_faucet_wallet

Expand All @@ -29,12 +23,9 @@
signer_quorum=2,
signer_entries=signer_entries,
)
signed_signer_list_set_tx = autofill_and_sign(signer_list_set_tx, master_wallet, client)

print("Constructed SignerListSet and submitting it to the ledger...")
signed_list_set_tx_response = send_reliable_submission(
signed_signer_list_set_tx, client
)
print("Constructing SignerListSet and submitting it to the ledger...")
pdp2121 marked this conversation as resolved.
Show resolved Hide resolved
signed_list_set_tx_response = submit_and_wait(signer_list_set_tx, master_wallet, client)
print("SignerListSet submitted, here's the response:")
print(signed_list_set_tx_response)

Expand Down
11 changes: 4 additions & 7 deletions snippets/partial_payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from xrpl.models.amounts import IssuedCurrencyAmount
from xrpl.models.requests import AccountLines
from xrpl.models.transactions import Payment, PaymentFlag, TrustSet
from xrpl.transaction import autofill_and_sign, send_reliable_submission
from xrpl.transaction import submit_and_wait
from xrpl.wallet import generate_faucet_wallet

# References
Expand All @@ -30,8 +30,7 @@
)

# Sign and autofill, then send transaction to the ledger
signed_trust_set_tx = autofill_and_sign(trust_set_tx, wallet2, client)
send_reliable_submission(signed_trust_set_tx, client)
submit_and_wait(trust_set_tx, wallet2, client)

# Both balances should be zero since nothing has been sent yet
print("Balances after trustline is claimed:")
Expand All @@ -51,8 +50,7 @@
)

# Sign and autofill, then send transaction to the ledger
signed_payment_tx = autofill_and_sign(payment_tx, wallet1, client)
payment_response = send_reliable_submission(signed_payment_tx, client)
payment_response = submit_and_wait(payment_tx, wallet1, client)
print(payment_response)

# Issuer (wallet1) should have -3840 FOO and destination (wallet2) should have 3840 FOO
Expand Down Expand Up @@ -86,8 +84,7 @@
)

# Sign and autofill, then send transaction to the ledger
signed_partial_payment_tx = autofill_and_sign(partial_payment_tx, wallet2, client)
partial_payment_response = send_reliable_submission(signed_partial_payment_tx, client)
partial_payment_response = submit_and_wait(partial_payment_tx, wallet2, client)
print(partial_payment_response)

# Tried sending 4000 of 3840 FOO -> wallet1 and wallet2 should have 0 FOO
Expand Down
9 changes: 3 additions & 6 deletions snippets/reliable_transaction_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from xrpl.clients import JsonRpcClient
from xrpl.models.requests import Tx
from xrpl.models.transactions import Payment
from xrpl.transaction import autofill_and_sign, send_reliable_submission
from xrpl.transaction import submit_and_wait
from xrpl.wallet import generate_faucet_wallet

# References:
Expand All @@ -30,11 +30,8 @@
destination=wallet2.classic_address,
)

# Sign and autofill the transaction (prepares it to be ready to submit)
signed_payment_tx = autofill_and_sign(payment_tx, wallet1, client)

# Submits transaction and waits for response (validated or rejected)
payment_response = send_reliable_submission(signed_payment_tx, client)
# Sign, autofill, submit transaction and waits for response (validated or rejected)
pdp2121 marked this conversation as resolved.
Show resolved Hide resolved
payment_response = submit_and_wait(payment_tx, wallet1, client)
print("Transaction was submitted")

# Create a Transaction request to see transaction
Expand Down
8 changes: 3 additions & 5 deletions snippets/send_escrow.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from xrpl.clients import JsonRpcClient
from xrpl.models.requests import AccountObjects
from xrpl.models.transactions import EscrowCreate, EscrowFinish
from xrpl.transaction import autofill_and_sign, send_reliable_submission
from xrpl.transaction.reliable_submission import submit_and_wait
from xrpl.utils import datetime_to_ripple_time
from xrpl.wallet import generate_faucet_wallet

Expand Down Expand Up @@ -37,8 +37,7 @@
finish_after=finish_after,
)

signed_create_tx = autofill_and_sign(create_tx, wallet1, client)
create_escrow_response = send_reliable_submission(signed_create_tx, client)
create_escrow_response = submit_and_wait(create_tx, wallet1, client)
print(create_escrow_response)

# Create an AccountObjects request and have the client call it to see if escrow exists
Expand All @@ -55,8 +54,7 @@
offer_sequence=create_escrow_response.result["Sequence"],
)

signed_finish_tx = autofill_and_sign(finish_tx, wallet1, client)
send_reliable_submission(signed_finish_tx, client)
submit_and_wait(finish_tx, wallet1, client)

# If escrow went through successfully, 1000000 exchanged
print("Balances of wallets after Escrow was sent:")
Expand Down
8 changes: 3 additions & 5 deletions snippets/set_regular_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from xrpl.account import get_balance
from xrpl.clients import JsonRpcClient
from xrpl.models.transactions import Payment, SetRegularKey
from xrpl.transaction import autofill_and_sign, send_reliable_submission
from xrpl.transaction import submit_and_wait
from xrpl.wallet import generate_faucet_wallet

# References
Expand All @@ -28,8 +28,7 @@
account=wallet1.classic_address, regular_key=regular_key_wallet.classic_address
)

signed_tx = autofill_and_sign(tx, wallet1, client)
set_regular_key_response = send_reliable_submission(signed_tx, client)
set_regular_key_response = submit_and_wait(tx, wallet1, client)

print("Response for successful SetRegularKey tx:")
print(set_regular_key_response)
Expand All @@ -42,8 +41,7 @@
amount="1000",
)

signed_payment = autofill_and_sign(payment, regular_key_wallet, client)
payment_response = send_reliable_submission(signed_payment, client)
payment_response = submit_and_wait(payment, regular_key_wallet, client)

print("Response for tx signed using Regular Key:")
print(payment_response)
Expand Down
74 changes: 74 additions & 0 deletions tests/integration/sugar/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
get_transaction_from_hash,
send_reliable_submission,
sign,
submit_and_wait,
)
from xrpl.asyncio.transaction import (
submit_transaction as submit_transaction_alias_async,
Expand Down Expand Up @@ -455,3 +456,76 @@ async def test_reliable_submission_no_last_ledger_sequence(self, client):
signed_payment_transaction = await sign(payment_transaction, WALLET)
with self.assertRaises(XRPLReliableSubmissionException):
await send_reliable_submission(signed_payment_transaction, client)


class TestSubmitAndWait(IntegrationTestCase):
@test_async_and_sync(
globals(),
[
"xrpl.transaction.submit_and_wait",
"xrpl.account.get_next_valid_seq_number",
"xrpl.ledger.get_fee",
],
)
async def test_submit_and_wait_simple(self, client):
WALLET.sequence = await get_next_valid_seq_number(ACCOUNT, client)
pdp2121 marked this conversation as resolved.
Show resolved Hide resolved
account_set = AccountSet(
account=ACCOUNT,
sequence=WALLET.sequence,
set_flag=SET_FLAG,
)
await accept_ledger_async()
response = await submit_and_wait(account_set, WALLET, client)
self.assertTrue(response.result["validated"])
self.assertEqual(response.result["meta"]["TransactionResult"], "tesSUCCESS")
self.assertTrue(response.is_successful())
self.assertEqual(response.result["Fee"], await get_fee(client))
WALLET.sequence += 1

@test_async_and_sync(
globals(),
[
"xrpl.transaction.submit_and_wait",
"xrpl.account.get_next_valid_seq_number",
"xrpl.ledger.get_fee",
],
)
async def test_submit_and_wait_payment(self, client):
WALLET.sequence = await get_next_valid_seq_number(ACCOUNT, client)
payment_dict = {
"account": ACCOUNT,
"sequence": WALLET.sequence,
"amount": "10",
"destination": DESTINATION,
}
payment_transaction = Payment.from_dict(payment_dict)
pdp2121 marked this conversation as resolved.
Show resolved Hide resolved
await accept_ledger_async()
response = await submit_and_wait(payment_transaction, WALLET, client)
self.assertTrue(response.result["validated"])
self.assertEqual(response.result["meta"]["TransactionResult"], "tesSUCCESS")
self.assertTrue(response.is_successful())
self.assertEqual(response.result["Fee"], await get_fee(client))
WALLET.sequence += 1

@test_async_and_sync(
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):
WALLET.sequence = await get_next_valid_seq_number(ACCOUNT, client)
payment_dict = {
"account": ACCOUNT,
"sequence": WALLET.sequence,
"last_ledger_sequence": await get_latest_validated_ledger_sequence(client),
"fee": "10",
"amount": "100",
"destination": DESTINATION,
}
payment_transaction = Payment.from_dict(payment_dict)
await accept_ledger_async()
with self.assertRaises(XRPLReliableSubmissionException):
await submit_and_wait(payment_transaction, WALLET, client)
2 changes: 2 additions & 0 deletions xrpl/asyncio/transaction/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from xrpl.asyncio.transaction.reliable_submission import (
XRPLReliableSubmissionException,
send_reliable_submission,
submit_and_wait,
)

__all__ = [
Expand All @@ -27,6 +28,7 @@
"sign",
"sign_and_submit",
"submit",
"submit_and_wait",
"submit_transaction",
"transaction_json_to_binary_codec_form",
"send_reliable_submission",
Expand Down
32 changes: 31 additions & 1 deletion xrpl/asyncio/transaction/reliable_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

from xrpl.asyncio.clients import Client
from xrpl.asyncio.ledger import get_latest_validated_ledger_sequence
from xrpl.asyncio.transaction.main import submit
from xrpl.asyncio.transaction.main import safe_sign_and_autofill_transaction, submit
from xrpl.clients import XRPLRequestFailureException
from xrpl.constants import XRPLException
from xrpl.models.requests import Tx
from xrpl.models.response import Response
from xrpl.models.transactions.transaction import Transaction
from xrpl.wallet.main import Wallet

_LEDGER_CLOSE_TIME: Final[int] = 1

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there plans to get rid of send_reliable_submission in xrpl-py 2.0?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe so, and it will be a breaking change. @JST5000 any ideas?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be ok with that. I created a ticket for it and updated our 2.0 release plan to include it.

Expand Down Expand Up @@ -113,3 +114,32 @@ async def send_reliable_submission(
return await _wait_for_final_transaction_outcome(
transaction_hash, client, prelim_result, 0
)


async def submit_and_wait(
pdp2121 marked this conversation as resolved.
Show resolved Hide resolved
transaction: Transaction,
pdp2121 marked this conversation as resolved.
Show resolved Hide resolved
wallet: Wallet,
pdp2121 marked this conversation as resolved.
Show resolved Hide resolved
client: Client,
check_fee: bool = True,
pdp2121 marked this conversation as resolved.
Show resolved Hide resolved
) -> Response:
"""
Signs a transaction (locally, without trusting external rippled nodes), submits,
and verifies that it has been included in a validated ledger (or has errored
/will not be included for some reason).
pdp2121 marked this conversation as resolved.
Show resolved Hide resolved
`See Reliable Transaction Submission
<https://xrpl.org/reliable-transaction-submission.html>`_

Args:
transaction: the transaction to be signed and submitted.
wallet: the wallet with which to sign the transaction.
client: the network client with which to submit the transaction.
check_fee: whether to check if the fee is higher than the expected transaction
type fee. Defaults to True.

Returns:
The response from the ledger.
"""
signed_transaction = await safe_sign_and_autofill_transaction(
transaction, wallet, client, check_fee
)
return await send_reliable_submission(signed_transaction, client)
6 changes: 5 additions & 1 deletion xrpl/transaction/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
submit_transaction,
)
from xrpl.transaction.multisign import multisign
from xrpl.transaction.reliable_submission import send_reliable_submission
from xrpl.transaction.reliable_submission import (
send_reliable_submission,
submit_and_wait,
)

__all__ = [
"autofill",
Expand All @@ -28,6 +31,7 @@
"sign",
"sign_and_submit",
"submit",
"submit_and_wait",
"submit_transaction",
"transaction_json_to_binary_codec_form",
"send_reliable_submission",
Expand Down
35 changes: 35 additions & 0 deletions xrpl/transaction/reliable_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
from xrpl.asyncio.transaction import (
send_reliable_submission as async_send_reliable_submission,
)
from xrpl.asyncio.transaction import submit_and_wait as async_submit_and_wait
from xrpl.clients.sync_client import SyncClient
from xrpl.models.response import Response
from xrpl.models.transactions.transaction import Transaction
from xrpl.wallet.main import Wallet


def send_reliable_submission(transaction: Transaction, client: SyncClient) -> Response:
Expand All @@ -30,3 +32,36 @@ def send_reliable_submission(transaction: Transaction, client: SyncClient) -> Re
The response from a validated ledger.
"""
return asyncio.run(async_send_reliable_submission(transaction, client))


def submit_and_wait(
transaction: Transaction,
wallet: Wallet,
client: SyncClient,
check_fee: bool = True,
) -> Response:
"""
Signs a transaction (locally, without trusting external rippled nodes), submits,
and verifies that it has been included in a validated ledger (or has errored
/will not be included for some reason).
`See Reliable Transaction Submission
<https://xrpl.org/reliable-transaction-submission.html>`_
pdp2121 marked this conversation as resolved.
Show resolved Hide resolved

Args:
transaction: the transaction to be signed and submitted.
wallet: the wallet with which to sign the transaction.
client: the network client with which to submit the transaction.
check_fee: whether to check if the fee is higher than the expected transaction
type fee. Defaults to True.

Returns:
The response from the ledger.
"""
return asyncio.run(
async_submit_and_wait(
transaction,
wallet,
client,
check_fee,
)
)