|
1 | 1 | """Tests for stake address registration.""" |
2 | 2 |
|
3 | 3 | import logging |
| 4 | +import pathlib as pl |
4 | 5 |
|
5 | 6 | import allure |
6 | 7 | import pytest |
@@ -668,3 +669,141 @@ def _build_dereg() -> clusterlib.TxRawOutput: |
668 | 669 | ) |
669 | 670 | err_msg = str(excinfo.value) |
670 | 671 | 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