Skip to content

Commit

Permalink
Merge pull request #573 from mkoura/plutus_test
Browse files Browse the repository at this point in the history
First Plutus test
  • Loading branch information
mkoura committed Jun 17, 2021
2 parents b6e3838 + 06e080d commit 41b9c48
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 10 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Expand Up @@ -6,7 +6,7 @@ repos:
- id: reorder-python-imports
language_version: python3
- repo: https://github.com/ambv/black
rev: 21.5b1
rev: 21.6b0
hooks:
- id: black
args: [--safe, --quiet]
Expand All @@ -32,7 +32,7 @@ repos:
language_version: python3
additional_dependencies: [flake8-comprehensions]
- repo: https://github.com/asottile/pyupgrade
rev: v2.17.0
rev: v2.19.4
hooks:
- id: pyupgrade
language_version: python3
Expand Down
@@ -0,0 +1,5 @@
{
"type": "PlutusScriptV1",
"description": "",
"cborHex": "5899589701000033200200333200200200333333200200200200200200332002002002002000051200001200001200120020020020020030050062002001200200200200200330040070062001200200200200200300300620012002002002002003002006200120020020020020030010062000011120020000212002001200200330010040031200001112002001200330010030021120000101"
}
189 changes: 189 additions & 0 deletions cardano_node_tests/tests/test_smart_contracts.py
@@ -0,0 +1,189 @@
"""Tests for smart contracts."""
import logging
from pathlib import Path

import allure
import pytest
from _pytest.tmpdir import TempdirFactory
from cardano_clusterlib import clusterlib

from cardano_node_tests.utils import cluster_management
from cardano_node_tests.utils import clusterlib_utils
from cardano_node_tests.utils import helpers
from cardano_node_tests.utils.versions import VERSIONS

LOGGER = logging.getLogger(__name__)
DATA_DIR = Path(__file__).parent / "data"


@pytest.fixture(scope="module")
def create_temp_dir(tmp_path_factory: TempdirFactory):
"""Create a temporary dir."""
p = Path(tmp_path_factory.getbasetemp()).joinpath(helpers.get_id_for_mktemp(__file__)).resolve()
p.mkdir(exist_ok=True, parents=True)
return p


@pytest.fixture
def temp_dir(create_temp_dir: Path):
"""Change to a temporary dir."""
with helpers.change_cwd(create_temp_dir):
yield create_temp_dir


# use the "temp_dir" fixture for all tests automatically
pytestmark = pytest.mark.usefixtures("temp_dir")


@pytest.mark.skipif(
VERSIONS.transaction_era < VERSIONS.ALONZO,
reason="runs only with Alonzo+ TX",
)
class TestPlutus:
"""Tests for Plutus smart contracts."""

ALWAYS_SUCCEEDS_PLUTUS = DATA_DIR / "untyped-always-succeeds-txin.plutus"

@pytest.fixture
def payment_addr(
self,
cluster_manager: cluster_management.ClusterManager,
cluster: clusterlib.ClusterLib,
) -> clusterlib.AddressRecord:
"""Create new payment address."""
with cluster_manager.cache_fixture() as fixture_cache:
if fixture_cache.value:
return fixture_cache.value # type: ignore

addr = cluster.gen_payment_addr_and_keys(
name=f"token_transfer_ci{cluster_manager.cluster_instance_num}",
)
fixture_cache.value = addr

# fund source addresses
clusterlib_utils.fund_from_faucet(
addr,
cluster_obj=cluster,
faucet_data=cluster_manager.cache.addrs_data["user1"],
amount=2000_000_000,
)

return addr

@allure.link(helpers.get_vcs_link())
@pytest.mark.testnets
def test_txin_locking(
self, cluster: clusterlib.ClusterLib, payment_addr: clusterlib.AddressRecord
):
"""Test locking a Tx output with a plutus script and spending the locked UTxO.
Corresponds to Exercise 3 for Alonzo blue.
* create a Tx ouput with a datum hash at the script address
* check that the expected amount was locked at the script address
* spend the locked UTxO
* check that the expected amount was spent
"""
amount = 50_000_000
expected_fee = 801_000_000
datum_value = "49"

temp_template = helpers.get_func_name()

script_address = cluster.gen_script_addr(
addr_name=temp_template, script_file=self.ALWAYS_SUCCEEDS_PLUTUS
)

script_init_balance = cluster.get_address_balance(script_address)

# create a Tx ouput with a datum hash at the script address
tx_files_datum = clusterlib.TxFiles(
signing_key_files=[payment_addr.skey_file],
)
datum_hash = cluster.get_hash_script_data(script_data_value=datum_value)
txouts_datum = [
clusterlib.TxOut(
address=script_address, amount=amount + expected_fee, datum_hash=datum_hash
),
clusterlib.TxOut(address=payment_addr.address, amount=expected_fee), # for collateral
]
fee_datum = cluster.calculate_tx_fee(
src_address=payment_addr.address,
txouts=txouts_datum,
tx_name=f"{temp_template}_datum_hash",
tx_files=tx_files_datum,
# TODO: workaround for https://github.com/input-output-hk/cardano-node/issues/1892
witness_count_add=2,
)
tx_raw_output_datum = cluster.build_raw_tx(
src_address=payment_addr.address,
tx_name=f"{temp_template}_datum_hash",
txouts=txouts_datum,
tx_files=tx_files_datum,
fee=fee_datum,
join_txouts=False, # don't join change and collateral txouts, we need separate UTxOs
)
tx_signed_datum = cluster.sign_tx(
tx_body_file=tx_raw_output_datum.out_file,
signing_key_files=tx_files_datum.signing_key_files,
tx_name=f"{temp_template}_datum_hash",
)
cluster.submit_tx(tx_file=tx_signed_datum, txins=tx_raw_output_datum.txins)

