From b5794e0af49411d916c9d4384a1fb5309bd8a015 Mon Sep 17 00:00:00 2001 From: saratomaz Date: Mon, 5 Aug 2024 21:24:06 +0100 Subject: [PATCH] Check drep metadata in dbsync --- .../tests/tests_conway/test_drep.py | 16 ++++--- cardano_node_tests/utils/dbsync_queries.py | 39 +++++++++++++++ cardano_node_tests/utils/dbsync_utils.py | 48 ++++++++++++++++++- 3 files changed, 95 insertions(+), 8 deletions(-) diff --git a/cardano_node_tests/tests/tests_conway/test_drep.py b/cardano_node_tests/tests/tests_conway/test_drep.py index aca6f8f72..38688d2fc 100644 --- a/cardano_node_tests/tests/tests_conway/test_drep.py +++ b/cardano_node_tests/tests/tests_conway/test_drep.py @@ -32,6 +32,7 @@ from cardano_node_tests.utils.versions import VERSIONS LOGGER = logging.getLogger(__name__) +DATA_DIR = pl.Path(__file__).parent.parent / "data" pytestmark = pytest.mark.skipif( VERSIONS.transaction_era < VERSIONS.CONWAY, @@ -323,16 +324,16 @@ def test_register_and_retire_drep( temp_template = common.get_test_id(cluster) errors_final = [] - # Register DRep + drep_metadata_file = DATA_DIR / "drep_metadata.json" - 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) + # Register DRep + drep_metadata_url = "https://tinyurl.com/w7vd3ek6" reqc.cli012.start(url=helpers.get_vcs_link()) drep_metadata_hash = cluster.g_conway_governance.drep.get_metadata_hash( drep_metadata_file=drep_metadata_file ) + with open(drep_metadata_file, encoding="utf-8") as anchor_fp: + drep_metadata_content = json.load(anchor_fp) _url = helpers.get_vcs_link() [r.start(url=_url) for r in (reqc.cli008, reqc.cli009, reqc.cli010, reqc.cip021)] @@ -378,11 +379,14 @@ def test_register_and_retire_drep( assert ( metadata_anchor["dataHash"] == drep_metadata_hash - == "592e53f74765c8c6c97dfda2fd6038236ffc7ad55800592118d9e36ad1c8140d" + == "18b4b10150eab04ba66c8f9cb497ff05c6c31b9c9825388481c1790ce76b6b90" ), "Unexpected metadata hash" assert metadata_anchor["url"] == drep_metadata_url, "Unexpected metadata url" try: dbsync_utils.check_drep_registration(drep=reg_drep, drep_state=reg_drep_state) + dbsync_utils.check_off_chain_drep_registration( + drep=reg_drep, metadata=drep_metadata_content + ) except AssertionError as exc: str_exc = str(exc) errors_final.append(f"DB-Sync unexpected DRep registration error: {str_exc}") diff --git a/cardano_node_tests/utils/dbsync_queries.py b/cardano_node_tests/utils/dbsync_queries.py index 53a4f8cc7..361809a47 100644 --- a/cardano_node_tests/utils/dbsync_queries.py +++ b/cardano_node_tests/utils/dbsync_queries.py @@ -524,6 +524,26 @@ class TreasuryWithdrawalDBRow: amount: int +@dataclasses.dataclass(frozen=True) +class OffChainVoteDrepDataDBRow: + # pylint: disable-next=invalid-name + id: int + hash: memoryview + language: str + comment: str + json: dict + bytes: memoryview + warning: str + is_valid: bool + payment_address: str + given_name: str + objectives: str + motivations: str + qualifications: str + image_url: str + image_hash: str + + @contextlib.contextmanager def execute(query: str, vars: tp.Sequence = ()) -> tp.Iterator[psycopg2.extensions.cursor]: # pylint: disable=redefined-builtin @@ -1331,3 +1351,22 @@ def query_treasury_withdrawal(txhash: str) -> tp.Generator[TreasuryWithdrawalDBR with execute(query=query, vars=(rf"\x{txhash}",)) as cur: while (result := cur.fetchone()) is not None: yield TreasuryWithdrawalDBRow(*result) + + +def query_off_chain_vote_drep_data( + voting_anchor_id: int, +) -> tp.Generator[OffChainVoteDrepDataDBRow, None, None]: + """Query off_chain_vote_drep_data table in db-sync.""" + query = ( + "SELECT" + " vd.id, vd.hash, vd.language, vd.comment, vd.json, vd.bytes, vd.warning, vd.is_valid," + " drep.payment_address, drep.given_name, drep.objectives, drep.motivations," + " drep.qualifications, drep.image_url, drep.image_hash " + "FROM off_chain_vote_drep_data as drep " + "INNER JOIN off_chain_vote_data as vd ON vd.id = drep.off_chain_vote_data_id " + "WHERE vd.voting_anchor_id = %s;" + ) + + with execute(query=query, vars=(voting_anchor_id,)) as cur: + while (result := cur.fetchone()) is not None: + yield OffChainVoteDrepDataDBRow(*result) diff --git a/cardano_node_tests/utils/dbsync_utils.py b/cardano_node_tests/utils/dbsync_utils.py index 4f9904549..1d1f1ee37 100644 --- a/cardano_node_tests/utils/dbsync_utils.py +++ b/cardano_node_tests/utils/dbsync_utils.py @@ -487,6 +487,8 @@ def retry_query(query_func: tp.Callable, timeout: int = 20) -> tp.Any: time.sleep(sleep_time) try: response = query_func() + if not response: + raise AssertionError(NO_REPONSE_STR) break except AssertionError as exc: if NO_REPONSE_STR in str(exc) and time.time() < end_time: @@ -1119,7 +1121,7 @@ def check_drep_registration( drep_data = get_drep(drep_hash=drep.drep_id, drep_deposit=drep.deposit) - assert drep_data, f"No data returned from db-sync for DRep {drep.drep_id} registartion" + assert drep_data, f"No data returned from db-sync for DRep {drep.drep_id} registration" assert ( drep_state[0][0]["keyHash"] == drep_data.hash_hex ), f"DRep {drep.drep_id} not present in registration table in db-sync" @@ -1139,7 +1141,7 @@ def check_drep_deregistration( drep_data = get_drep(drep_hash=drep.drep_id, drep_deposit=-drep.deposit) - assert drep_data, f"No data returned from db-sync for DRep {drep.drep_id} deregistartion" + assert drep_data, f"No data returned from db-sync for DRep {drep.drep_id} deregistration" assert ( drep.drep_id == drep_data.hash_hex ), f"Deregistered DRep {drep.drep_id} not present in registration table in db-sync" @@ -1249,3 +1251,45 @@ def check_reward_rest( row.spendable_epoch == row.earned_epoch + 1 ), "Wrong relation between earned and spendable epochs in db-sync" assert row.type == "treasury", "Type not marked as treasury in db-sync" + + +def check_off_chain_drep_registration( + drep: governance_utils.DRepRegistration, metadata: dict +) -> None: + """Check drep off chain data in db-sync.""" + if not configuration.HAS_DBSYNC: + return + + errors = [] + + drep_data = get_drep(drep_hash=drep.drep_id, drep_deposit=drep.deposit) + + assert drep_data, f"No data returned from db-sync for DRep {drep.drep_id} deregistration" + + def _query_func() -> list: + return list( + dbsync_queries.query_off_chain_vote_drep_data( + voting_anchor_id=drep_data.voting_anchor_id + ) + ) + + drep_off_chain_metadata = retry_query(query_func=_query_func, timeout=300)[0] + expected_metadata = metadata["body"] + + if drep_off_chain_metadata.payment_address != expected_metadata["paymentAddress"]: + errors.append("'paymentAddress' value is different than expected;") + + if drep_off_chain_metadata.given_name != expected_metadata["givenName"]: + errors.append("'givenName' value is different than expected;") + + if drep_off_chain_metadata.objectives != expected_metadata["objectives"]: + errors.append("'objectives' value is different than expected;") + + if drep_off_chain_metadata.motivations != expected_metadata["motivations"]: + errors.append("'motivations' value is different than expected;") + + if drep_off_chain_metadata.qualifications != expected_metadata["qualifications"]: + errors.append("'qualifications' value is different than expected;") + + if errors: + raise AssertionError("\n".join(errors))