From 02a8a34fe8f2169f808efe98ea99c35a7b1993b2 Mon Sep 17 00:00:00 2001 From: Kasey White Date: Fri, 16 Sep 2022 04:35:20 -0400 Subject: [PATCH] expose tx simulation with simulate cli command --- Cargo.lock | 1 + crates/cli/src/args.rs | 34 +++---------------- crates/cli/src/main.rs | 22 ++++++++++-- crates/uplc/Cargo.toml | 1 + crates/uplc/src/transaction_eval.rs | 8 ++--- .../transaction_eval/{utils.rs => eval.rs} | 7 ++-- .../src/transaction_eval/script_context.rs | 12 ++++++- 7 files changed, 44 insertions(+), 41 deletions(-) rename crates/uplc/src/transaction_eval/{utils.rs => eval.rs} (99%) diff --git a/Cargo.lock b/Cargo.lock index e123a658..bc815bba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -688,6 +688,7 @@ dependencies = [ "peg", "pretty", "proptest", + "serde", "serde_json", "thiserror", ] diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs index 15ffa8fb..c861c25b 100644 --- a/crates/cli/src/args.rs +++ b/crates/cli/src/args.rs @@ -1,7 +1,6 @@ -use std::{collections::HashMap, path::PathBuf}; +use std::path::PathBuf; use clap::{Parser, Subcommand}; -use serde::Deserialize; /// Cardano smart contract toolchain #[derive(Parser)] @@ -26,36 +25,13 @@ pub enum TxCommand { cbor: bool, #[clap(short, long)] resolved_inputs: PathBuf, + #[clap(short, long)] + slot_length: u64, + #[clap(short, long)] + zero_time: u64, }, } -#[derive(Deserialize)] -pub struct ResolvedInputOld { - pub input: Input, - pub output: Output, -} - -#[derive(Deserialize)] -pub struct Input { - pub tx_hash: String, - pub index: u64, -} - -#[derive(Deserialize)] -pub struct Output { - pub address: String, - pub value: (u64, HashMap>), - pub datum: Option, - pub script: Option, -} - -#[derive(Deserialize)] -#[serde(rename_all = "snake_case")] -pub enum OutputDatum { - DatumHash(String), - Datum(String), -} - /// Commands for working with Untyped Plutus Core #[derive(Subcommand)] pub enum UplcCommand { diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 604c1fd8..54d4cb3c 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1,6 +1,7 @@ use std::{ fmt::Write as _, - fs::{self}, + fs::{self, File}, + io::BufReader, }; use pallas_traverse::{Era, MultiEraTx}; @@ -8,6 +9,8 @@ use uplc::{ ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Program, Term}, machine::cost_model::ExBudget, parser, + transaction_eval::eval_tx, + transaction_eval::script_context::{ResolvedInput, SlotConfig}, }; mod args; @@ -22,7 +25,9 @@ fn main() -> anyhow::Result<()> { TxCommand::Simulate { input, cbor, - resolved_inputs: _, + resolved_inputs, + slot_length, + zero_time, } => { let tx_bytes = if cbor { fs::read(input)? @@ -37,7 +42,18 @@ fn main() -> anyhow::Result<()> { println!("Simulating: {}", tx.hash()); - + if let Some(tx_babbage) = tx.as_babbage() { + let file = File::open(&resolved_inputs)?; + let reader = BufReader::new(file); + let resolved_inputs: Vec = serde_json::from_reader(reader)?; + + let slot_config = SlotConfig { + zero_time, + slot_length, + }; + + eval_tx(tx_babbage, &resolved_inputs, &slot_config)?; + } } }, Args::Uplc(uplc_cmd) => match uplc_cmd { diff --git a/crates/uplc/Cargo.toml b/crates/uplc/Cargo.toml index 4ebe5993..56e4b6ef 100644 --- a/crates/uplc/Cargo.toml +++ b/crates/uplc/Cargo.toml @@ -25,6 +25,7 @@ peg = "0.8.0" pretty = "0.11.3" thiserror = "1.0.31" anyhow = "1.0.57" +serde = { version = "1.0.144", features = ["derive"] } serde_json = "1.0.85" [dev-dependencies] diff --git a/crates/uplc/src/transaction_eval.rs b/crates/uplc/src/transaction_eval.rs index 941a48c6..87cb3056 100644 --- a/crates/uplc/src/transaction_eval.rs +++ b/crates/uplc/src/transaction_eval.rs @@ -2,9 +2,9 @@ use pallas_primitives::babbage::{MintedTx, Redeemer}; use self::script_context::{ResolvedInput, SlotConfig}; -mod script_context; +mod eval; +pub mod script_context; mod to_plutus_data; -mod utils; pub fn eval_tx( tx: &MintedTx, @@ -14,13 +14,13 @@ pub fn eval_tx( ) -> anyhow::Result> { let redeemers = tx.transaction_witness_set.redeemer.as_ref(); - let lookup_table = utils::get_script_and_datum_lookup_table(tx, utxos); + let lookup_table = eval::get_script_and_datum_lookup_table(tx, utxos); match redeemers { Some(rs) => { let mut collected_redeemers = vec![]; for redeemer in rs.iter() { - collected_redeemers.push(utils::eval_redeemer( + collected_redeemers.push(eval::eval_redeemer( tx, utxos, slot_config, diff --git a/crates/uplc/src/transaction_eval/utils.rs b/crates/uplc/src/transaction_eval/eval.rs similarity index 99% rename from crates/uplc/src/transaction_eval/utils.rs rename to crates/uplc/src/transaction_eval/eval.rs index 554e8832..7fc37e73 100644 --- a/crates/uplc/src/transaction_eval/utils.rs +++ b/crates/uplc/src/transaction_eval/eval.rs @@ -7,9 +7,9 @@ use pallas_addresses::{Address, ScriptHash, StakePayload}; use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray}; use pallas_crypto::hash::Hash; use pallas_primitives::babbage::{ - Certificate, DatumHash, DatumOption, ExUnits, Mint, MintedTx, - PlutusV1Script, PlutusV2Script, PolicyId, Redeemer, RedeemerTag, RewardAccount, Script, - StakeCredential, TransactionInput, TransactionOutput, Value, Withdrawals, + Certificate, DatumHash, DatumOption, ExUnits, Mint, MintedTx, PlutusV1Script, PlutusV2Script, + PolicyId, Redeemer, RedeemerTag, RewardAccount, Script, StakeCredential, TransactionInput, + TransactionOutput, Value, Withdrawals, }; use pallas_traverse::{ComputeHash, OriginalHash}; use std::{collections::HashMap, convert::TryInto, ops::Deref, vec}; @@ -712,4 +712,3 @@ pub fn eval_redeemer( }, } } - diff --git a/crates/uplc/src/transaction_eval/script_context.rs b/crates/uplc/src/transaction_eval/script_context.rs index 1f8eb9d8..4e883464 100644 --- a/crates/uplc/src/transaction_eval/script_context.rs +++ b/crates/uplc/src/transaction_eval/script_context.rs @@ -4,8 +4,9 @@ use pallas_primitives::babbage::{ AddrKeyhash, Certificate, Coin, DatumHash, Mint, PlutusData, PolicyId, Redeemer, RewardAccount, StakeCredential, TransactionInput, TransactionOutput, Value, Withdrawals, }; +use serde::Deserialize; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Deserialize)] pub struct ResolvedInput { pub input: TransactionInput, pub output: TransactionOutput, @@ -83,3 +84,12 @@ pub struct SlotConfig { pub slot_length: u64, pub zero_time: u64, } + +impl Default for SlotConfig { + fn default() -> Self { + Self { + slot_length: 1000, + zero_time: 1596491091, + } + } +}