script_datum_balance = cluster.get_address_balance(script_address)
assert (
script_datum_balance == script_init_balance + amount + expected_fee
), f"Incorrect balance for script address `{script_address}`"

src_init_balance = cluster.get_address_balance(payment_addr.address)

# spend the "locked" UTxO
txid_body = cluster.get_txid(tx_body_file=tx_raw_output_datum.out_file)
script_utxo = clusterlib.UTXOData(
utxo_hash=txid_body,
utxo_ix=0,
amount=amount + expected_fee,
address=script_address,
)
collateral_utxo = clusterlib.UTXOData(
utxo_hash=txid_body, utxo_ix=1, amount=expected_fee, address=payment_addr.address
)
plutus_txins = [
clusterlib.PlutusTxIn(
txin=script_utxo,
collateral=collateral_utxo,
script_file=self.ALWAYS_SUCCEEDS_PLUTUS,
execution_units=(200000000, 200000000),
datum_value=datum_value,
redeemer_value=datum_value,
)
]
txouts_spend = [
clusterlib.TxOut(address=payment_addr.address, amount=amount),
]
tx_files_spend = clusterlib.TxFiles(
signing_key_files=[payment_addr.skey_file],
)
tx_raw_output_spend = cluster.build_raw_tx_bare(
out_file=f"{temp_template}_spend_tx.body",
txouts=txouts_spend,
tx_files=tx_files_spend,
fee=expected_fee,
plutus_txins=plutus_txins,
)
tx_signed_spend = cluster.sign_tx(
tx_body_file=tx_raw_output_spend.out_file,
signing_key_files=tx_files_spend.signing_key_files,
tx_name=f"{temp_template}_spend",
)
cluster.submit_tx(
tx_file=tx_signed_spend, txins=[t.txin for t in tx_raw_output_spend.plutus_txins]
)

assert (
cluster.get_address_balance(payment_addr.address) == src_init_balance + amount
), f"Incorrect balance for source address `{payment_addr.address}`"

assert (
cluster.get_address_balance(script_address) == script_init_balance
), f"Incorrect balance for script address `{script_address}`"
4 changes: 2 additions & 2 deletions nix/cardano-clusterlib.nix
Expand Up @@ -2,10 +2,10 @@

buildPythonPackage rec {
pname = "cardano-clusterlib";
version = "0.1.24";
version = "0.1.25";
src = fetchPypi {
inherit pname version;
sha256 = "0x8256w83bbvz4jdjv0hmxx3gd985s6smlki0p2ljh2nxx3vv6gz";
sha256 = "1x922rc9slqvxhs6ahyajqbw51wim6lmvxnvjwsahs4ibyvcnf79";
};
doCheck = false;
nativeBuildInputs = [ setuptools_scm ];
Expand Down
12 changes: 6 additions & 6 deletions nix/sources.json
Expand Up @@ -5,10 +5,10 @@
"homepage": "https://cardano.org",
"owner": "input-output-hk",
"repo": "cardano-node",
"rev": "55577d74986a2fdeb4d0ec8637122f14e185997c",
"sha256": "1w9jnqhzvwbabfv2p9c5l43pm7l7in7xkw00pm71fwpkk7ngm2dp",
"rev": "400082015bfb1e8233b42225d9eb99fb4524e0b2",
"sha256": "1iyk5sx3zdf6kan3nwfjk3ijy4rgclq9c9kypjk70c67r7m0lnsb",
"type": "tarball",
"url": "https://github.com/input-output-hk/cardano-node/archive/55577d74986a2fdeb4d0ec8637122f14e185997c.tar.gz",
"url": "https://github.com/input-output-hk/cardano-node/archive/400082015bfb1e8233b42225d9eb99fb4524e0b2.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs": {
Expand All @@ -17,10 +17,10 @@
"homepage": "https://github.com/NixOS/nixpkgs",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "03aa75f46d14e3323d03262ca424b2e7f0aab99c",
"sha256": "08krad9fgn0i9cn6b7ddfwsd383xk0zscz1aabz6338qf8qjb2sb",
"rev": "7c845e60cd5bfe3cccce1798aca2a3a5bc7c3d04",
"sha256": "1k0ifnjql6wpx9xpzl49k880jxrdiyq471jzd5nm0p2vaiymfdn5",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/03aa75f46d14e3323d03262ca424b2e7f0aab99c.tar.gz",
"url": "https://github.com/NixOS/nixpkgs/archive/7c845e60cd5bfe3cccce1798aca2a3a5bc7c3d04.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}
}

0 comments on commit 41b9c48

Please sign in to comment.