Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 5 additions & 2 deletions cardano_node_tests/tests/test_node_upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ def test_submit_tx(
* Submit the transaction to the upgraded node
* Wait for transaction to be included in a block
* Verify transaction was successfully submitted and processed
* Check expected balances after transaction submission
* Verify transaction inputs were spent
* Demonstrates backward compatibility of transaction format across versions/eras
"""
temp_template = common.get_test_id(cluster)
Expand Down Expand Up @@ -515,4 +515,7 @@ def test_submit_tx(
)

cluster.g_transaction.submit_tx_bare(tx_file=tx_file)
cluster.wait_for_new_block(2)

txins = cluster.g_transaction.view_tx_dict(tx_file=tx_file).get("inputs") or []
assert txins, "No inputs found in the transaction"
clusterlib_utils.check_txins_spent(cluster_obj=cluster, txins=txins)
12 changes: 6 additions & 6 deletions cardano_node_tests/tests/tests_plutus/spend_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,12 @@ def _build_spend_locked_txin( # noqa: C901
if not script_valid:
cluster_obj.g_transaction.submit_tx_bare(tx_file=tx_signed)

cluster_obj.wait_for_new_block(new_blocks=2)
# Check that the collateral UTxO was spent
try:
clusterlib_utils.check_txins_spent(cluster_obj=cluster_obj, txins=collateral_utxos)
except AssertionError:
issues.consensus_973.finish_test()

try:
cluster_obj.g_transaction.submit_tx_bare(tx_file=tx_signed)
except clusterlib.CLIError as exc:
Expand All @@ -308,11 +313,6 @@ def _build_spend_locked_txin( # noqa: C901
else:
pytest.fail("Transaction was not submitted successfully")

# Check that the collateral UTxO was spent
spent_collateral_utxo = cluster_obj.g_query.get_utxo(utxo=collateral_utxos)
if spent_collateral_utxo:
issues.consensus_973.finish_test()

assert (
cluster_obj.g_query.get_address_balance(dst_addr.address)
== dst_init_balance - collateral_utxos[0].amount
Expand Down
12 changes: 6 additions & 6 deletions cardano_node_tests/tests/tests_plutus/spend_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,12 @@ def _spend_locked_txin( # noqa: C901
if not script_valid:
cluster_obj.g_transaction.submit_tx_bare(tx_file=tx_signed)

cluster_obj.wait_for_new_block(new_blocks=2)
# Check that the collateral UTxO was spent
try:
clusterlib_utils.check_txins_spent(cluster_obj=cluster_obj, txins=collateral_utxos)
except AssertionError:
issues.consensus_973.finish_test()

try:
cluster_obj.g_transaction.submit_tx_bare(tx_file=tx_signed)
except clusterlib.CLIError as exc:
Expand All @@ -303,11 +308,6 @@ def _spend_locked_txin( # noqa: C901
else:
pytest.fail("Transaction was not submitted successfully")

# Check that the collateral UTxO was spent
spent_collateral_utxo = cluster_obj.g_query.get_utxo(utxo=collateral_utxos)
if spent_collateral_utxo:
issues.consensus_973.finish_test()

assert (
cluster_obj.g_query.get_address_balance(dst_addr.address)
== dst_init_balance - collateral_utxos[0].amount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,12 @@ def test_with_total_return_collateral(
issues.consensus_947.finish_test()
raise

cluster.wait_for_new_block(new_blocks=2)
# Check that the collateral UTxO was spent
try:
clusterlib_utils.check_txins_spent(cluster_obj=cluster, txins=collateral_utxos)
except AssertionError:
issues.consensus_973.finish_test()

try:
cluster.g_transaction.submit_tx_bare(
tx_file=tx_output_redeem.out_file.with_suffix(".signed")
Expand All @@ -217,11 +222,6 @@ def test_with_total_return_collateral(
else:
pytest.fail("Transaction was not submitted successfully")

# Check that collateral was taken
spent_collateral_utxo = cluster.g_query.get_utxo(utxo=collateral_utxos)
if spent_collateral_utxo:
issues.consensus_973.finish_test()

# Check that input UTxOs were not spent
assert cluster.g_query.get_utxo(utxo=tx_output_redeem.txins), "Payment UTxO was spent"
assert cluster.g_query.get_utxo(utxo=script_utxos), "Script UTxO was spent"
Expand Down Expand Up @@ -346,7 +346,12 @@ def test_collateral_with_tokens(
issues.consensus_947.finish_test()
raise

cluster.wait_for_new_block(new_blocks=2)
# Check that the collateral UTxO was spent
try:
clusterlib_utils.check_txins_spent(cluster_obj=cluster, txins=collateral_utxos)
except AssertionError:
issues.consensus_973.finish_test()

try:
cluster.g_transaction.submit_tx_bare(
tx_file=tx_output_redeem.out_file.with_suffix(".signed")
Expand All @@ -364,11 +369,6 @@ def test_collateral_with_tokens(
else:
pytest.fail("Transaction was not submitted successfully")

# Check that collateral was taken
spent_collateral_utxo = cluster.g_query.get_utxo(utxo=collateral_utxos)
if spent_collateral_utxo:
issues.consensus_973.finish_test()

# Check that input UTxOs were not spent
assert cluster.g_query.get_utxo(utxo=tx_output_redeem.txins), "Payment UTxO was spent"
assert cluster.g_query.get_utxo(utxo=script_utxos), "Script UTxO was spent"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,12 @@ def test_with_total_return_collateral(
raise
issues.consensus_947.finish_test()

cluster.wait_for_new_block(new_blocks=2)
# Check that the collateral UTxO was spent
try:
clusterlib_utils.check_txins_spent(cluster_obj=cluster, txins=collateral_utxos)
except AssertionError:
issues.consensus_973.finish_test()

try:
cluster.g_transaction.submit_tx_bare(tx_file=tx_signed_redeem)
except clusterlib.CLIError as exc:
Expand All @@ -178,11 +183,6 @@ def test_with_total_return_collateral(
else:
pytest.fail("Transaction was not submitted successfully")

# Check that the collateral UTxO was spent
spent_collateral_utxo = cluster.g_query.get_utxo(utxo=collateral_utxos)
if spent_collateral_utxo:
issues.consensus_973.finish_test()

# Check that the right amount of collateral was spent
dst_balance = cluster.g_query.get_address_balance(dst_addr.address)
assert dst_balance == dst_init_balance - redeem_cost.collateral, (
Expand Down Expand Up @@ -323,7 +323,12 @@ def test_collateral_with_tokens(
raise
issues.consensus_947.finish_test()

cluster.wait_for_new_block(new_blocks=2)
# Check that the collateral UTxO was spent
try:
clusterlib_utils.check_txins_spent(cluster_obj=cluster, txins=collateral_utxos)
except AssertionError:
issues.consensus_973.finish_test()

try:
cluster.g_transaction.submit_tx_bare(tx_file=tx_signed_redeem)
except clusterlib.CLIError as exc:
Expand All @@ -339,11 +344,6 @@ def test_collateral_with_tokens(
else:
pytest.fail("Transaction was not submitted successfully")

# Check that the collateral UTxO was spent
spent_collateral_utxo = cluster.g_query.get_utxo(utxo=collateral_utxos)
if spent_collateral_utxo:
issues.consensus_973.finish_test()

# Check that the right amount of collateral was spent and that the tokens were returned

txid_redeem = cluster.g_transaction.get_txid(tx_body_file=tx_output_redeem.out_file)
Expand Down
52 changes: 44 additions & 8 deletions cardano_node_tests/utils/clusterlib_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1585,17 +1585,53 @@ def cli_has(command: str) -> bool:


def check_txins_spent(
*, cluster_obj: clusterlib.ClusterLib, txins: list[clusterlib.UTXOData], wait_blocks: int = 2
*,
cluster_obj: clusterlib.ClusterLib,
txins: tp.Sequence[clusterlib.UTXOData | str],
wait_blocks: int | None = None,
attempts: int = 10,
) -> None:
"""Check that txins were spent."""
if wait_blocks > 0:
cluster_obj.wait_for_new_block(wait_blocks)
"""Wait until txins are spent, i.e. until the transactions spending them make it to the chain.

utxo_data = cluster_obj.g_query.get_utxo(utxo=txins)
The txins are checked right away, as the transactions may already be on chain. If some
of the txins are not spent yet, wait for new blocks and check again. Unlike
`submit_tx`, the transactions are not resubmitted.

if utxo_data:
msg = f"Some txins were not spent: {txins}"
raise AssertionError(msg)
Args:
cluster_obj: An instance of `clusterlib.ClusterLib`.
txins: Input UTxOs, as `clusterlib.UTXOData` records or `TxId#TxIx` strings.
wait_blocks: A number of new blocks to wait for before checking again
(default = `cluster_obj.confirm_blocks`).
attempts: Max number of checks after waiting for new blocks. With 0, check just once,
without waiting.

Raises:
AssertionError: If some of the txins were not spent in time.
"""
txins_str = [t if isinstance(t, str) else f"{t.utxo_hash}#{t.utxo_ix}" for t in txins]
if not txins_str:
return

wait_blocks = cluster_obj.confirm_blocks if wait_blocks is None else wait_blocks
if wait_blocks < 1:
msg = f"`wait_blocks` must be a positive number, got {wait_blocks}."
raise ValueError(msg)

unspent: list[clusterlib.UTXOData] = []
for r in range(attempts + 1):
if r > 0:
cluster_obj.wait_for_new_block(new_blocks=wait_blocks)

unspent = cluster_obj.g_query.get_utxo(txin=txins_str)
if not unspent:
return

unspent_str = sorted({f"{u.utxo_hash}#{u.utxo_ix}" for u in unspent})
msg = (
f"Some txins were not spent after waiting for {attempts * wait_blocks} blocks: "
f"{unspent_str}"
)
raise AssertionError(msg)


def create_reference_utxo(
Expand Down
17 changes: 14 additions & 3 deletions cardano_node_tests/utils/defragment_utxos.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

from cardano_clusterlib import clusterlib

from cardano_node_tests.utils import clusterlib_utils

LOGGER = logging.getLogger(__name__)


Expand All @@ -17,7 +19,6 @@ def defragment(
name_template: str = "",
) -> None:
"""Defragment address UTxOs."""
new_blocks = 3
name_template = f"{name_template}_" if name_template else ""

loop = 1
Expand All @@ -41,6 +42,7 @@ def defragment(

batch_size = min(100, utxos_len)
batch_num = 1
loop_txins: list[clusterlib.UTXOData] = []
for b in range(0, utxos_len, batch_size):
LOGGER.info(f"Defragmenting UTxOs: Running loop {loop}, batch {batch_num}")
batch = utxos[b : b + batch_size]
Expand All @@ -58,8 +60,17 @@ def defragment(
signing_key_files=[skey_file],
)
cluster_obj.g_transaction.submit_tx_bare(tx_file=tx_signed_file)
# A Tx is applied atomically, so it is enough to check a single txin per Tx.
# Checking all of them could exceed the command line length limit.
loop_txins.append(tx_output.txins[0])
batch_num += 1

LOGGER.info(f"Defragmenting UTxOs: Waiting for {new_blocks} new blocks after loop {loop}")
cluster_obj.wait_for_new_block(new_blocks=new_blocks)
LOGGER.info(
f"Defragmenting UTxOs: Waiting for the Txs of loop {loop} to make it to the chain"
)
try:
clusterlib_utils.check_txins_spent(cluster_obj=cluster_obj, txins=loop_txins)
except AssertionError:
# Defragmentation is best-effort, the next loop works with the current UTxOs
LOGGER.warning(f"Defragmenting UTxOs: Some Txs of loop {loop} didn't make it")
loop += 1
Loading