Skip to content

Commit

Permalink
Add witness redeemer tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mkoura committed Nov 10, 2021
1 parent 0bd9db0 commit 7ff694b
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 0 deletions.
5 changes: 5 additions & 0 deletions cardano_node_tests/tests/data/golden_extended.skey
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "PaymentExtendedSigningKeyShelley_ed25519_bip32",
"description": "Payment Signing Key",
"cborHex": "5880d831066e077fd7c40d1918fd3452d875a80d1df82c00a8e0ee16cbfb24fb3d5a5d3ec4b707ce1bf396c140b7bd712b63cc3dc89e4294b4a1add0d850ef78c19bdc0f2a0f5186b1b9700766bcec7f455f8a94eb07d8552a1e0bb6cc9fae21ad3d589ad5c48d079ba1fd7bc334e4cea080025d5f70f68a3af78a3e1dcdfc097ac3"
}
5 changes: 5 additions & 0 deletions cardano_node_tests/tests/data/plutus/witness-redeemer.plutus
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "PlutusScriptV1",
"description": "",
"cborHex": "590a34590a310100003232323322332233322232333222333222333333332222222233223333322222333322223332223322332233223332223322332233223322332232323322323232323232323232323232323232323232323232323232323232323232323233500175c446604a9201216e6f74207369676e65642062792072656465656d6572207075626b657968617368003301c302600100212222300533003300400230060012533530370011058135018353057335738921025064000584988c8c8c8c8c8c8cccd5cd19b8735573aa00a90001280112803a4c266052a002a0042600c6ae8540084c050d5d09aba25001135573ca00226ea80084d405d262323232323232323232323232323232323232323232323333573466e1cd55cea80aa40004a0044a02e930999999999981d2800a8012801a8022802a8032803a8042804a805099a81080b1aba15012133502001635742a0202666aa032eb94060d5d0a8070999aa80c3ae501735742a018266a03a0426ae8540284cd4070cd54078085d69aba15008133501675a6ae8540184cd4069d71aba150041335019335501b75c0346ae8540084c080d5d09aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135573ca00226ea80084d40592623232323232323333573466e1cd55cea802a40004a0044a00e93099815a800a8010980b9aba1500213005357426ae8940044d55cf280089baa0021350154988c8c8c8c8c8c8c8c8cccd5cd19b8735573aa00e90001280112804a4c266605ca002a004a006260106ae8540104ccd54029d728049aba15002133500775c6ae84d5d1280089aba25001135573ca00226ea80084d40512623232323232323333573466e1cd55cea802a40004a0044a00e93099816a800a8010980a1aba150021335005012357426ae8940044d55cf280089baa002135013498488c8c8c8c8c8c8cccd5cd19b87500448000940089401126135030500113006357426aae79400c4cccd5cd19b87500148008940b89401126135573aa00226ea80084d404d261335500175ceb444888c8c8c004dd58019a80090008918009aa82b11191919191919191999aab9f008550572530021200105c350022200135001220023555505d12223300321300a357440124266a0b4a00aa600624002266aa0b4a002a004260106aae7540084c018d55cf280089aba10011223232323232323333573466e1cd55cea802a40004a0044a00e93099a817a800a801099a8038031aba150021335007005357426ae8940044d55cf280089baa002135010498488c8c8c8c8c8c8cccd5cd19b8735573aa00a90001280112803a4c266a064a002a004266a01000c6ae8540084c020d5d09aba25001135573ca00226ea80084d403d261223232323232323333573466e1cd55cea802a40004a0044a00e93099a817a800a801099a8038031aba1500213007357426ae8940044d55cf280089baa00213500e498488c8c8c8c8c8c8c8cccd5cd19b87500548010940e0940092613333573466e1d4011200225002250044984d40dd40044c018d5d09aab9e500313333573466e1d4005200025035250044984d55cea80089baa00213500d4988c8c8c8cccd5cd19b8750024800880c0940092613333573466e1d40052000202e250034984d55ce9baa00213500b498488c8c8c004dd60019a80090008918009aa827911999aab9f0012504d233504c30063574200460066ae88008138800444888c8c8c8c8c8c8cccd5cd19b8735573aa00a90001280112803a4c266aa0a2a002a0042600e6ae8540084c014d5d09aba25001135573ca00226ea80084d402926232323232323232323232323232323333573466e1d4029200625002250044984c0f940044c038d5d09aab9e500b13333573466e1d401d200425002250044984c0e540044c030d5d09aab9e500813333573466e1d4011200225002250044984c0d540044c02cd5d09aab9e500513333573466e1d4005200025003250064984d55cea80189819a80089bae357426aae7940044dd500109a803a4c4646464646464646464646464646464646464646464646464646666ae68cdc3a80aa401840a04a0049309999ab9a3370ea028900510281280124c26666ae68cdc3a809a40104a0044a00c930998252800a80109bae35742a00426eb4d5d09aba25001135573ca02426666ae68cdc3a8072400c4a0044a00c930998232800a80109bae35742a00426eb8d5d09aba25001135573ca01a26666ae68cdc3a804a40084a0044a00c93099822a800a801098069aba150021375c6ae84d5d1280089aab9e500813333573466e1d4011200225002250044984c10540044c020d5d09aab9e500513333573466e1d4005200025003250064984d55cea8018981da800898021aba135573ca00226ea80084d40192623232323232323232323232323333573466e1d4021200225002250084984ccc11940054009400c4dd69aba150041375a6ae8540084dd69aba135744a00226ae8940044d55cf280289999ab9a3370ea0029000128019280324c26aae75400c4c0fd40044c010d5d09aab9e50011375400426a00a93119191919191919191999ab9a3370ea0089001128011280224c26088a00226eb8d5d09aab9e500513333573466e1d4005200025003250064984d55cea80189820a80089bae357426aae7940044dd500109a80224c46464646464646666ae68cdc39aab9d500548000940089401d26133034500150021300635742a00426eb4d5d09aba25001135573ca00226ea80084d400d2623232323333573466e1cd55cea801240004a0044a0089309bae357426aae7940044dd500109a80124c24c446a601e0044444444444a66a6a042666aa601e24002a01a4a66a6056666ae68cdc780600081681609a8120008a811801908168815899a803a800a80a891299a9a80a8011080188009a80090008918009aa81f910891911299a9a81f00089a80400211099a8029802001199aa98040900080300200089a803000891a9a80180091000891a9a8010009100109109198008018010900091299a980b800880c899ab9c0020182353002001220022212330010030022001222222222212333333333300100b00a00900800700600500400300220012212330010030022001222123330010040030022001221233001003002200112122300200311220011200112212330010030021200112212330010030021200112212330010030021200112200212200120011212223003004112220021122200112001212222300400521222230030052122223002005212222300100520012212330010030022001212222222300700822122222223300600900821222222230050081222222200412222222003221222222233002009008221222222233001009008200121223002003222122333001005004003200121223002003212230010032001112500411220021221223300100400312001120012001112212330010030021120011123230010012233003300200200111112335002212330012350032230020032350032230010030011232323001001223300330020020012212353004123530040033500300100101"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"bytes": "5ffd632484fae2d10bfeb1ec9b827bc57c3672da7eb8a0dd374245a9"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"bytes": "520719ebd328d3bd3a403a29dadaf6981bbddb5e8ff4e47d3f767f26"}
262 changes: 262 additions & 0 deletions cardano_node_tests/tests/test_smart_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
TIME_RANGE_PLUTUS = PLUTUS_DIR / "time_range.plutus"
CONTEXT_EQUIVALENCE_PLUTUS = PLUTUS_DIR / "context-equivalence-test.plutus"
MINTING_CONTEXT_EQUIVALENCE_PLUTUS = PLUTUS_DIR / "minting-context-equivalence-test.plutus"
MINTING_WITNESS_REDEEMER_PLUTUS = PLUTUS_DIR / "witness-redeemer.plutus"

