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

Add db-sync checks for conway param update proposals [ CIP-080 -> CIP 083 ] #2414

Merged
merged 7 commits into from
Jul 9, 2024
4 changes: 4 additions & 0 deletions cardano_node_tests/tests/reqs_conway.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ def __r(id: str) -> requirements.Req:
cip077 = __r("CIP077")
cip078 = __r("CIP078")
cip079 = __r("CIP079")
cip080 = __r("CIP080")
cip081 = __r("CIP081")
cip082 = __r("CIP082")
cip083 = __r("CIP083")

# https://github.com/IntersectMBO/cardano-test-plans/blob/main/docs/user-stories/02-cardano-cli.md
cli001 = __r("CLI001")
Expand Down
68 changes: 68 additions & 0 deletions cardano_node_tests/tests/tests_conway/test_pparam_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from cardano_node_tests.tests.tests_conway import conway_common
from cardano_node_tests.utils import clusterlib_utils
from cardano_node_tests.utils import configuration
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.versions import VERSIONS
Expand Down Expand Up @@ -216,6 +217,7 @@ class TestPParamUpdate:

@allure.link(helpers.get_vcs_link())
@pytest.mark.long
@pytest.mark.dbsync
def test_pparam_update( # noqa: C901
self,
cluster_lock_governance: governance_utils.GovClusterT,
Expand Down Expand Up @@ -243,6 +245,7 @@ def test_pparam_update( # noqa: C901
cluster, governance_data = cluster_lock_governance
temp_template = common.get_test_id(cluster)
cost_proposal_file = DATA_DIR / "cost_models_list.json"
db_errors_final = []
is_in_bootstrap = conway_common.is_in_bootstrap(cluster_obj=cluster)

if is_in_bootstrap and not configuration.HAS_CC:
Expand Down Expand Up @@ -716,6 +719,15 @@ def _check_proposed_pparams(
else True,
)

# db-sync check
try:
dbsync_utils.check_conway_gov_action_proposal_description(
net_nodrep_prop_rec.future_pparams, net_nodrep_prop_rec.action_txid
)
dbsync_utils.check_conway_param_update_proposal(net_nodrep_prop_rec.future_pparams)
except AssertionError as exc:
db_errors_final.append(f"db-sync network params update error: {exc}")

# Vote on update proposals from network group that will NOT get approved by CC
if configuration.HAS_CC:
reqc.cip062_02.start(url=helpers.get_vcs_link())
Expand Down Expand Up @@ -760,6 +772,15 @@ def _check_proposed_pparams(
else True,
)

# db-sync check
try:
dbsync_utils.check_conway_gov_action_proposal_description(
eco_nodrep_prop_rec.future_pparams, eco_nodrep_prop_rec.action_txid
)
dbsync_utils.check_conway_param_update_proposal(eco_nodrep_prop_rec.future_pparams)
except AssertionError as exc:
db_errors_final.append(f"db-sync economic params update error: {exc}")

# Vote on update proposals from economic group that will NOT get approved by CC
if configuration.HAS_CC:
eco_nocc_update_proposals = list(helpers.flatten(economic_g_proposals))
Expand Down Expand Up @@ -827,6 +848,15 @@ def _check_proposed_pparams(
approve_drep=None,
)

# db-sync check
try:
dbsync_utils.check_conway_gov_action_proposal_description(
tech_nodrep_prop_rec.future_pparams, tech_nodrep_prop_rec.action_txid
)
dbsync_utils.check_conway_param_update_proposal(tech_nodrep_prop_rec.future_pparams)
except AssertionError as exc:
db_errors_final.append(f"db-sync technical params update error: {exc}")

# Vote on update proposals from technical group that will NOT get approved by CC
if configuration.HAS_CC:
tech_nocc_prop_rec = _propose_pparams_update(
Expand Down Expand Up @@ -911,6 +941,15 @@ def _check_proposed_pparams(
else True,
)

# db-sync check
try:
dbsync_utils.check_conway_gov_action_proposal_description(
gov_nodrep_prop_rec.future_pparams, gov_nodrep_prop_rec.action_txid
)
dbsync_utils.check_conway_param_update_proposal(gov_nodrep_prop_rec.future_pparams)
except AssertionError as exc:
db_errors_final.append(f"db-sync governance params update error: {exc}")

# Vote on update proposals from governance group that will NOT get approved by CC
if configuration.HAS_CC:
gov_nocc_update_proposals = list(helpers.flatten(governance_g_proposals))
Expand Down Expand Up @@ -964,6 +1003,15 @@ def _check_proposed_pparams(
else True,
)

# db-sync check
try:
dbsync_utils.check_conway_gov_action_proposal_description(
mix_nodrep_prop_rec.future_pparams, mix_nodrep_prop_rec.action_txid
)
dbsync_utils.check_conway_param_update_proposal(mix_nodrep_prop_rec.future_pparams)
except AssertionError as exc:
db_errors_final.append(f"db-sync mixed group params update error: {exc}")

# Vote on update proposals from mix of groups that will NOT get approved by CC
if configuration.HAS_CC:
mix_nocc_update_proposals = list(
Expand Down Expand Up @@ -1036,6 +1084,16 @@ def _check_proposed_pparams(
)
fin_approve_epoch = cluster.g_query.get_epoch()

# db-sync check
[r.start(url=_url) for r in (reqc.cip080, reqc.cip081, reqc.cip082, reqc.cip083)]
try:
dbsync_utils.check_conway_gov_action_proposal_description(
fin_prop_rec.future_pparams, fin_prop_rec.action_txid
)
dbsync_utils.check_conway_param_update_proposal(fin_prop_rec.future_pparams)
except AssertionError as exc:
db_errors_final.append(f"db-sync 'final' params update error: {exc}")

# Vote on another update proposals from mix of groups. The proposal will get approved,
# but not enacted, because it comes after the "final" action that was accepted to the chain
# first.
Expand Down Expand Up @@ -1150,6 +1208,12 @@ def _check_state(state: dict):
if is_spo_total_below_threshold:
reqc.cip064_04.success()

# db-sync check
try:
dbsync_utils.check_conway_param_update_enactment(enact_gov_state, _cur_epoch)
except AssertionError as exc:
db_errors_final.append(f"db-sync params enactment error: {exc}")

if proposed_pparams_errors:
proposed_pparams_errors_str = "\n".join(proposed_pparams_errors)
raise AssertionError(proposed_pparams_errors_str)
Expand All @@ -1175,6 +1239,10 @@ 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])

if db_errors_final:
raise AssertionError("\n".join(db_errors_final))
[r.success() for r in (reqc.cip080, reqc.cip081, reqc.cip082, reqc.cip083)]


class TestPParamData:
"""Tests for checking protocol parameters keys and values."""
Expand Down
112 changes: 106 additions & 6 deletions cardano_node_tests/utils/dbsync_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ class ParamProposalDBRow:
protocol_minor: int
min_utxo_value: int
min_pool_cost: int
coins_per_utxo_word: int
coins_per_utxo_size: int
cost_model_id: int
price_mem: float
price_step: float
Expand Down Expand Up @@ -357,6 +357,7 @@ class ParamProposalDBRow:
gov_action_deposit: int
drep_deposit: int
drep_activity: str
pvtpp_security_group: float
min_fee_ref_script_cost_per_byte: float


Expand All @@ -371,6 +372,66 @@ class EpochDBRow:
epoch_number: int


@dataclasses.dataclass(frozen=True)
class EpochParamDBRow:
# pylint: disable=too-many-instance-attributes disable-next=invalid-name
id: int
epoch_no: int
min_fee_a: int
min_fee_b: int
max_block_size: int
max_tx_size: int
max_bh_size: int
key_deposit: int
pool_deposit: int
max_epoch: int
optimal_pool_count: int
influence: float
monetary_expand_rate: float
treasury_growth_rate: float
decentralisation: float
protocol_major: int
protocol_minor: int
min_utxo_value: int
min_pool_cost: int
nonce: memoryview
cost_model_id: int
price_mem: float
price_step: float
max_tx_ex_mem: int
max_tx_ex_steps: int
max_block_ex_mem: int
max_block_ex_steps: int
max_val_size: int
collateral_percent: int
max_collateral_inputs: int
block_id: int
extra_entropy: memoryview
coins_per_utxo_size: int
pvt_motion_no_confidence: float
pvt_committee_normal: float
pvt_committee_no_confidence: float
pvt_hard_fork_initiation: float
dvt_motion_no_confidence: float
dvt_committee_normal: float
dvt_committee_no_confidence: float
dvt_update_to_constitution: float
dvt_hard_fork_initiation: float
dvt_p_p_network_group: float
dvt_p_p_economic_group: float
dvt_p_p_technical_group: float
dvt_p_p_gov_group: float
dvt_treasury_withdrawal: float
committee_min_size: int
committee_max_term_length: int
gov_action_lifetime: int
gov_action_deposit: int
drep_deposit: int
drep_activity: int
pvtpp_security_group: float
min_fee_ref_script_cost_per_byte: float


@dataclasses.dataclass(frozen=True)
class CommitteeRegistrationDBRow:
# pylint: disable-next=invalid-name
Expand Down Expand Up @@ -416,7 +477,7 @@ class GovActionProposalDBRow:
expiration: int
voting_anchor_id: int
type: str
description: str
description: dict
param_proposal: int
ratified_epoch: int
enacted_epoch: int
Expand Down Expand Up @@ -925,6 +986,34 @@ def query_epoch_stake(
yield EpochStakeDBRow(*result)


def query_epoch_param(epoch_no: int = 0) -> EpochParamDBRow:
"""Query epoch param record in db-sync."""
query_var = epoch_no

query = (
"SELECT "
" id, epoch_no, min_fee_a, min_fee_b, max_block_size, max_tx_size, max_bh_size, "
" key_deposit, pool_deposit, max_epoch, optimal_pool_count, influence, "
" monetary_expand_rate, treasury_growth_rate, decentralisation, protocol_major, "
" protocol_minor, min_utxo_value, min_pool_cost, nonce, cost_model_id, price_mem, "
" price_step, max_tx_ex_mem, max_tx_ex_steps, max_block_ex_mem, max_block_ex_steps, "
" max_val_size, collateral_percent, max_collateral_inputs, block_id, extra_entropy, "
" coins_per_utxo_size, pvt_motion_no_confidence, pvt_committee_normal, "
" pvt_committee_no_confidence, pvt_hard_fork_initiation, dvt_motion_no_confidence, "
" dvt_committee_normal, dvt_committee_no_confidence, dvt_update_to_constitution, "
" dvt_hard_fork_initiation, dvt_p_p_network_group, dvt_p_p_economic_group, "
" dvt_p_p_technical_group, dvt_p_p_gov_group, dvt_treasury_withdrawal, committee_min_size, "
" committee_max_term_length, gov_action_lifetime, gov_action_deposit, drep_deposit, "
" drep_activity, pvtpp_security_group, min_fee_ref_script_cost_per_byte "
" FROM epoch_param "
" WHERE epoch_no = %s "
)

with execute(query=query, vars=(query_var,)) as cur:
results = cur.fetchone()
return EpochParamDBRow(*results)


def query_blocks(
pool_id_bech32: str = "", epoch_from: int = 0, epoch_to: int = 99999999
) -> tp.Generator[BlockDBRow, None, None]:
Expand Down Expand Up @@ -977,11 +1066,21 @@ def query_datum(datum_hash: str) -> tp.Generator[DatumDBRow, None, None]:
yield DatumDBRow(*result)


def query_cost_model() -> tp.Dict[str, tp.Dict[str, tp.Any]]:
"""Query last cost-model record in db-sync."""
def query_cost_model(model_id: int = -1) -> tp.Dict[str, tp.Dict[str, tp.Any]]:
"""Query last cost model record (if id not specified) in db-sync."""
query = "SELECT * FROM cost_model ORDER BY ID DESC LIMIT 1"
query_var: tp.Union[int, str]

with execute(query=query) as cur:
if model_id != -1:
id_query = "WHERE id = %s "
query_var = model_id
else:
id_query = ""
query_var = ""

query = f"SELECT * FROM cost_model {id_query} ORDER BY ID DESC LIMIT 1"

with execute(query=query, vars=(query_var,)) as cur:
results = cur.fetchone()
cost_model: tp.Dict[str, tp.Dict[str, tp.Any]] = results[1] if results else {}
return cost_model
Expand Down Expand Up @@ -1014,7 +1113,8 @@ def query_param_proposal(txhash: str = "") -> ParamProposalDBRow:
" p.dvt_p_p_network_group, p.dvt_p_p_economic_group, p.dvt_p_p_technical_group,"
" p.dvt_p_p_gov_group, p.dvt_treasury_withdrawal, p.committee_min_size,"
" p.committee_max_term_length, p.gov_action_lifetime, p.gov_action_deposit,"
" p.drep_deposit, p.drep_activity, p.min_fee_ref_script_cost_per_byte "
" p.drep_deposit, p.drep_activity, p.pvtpp_security_group,"
" p.min_fee_ref_script_cost_per_byte "
"FROM param_proposal AS p "
"INNER JOIN tx ON tx.id = p.registered_tx_id "
f"{hash_query}"
Expand Down
Loading
Loading