mesmo 0.1.0-pre8

Rust bindings for Cardano Client Lib (CCL) via GraalVM native library
//! End-to-end coverage of every TxPlan intent through the native library.
//!
//! The fixtures in `test-fixtures/quicktx-intents/` are generated by the JVM QuickTxIntentsTest via
//! `TxPlan.from(tx).toYaml()`; here each is built through the native library via the Rust wrapper.
//! Mirrors the Go `intents_test.go` for cross-wrapper parity.
//!
//! Run from wrappers/rust:
//!   MESMO_LIB_PATH=../../core/build/native/nativeCompile \
//!     cargo test --test intents_test -- --test-threads=1

use mesmo::Mesmo;
use serde_json::{json, Value};
use std::fs;
use std::path::{Path, PathBuf};

const SENDER: &str = "addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp";
const SENDER2: &str = "addr_test1qz7svwszky8gcmhrfza7a89z9u0dfzd3l7h23sqlc5yml7ejcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwqcqrvr0";
const SCRIPT_ADDR: &str = "addr_test1wpunlryvl7aqsxe22erzlsseej87v5kk5vutvtrmzdy8dect48z0w";
const SCRIPT_DATUM_HASH: &str = "9e1199a988ba72ffd6e9c269cadb3b53b5f360ff99f112d9b2ee30c4d74ad88b";
const SCRIPT_TX_HASH: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";

fn fixtures_dir() -> PathBuf {
    Path::new(env!("CARGO_MANIFEST_DIR")).join("../../test-fixtures/quicktx-intents")
}

// Protocol parameters incl. the Conway deposits the governance/staking/pool intents need.
fn protocol_params() -> Value {
    json!({
        "min_fee_a": 44, "min_fee_b": 155381, "max_tx_size": 16384, "max_val_size": "5000",
        "key_deposit": "2000000", "pool_deposit": "500000000", "drep_deposit": "2000000",
        "gov_action_deposit": "1000000000", "coins_per_utxo_size": "4310",
        "max_tx_ex_mem": "14000000", "max_tx_ex_steps": "10000000000",
        "price_mem": 0.0577, "price_step": 0.0000721, "collateral_percent": 150,
        "max_collateral_inputs": 3, "min_fee_ref_script_cost_per_byte": 15
    })
}

fn utxos() -> Value {
    json!([
        {"tx_hash": "a".repeat(64), "output_index": 0, "address": SENDER,
         "amount": [{"unit": "lovelace", "quantity": "2000000000"}]},
        {"tx_hash": "c".repeat(64), "output_index": 0, "address": SENDER,
         "amount": [{"unit": "lovelace", "quantity": "5000000"}]},
        {"tx_hash": "a".repeat(64), "output_index": 1, "address": SENDER2,
         "amount": [{"unit": "lovelace", "quantity": "2000000000"}]}
    ])
}

#[test]
fn intents_build_e2e() {
    let lib = Mesmo::new().expect("create lib");
    let pp = protocol_params();
    let u = utxos();

    let mut count = 0;
    for entry in fs::read_dir(fixtures_dir()).expect("read fixtures dir") {
        let path = entry.unwrap().path();
        if path.extension().and_then(|e| e.to_str()) != Some("yaml") {
            continue;
        }
        let yaml = fs::read_to_string(&path).unwrap();
        let result = lib
            .quicktx()
            .build(&yaml, &u, &pp, None, 1)
            .unwrap_or_else(|e| panic!("build {:?}: {:?}", path.file_name().unwrap(), e));
        assert_eq!(result.tx_hash.len(), 64, "{:?}", path.file_name().unwrap());
        assert!(!result.tx_cbor.is_empty());
        count += 1;
    }
    assert!(count >= 19, "expected >= 19 intent fixtures, found {}", count);
}

#[test]
fn plutus_mint_e2e() {
    let lib = Mesmo::new().expect("create lib");
    let yaml = fs::read_to_string(fixtures_dir().join("plutus/script_minting.yaml")).unwrap();
    let u = json!([{"tx_hash": "a".repeat(64), "output_index": 0, "address": SENDER,
                    "amount": [{"unit": "lovelace", "quantity": "2000000000"}]}]);
    let exec = json!([{"mem": 2000000, "steps": 500000000}]);

    let result = lib.quicktx().build(&yaml, &u, &protocol_params(), Some(&exec), 0).expect("mint");
    assert_eq!(result.tx_hash.len(), 64);
    assert!(lib.quicktx().build(&yaml, &u, &protocol_params(), None, 0).is_err());
}

#[test]
fn plutus_spend_e2e() {
    let lib = Mesmo::new().expect("create lib");
    let yaml = fs::read_to_string(fixtures_dir().join("plutus/script_collect_from.yaml")).unwrap();
    let u = json!([
        {"tx_hash": SCRIPT_TX_HASH, "output_index": 0, "address": SCRIPT_ADDR,
         "amount": [{"unit": "lovelace", "quantity": "10000000"}], "data_hash": SCRIPT_DATUM_HASH},
        {"tx_hash": "a".repeat(64), "output_index": 0, "address": SENDER,
         "amount": [{"unit": "lovelace", "quantity": "2000000000"}]}
    ]);
    let exec = json!([{"mem": 2000000, "steps": 500000000}]);

    let result = lib.quicktx().build(&yaml, &u, &protocol_params(), Some(&exec), 0).expect("spend");
    assert_eq!(result.tx_hash.len(), 64);
    assert!(lib.quicktx().build(&yaml, &u, &protocol_params(), None, 0).is_err());
}