SIGNING_KEY_GOLDEN = DATA_DIR / "golden_normal.skey"
SIGNING_KEY_GOLDEN_EXTENDED = DATA_DIR / "golden_extended.skey"


class PlutusOp(NamedTuple):
Expand Down Expand Up @@ -1604,6 +1606,266 @@ def test_minting(
dbsync_utils.check_tx(cluster_obj=cluster, tx_raw_output=tx_raw_output_step1)
dbsync_utils.check_tx(cluster_obj=cluster, tx_raw_output=tx_raw_output_step2)

@allure.link(helpers.get_vcs_link())
@pytest.mark.dbsync
@pytest.mark.testnets
@pytest.mark.parametrize(
"key",
(
"normal",
"extended",
),
)
def test_witness_redeemer(
self,
cluster: clusterlib.ClusterLib,
payment_addrs: List[clusterlib.AddressRecord],
key: str,
):
"""Test minting a token with a plutus script.
* fund the token issuer and create a UTxO for collateral
* check that the expected amount was transferred to token issuer's address
* mint the token using a plutus script with required signer
* check that the token was minted and collateral UTxO was not spent
* (optional) check transactions in db-sync
"""
# pylint: disable=too-many-locals
temp_template = clusterlib_utils.get_temp_template(cluster)
payment_addr = payment_addrs[0]
issuer_addr = payment_addrs[1]

lovelace_amount = 5000_000
token_amount = 5
plutusrequiredtime = 700_000_000
plutusrequiredspace = 10_000_000
fee_step2 = int(plutusrequiredspace + plutusrequiredtime) + 10_000_000
collateral_amount = int(fee_step2 * 1.5)

if key == "normal":
redeemer_file = PLUTUS_DIR / "witness_golden_normal.datum"
signing_key_golden = SIGNING_KEY_GOLDEN
else:
redeemer_file = PLUTUS_DIR / "witness_golden_extended.datum"
signing_key_golden = SIGNING_KEY_GOLDEN_EXTENDED

issuer_init_balance = cluster.get_address_balance(issuer_addr.address)

# Step 1: fund the token issuer

tx_files_step1 = clusterlib.TxFiles(
signing_key_files=[payment_addr.skey_file],
)
txouts_step1 = [
clusterlib.TxOut(address=issuer_addr.address, amount=lovelace_amount + fee_step2),
# for collateral
clusterlib.TxOut(address=issuer_addr.address, amount=collateral_amount),
]
fee_step1 = cluster.calculate_tx_fee(
src_address=payment_addr.address,
txouts=txouts_step1,
tx_name=f"{temp_template}_step1",
tx_files=tx_files_step1,
# TODO: workaround for https://github.com/input-output-hk/cardano-node/issues/1892
witness_count_add=2,
)
tx_raw_output_step1 = cluster.build_raw_tx(
src_address=payment_addr.address,
tx_name=f"{temp_template}_step1",
txouts=txouts_step1,
tx_files=tx_files_step1,
fee=fee_step1,
# don't join 'change' and 'collateral' txouts, we need separate UTxOs
join_txouts=False,
)
tx_signed_step1 = cluster.sign_tx(
tx_body_file=tx_raw_output_step1.out_file,
signing_key_files=tx_files_step1.signing_key_files,
tx_name=f"{temp_template}_step1",
)
cluster.submit_tx(tx_file=tx_signed_step1, txins=tx_raw_output_step1.txins)

issuer_step1_balance = cluster.get_address_balance(issuer_addr.address)
assert (
issuer_step1_balance
== issuer_init_balance + lovelace_amount + fee_step2 + collateral_amount
), f"Incorrect balance for token issuer address `{issuer_addr.address}`"

# Step 2: mint the "qacoin"

txid_step1 = cluster.get_txid(tx_body_file=tx_raw_output_step1.out_file)
mint_utxos = cluster.get_utxo(txin=f"{txid_step1}#0")
collateral_utxo = clusterlib.UTXOData(
utxo_hash=txid_step1, utxo_ix=1, amount=collateral_amount, address=issuer_addr.address
)
plutus_mint_data = [
clusterlib.PlutusMint(
txins=mint_utxos,
collaterals=[collateral_utxo],
script_file=MINTING_WITNESS_REDEEMER_PLUTUS,
execution_units=(plutusrequiredtime, plutusrequiredspace),
redeemer_file=redeemer_file,
)
]

policyid = cluster.get_policyid(MINTING_WITNESS_REDEEMER_PLUTUS)
asset_name = f"qacoin{clusterlib.get_rand_str(4)}".encode("utf-8").hex()
token = f"{policyid}.{asset_name}"
mint = [clusterlib.TxOut(address=issuer_addr.address, amount=token_amount, coin=token)]

tx_files_step2 = clusterlib.TxFiles(
signing_key_files=[issuer_addr.skey_file, signing_key_golden],
)
txouts_step2 = [
clusterlib.TxOut(address=issuer_addr.address, amount=lovelace_amount),
*mint,
]
tx_raw_output_step2 = cluster.build_raw_tx_bare(
out_file=f"{temp_template}_step2_tx.body",
txouts=txouts_step2,
tx_files=tx_files_step2,
fee=fee_step2,
plutus_mint=plutus_mint_data,
required_signers=[signing_key_golden],
mint=mint,
)
tx_signed_step2 = cluster.sign_tx(
tx_body_file=tx_raw_output_step2.out_file,
signing_key_files=tx_files_step2.signing_key_files,
tx_name=f"{temp_template}_step2",
)
cluster.submit_tx(tx_file=tx_signed_step2, txins=mint_utxos)

assert (
cluster.get_address_balance(issuer_addr.address)
== issuer_init_balance + collateral_amount + lovelace_amount
), f"Incorrect balance for token issuer address `{issuer_addr.address}`"

token_utxo = cluster.get_utxo(address=issuer_addr.address, coins=[token])
assert token_utxo and token_utxo[0].amount == token_amount, "The token was not minted"

dbsync_utils.check_tx(cluster_obj=cluster, tx_raw_output=tx_raw_output_step1)
dbsync_utils.check_tx(cluster_obj=cluster, tx_raw_output=tx_raw_output_step2)

@allure.link(helpers.get_vcs_link())
@pytest.mark.testnets
def test_witness_redeemer_missing_signer(
self, cluster: clusterlib.ClusterLib, payment_addrs: List[clusterlib.AddressRecord]
):
"""Test minting a token with a plutus script.
Expect failure.
* fund the token issuer and create a UTxO for collateral
* check that the expected amount was transferred to token issuer's address
* try to mint the token using a plutus script and a TX with signing key missing for
the required signer
* check that the token was minted and collateral UTxO was not spent
* (optional) check transactions in db-sync
"""
# pylint: disable=too-many-locals
temp_template = clusterlib_utils.get_temp_template(cluster)
payment_addr = payment_addrs[0]
issuer_addr = payment_addrs[1]

lovelace_amount = 5000_000
token_amount = 5
plutusrequiredtime = 700_000_000
plutusrequiredspace = 10_000_000
fee_step2 = int(plutusrequiredspace + plutusrequiredtime) + 10_000_000
collateral_amount = int(fee_step2 * 1.5)

redeemer_file = PLUTUS_DIR / "witness_golden_normal.datum"

issuer_init_balance = cluster.get_address_balance(issuer_addr.address)

# Step 1: fund the token issuer

tx_files_step1 = clusterlib.TxFiles(
signing_key_files=[payment_addr.skey_file],
)
txouts_step1 = [
clusterlib.TxOut(address=issuer_addr.address, amount=lovelace_amount + fee_step2),
# for collateral
clusterlib.TxOut(address=issuer_addr.address, amount=collateral_amount),
]
fee_step1 = cluster.calculate_tx_fee(
src_address=payment_addr.address,
txouts=txouts_step1,
tx_name=f"{temp_template}_step1",
tx_files=tx_files_step1,
# TODO: workaround for https://github.com/input-output-hk/cardano-node/issues/1892
witness_count_add=2,
)
tx_raw_output_step1 = cluster.build_raw_tx(
src_address=payment_addr.address,
tx_name=f"{temp_template}_step1",
txouts=txouts_step1,
tx_files=tx_files_step1,
fee=fee_step1,
# don't join 'change' and 'collateral' txouts, we need separate UTxOs
join_txouts=False,
)
tx_signed_step1 = cluster.sign_tx(
tx_body_file=tx_raw_output_step1.out_file,
signing_key_files=tx_files_step1.signing_key_files,
tx_name=f"{temp_template}_step1",
)
cluster.submit_tx(tx_file=tx_signed_step1, txins=tx_raw_output_step1.txins)

issuer_step1_balance = cluster.get_address_balance(issuer_addr.address)
assert (
issuer_step1_balance
== issuer_init_balance + lovelace_amount + fee_step2 + collateral_amount
), f"Incorrect balance for token issuer address `{issuer_addr.address}`"

# Step 2: mint the "qacoin"

txid_step1 = cluster.get_txid(tx_body_file=tx_raw_output_step1.out_file)
mint_utxos = cluster.get_utxo(txin=f"{txid_step1}#0")
collateral_utxo = clusterlib.UTXOData(
utxo_hash=txid_step1, utxo_ix=1, amount=collateral_amount, address=issuer_addr.address
)
plutus_mint_data = [
clusterlib.PlutusMint(
txins=mint_utxos,
collaterals=[collateral_utxo],
script_file=MINTING_WITNESS_REDEEMER_PLUTUS,
execution_units=(plutusrequiredtime, plutusrequiredspace),
redeemer_file=redeemer_file,
)
]

policyid = cluster.get_policyid(MINTING_WITNESS_REDEEMER_PLUTUS)
asset_name = f"qacoin{clusterlib.get_rand_str(4)}".encode("utf-8").hex()
token = f"{policyid}.{asset_name}"
mint = [clusterlib.TxOut(address=issuer_addr.address, amount=token_amount, coin=token)]

tx_files_step2 = clusterlib.TxFiles(
signing_key_files=[issuer_addr.skey_file],
)
txouts_step2 = [
clusterlib.TxOut(address=issuer_addr.address, amount=lovelace_amount),
*mint,
]
tx_raw_output_step2 = cluster.build_raw_tx_bare(
out_file=f"{temp_template}_step2_tx.body",
txouts=txouts_step2,
tx_files=tx_files_step2,
fee=fee_step2,
plutus_mint=plutus_mint_data,
required_signers=[SIGNING_KEY_GOLDEN],
mint=mint,
)
tx_signed_step2 = cluster.sign_tx(
tx_body_file=tx_raw_output_step2.out_file,
signing_key_files=tx_files_step2.signing_key_files,
tx_name=f"{temp_template}_step2",
)
with pytest.raises(clusterlib.CLIError) as excinfo:
cluster.submit_tx(tx_file=tx_signed_step2, txins=mint_utxos)
assert "MissingRequiredSigners" in str(excinfo.value)

@allure.link(helpers.get_vcs_link())
@pytest.mark.dbsync
@pytest.mark.testnets
Expand Down

0 comments on commit 7ff694b

Please sign in to comment.