expose tx simulation with simulate cli command
This commit is contained in:
parent
3f27bd9f13
commit
02a8a34fe8
|
@ -688,6 +688,7 @@ dependencies = [
|
||||||
"peg",
|
"peg",
|
||||||
"pretty",
|
"pretty",
|
||||||
"proptest",
|
"proptest",
|
||||||
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::{collections::HashMap, path::PathBuf};
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
/// Cardano smart contract toolchain
|
/// Cardano smart contract toolchain
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
@ -26,36 +25,13 @@ pub enum TxCommand {
|
||||||
cbor: bool,
|
cbor: bool,
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
resolved_inputs: PathBuf,
|
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<String, HashMap<String, u64>>),
|
|
||||||
pub datum: Option<OutputDatum>,
|
|
||||||
pub script: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub enum OutputDatum {
|
|
||||||
DatumHash(String),
|
|
||||||
Datum(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Commands for working with Untyped Plutus Core
|
/// Commands for working with Untyped Plutus Core
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
pub enum UplcCommand {
|
pub enum UplcCommand {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Write as _,
|
fmt::Write as _,
|
||||||
fs::{self},
|
fs::{self, File},
|
||||||
|
io::BufReader,
|
||||||
};
|
};
|
||||||
|
|
||||||
use pallas_traverse::{Era, MultiEraTx};
|
use pallas_traverse::{Era, MultiEraTx};
|
||||||
|
@ -8,6 +9,8 @@ use uplc::{
|
||||||
ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Program, Term},
|
ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Program, Term},
|
||||||
machine::cost_model::ExBudget,
|
machine::cost_model::ExBudget,
|
||||||
parser,
|
parser,
|
||||||
|
transaction_eval::eval_tx,
|
||||||
|
transaction_eval::script_context::{ResolvedInput, SlotConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod args;
|
mod args;
|
||||||
|
@ -22,7 +25,9 @@ fn main() -> anyhow::Result<()> {
|
||||||
TxCommand::Simulate {
|
TxCommand::Simulate {
|
||||||
input,
|
input,
|
||||||
cbor,
|
cbor,
|
||||||
resolved_inputs: _,
|
resolved_inputs,
|
||||||
|
slot_length,
|
||||||
|
zero_time,
|
||||||
} => {
|
} => {
|
||||||
let tx_bytes = if cbor {
|
let tx_bytes = if cbor {
|
||||||
fs::read(input)?
|
fs::read(input)?
|
||||||
|
@ -37,7 +42,18 @@ fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
println!("Simulating: {}", tx.hash());
|
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<ResolvedInput> = 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 {
|
Args::Uplc(uplc_cmd) => match uplc_cmd {
|
||||||
|
|
|
@ -25,6 +25,7 @@ peg = "0.8.0"
|
||||||
pretty = "0.11.3"
|
pretty = "0.11.3"
|
||||||
thiserror = "1.0.31"
|
thiserror = "1.0.31"
|
||||||
anyhow = "1.0.57"
|
anyhow = "1.0.57"
|
||||||
|
serde = { version = "1.0.144", features = ["derive"] }
|
||||||
serde_json = "1.0.85"
|
serde_json = "1.0.85"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -2,9 +2,9 @@ use pallas_primitives::babbage::{MintedTx, Redeemer};
|
||||||
|
|
||||||
use self::script_context::{ResolvedInput, SlotConfig};
|
use self::script_context::{ResolvedInput, SlotConfig};
|
||||||
|
|
||||||
mod script_context;
|
mod eval;
|
||||||
|
pub mod script_context;
|
||||||
mod to_plutus_data;
|
mod to_plutus_data;
|
||||||
mod utils;
|
|
||||||
|
|
||||||
pub fn eval_tx(
|
pub fn eval_tx(
|
||||||
tx: &MintedTx,
|
tx: &MintedTx,
|
||||||
|
@ -14,13 +14,13 @@ pub fn eval_tx(
|
||||||
) -> anyhow::Result<Vec<Redeemer>> {
|
) -> anyhow::Result<Vec<Redeemer>> {
|
||||||
let redeemers = tx.transaction_witness_set.redeemer.as_ref();
|
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 {
|
match redeemers {
|
||||||
Some(rs) => {
|
Some(rs) => {
|
||||||
let mut collected_redeemers = vec![];
|
let mut collected_redeemers = vec![];
|
||||||
for redeemer in rs.iter() {
|
for redeemer in rs.iter() {
|
||||||
collected_redeemers.push(utils::eval_redeemer(
|
collected_redeemers.push(eval::eval_redeemer(
|
||||||
tx,
|
tx,
|
||||||
utxos,
|
utxos,
|
||||||
slot_config,
|
slot_config,
|
||||||
|
|
|
@ -7,9 +7,9 @@ use pallas_addresses::{Address, ScriptHash, StakePayload};
|
||||||
use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray};
|
use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray};
|
||||||
use pallas_crypto::hash::Hash;
|
use pallas_crypto::hash::Hash;
|
||||||
use pallas_primitives::babbage::{
|
use pallas_primitives::babbage::{
|
||||||
Certificate, DatumHash, DatumOption, ExUnits, Mint, MintedTx,
|
Certificate, DatumHash, DatumOption, ExUnits, Mint, MintedTx, PlutusV1Script, PlutusV2Script,
|
||||||
PlutusV1Script, PlutusV2Script, PolicyId, Redeemer, RedeemerTag, RewardAccount, Script,
|
PolicyId, Redeemer, RedeemerTag, RewardAccount, Script, StakeCredential, TransactionInput,
|
||||||
StakeCredential, TransactionInput, TransactionOutput, Value, Withdrawals,
|
TransactionOutput, Value, Withdrawals,
|
||||||
};
|
};
|
||||||
use pallas_traverse::{ComputeHash, OriginalHash};
|
use pallas_traverse::{ComputeHash, OriginalHash};
|
||||||
use std::{collections::HashMap, convert::TryInto, ops::Deref, vec};
|
use std::{collections::HashMap, convert::TryInto, ops::Deref, vec};
|
||||||
|
@ -712,4 +712,3 @@ pub fn eval_redeemer(
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,9 @@ use pallas_primitives::babbage::{
|
||||||
AddrKeyhash, Certificate, Coin, DatumHash, Mint, PlutusData, PolicyId, Redeemer, RewardAccount,
|
AddrKeyhash, Certificate, Coin, DatumHash, Mint, PlutusData, PolicyId, Redeemer, RewardAccount,
|
||||||
StakeCredential, TransactionInput, TransactionOutput, Value, Withdrawals,
|
StakeCredential, TransactionInput, TransactionOutput, Value, Withdrawals,
|
||||||
};
|
};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Deserialize)]
|
||||||
pub struct ResolvedInput {
|
pub struct ResolvedInput {
|
||||||
pub input: TransactionInput,
|
pub input: TransactionInput,
|
||||||
pub output: TransactionOutput,
|
pub output: TransactionOutput,
|
||||||
|
@ -83,3 +84,12 @@ pub struct SlotConfig {
|
||||||
pub slot_length: u64,
|
pub slot_length: u64,
|
||||||
pub zero_time: u64,
|
pub zero_time: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for SlotConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
slot_length: 1000,
|
||||||
|
zero_time: 1596491091,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue