Skip to content

Commit 1e663ff

Browse files
committed
feat(tests): add incomplete multisig stake addr registration test
- Add test for registering a multisig stake address while missing either a script or a signing key. - Expect failure in both scenarios. - Scenario 1: Build a Tx with the registration certificate, without passing the script to the transaction build command. - Scenario 2: One signing key is missing when witnessing the Tx.
1 parent cbab025 commit 1e663ff

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed

cardano_node_tests/tests/test_addr_registration.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Tests for stake address registration."""
22

33
import logging
4+
import pathlib as pl
45

56
import allure
67
import pytest
@@ -668,3 +669,141 @@ def _build_dereg() -> clusterlib.TxRawOutput:
668669
)
669670
err_msg = str(excinfo.value)
670671
assert "StakeKeyNotRegisteredDELEG" in err_msg, err_msg
672+
673+
@allure.link(helpers.get_vcs_link())
674+
@common.PARAM_USE_BUILD_CMD
675+
@pytest.mark.parametrize("issue", ("missing_script", "missing_skey"))
676+
@pytest.mark.smoke
677+
@pytest.mark.testnets
678+
def test_incomplete_multisig(
679+
self,
680+
cluster: clusterlib.ClusterLib,
681+
pool_users: list[clusterlib.PoolUser],
682+
use_build_cmd: bool,
683+
issue: str,
684+
):
685+
"""Try to register a multisig stake address while missing either a script or an skey.
686+
687+
Expect failure.
688+
689+
* Create a multisig script to be used as stake credentials
690+
* Create stake address registration certificate
691+
* Create a Tx for the registration certificate
692+
* Scenario1: Build a Tx with the registration certificate, without passing the the script
693+
to the transaction build command
694+
* Scenario 2: One skey is missing when witnesing the Tx
695+
* Incrementally sign the Tx and submit the registration certificate
696+
* Check the expected failure
697+
"""
698+
temp_template = common.get_test_id(cluster)
699+
payment_addr = pool_users[0].payment
700+
701+
# Create a multisig script to be used as stake credentials
702+
stake_key_recs = [
703+
cluster.g_stake_address.gen_stake_key_pair(key_name=f"{temp_template}_sig_{i}")
704+
for i in range(1, 6)
705+
]
706+
multisig_script = clusterlib_utils.build_stake_multisig_script(
707+
cluster_obj=cluster,
708+
script_name=temp_template,
709+
script_type_arg=clusterlib.MultiSigTypeArgs.ALL,
710+
stake_vkey_files=[r.vkey_file for r in stake_key_recs],
711+
)
712+
713+
# Create stake address registration cert
714+
address_deposit = common.get_conway_address_deposit(cluster_obj=cluster)
715+
716+
stake_addr_reg_cert_file = cluster.g_stake_address.gen_stake_addr_registration_cert(
717+
addr_name=f"{temp_template}_addr0",
718+
deposit_amt=address_deposit,
719+
stake_script_file=multisig_script,
720+
)
721+
722+
signing_key_files = [payment_addr.skey_file, *[r.skey_file for r in stake_key_recs]]
723+
724+
def _submit_tx(
725+
name_template: str,
726+
tx_files: clusterlib.TxFiles | None = None,
727+
complex_certs: list[clusterlib.ComplexCert] | tuple[()] = (),
728+
signing_key_files: list[pl.Path] | tuple[()] = (),
729+
) -> clusterlib.TxRawOutput:
730+
witness_len = len(signing_key_files)
731+
732+
if use_build_cmd:
733+
tx_output = cluster.g_transaction.build_tx(
734+
src_address=payment_addr.address,
735+
tx_name=name_template,
736+
tx_files=tx_files,
737+
complex_certs=complex_certs,
738+
fee_buffer=2_000_000,
739+
witness_override=witness_len,
740+
)
741+
else:
742+
fee = cluster.g_transaction.calculate_tx_fee(
743+
src_address=payment_addr.address,
744+
tx_name=name_template,
745+
tx_files=tx_files,
746+
complex_certs=complex_certs,
747+
witness_count_add=witness_len,
748+
)
749+
tx_output = cluster.g_transaction.build_raw_tx(
750+
src_address=payment_addr.address,
751+
tx_name=name_template,
752+
tx_files=tx_files,
753+
complex_certs=complex_certs,
754+
fee=fee,
755+
)
756+
757+
# Create witness file for each key
758+
witness_files = [
759+
cluster.g_transaction.witness_tx(
760+
tx_body_file=tx_output.out_file,
761+
witness_name=f"{name_template}_skey{idx}",
762+
signing_key_files=[skey],
763+
)
764+
for idx, skey in enumerate(signing_key_files, start=1)
765+
]
766+
767+
# Sign TX using witness files
768+
tx_witnessed_file = cluster.g_transaction.assemble_tx(
769+
tx_body_file=tx_output.out_file,
770+
witness_files=witness_files,
771+
tx_name=name_template,
772+
)
773+
774+
# Submit signed TX
775+
cluster.g_transaction.submit_tx(tx_file=tx_witnessed_file, txins=tx_output.txins)
776+
777+
return tx_output
778+
779+
# Scenario1: Build a Tx with the registration certificate, without passing the the script
780+
# to the transaction build command.
781+
if issue == "missing_script":
782+
tx_files_script = clusterlib.TxFiles(certificate_files=[stake_addr_reg_cert_file])
783+
with pytest.raises(clusterlib.CLIError) as excinfo:
784+
_submit_tx(
785+
name_template=temp_template,
786+
tx_files=tx_files_script,
787+
signing_key_files=signing_key_files,
788+
)
789+
err_msg = str(excinfo.value)
790+
assert "MissingScriptWitnessesUTXOW" in err_msg, err_msg
791+
792+
# Scenario2: One skey is missing when witnesing the Tx
793+
elif issue == "missing_skey":
794+
reg_cert_script = clusterlib.ComplexCert(
795+
certificate_file=stake_addr_reg_cert_file,
796+
script_file=multisig_script,
797+
)
798+
with pytest.raises(clusterlib.CLIError) as excinfo:
799+
_submit_tx(
800+
name_template=temp_template,
801+
complex_certs=[reg_cert_script],
802+
signing_key_files=signing_key_files[:-1],
803+
)
804+
err_msg = str(excinfo.value)
805+
assert "ScriptWitnessNotValidatingUTXOW" in err_msg, err_msg
806+
807+
else:
808+
err = f"Invalid issue: {issue}"
809+
raise ValueError(err)

0 commit comments

Comments
 (0)