diff --git a/cardano_node_tests/tests/reqs_conway.py b/cardano_node_tests/tests/reqs_conway.py index dbaa4e986..06b0f1144 100644 --- a/cardano_node_tests/tests/reqs_conway.py +++ b/cardano_node_tests/tests/reqs_conway.py @@ -124,6 +124,13 @@ def __r(id: str) -> requirements.Req: cip082 = __r("CIP082") cip083 = __r("CIP083") +cip085 = __r("CIP085") +cip086 = __r("CIP086") +cip087 = __r("CIP087") +cip088 = __r("CIP088") +cip089 = __r("CIP089") +cip090 = __r("CIP090") + # https://github.com/IntersectMBO/cardano-test-plans/blob/main/docs/user-stories/02-cardano-cli.md cli001 = __r("CLI001") cli002 = __r("CLI002") diff --git a/cardano_node_tests/tests/tests_conway/test_committee.py b/cardano_node_tests/tests/tests_conway/test_committee.py index 468ca2991..644b27e63 100644 --- a/cardano_node_tests/tests/tests_conway/test_committee.py +++ b/cardano_node_tests/tests/tests_conway/test_committee.py @@ -386,6 +386,7 @@ def test_add_rm_committee_members( # noqa: C901 - check that it's not possible to vote on enacted action * check output of votes and action `view` commands + * check deposit is returned to user reward account after enactment """ # pylint: disable=too-many-locals,too-many-statements,too-many-branches cluster, governance_data = cluster_lock_governance @@ -394,6 +395,10 @@ def test_add_rm_committee_members( # noqa: C901 if conway_common.is_in_bootstrap(cluster_obj=cluster): pytest.skip("Cannot run during bootstrap period.") + init_return_account_balance = cluster.g_query.get_stake_addr_info( + pool_user_lg.stake.address + ).reward_account_balance + deposit_amt = cluster.conway_genesis["govActionDeposit"] # Check if total delegated stake is below the threshold. This can be used to check that @@ -984,6 +989,18 @@ def _check_rem_state(gov_state: tp.Dict[str, tp.Any]): governance_utils.check_vote_view(cluster_obj=cluster, vote_data=voted_votes_rem.spo[0]) reqc.cip067.success() + reqc.cip034en.start(url=helpers.get_vcs_link()) + enact_deposit_returned = cluster.g_query.get_stake_addr_info( + pool_user_lg.stake.address + ).reward_account_balance + + assert ( + enact_deposit_returned + == init_return_account_balance + + deposit_amt * 2 # 2 * deposit_amt for add and rem actions + ), "Incorrect return account balance" + reqc.cip034en.success() + if xfail_ledger_4001_msgs: ledger_4001 = issues.ledger_4001.copy() ledger_4001.message = "; ".join(xfail_ledger_4001_msgs) diff --git a/cardano_node_tests/tests/tests_conway/test_drep.py b/cardano_node_tests/tests/tests_conway/test_drep.py index 474014333..1c46f7961 100644 --- a/cardano_node_tests/tests/tests_conway/test_drep.py +++ b/cardano_node_tests/tests/tests_conway/test_drep.py @@ -1,12 +1,16 @@ """Tests for Conway governance DRep functionality.""" +import binascii import dataclasses +import hashlib +import json import logging import pathlib as pl import pickle import typing as tp import allure +import cbor2 import pytest from _pytest.fixtures import FixtureRequest from cardano_clusterlib import clusterlib @@ -23,6 +27,7 @@ from cardano_node_tests.utils import dbsync_utils from cardano_node_tests.utils import governance_utils from cardano_node_tests.utils import helpers +from cardano_node_tests.utils import submit_api from cardano_node_tests.utils import submit_utils from cardano_node_tests.utils.versions import VERSIONS @@ -251,6 +256,49 @@ def custom_drep_wp( class TestDReps: """Tests for DReps.""" + @allure.link(helpers.get_vcs_link()) + @pytest.mark.testnets + @pytest.mark.smoke + def test_drep_id_is_blake2b_224_of_drep_vkey( + self, + cluster: clusterlib.ClusterLib, + ): + """Test proper drep id is being generated. + + * Register a drep + * Hash drep vkey using blake2b_224 + * Check drep ID generated from cli is same as blake2b_224 hash of drep vkey + """ + reqc.cip085.start(url=helpers.get_vcs_link()) + temp_template = common.get_test_id(cluster) + drep_metadata_url = "https://www.the-drep.com" + drep_metadata_file = f"{temp_template}_drep_metadata.json" + drep_metadata_content = {"name": "The DRep", "ranking": "uno"} + helpers.write_json(out_file=drep_metadata_file, content=drep_metadata_content) + drep_metadata_hash = cluster.g_conway_governance.drep.get_metadata_hash( + drep_metadata_file=drep_metadata_file + ) + # Get a drep registration record + reg_drep = governance_utils.get_drep_reg_record( + cluster_obj=cluster, + name_template=temp_template, + drep_metadata_url=drep_metadata_url, + drep_metadata_hash=drep_metadata_hash, + ) + vkey_file_path = reg_drep.key_pair.vkey_file + # Get drep vkey from vkey file + with open(vkey_file_path) as vkey_file: + vkey_file_json = json.loads(vkey_file.read()) + cbor_hex = vkey_file_json["cborHex"] + cbor_binary = binascii.unhexlify(cbor_hex) + decoded_data = cbor2.loads(cbor_binary) + blake2b_224 = hashlib.blake2b(digest_size=28) + blake2b_224.update(decoded_data) + # Obtain blake2b_224 hash of drep vkey + hash_digest = blake2b_224.hexdigest() + assert reg_drep.drep_id == hash_digest, "Drep ID hash is not blake2b_224." + reqc.cip085.success() + @allure.link(helpers.get_vcs_link()) @submit_utils.PARAM_SUBMIT_METHOD @common.PARAM_USE_BUILD_CMD @@ -527,6 +575,279 @@ def test_no_witness_register_and_retire( # noqa: C901 if errors_final: raise AssertionError("\n".join(errors_final)) + @allure.link(helpers.get_vcs_link()) + @pytest.mark.testnets + @pytest.mark.smoke + def test_no_multiple_delegation( + self, + cluster: clusterlib.ClusterLib, + cluster_manager: cluster_management.ClusterManager, + payment_addr: clusterlib.AddressRecord, + pool_user: clusterlib.PoolUser, + ): + """Test No multiple delegation to different dreps. + + * Create 2 Dreps + * Create vote delegation certifcate to both dreps + * Submit both certificates + * check that the Drep certificate placed at last of the certificates is delegated to + """ + temp_template = common.get_test_id(cluster) + deposit_amt = cluster.g_query.get_address_deposit() + key1 = helpers.get_current_line_str() + drep1 = get_custom_drep( + name_template=f"custom_drep_1_{temp_template}", + cluster_manager=cluster_manager, + cluster_obj=cluster, + payment_addr=payment_addr, + caching_key=key1, + ) + + key2 = helpers.get_current_line_str() + drep2 = get_custom_drep( + name_template=f"custom_drep_2_{temp_template}", + cluster_manager=cluster_manager, + cluster_obj=cluster, + payment_addr=payment_addr, + caching_key=key2, + ) + + # Create stake address registration cert + reg_cert = cluster.g_stake_address.gen_stake_addr_registration_cert( + addr_name=f"{temp_template}_addr0", + deposit_amt=deposit_amt, + stake_vkey_file=pool_user.stake.vkey_file, + ) + + reqc.cip087.start(url=helpers.get_vcs_link()) + # Create vote delegation cert for drep 1 + deleg_cert_1 = cluster.g_stake_address.gen_vote_delegation_cert( + addr_name=f"{temp_template}_addr1", + stake_vkey_file=pool_user.stake.vkey_file, + drep_key_hash=drep1.drep_id, + always_abstain=False, + always_no_confidence=False, + ) + + # Create vote delegation cert for drep 2 + deleg_cert_2 = cluster.g_stake_address.gen_vote_delegation_cert( + addr_name=f"{temp_template}_addr2", + stake_vkey_file=pool_user.stake.vkey_file, + drep_key_hash=drep2.drep_id, + always_abstain=False, + always_no_confidence=False, + ) + + # Submit two vote delegation certificate at once + tx_files = clusterlib.TxFiles( + certificate_files=[reg_cert, deleg_cert_2, deleg_cert_1], + signing_key_files=[payment_addr.skey_file, pool_user.stake.skey_file], + ) + + # Make sure we have enough time to finish the registration/delegation in one epoch + clusterlib_utils.wait_for_epoch_interval( + cluster_obj=cluster, start=1, stop=common.EPOCH_STOP_SEC_LEDGER_STATE + ) + + clusterlib_utils.build_and_submit_tx( + cluster_obj=cluster, + name_template=temp_template, + src_address=payment_addr.address, + use_build_cmd=True, + tx_files=tx_files, + deposit=deposit_amt, + ) + stake_addr_info = cluster.g_query.get_stake_addr_info(pool_user.stake.address) + + assert stake_addr_info.vote_delegation == governance_utils.get_drep_cred_name( + drep_id=drep1.drep_id + ), "Votes are NOT delegated to the correct DRep 1 placed at last of certificates list." + reqc.cip087.success() + + @allure.link(helpers.get_vcs_link()) + @pytest.mark.parametrize("drep", ("always_abstain", "always_no_confidence", "custom")) + @pytest.mark.testnets + @pytest.mark.smoke + def test_no_delegation_without_stake_registration( + self, + cluster: clusterlib.ClusterLib, + payment_addr: clusterlib.AddressRecord, + pool_user: clusterlib.PoolUser, + custom_drep: governance_utils.DRepRegistration, + drep: str, + ): + """Test No voting delegation without registering stake address first. + + * Use a wallet without registered stake address + * Create vote delegation certifcate using unregistered wallet stake key + * Submit the certificate + * Expect error StakeKeyNotRegisteredDELEG + """ + temp_template = common.get_test_id(cluster) + deposit_amt = cluster.g_query.get_address_deposit() + + reqc.cip088.start(url=helpers.get_vcs_link()) + # Create vote delegation cert + deleg_cert = cluster.g_stake_address.gen_vote_delegation_cert( + addr_name=f"{temp_template}_addr1", + stake_vkey_file=pool_user.stake.vkey_file, + drep_key_hash=custom_drep.drep_id if drep == "custom" else "", + always_abstain=drep == "always_abstain", + always_no_confidence=drep == "always_no_confidence", + ) + + tx_files = clusterlib.TxFiles( + certificate_files=[deleg_cert], + signing_key_files=[payment_addr.skey_file, pool_user.stake.skey_file], + ) + + # Make sure we have enough time to finish the delegation in one epoch + clusterlib_utils.wait_for_epoch_interval( + cluster_obj=cluster, start=1, stop=common.EPOCH_STOP_SEC_LEDGER_STATE + ) + + # Expecting error as stake address is not registered + with pytest.raises(clusterlib.CLIError) as excinfo: + clusterlib_utils.build_and_submit_tx( + cluster_obj=cluster, + name_template=temp_template, + src_address=payment_addr.address, + use_build_cmd=True, + tx_files=tx_files, + deposit=deposit_amt, + ) + + err_msg = str(excinfo.value) + assert "StakeKeyNotRegisteredDELEG" in err_msg, err_msg + reqc.cip088.success() + + @allure.link(helpers.get_vcs_link()) + @submit_utils.PARAM_SUBMIT_METHOD + @common.PARAM_USE_BUILD_CMD + @pytest.mark.testnets + @pytest.mark.smoke + def test_drep_no_retirement_before_register( + self, + cluster: clusterlib.ClusterLib, + payment_addr: clusterlib.AddressRecord, + use_build_cmd: bool, + submit_method: str, + ): + """Test No Drep retirement before register. + + * Create a retirement certificate without registering + * Submit certificate + * check it is not possible to retire before register + """ + temp_template = common.get_test_id(cluster) + drep_keys = cluster.g_conway_governance.drep.gen_key_pair( + key_name=temp_template, destination_dir="." + ) + deposit = cluster.conway_genesis["dRepDeposit"] + + reqc.cip089.start(url=helpers.get_vcs_link()) + ret_cert = cluster.g_conway_governance.drep.gen_retirement_cert( + cert_name=temp_template, + deposit_amt=deposit, + drep_vkey_file=drep_keys.vkey_file, + ) + tx_files_ret = clusterlib.TxFiles( + certificate_files=[ret_cert], + signing_key_files=[payment_addr.skey_file, drep_keys.skey_file], + ) + + # Expecting error for both cases as drep is not registered + with pytest.raises((clusterlib.CLIError, submit_api.SubmitApiError)) as excinfo: + clusterlib_utils.build_and_submit_tx( + cluster_obj=cluster, + name_template=f"{temp_template}_reg2", + src_address=payment_addr.address, + submit_method=submit_method, + use_build_cmd=use_build_cmd, + tx_files=tx_files_ret, + deposit=deposit, + ) + + err_msg = str(excinfo.value) + assert "ConwayDRepNotRegistered" in err_msg, err_msg + reqc.cip089.success() + + @allure.link(helpers.get_vcs_link()) + @submit_utils.PARAM_SUBMIT_METHOD + @common.PARAM_USE_BUILD_CMD + @pytest.mark.testnets + @pytest.mark.smoke + def test_drep_no_multiple_registration( + self, + cluster: clusterlib.ClusterLib, + payment_addr: clusterlib.AddressRecord, + use_build_cmd: bool, + submit_method: str, + ): + """Test Drep cannot be registered multiple time. + + * Generate drep keys + * Create a drep registration certificate + * Submit the registration certificate twice + * Expect ConwayDRepAlreadyRegistered on the second time + """ + temp_template = common.get_test_id(cluster) + drep_metadata_url = "https://www.the-drep.com" + drep_metadata_file = f"{temp_template}_drep_metadata.json" + drep_metadata_content = {"name": "The DRep", "ranking": "uno"} + helpers.write_json(out_file=drep_metadata_file, content=drep_metadata_content) + drep_metadata_hash = cluster.g_conway_governance.drep.get_metadata_hash( + drep_metadata_file=drep_metadata_file + ) + deposit_amt = cluster.conway_genesis["dRepDeposit"] + drep_keys = cluster.g_conway_governance.drep.gen_key_pair( + key_name=temp_template, destination_dir="." + ) + reqc.cip090.start(url=helpers.get_vcs_link()) + # Obtain drep registration certificate + reg_cert = cluster.g_conway_governance.drep.gen_registration_cert( + cert_name=temp_template, + deposit_amt=deposit_amt, + drep_vkey_file=drep_keys.vkey_file, + drep_metadata_url=drep_metadata_url, + drep_metadata_hash=drep_metadata_hash, + destination_dir=".", + ) + tx_files_reg = clusterlib.TxFiles( + certificate_files=[reg_cert], + signing_key_files=[payment_addr.skey_file, drep_keys.skey_file], + ) + + # Submit drep registration certificate + clusterlib_utils.build_and_submit_tx( + cluster_obj=cluster, + name_template=f"{temp_template}_reg", + src_address=payment_addr.address, + submit_method=submit_method, + use_build_cmd=use_build_cmd, + tx_files=tx_files_reg, + deposit=deposit_amt, + ) + + # Wait for some blocks and again submit drep registration certificate + cluster.wait_for_new_block(new_blocks=2) + + # Expecting error as drep is already registered + with pytest.raises((clusterlib.CLIError, submit_api.SubmitApiError)) as excinfo: + clusterlib_utils.build_and_submit_tx( + cluster_obj=cluster, + name_template=f"{temp_template}_reg2", + src_address=payment_addr.address, + submit_method=submit_method, + use_build_cmd=use_build_cmd, + tx_files=tx_files_reg, + deposit=deposit_amt, + ) + + err_msg = str(excinfo.value) + assert "ConwayDRepAlreadyRegistered" in err_msg, err_msg + reqc.cip090.success() + class TestDelegDReps: """Tests for votes delegation to DReps.""" @@ -916,6 +1237,120 @@ def _get_drep_rec( assert key in drep_states_all, f"DRep '{key}' not found in DRep state" assert rec == drep_states_all[key], f"DRep '{key}' state mismatch" + @allure.link(helpers.get_vcs_link()) + @pytest.mark.testnets + @pytest.mark.smoke + def test_change_delegation( + self, + cluster: clusterlib.ClusterLib, + cluster_manager: cluster_management.ClusterManager, + payment_addr: clusterlib.AddressRecord, + pool_user: clusterlib.PoolUser, + ): + """Test Change delegation to different dreps. + + * Create 2 Dreps + * Create vote delegation certifcate for first drep + * Submit certificate + * check that the delegation is of correct drep id + * Change delegation to drep2 and submit certificate + * Check vote delegation is updated to second drep + """ + temp_template = common.get_test_id(cluster) + deposit_amt = cluster.g_query.get_address_deposit() + key1 = helpers.get_current_line_str() + # Get first drep + drep1 = get_custom_drep( + name_template=f"custom_drep_1_{temp_template}", + cluster_manager=cluster_manager, + cluster_obj=cluster, + payment_addr=payment_addr, + caching_key=key1, + ) + + key2 = helpers.get_current_line_str() + # Get second drep + drep2 = get_custom_drep( + name_template=f"custom_drep_2_{temp_template}", + cluster_manager=cluster_manager, + cluster_obj=cluster, + payment_addr=payment_addr, + caching_key=key2, + ) + + # Create stake address registration cert + reg_cert = cluster.g_stake_address.gen_stake_addr_registration_cert( + addr_name=f"{temp_template}_addr0", + deposit_amt=deposit_amt, + stake_vkey_file=pool_user.stake.vkey_file, + ) + + # Create vote delegation cert + deleg_cert = cluster.g_stake_address.gen_vote_delegation_cert( + addr_name=f"{temp_template}_addr1", + stake_vkey_file=pool_user.stake.vkey_file, + drep_key_hash=drep1.drep_id, + always_abstain=False, + always_no_confidence=False, + ) + + tx_files = clusterlib.TxFiles( + certificate_files=[reg_cert, deleg_cert], + signing_key_files=[payment_addr.skey_file, pool_user.stake.skey_file], + ) + + # Make sure we have enough time to finish the registration/delegation in one epoch + clusterlib_utils.wait_for_epoch_interval( + cluster_obj=cluster, start=1, stop=common.EPOCH_STOP_SEC_LEDGER_STATE + ) + + clusterlib_utils.build_and_submit_tx( + cluster_obj=cluster, + name_template=temp_template, + src_address=payment_addr.address, + use_build_cmd=True, + tx_files=tx_files, + deposit=deposit_amt, + ) + stake_addr_info = cluster.g_query.get_stake_addr_info(pool_user.stake.address) + assert stake_addr_info.vote_delegation == governance_utils.get_drep_cred_name( + drep_id=drep1.drep_id + ), "Votes are NOT delegated to the correct DRep 1" + + reqc.cip086.start(url=helpers.get_vcs_link()) + # Change delegation to drep2 + deleg_cert = cluster.g_stake_address.gen_vote_delegation_cert( + addr_name=f"{temp_template}_addr2", + stake_vkey_file=pool_user.stake.vkey_file, + drep_key_hash=drep2.drep_id, + always_abstain=False, + always_no_confidence=False, + ) + + tx_files = clusterlib.TxFiles( + certificate_files=[deleg_cert], + signing_key_files=[payment_addr.skey_file, pool_user.stake.skey_file], + ) + + # Make sure we have enough time to finish the delegation in one epoch + clusterlib_utils.wait_for_epoch_interval( + cluster_obj=cluster, start=1, stop=common.EPOCH_STOP_SEC_LEDGER_STATE + ) + + clusterlib_utils.build_and_submit_tx( + cluster_obj=cluster, + name_template=temp_template, + src_address=payment_addr.address, + use_build_cmd=True, + tx_files=tx_files, + deposit=deposit_amt, + ) + stake_addr_info = cluster.g_query.get_stake_addr_info(pool_user.stake.address) + assert stake_addr_info.vote_delegation == governance_utils.get_drep_cred_name( + drep_id=drep2.drep_id + ), "Votes are NOT changed to the correct DRep 2" + reqc.cip086.success() + class TestDRepActivity: """Tests for DReps activity.""" diff --git a/cardano_node_tests/tests/tests_conway/test_info.py b/cardano_node_tests/tests/tests_conway/test_info.py index db6f2f902..78fa1854a 100644 --- a/cardano_node_tests/tests/tests_conway/test_info.py +++ b/cardano_node_tests/tests/tests_conway/test_info.py @@ -58,12 +58,18 @@ def test_info( * submit an "info" action * vote on the action * check the votes + * check for deposit return """ # pylint: disable=too-many-locals,too-many-statements cluster, governance_data = cluster_use_governance temp_template = common.get_test_id(cluster) action_deposit_amt = cluster.conway_genesis["govActionDeposit"] + # Get initial return account balance + init_return_account_balance = cluster.g_query.get_stake_addr_info( + pool_user_ug.stake.address + ).reward_account_balance + # Create an action rand_str = helpers.get_rand_str(4) @@ -101,6 +107,10 @@ def test_info( ) reqc.cli023.success() + # Get epoch where the action was submitted for keeping track of + # epoch to wait for the gov action expiry + action_epoch = cluster.g_query.get_epoch() + out_utxos_action = cluster.g_query.get_utxo(tx_raw_output=tx_output_action) assert ( clusterlib.filter_utxos(utxos=out_utxos_action, address=pool_user_ug.payment.address)[ @@ -239,3 +249,21 @@ def test_info( votes=governance_utils.VotedVotes(cc=votes_cc, drep=votes_drep, spo=votes_spo), txhash=vote_txid, ) + + # Check deposit is returned + reqc.cip034ex.start(url=helpers.get_vcs_link()) + + # First wait for gov action to expire according to gov action lifetime + # and epoch passed since + _cur_epoch = cluster.g_query.get_epoch() + action_lifetime_epoch = cluster.conway_genesis["govActionLifetime"] + epochs_to_expiration = action_lifetime_epoch + 2 + action_epoch - _cur_epoch + cluster.wait_for_new_epoch(new_epochs=epochs_to_expiration, padding_seconds=5) + + deposit_returned = cluster.g_query.get_stake_addr_info( + pool_user_ug.stake.address + ).reward_account_balance + assert ( + deposit_returned == init_return_account_balance + action_deposit_amt + ), "Incorrect return account balance" + reqc.cip034ex.success() diff --git a/cardano_node_tests/tests/tests_conway/test_pparam_update.py b/cardano_node_tests/tests/tests_conway/test_pparam_update.py index bb894d880..328222635 100644 --- a/cardano_node_tests/tests/tests_conway/test_pparam_update.py +++ b/cardano_node_tests/tests/tests_conway/test_pparam_update.py @@ -240,6 +240,8 @@ def test_pparam_update( # noqa: C901 * check that the action is enacted * check that only the ratified action that got accepted first to the chain gets enacted * check that it's not possible to vote on enacted action + * check that all deposit required for actions is returned back for both expired + and enacted actions """ # pylint: disable=too-many-locals,too-many-statements cluster, governance_data = cluster_lock_governance @@ -251,6 +253,10 @@ def test_pparam_update( # noqa: C901 if is_in_bootstrap and not configuration.HAS_CC: pytest.skip("The test doesn't work in bootstrap period without CC.") + init_return_account_balance = cluster.g_query.get_stake_addr_info( + pool_user_lg.stake.address + ).reward_account_balance + # Check if total delegated stake is below the threshold. This can be used to check that # undelegated stake is treated as Abstain. If undelegated stake was treated as Yes, than # missing votes would approve the action. @@ -634,13 +640,19 @@ def test_pparam_update( # noqa: C901 gov_state=cluster.g_conway_governance.query.gov_state(), ) + # For keeping track of how many proposals were submitted + # to check for all deposit required for action is returned back + submitted_proposal_count = 0 + def _propose_pparams_update( name_template: str, proposals: tp.List[clusterlib_utils.UpdateProposal], ) -> conway_common.PParamPropRec: anchor_url = f"http://www.pparam-action-{clusterlib.get_rand_str(4)}.com" anchor_data_hash = cluster.g_conway_governance.get_anchor_data_hash(text=anchor_url) - + # Increment count for a submitted proposal + nonlocal submitted_proposal_count + submitted_proposal_count += 1 return conway_common.propose_pparams_update( cluster_obj=cluster, name_template=name_template, @@ -1109,6 +1121,10 @@ def _check_proposed_pparams( mix_approved_prop_rec = _propose_pparams_update( name_template=f"{temp_template}_mix_approved", proposals=mix_approved_update_proposals ) + # Get epoch where the last action was submitted for keeping track of + # epoch to wait for all the gov actions expiry + last_action_epoch = cluster.g_query.get_epoch() + _check_proposed_pparams( update_proposals=mix_approved_prop_rec.proposals, protocol_params=mix_approved_prop_rec.future_pparams, @@ -1239,6 +1255,26 @@ def _check_state(state: dict): if fin_voted_votes.drep: governance_utils.check_vote_view(cluster_obj=cluster, vote_data=fin_voted_votes.drep[0]) + # Check deposit return for both after enactment and expiration + [r.start(url=helpers.get_vcs_link()) for r in (reqc.cip034ex, reqc.cip034en)] + + # First wait to ensure that all proposals are expired/enacted for deposit to be retuned + _cur_epoch = cluster.g_query.get_epoch() + action_lifetime_epoch = cluster.conway_genesis["govActionLifetime"] + epochs_to_expiration = action_lifetime_epoch + last_action_epoch - _cur_epoch + cluster.wait_for_new_epoch(new_epochs=epochs_to_expiration, padding_seconds=5) + + deposit_amt = cluster.conway_genesis["govActionDeposit"] + total_deposit_return = cluster.g_query.get_stake_addr_info( + pool_user_lg.stake.address + ).reward_account_balance + # Check total deposit return accounting for both expired and enaacted actions + assert ( + total_deposit_return + == init_return_account_balance + deposit_amt * submitted_proposal_count + ), "Incorrect return account balance" + [r.success() for r in (reqc.cip034ex, reqc.cip034en)] + if db_errors_final: raise AssertionError("\n".join(db_errors_final)) [r.success() for r in (reqc.cip080, reqc.cip081, reqc.cip082, reqc.cip083)]