Add (partial) support for simulating contract with proposal procedures
This covers every proposal procedures but protocol parameters, this one is yet to be done. It spans over 30+ fields, and felt like it is a big enough piece to tackle it on its own.
This commit is contained in:
parent
6b6bace8a5
commit
cfca0da4e9
|
@ -1942,7 +1942,7 @@ checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pallas-addresses"
|
name = "pallas-addresses"
|
||||||
version = "0.29.0"
|
version = "0.29.0"
|
||||||
source = "git+https://github.com/KtorZ/pallas.git?rev=8ea5a1adc9919b70b213dfe597e920d6e113120c#8ea5a1adc9919b70b213dfe597e920d6e113120c"
|
source = "git+https://github.com/KtorZ/pallas.git?rev=0cdd6393bb3fbceb3b5209ad248877b381822e90#0cdd6393bb3fbceb3b5209ad248877b381822e90"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base58",
|
"base58",
|
||||||
"bech32",
|
"bech32",
|
||||||
|
@ -1957,7 +1957,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pallas-codec"
|
name = "pallas-codec"
|
||||||
version = "0.29.0"
|
version = "0.29.0"
|
||||||
source = "git+https://github.com/KtorZ/pallas.git?rev=8ea5a1adc9919b70b213dfe597e920d6e113120c#8ea5a1adc9919b70b213dfe597e920d6e113120c"
|
source = "git+https://github.com/KtorZ/pallas.git?rev=0cdd6393bb3fbceb3b5209ad248877b381822e90#0cdd6393bb3fbceb3b5209ad248877b381822e90"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"minicbor",
|
"minicbor",
|
||||||
|
@ -1969,7 +1969,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pallas-crypto"
|
name = "pallas-crypto"
|
||||||
version = "0.29.0"
|
version = "0.29.0"
|
||||||
source = "git+https://github.com/KtorZ/pallas.git?rev=8ea5a1adc9919b70b213dfe597e920d6e113120c#8ea5a1adc9919b70b213dfe597e920d6e113120c"
|
source = "git+https://github.com/KtorZ/pallas.git?rev=0cdd6393bb3fbceb3b5209ad248877b381822e90#0cdd6393bb3fbceb3b5209ad248877b381822e90"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cryptoxide",
|
"cryptoxide",
|
||||||
"hex",
|
"hex",
|
||||||
|
@ -1982,7 +1982,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pallas-primitives"
|
name = "pallas-primitives"
|
||||||
version = "0.29.0"
|
version = "0.29.0"
|
||||||
source = "git+https://github.com/KtorZ/pallas.git?rev=8ea5a1adc9919b70b213dfe597e920d6e113120c#8ea5a1adc9919b70b213dfe597e920d6e113120c"
|
source = "git+https://github.com/KtorZ/pallas.git?rev=0cdd6393bb3fbceb3b5209ad248877b381822e90#0cdd6393bb3fbceb3b5209ad248877b381822e90"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base58",
|
"base58",
|
||||||
"bech32",
|
"bech32",
|
||||||
|
@ -1997,7 +1997,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pallas-traverse"
|
name = "pallas-traverse"
|
||||||
version = "0.29.0"
|
version = "0.29.0"
|
||||||
source = "git+https://github.com/KtorZ/pallas.git?rev=8ea5a1adc9919b70b213dfe597e920d6e113120c#8ea5a1adc9919b70b213dfe597e920d6e113120c"
|
source = "git+https://github.com/KtorZ/pallas.git?rev=0cdd6393bb3fbceb3b5209ad248877b381822e90#0cdd6393bb3fbceb3b5209ad248877b381822e90"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"itertools 0.13.0",
|
"itertools 0.13.0",
|
||||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -49,11 +49,11 @@ x86_64-unknown-linux-gnu = "ubuntu-22.04"
|
||||||
walkdir = "2.3.2"
|
walkdir = "2.3.2"
|
||||||
insta = { version = "1.30.0", features = ["yaml", "json", "redactions"] }
|
insta = { version = "1.30.0", features = ["yaml", "json", "redactions"] }
|
||||||
miette = { version = "7.2.0", features = ["fancy"] }
|
miette = { version = "7.2.0", features = ["fancy"] }
|
||||||
pallas-addresses = { git = "https://github.com/KtorZ/pallas.git", rev = "8ea5a1adc9919b70b213dfe597e920d6e113120c" }
|
pallas-addresses = { git = "https://github.com/KtorZ/pallas.git", rev = "0cdd6393bb3fbceb3b5209ad248877b381822e90" }
|
||||||
pallas-codec = { git = "https://github.com/KtorZ/pallas.git", rev = "8ea5a1adc9919b70b213dfe597e920d6e113120c", features = ["num-bigint"] }
|
pallas-codec = { git = "https://github.com/KtorZ/pallas.git", rev = "0cdd6393bb3fbceb3b5209ad248877b381822e90", features = ["num-bigint"] }
|
||||||
pallas-crypto = { git = "https://github.com/KtorZ/pallas.git", rev = "8ea5a1adc9919b70b213dfe597e920d6e113120c" }
|
pallas-crypto = { git = "https://github.com/KtorZ/pallas.git", rev = "0cdd6393bb3fbceb3b5209ad248877b381822e90" }
|
||||||
pallas-primitives = { git = "https://github.com/KtorZ/pallas.git", rev = "8ea5a1adc9919b70b213dfe597e920d6e113120c" }
|
pallas-primitives = { git = "https://github.com/KtorZ/pallas.git", rev = "0cdd6393bb3fbceb3b5209ad248877b381822e90" }
|
||||||
pallas-traverse = { git = "https://github.com/KtorZ/pallas.git", rev = "8ea5a1adc9919b70b213dfe597e920d6e113120c" }
|
pallas-traverse = { git = "https://github.com/KtorZ/pallas.git", rev = "0cdd6393bb3fbceb3b5209ad248877b381822e90" }
|
||||||
|
|
||||||
[profile.dev.package.insta]
|
[profile.dev.package.insta]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
|
@ -67,6 +67,8 @@ pub enum Error {
|
||||||
NonScriptWithdrawal,
|
NonScriptWithdrawal,
|
||||||
#[error("stake credential points to a non-script withdrawal")]
|
#[error("stake credential points to a non-script withdrawal")]
|
||||||
NonScriptStakeCredential,
|
NonScriptStakeCredential,
|
||||||
|
#[error("the designated procedure defines no guardrail script")]
|
||||||
|
NoGuardrailScriptForProcedure,
|
||||||
#[error("cost model not found for language\n{:>13} {:?}", "Language", .0)]
|
#[error("cost model not found for language\n{:>13} {:?}", "Language", .0)]
|
||||||
CostModelNotFound(Language),
|
CostModelNotFound(Language),
|
||||||
#[error("unsupported era, please use Conway\n{:>13} {0}", "Decoder error")]
|
#[error("unsupported era, please use Conway\n{:>13} {0}", "Decoder error")]
|
||||||
|
|
|
@ -4,9 +4,10 @@ use super::{
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use pallas_addresses::{Address, ScriptHash, ShelleyPaymentPart, StakePayload};
|
use pallas_addresses::{Address, ScriptHash, ShelleyPaymentPart, StakePayload};
|
||||||
|
use pallas_codec::utils::Nullable;
|
||||||
use pallas_primitives::conway::{
|
use pallas_primitives::conway::{
|
||||||
Certificate, MintedTx, PolicyId, RedeemerTag, RedeemersKey, RewardAccount, StakeCredential,
|
Certificate, GovAction, MintedTx, PolicyId, RedeemerTag, RedeemersKey, RewardAccount,
|
||||||
TransactionOutput,
|
StakeCredential, TransactionOutput,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
@ -106,14 +107,15 @@ pub fn scripts_needed(tx: &MintedTx, utxos: &[ResolvedInput]) -> Result<ScriptsN
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.map(|m| {
|
.map(|m| {
|
||||||
m.iter()
|
m.iter()
|
||||||
.filter_map(|cert| {
|
.enumerate()
|
||||||
|
.filter_map(|(ix, cert)| {
|
||||||
// only Dereg and Deleg certs can require scripts
|
// only Dereg and Deleg certs can require scripts
|
||||||
match cert {
|
match cert {
|
||||||
Certificate::StakeDeregistration(StakeCredential::Scripthash(h)) => {
|
Certificate::StakeDeregistration(StakeCredential::Scripthash(h)) => {
|
||||||
Some((ScriptPurpose::Certifying(cert.clone()), *h))
|
Some((ScriptPurpose::Certifying(ix, cert.clone()), *h))
|
||||||
}
|
}
|
||||||
Certificate::StakeDelegation(StakeCredential::Scripthash(h), _) => {
|
Certificate::StakeDelegation(StakeCredential::Scripthash(h), _) => {
|
||||||
Some((ScriptPurpose::Certifying(cert.clone()), *h))
|
Some((ScriptPurpose::Certifying(ix, cert.clone()), *h))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -132,14 +134,39 @@ pub fn scripts_needed(tx: &MintedTx, utxos: &[ResolvedInput]) -> Result<ScriptsN
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let mut propose = txb
|
||||||
|
.proposal_procedures
|
||||||
|
.as_deref()
|
||||||
|
.map(|m| {
|
||||||
|
m.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(ix, procedure)| match procedure.gov_action {
|
||||||
|
GovAction::ParameterChange(_, _, Nullable::Some(hash)) => {
|
||||||
|
Some((ScriptPurpose::Proposing(ix, procedure.clone()), hash))
|
||||||
|
}
|
||||||
|
GovAction::TreasuryWithdrawals(_, Nullable::Some(hash)) => {
|
||||||
|
Some((ScriptPurpose::Proposing(ix, procedure.clone()), hash))
|
||||||
|
}
|
||||||
|
GovAction::HardForkInitiation(..)
|
||||||
|
| GovAction::Information
|
||||||
|
| GovAction::NewConstitution(..)
|
||||||
|
| GovAction::TreasuryWithdrawals(..)
|
||||||
|
| GovAction::ParameterChange(..)
|
||||||
|
| GovAction::NoConfidence(..)
|
||||||
|
| GovAction::UpdateCommittee(..) => None,
|
||||||
|
})
|
||||||
|
.collect::<ScriptsNeeded>()
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
assert!(txb.proposal_procedures.is_none());
|
|
||||||
assert!(txb.voting_procedures.is_none());
|
assert!(txb.voting_procedures.is_none());
|
||||||
|
|
||||||
needed.append(&mut spend);
|
needed.append(&mut spend);
|
||||||
needed.append(&mut reward);
|
needed.append(&mut reward);
|
||||||
needed.append(&mut cert);
|
needed.append(&mut cert);
|
||||||
needed.append(&mut mint);
|
needed.append(&mut mint);
|
||||||
|
needed.append(&mut propose);
|
||||||
|
|
||||||
Ok(needed)
|
Ok(needed)
|
||||||
}
|
}
|
||||||
|
@ -191,7 +218,7 @@ pub fn has_exact_set_of_redeemers(
|
||||||
let extra: Vec<_> = wits_redeemer_keys
|
let extra: Vec<_> = wits_redeemer_keys
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|x| !needed_redeemer_keys.contains(x))
|
.filter(|x| !needed_redeemer_keys.contains(x))
|
||||||
.map(|x| format!("{x:?}"))
|
.map(|x| format!("{:?}[{:?}]", x.tag, x.index))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if !missing.is_empty() || !extra.is_empty() {
|
if !missing.is_empty() || !extra.is_empty() {
|
||||||
|
@ -281,7 +308,7 @@ fn build_redeemer_key(
|
||||||
Ok(redeemer_key)
|
Ok(redeemer_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptPurpose::Certifying(d) => {
|
ScriptPurpose::Certifying(_, d) => {
|
||||||
let redeemer_key = tx_body
|
let redeemer_key = tx_body
|
||||||
.certificates
|
.certificates
|
||||||
.as_deref()
|
.as_deref()
|
||||||
|
@ -294,5 +321,19 @@ fn build_redeemer_key(
|
||||||
|
|
||||||
Ok(redeemer_key)
|
Ok(redeemer_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScriptPurpose::Proposing(_, procedure) => {
|
||||||
|
let redeemer_key = tx_body
|
||||||
|
.proposal_procedures
|
||||||
|
.as_deref()
|
||||||
|
.map(|m| m.iter().position(|x| x == procedure))
|
||||||
|
.unwrap_or_default()
|
||||||
|
.map(|index| RedeemersKey {
|
||||||
|
tag: RedeemerTag::Propose,
|
||||||
|
index: index as u32,
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(redeemer_key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,12 +6,16 @@ use crate::{
|
||||||
machine::runtime::{convert_constr_to_tag, ANY_TAG},
|
machine::runtime::{convert_constr_to_tag, ANY_TAG},
|
||||||
tx::script_context::from_alonzo_output,
|
tx::script_context::from_alonzo_output,
|
||||||
};
|
};
|
||||||
use pallas_addresses::{Address, ShelleyDelegationPart, ShelleyPaymentPart, StakePayload};
|
use pallas_addresses::{
|
||||||
use pallas_codec::utils::{AnyUInt, Bytes, Int, KeyValuePairs, NonEmptyKeyValuePairs};
|
Address, ShelleyDelegationPart, ShelleyPaymentPart, StakeAddress, StakePayload,
|
||||||
|
};
|
||||||
|
use pallas_codec::utils::{AnyUInt, Bytes, Int, KeyValuePairs, NonEmptyKeyValuePairs, Nullable};
|
||||||
use pallas_crypto::hash::Hash;
|
use pallas_crypto::hash::Hash;
|
||||||
use pallas_primitives::conway::{
|
use pallas_primitives::conway::{
|
||||||
AssetName, BigInt, Certificate, Coin, Constr, DatumOption, Mint, PlutusData, PolicyId,
|
AssetName, BigInt, Certificate, Coin, Constitution, Constr, DatumOption, GovAction,
|
||||||
PseudoScript, Redeemer, ScriptRef, StakeCredential, TransactionInput, TransactionOutput, Value,
|
GovActionId, Mint, PlutusData, PolicyId, ProposalProcedure, ProtocolParamUpdate, PseudoScript,
|
||||||
|
RationalNumber, Redeemer, ScriptRef, StakeCredential, TransactionInput, TransactionOutput,
|
||||||
|
Value,
|
||||||
};
|
};
|
||||||
use pallas_traverse::ComputeHash;
|
use pallas_traverse::ComputeHash;
|
||||||
|
|
||||||
|
@ -34,6 +38,8 @@ fn empty_constr(index: u64) -> PlutusData {
|
||||||
|
|
||||||
struct WithWrappedTransactionId<'a, T>(&'a T);
|
struct WithWrappedTransactionId<'a, T>(&'a T);
|
||||||
|
|
||||||
|
struct WithWrappedStakeCredential<'a, T>(&'a T);
|
||||||
|
|
||||||
struct WithZeroAdaAsset<'a, T>(&'a T);
|
struct WithZeroAdaAsset<'a, T>(&'a T);
|
||||||
|
|
||||||
struct WithOptionDatum<'a, T>(&'a T);
|
struct WithOptionDatum<'a, T>(&'a T);
|
||||||
|
@ -47,6 +53,23 @@ pub struct MintValue {
|
||||||
pub mint_value: Mint,
|
pub mint_value: Mint,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for bool {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self {
|
||||||
|
false => empty_constr(0),
|
||||||
|
true => empty_constr(1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ToPlutusData for StakeAddress {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self.payload() {
|
||||||
|
StakePayload::Stake(x) => wrap_with_constr(0, x.to_plutus_data()),
|
||||||
|
StakePayload::Script(x) => wrap_with_constr(1, x.to_plutus_data()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToPlutusData for Address {
|
impl ToPlutusData for Address {
|
||||||
fn to_plutus_data(&self) -> PlutusData {
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
match self {
|
match self {
|
||||||
|
@ -64,12 +87,16 @@ impl ToPlutusData for Address {
|
||||||
};
|
};
|
||||||
|
|
||||||
let stake_part_plutus_data = match stake_part {
|
let stake_part_plutus_data = match stake_part {
|
||||||
ShelleyDelegationPart::Key(stake_keyhash) => {
|
ShelleyDelegationPart::Key(stake_keyhash) => Some(wrap_with_constr(
|
||||||
Some(StakeCredential::AddrKeyhash(*stake_keyhash)).to_plutus_data()
|
0,
|
||||||
}
|
StakeCredential::AddrKeyhash(*stake_keyhash).to_plutus_data(),
|
||||||
ShelleyDelegationPart::Script(script_hash) => {
|
))
|
||||||
Some(StakeCredential::Scripthash(*script_hash)).to_plutus_data()
|
.to_plutus_data(),
|
||||||
}
|
ShelleyDelegationPart::Script(script_hash) => Some(wrap_with_constr(
|
||||||
|
0,
|
||||||
|
StakeCredential::Scripthash(*script_hash).to_plutus_data(),
|
||||||
|
))
|
||||||
|
.to_plutus_data(),
|
||||||
ShelleyDelegationPart::Pointer(pointer) => Some(wrap_multiple_with_constr(
|
ShelleyDelegationPart::Pointer(pointer) => Some(wrap_multiple_with_constr(
|
||||||
1,
|
1,
|
||||||
vec![
|
vec![
|
||||||
|
@ -84,17 +111,7 @@ impl ToPlutusData for Address {
|
||||||
|
|
||||||
wrap_multiple_with_constr(0, vec![payment_part_plutus_data, stake_part_plutus_data])
|
wrap_multiple_with_constr(0, vec![payment_part_plutus_data, stake_part_plutus_data])
|
||||||
}
|
}
|
||||||
Address::Stake(stake_address) => {
|
Address::Stake(stake_address) => stake_address.to_plutus_data(),
|
||||||
// This is right now only used in Withdrawals (Reward account)
|
|
||||||
match stake_address.payload() {
|
|
||||||
StakePayload::Stake(stake_keyhash) => {
|
|
||||||
StakeCredential::AddrKeyhash(*stake_keyhash).to_plutus_data()
|
|
||||||
}
|
|
||||||
StakePayload::Script(script_hash) => {
|
|
||||||
StakeCredential::Scripthash(*script_hash).to_plutus_data()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,12 +247,24 @@ impl ToPlutusData for i64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for u32 {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
PlutusData::BigInt(BigInt::Int(Int::try_from(*self as i128).unwrap()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToPlutusData for u64 {
|
impl ToPlutusData for u64 {
|
||||||
fn to_plutus_data(&self) -> PlutusData {
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
PlutusData::BigInt(BigInt::Int(Int::try_from(*self as i128).unwrap()))
|
PlutusData::BigInt(BigInt::Int(Int::try_from(*self as i128).unwrap()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for usize {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
PlutusData::BigInt(BigInt::Int(Int::try_from(*self as i128).unwrap()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ToPlutusData for WithZeroAdaAsset<'a, Value> {
|
impl<'a> ToPlutusData for WithZeroAdaAsset<'a, Value> {
|
||||||
fn to_plutus_data(&self) -> PlutusData {
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
|
@ -443,16 +472,13 @@ impl ToPlutusData for TransactionOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToPlutusData for StakeCredential {
|
impl ToPlutusData for StakeCredential {
|
||||||
// Stake Credential needs to be wrapped inside another Constr, because we could have either a StakingHash or a StakingPtr
|
|
||||||
// The current implementation of StakeCredential doesn't capture the credential of a Pointer address.
|
|
||||||
// So a StakeCredential for a Pointer address needs to be converted separately
|
|
||||||
fn to_plutus_data(&self) -> PlutusData {
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
match self {
|
match self {
|
||||||
StakeCredential::AddrKeyhash(addr_keyhas) => {
|
StakeCredential::AddrKeyhash(addr_keyhas) => {
|
||||||
wrap_with_constr(0, wrap_with_constr(0, addr_keyhas.to_plutus_data()))
|
wrap_with_constr(0, addr_keyhas.to_plutus_data())
|
||||||
}
|
}
|
||||||
StakeCredential::Scripthash(script_hash) => {
|
StakeCredential::Scripthash(script_hash) => {
|
||||||
wrap_with_constr(0, wrap_with_constr(1, script_hash.to_plutus_data()))
|
wrap_with_constr(1, script_hash.to_plutus_data())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -722,6 +748,10 @@ impl<'a> ToPlutusData for WithWrappedTransactionId<'a, ScriptPurpose> {
|
||||||
ScriptPurpose::Spending(out_ref, ()) => {
|
ScriptPurpose::Spending(out_ref, ()) => {
|
||||||
wrap_with_constr(1, WithWrappedTransactionId(out_ref).to_plutus_data())
|
wrap_with_constr(1, WithWrappedTransactionId(out_ref).to_plutus_data())
|
||||||
}
|
}
|
||||||
|
// NOTE: This is a _small_ abuse of the 'WithWrappedTransactionId'. We know the wrapped
|
||||||
|
// is needed for V1 and V2, and it also appears that for V1 and V2, the certifying
|
||||||
|
// purpose mustn't include the certificate index. So, we also short-circuit it here.
|
||||||
|
ScriptPurpose::Certifying(_, dcert) => wrap_with_constr(3, dcert.to_plutus_data()),
|
||||||
otherwise => otherwise.to_plutus_data(),
|
otherwise => otherwise.to_plutus_data(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -735,11 +765,167 @@ impl ToPlutusData for ScriptPurpose {
|
||||||
ScriptPurpose::Rewarding(stake_credential) => {
|
ScriptPurpose::Rewarding(stake_credential) => {
|
||||||
wrap_with_constr(2, stake_credential.to_plutus_data())
|
wrap_with_constr(2, stake_credential.to_plutus_data())
|
||||||
}
|
}
|
||||||
ScriptPurpose::Certifying(dcert) => wrap_with_constr(3, dcert.to_plutus_data()),
|
ScriptPurpose::Certifying(ix, dcert) => {
|
||||||
|
wrap_multiple_with_constr(3, vec![ix.to_plutus_data(), dcert.to_plutus_data()])
|
||||||
|
}
|
||||||
|
ScriptPurpose::Proposing(ix, procedure) => {
|
||||||
|
wrap_multiple_with_constr(5, vec![ix.to_plutus_data(), procedure.to_plutus_data()])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for ProposalProcedure {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
wrap_multiple_with_constr(
|
||||||
|
0,
|
||||||
|
vec![
|
||||||
|
self.deposit.to_plutus_data(),
|
||||||
|
Address::from_bytes(&self.reward_account)
|
||||||
|
.unwrap()
|
||||||
|
.to_plutus_data(),
|
||||||
|
self.gov_action.to_plutus_data(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ToPlutusData for Nullable<T>
|
||||||
|
where
|
||||||
|
T: ToPlutusData + Clone,
|
||||||
|
{
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self {
|
||||||
|
Nullable::Some(t) => wrap_with_constr(0, t.to_plutus_data()),
|
||||||
|
Nullable::Null | Nullable::Undefined => empty_constr(1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for GovActionId {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
wrap_multiple_with_constr(
|
||||||
|
0,
|
||||||
|
vec![
|
||||||
|
self.transaction_id.to_plutus_data(),
|
||||||
|
self.action_index.to_plutus_data(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for ProtocolParamUpdate {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
todo!("ToPlutusData for ProtocolParamUpdate")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for GovAction {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
match self {
|
||||||
|
GovAction::ParameterChange(previous_action, params, guardrail) => {
|
||||||
|
wrap_multiple_with_constr(
|
||||||
|
0,
|
||||||
|
vec![
|
||||||
|
previous_action.to_plutus_data(),
|
||||||
|
params.as_ref().to_plutus_data(),
|
||||||
|
guardrail.to_plutus_data(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
GovAction::HardForkInitiation(previous_action, version) => wrap_multiple_with_constr(
|
||||||
|
1,
|
||||||
|
vec![previous_action.to_plutus_data(), version.to_plutus_data()],
|
||||||
|
),
|
||||||
|
GovAction::TreasuryWithdrawals(withdrawals, guardrail) => wrap_multiple_with_constr(
|
||||||
|
2,
|
||||||
|
vec![
|
||||||
|
KeyValuePairs::from(
|
||||||
|
withdrawals
|
||||||
|
.iter()
|
||||||
|
.map(|(reward_account, amount)| {
|
||||||
|
(
|
||||||
|
Address::from_bytes(reward_account)
|
||||||
|
.expect("Invalid stake address in treasury withdrawal?"),
|
||||||
|
*amount,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
.to_plutus_data(),
|
||||||
|
guardrail.to_plutus_data(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GovAction::NoConfidence(previous_action) => {
|
||||||
|
wrap_with_constr(3, previous_action.to_plutus_data())
|
||||||
|
}
|
||||||
|
GovAction::UpdateCommittee(previous_action, removed, added, quorum) => {
|
||||||
|
wrap_multiple_with_constr(
|
||||||
|
4,
|
||||||
|
vec![
|
||||||
|
previous_action.to_plutus_data(),
|
||||||
|
removed.to_plutus_data(),
|
||||||
|
added.to_plutus_data(),
|
||||||
|
quorum.to_plutus_data(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
GovAction::NewConstitution(previous_action, constitution) => wrap_multiple_with_constr(
|
||||||
|
5,
|
||||||
|
vec![
|
||||||
|
previous_action.to_plutus_data(),
|
||||||
|
constitution.to_plutus_data(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GovAction::Information => empty_constr(6),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for Constitution {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
wrap_with_constr(0, self.guardrail_script.to_plutus_data())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPlutusData for RationalNumber {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
(self.numerator, self.denominator).to_plutus_data()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ToPlutusData for WithWrappedStakeCredential<'a, Vec<(Address, Coin)>> {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
self.0
|
||||||
|
.iter()
|
||||||
|
.map(|(reward_account, amount)| {
|
||||||
|
(
|
||||||
|
wrap_with_constr(0, reward_account.to_plutus_data()),
|
||||||
|
*amount,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.to_plutus_data()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ToPlutusData for WithWrappedStakeCredential<'a, KeyValuePairs<Address, Coin>> {
|
||||||
|
fn to_plutus_data(&self) -> PlutusData {
|
||||||
|
KeyValuePairs::from(
|
||||||
|
self.0
|
||||||
|
.iter()
|
||||||
|
.map(|(reward_account, amount)| {
|
||||||
|
(
|
||||||
|
wrap_with_constr(0, reward_account.to_plutus_data()),
|
||||||
|
*amount,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
.to_plutus_data()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> ToPlutusData for ScriptInfo<T>
|
impl<T> ToPlutusData for ScriptInfo<T>
|
||||||
where
|
where
|
||||||
T: ToPlutusData,
|
T: ToPlutusData,
|
||||||
|
@ -753,7 +939,12 @@ where
|
||||||
ScriptInfo::Rewarding(stake_credential) => {
|
ScriptInfo::Rewarding(stake_credential) => {
|
||||||
wrap_with_constr(2, stake_credential.to_plutus_data())
|
wrap_with_constr(2, stake_credential.to_plutus_data())
|
||||||
}
|
}
|
||||||
ScriptInfo::Certifying(dcert) => wrap_with_constr(3, dcert.to_plutus_data()),
|
ScriptInfo::Certifying(ix, dcert) => {
|
||||||
|
wrap_multiple_with_constr(3, vec![ix.to_plutus_data(), dcert.to_plutus_data()])
|
||||||
|
}
|
||||||
|
ScriptInfo::Proposing(ix, procedure) => {
|
||||||
|
wrap_multiple_with_constr(5, vec![ix.to_plutus_data(), procedure.to_plutus_data()])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -772,7 +963,7 @@ impl ToPlutusData for TxInfo {
|
||||||
WithZeroAdaAsset(&tx_info.fee).to_plutus_data(),
|
WithZeroAdaAsset(&tx_info.fee).to_plutus_data(),
|
||||||
WithZeroAdaAsset(&tx_info.mint).to_plutus_data(),
|
WithZeroAdaAsset(&tx_info.mint).to_plutus_data(),
|
||||||
tx_info.certificates.to_plutus_data(),
|
tx_info.certificates.to_plutus_data(),
|
||||||
tx_info.withdrawals.to_plutus_data(),
|
WithWrappedStakeCredential(&tx_info.withdrawals).to_plutus_data(),
|
||||||
tx_info.valid_range.to_plutus_data(),
|
tx_info.valid_range.to_plutus_data(),
|
||||||
tx_info.signatories.to_plutus_data(),
|
tx_info.signatories.to_plutus_data(),
|
||||||
tx_info.data.to_plutus_data(),
|
tx_info.data.to_plutus_data(),
|
||||||
|
@ -789,7 +980,7 @@ impl ToPlutusData for TxInfo {
|
||||||
WithZeroAdaAsset(&tx_info.fee).to_plutus_data(),
|
WithZeroAdaAsset(&tx_info.fee).to_plutus_data(),
|
||||||
WithZeroAdaAsset(&tx_info.mint).to_plutus_data(),
|
WithZeroAdaAsset(&tx_info.mint).to_plutus_data(),
|
||||||
tx_info.certificates.to_plutus_data(),
|
tx_info.certificates.to_plutus_data(),
|
||||||
tx_info.withdrawals.to_plutus_data(),
|
WithWrappedStakeCredential(&tx_info.withdrawals).to_plutus_data(),
|
||||||
tx_info.valid_range.to_plutus_data(),
|
tx_info.valid_range.to_plutus_data(),
|
||||||
tx_info.signatories.to_plutus_data(),
|
tx_info.signatories.to_plutus_data(),
|
||||||
WithWrappedTransactionId(&tx_info.redeemers).to_plutus_data(),
|
WithWrappedTransactionId(&tx_info.redeemers).to_plutus_data(),
|
||||||
|
@ -813,7 +1004,7 @@ impl ToPlutusData for TxInfo {
|
||||||
tx_info.data.to_plutus_data(),
|
tx_info.data.to_plutus_data(),
|
||||||
tx_info.id.to_plutus_data(),
|
tx_info.id.to_plutus_data(),
|
||||||
Data::map(vec![]), // TODO tx_info.votes :: Map Voter (Map GovernanceActionId Vote)
|
Data::map(vec![]), // TODO tx_info.votes :: Map Voter (Map GovernanceActionId Vote)
|
||||||
Data::list(vec![]), // TODO tx_info.proposal_procedures :: [ProposalProcedure]
|
tx_info.proposal_procedures.to_plutus_data(),
|
||||||
empty_constr(1), // TODO tx_info.current_treasury_amount :: Haskell.Maybe V2.Lovelace
|
empty_constr(1), // TODO tx_info.current_treasury_amount :: Haskell.Maybe V2.Lovelace
|
||||||
empty_constr(1), // TODO tx_info.treasury_donation :: Haskell.Maybe V2.Lovelace
|
empty_constr(1), // TODO tx_info.treasury_donation :: Haskell.Maybe V2.Lovelace
|
||||||
],
|
],
|
||||||
|
@ -847,12 +1038,3 @@ impl ToPlutusData for ScriptContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToPlutusData for bool {
|
|
||||||
fn to_plutus_data(&self) -> PlutusData {
|
|
||||||
match self {
|
|
||||||
false => empty_constr(0),
|
|
||||||
true => empty_constr(1),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue