Skip to content

Commit

Permalink
Test for datum reserialization in db-sync
Browse files Browse the repository at this point in the history
  • Loading branch information
mkoura committed Aug 4, 2022
1 parent 8823f1a commit ca51c13
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 2 deletions.
Binary file not shown.
1 change: 1 addition & 0 deletions cardano_node_tests/tests/plutus_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
DATUM_WITNESS_GOLDEN_NORMAL = PLUTUS_DIR / "witness_golden_normal.datum"
DATUM_WITNESS_GOLDEN_EXTENDED = PLUTUS_DIR / "witness_golden_extended.datum"
DATUM_BIG = PLUTUS_DIR / "big.datum"
DATUM_FINITE_TYPED_CBOR = PLUTUS_DIR / "typed-finite.datum.cbor"

SIGNING_KEY_GOLDEN = DATA_DIR / "golden_normal.skey"
SIGNING_KEY_GOLDEN_EXTENDED = DATA_DIR / "golden_extended.skey"
Expand Down
76 changes: 74 additions & 2 deletions cardano_node_tests/tests/test_plutus_v2_spend_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from cardano_node_tests.tests import plutus_common
from cardano_node_tests.utils import cluster_management
from cardano_node_tests.utils import clusterlib_utils
from cardano_node_tests.utils import dbsync_queries
from cardano_node_tests.utils import dbsync_utils
from cardano_node_tests.utils import helpers
from cardano_node_tests.utils import tx_view
Expand Down Expand Up @@ -121,12 +122,20 @@ def _fund_script(
inline_datum_value=(
plutus_op.datum_value if plutus_op.datum_value and use_inline_datum else ""
),
inline_datum_cbor_file=(
plutus_op.datum_cbor_file if plutus_op.datum_cbor_file and use_inline_datum else ""
),
datum_hash_file=(
plutus_op.datum_file if plutus_op.datum_file and not use_inline_datum else ""
),
datum_hash_value=(
plutus_op.datum_value if plutus_op.datum_value and not use_inline_datum else ""
),
datum_hash_cbor_file=(
plutus_op.datum_cbor_file
if plutus_op.datum_cbor_file and not use_inline_datum
else ""
),
),
# for collateral
clusterlib.TxOut(
Expand Down Expand Up @@ -181,14 +190,15 @@ def _fund_script(

# check if inline datum is returned by 'query utxo'
if use_inline_datum:
expected_datum = None
if plutus_op.datum_file:
with open(plutus_op.datum_file, encoding="utf-8") as json_datum:
expected_datum = json.load(json_datum)
else:
elif plutus_op.datum_value:
expected_datum = plutus_op.datum_value

assert (
script_utxos[0].inline_datum == expected_datum
expected_datum is None or script_utxos[0].inline_datum == expected_datum
), "The inline datum returned by 'query utxo' is different than the expected"

# check "transaction view"
Expand Down Expand Up @@ -339,6 +349,68 @@ def test_txout_locking(
utxo=reference_utxo
), "Reference input was spent"

@allure.link(helpers.get_vcs_link())
@pytest.mark.needs_dbsync
def test_datum_bytes_in_dbsync(
self,
cluster: clusterlib.ClusterLib,
payment_addrs: List[clusterlib.AddressRecord],
):
"""Test that datum bytes in db-sync corresponds to original datum.
* create a Tx output with an inline datum at the script address
* double-check that the UTxO datum hash corresponds to the datum CBOR file
* check that datum bytes in db-sync corresponds to the original datum
"""
temp_template = common.get_test_id(cluster)
amount = 2_000_000

plutus_op = plutus_common.PlutusOp(
script_file=plutus_common.ALWAYS_SUCCEEDS_PLUTUS_V2,
datum_cbor_file=plutus_common.DATUM_FINITE_TYPED_CBOR,
redeemer_cbor_file=plutus_common.DATUM_FINITE_TYPED_CBOR,
execution_cost=plutus_common.ALWAYS_SUCCEEDS_COST,
)
assert plutus_op.execution_cost # for mypy

redeem_cost = plutus_common.compute_cost(
execution_cost=plutus_op.execution_cost, protocol_params=cluster.get_protocol_params()
)

# create a Tx output with an inline datum at the script address
script_utxos, *__ = _fund_script(
temp_template=temp_template,
cluster=cluster,
payment_addr=payment_addrs[0],
dst_addr=payment_addrs[1],
plutus_op=plutus_op,
amount=amount,
redeem_cost=redeem_cost,
use_inline_datum=True,
)
script_utxo = script_utxos[0]

# double-check that the UTxO datum hash corresponds to the datum CBOR file
datum_hash = cluster.get_hash_script_data(
script_data_cbor_file=plutus_common.DATUM_FINITE_TYPED_CBOR
)
assert datum_hash == script_utxo.inline_datum_hash, "Unexpected datum hash"

# check that datum bytes in db-sync corresponds to the original datum
with open(plutus_common.DATUM_FINITE_TYPED_CBOR, "rb") as in_fp:
orig_cbor_bin = in_fp.read()
orig_cbor_hex = orig_cbor_bin.hex()

datum_db_response = list(
dbsync_queries.query_datum(datum_hash=script_utxo.inline_datum_hash)
)
db_cbor_hex = datum_db_response[0].bytes.hex()

# see https://github.com/input-output-hk/cardano-db-sync/issues/1214
assert (
db_cbor_hex == orig_cbor_hex
), "Datum bytes in db-sync doesn't correspond to the original datum"


@pytest.mark.testnets
class TestNegativeInlineDatum:
Expand Down
17 changes: 17 additions & 0 deletions cardano_node_tests/utils/dbsync_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ class BlockDBRow(NamedTuple):
pool_id: str


class DatumDBRow(NamedTuple):
id: int
datum_hash: memoryview
tx_id: int
value: dict
bytes: memoryview


class SchemaVersionStages(NamedTuple):
one: int
two: int
Expand Down Expand Up @@ -624,3 +632,12 @@ def query_table_names() -> List[str]:
results: List[Tuple[str]] = cur.fetchall()
table_names = [r[0] for r in results]
return table_names


def query_datum(datum_hash: str) -> Generator[DatumDBRow, None, None]:
"""Query datum record in db-sync."""
query = "SELECT id, hash, tx_id, value, bytes FROM datum WHERE hash = %s;"

with execute(query=query, vars=(rf"\x{datum_hash}",)) as cur:
while (result := cur.fetchone()) is not None:
yield DatumDBRow(*result)

0 comments on commit ca51c13

Please sign in to comment.