feat: more errors
This commit is contained in:
parent
6e901de2f0
commit
9bab3187b1
File diff suppressed because one or more lines are too long
|
@ -2,6 +2,25 @@ use crate::machine;
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("Runtime error")]
|
#[error("{0}")]
|
||||||
|
Address(#[from] pallas_addresses::Error),
|
||||||
|
#[error("Only shelley reward addresses can be a part of withdrawals")]
|
||||||
|
BadWithdrawalAddress,
|
||||||
|
#[error("{0}")]
|
||||||
|
FragmentDecode(#[from] pallas_primitives::Error),
|
||||||
|
#[error("{0}")]
|
||||||
Machine(#[from] machine::Error),
|
Machine(#[from] machine::Error),
|
||||||
|
#[error("Can't eval without redeemers")]
|
||||||
|
NoRedeemers,
|
||||||
|
#[error("Mismatch in required redeemers: {} {}", .missing.join(" "), .extra.join(" "))]
|
||||||
|
RequiredRedeemersMismatch {
|
||||||
|
missing: Vec<String>,
|
||||||
|
extra: Vec<String>,
|
||||||
|
},
|
||||||
|
#[error("Resolved Input not found")]
|
||||||
|
ResolvedInputNotFound,
|
||||||
|
#[error("A key hash cannot be the hash of a script")]
|
||||||
|
ScriptKeyHash,
|
||||||
|
#[error("Wrong era, Please use Babbage or Alonzo: {0}")]
|
||||||
|
WrongEra(#[from] pallas_codec::minicbor::decode::Error),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use pallas_addresses::{ScriptHash, Address, ShelleyPaymentPart, StakePayload};
|
use pallas_addresses::{Address, ScriptHash, ShelleyPaymentPart, StakePayload};
|
||||||
use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray};
|
use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray};
|
||||||
use pallas_primitives::babbage::{MintedTx, TransactionOutput, StakeCredential, Certificate, RedeemerTag, RewardAccount, PolicyId};
|
use pallas_primitives::babbage::{
|
||||||
|
Certificate, MintedTx, PolicyId, RedeemerTag, RewardAccount, StakeCredential, TransactionOutput,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{script_context::{ScriptPurpose, ResolvedInput}, eval::{ScriptVersion, DataLookupTable}};
|
use super::{
|
||||||
|
error::Error,
|
||||||
|
eval::{DataLookupTable, ScriptVersion},
|
||||||
|
script_context::{ResolvedInput, ScriptPurpose},
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: include in pallas eventually?
|
// TODO: include in pallas eventually?
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
@ -20,8 +26,8 @@ pub fn eval_phase_one(
|
||||||
tx: &MintedTx,
|
tx: &MintedTx,
|
||||||
utxos: &[ResolvedInput],
|
utxos: &[ResolvedInput],
|
||||||
lookup_table: &DataLookupTable,
|
lookup_table: &DataLookupTable,
|
||||||
) -> anyhow::Result<()> {
|
) -> Result<(), Error> {
|
||||||
let scripts_needed = scripts_needed(tx, utxos);
|
let scripts_needed = scripts_needed(tx, utxos)?;
|
||||||
|
|
||||||
validate_missing_scripts(&scripts_needed, lookup_table.scripts())?;
|
validate_missing_scripts(&scripts_needed, lookup_table.scripts())?;
|
||||||
|
|
||||||
|
@ -33,41 +39,32 @@ pub fn eval_phase_one(
|
||||||
pub fn validate_missing_scripts(
|
pub fn validate_missing_scripts(
|
||||||
needed: &AlonzoScriptsNeeded,
|
needed: &AlonzoScriptsNeeded,
|
||||||
txscripts: HashMap<ScriptHash, ScriptVersion>,
|
txscripts: HashMap<ScriptHash, ScriptVersion>,
|
||||||
) -> anyhow::Result<()> {
|
) -> Result<(), Error> {
|
||||||
let received_hashes = txscripts
|
let received_hashes = txscripts.keys().map(|x| *x).collect::<Vec<ScriptHash>>();
|
||||||
.keys()
|
|
||||||
.map(|x| *x)
|
|
||||||
.collect::<Vec<ScriptHash>>();
|
|
||||||
|
|
||||||
let needed_hashes = needed
|
let needed_hashes = needed.iter().map(|x| x.1).collect::<Vec<ScriptHash>>();
|
||||||
.iter()
|
|
||||||
.map(|x| x.1)
|
|
||||||
.collect::<Vec<ScriptHash>>();
|
|
||||||
|
|
||||||
let missing: Vec<_> = needed_hashes
|
let missing: Vec<_> = needed_hashes
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|x| !received_hashes.contains(x))
|
.filter(|x| !received_hashes.contains(x))
|
||||||
.map(|x| format!(
|
.map(|x| format!("[Missing (sh: {})]", x))
|
||||||
"[Missing (sh: {})]",
|
|
||||||
x
|
|
||||||
))
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let extra: Vec<_> = received_hashes
|
let extra: Vec<_> = received_hashes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|x| !needed_hashes.contains(x))
|
.filter(|x| !needed_hashes.contains(x))
|
||||||
.map(|x| format!(
|
.map(|x| format!("[Extraneous (sh: {:?})]", x))
|
||||||
"[Extraneous (sh: {:?})]",
|
|
||||||
x
|
|
||||||
))
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if missing.len() > 0 || extra.len() > 0 {
|
if missing.len() > 0 || extra.len() > 0 {
|
||||||
let missing_errors = missing.join(" ");
|
let missing_errors = missing.join(" ");
|
||||||
let extra_errors = extra.join(" ");
|
let extra_errors = extra.join(" ");
|
||||||
|
|
||||||
unreachable!("Mismatch in required scripts: {} {}", missing_errors, extra_errors);
|
unreachable!(
|
||||||
|
"Mismatch in required scripts: {} {}",
|
||||||
|
missing_errors, extra_errors
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -76,36 +73,33 @@ pub fn validate_missing_scripts(
|
||||||
pub fn scripts_needed(
|
pub fn scripts_needed(
|
||||||
tx: &MintedTx,
|
tx: &MintedTx,
|
||||||
utxos: &[ResolvedInput],
|
utxos: &[ResolvedInput],
|
||||||
) -> AlonzoScriptsNeeded {
|
) -> Result<AlonzoScriptsNeeded, Error> {
|
||||||
let mut needed = Vec::new();
|
let mut needed = Vec::new();
|
||||||
|
|
||||||
let txb = tx.transaction_body.clone();
|
let txb = tx.transaction_body.clone();
|
||||||
|
|
||||||
let mut spend = txb.inputs
|
let mut spend = Vec::new();
|
||||||
.iter()
|
|
||||||
.map(|input| {
|
for input in txb.inputs {
|
||||||
let utxo = match utxos.iter().find(|utxo| utxo.input == *input) {
|
let utxo = match utxos.iter().find(|utxo| utxo.input == input) {
|
||||||
Some(u) => u,
|
Some(u) => u,
|
||||||
None => panic!("Resolved input not found."),
|
None => return Err(Error::ResolvedInputNotFound),
|
||||||
};
|
};
|
||||||
|
|
||||||
let address = Address::from_bytes(match &utxo.output {
|
let address = Address::from_bytes(match &utxo.output {
|
||||||
TransactionOutput::Legacy(output) => output.address.as_ref(),
|
TransactionOutput::Legacy(output) => output.address.as_ref(),
|
||||||
TransactionOutput::PostAlonzo(output) => output.address.as_ref(),
|
TransactionOutput::PostAlonzo(output) => output.address.as_ref(),
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if let Address::Shelley(a) = address {
|
if let Address::Shelley(a) = address {
|
||||||
if let ShelleyPaymentPart::Script(h) = a.payment() {
|
if let ShelleyPaymentPart::Script(h) = a.payment() {
|
||||||
return Some((ScriptPurpose::Spending(input.clone()), *h))
|
spend.push((ScriptPurpose::Spending(input.clone()), *h));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
let mut reward = txb
|
||||||
})
|
.withdrawals
|
||||||
.flatten()
|
|
||||||
.collect::<AlonzoScriptsNeeded>();
|
|
||||||
|
|
||||||
let mut reward = txb.withdrawals
|
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap_or(&KeyValuePairs::Indef(vec![]))
|
.unwrap_or(&KeyValuePairs::Indef(vec![]))
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -115,7 +109,7 @@ pub fn scripts_needed(
|
||||||
if let Address::Stake(a) = address {
|
if let Address::Stake(a) = address {
|
||||||
if let StakePayload::Script(h) = a.payload() {
|
if let StakePayload::Script(h) = a.payload() {
|
||||||
let cred = StakeCredential::Scripthash(*h);
|
let cred = StakeCredential::Scripthash(*h);
|
||||||
return Some((ScriptPurpose::Rewarding(cred), *h))
|
return Some((ScriptPurpose::Rewarding(cred), *h));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +118,8 @@ pub fn scripts_needed(
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect::<AlonzoScriptsNeeded>();
|
.collect::<AlonzoScriptsNeeded>();
|
||||||
|
|
||||||
let mut cert = txb.certificates
|
let mut cert = txb
|
||||||
|
.certificates
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -133,23 +128,22 @@ pub fn scripts_needed(
|
||||||
match cert {
|
match cert {
|
||||||
Certificate::StakeDeregistration(StakeCredential::Scripthash(h)) => {
|
Certificate::StakeDeregistration(StakeCredential::Scripthash(h)) => {
|
||||||
Some((ScriptPurpose::Certifying(cert.clone()), *h))
|
Some((ScriptPurpose::Certifying(cert.clone()), *h))
|
||||||
},
|
}
|
||||||
Certificate::StakeDelegation(StakeCredential::Scripthash(h), _) => {
|
Certificate::StakeDelegation(StakeCredential::Scripthash(h), _) => {
|
||||||
Some((ScriptPurpose::Certifying(cert.clone()), *h))
|
Some((ScriptPurpose::Certifying(cert.clone()), *h))
|
||||||
},
|
}
|
||||||
_ => None
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect::<AlonzoScriptsNeeded>();
|
.collect::<AlonzoScriptsNeeded>();
|
||||||
|
|
||||||
let mut mint = txb.mint
|
let mut mint = txb
|
||||||
|
.mint
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap_or(&KeyValuePairs::Indef(vec![]))
|
.unwrap_or(&KeyValuePairs::Indef(vec![]))
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(policy_id, _)| {
|
.map(|(policy_id, _)| (ScriptPurpose::Minting(*policy_id), *policy_id))
|
||||||
(ScriptPurpose::Minting(*policy_id), *policy_id)
|
|
||||||
})
|
|
||||||
.collect::<AlonzoScriptsNeeded>();
|
.collect::<AlonzoScriptsNeeded>();
|
||||||
|
|
||||||
needed.append(&mut spend);
|
needed.append(&mut spend);
|
||||||
|
@ -157,91 +151,91 @@ pub fn scripts_needed(
|
||||||
needed.append(&mut cert);
|
needed.append(&mut cert);
|
||||||
needed.append(&mut mint);
|
needed.append(&mut mint);
|
||||||
|
|
||||||
needed
|
Ok(needed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// hasExactSetOfRedeemers in Ledger Spec, but we pass `txscripts` directly
|
/// hasExactSetOfRedeemers in Ledger Spec, but we pass `txscripts` directly
|
||||||
pub fn has_exact_set_of_redeemers(
|
pub fn has_exact_set_of_redeemers(
|
||||||
tx: &MintedTx,
|
tx: &MintedTx,
|
||||||
needed: &AlonzoScriptsNeeded,
|
needed: &AlonzoScriptsNeeded,
|
||||||
txscripts: HashMap<ScriptHash, ScriptVersion>,
|
tx_scripts: HashMap<ScriptHash, ScriptVersion>,
|
||||||
) -> anyhow::Result<()> {
|
) -> Result<(), Error> {
|
||||||
let redeemers_needed = needed
|
let mut redeemers_needed = Vec::new();
|
||||||
.iter()
|
|
||||||
.map(|(sp, sh)| {
|
|
||||||
let rp = rdptr(tx, sp);
|
|
||||||
let script = txscripts.get(&sh);
|
|
||||||
|
|
||||||
match (rp, script) {
|
for (script_purpose, script_hash) in needed {
|
||||||
(Some(ptr), Some(script)) => match script {
|
let redeemer_ptr = build_redeemer_ptr(tx, script_purpose)?;
|
||||||
ScriptVersion::V1(_) => Some((ptr, sp.clone(), *sh)),
|
let script = tx_scripts.get(&script_hash);
|
||||||
ScriptVersion::V2(_) => Some((ptr, sp.clone(), *sh)),
|
|
||||||
ScriptVersion::Native(_) => None,
|
if let (Some(ptr), Some(script)) = (redeemer_ptr, script) {
|
||||||
},
|
match script {
|
||||||
_ => None
|
ScriptVersion::V1(_) => {
|
||||||
|
redeemers_needed.push((ptr, script_purpose.clone(), *script_hash))
|
||||||
|
}
|
||||||
|
ScriptVersion::V2(_) => {
|
||||||
|
redeemers_needed.push((ptr, script_purpose.clone(), *script_hash))
|
||||||
|
}
|
||||||
|
ScriptVersion::Native(_) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.flatten()
|
|
||||||
.collect::<Vec<(RedeemerPtr, ScriptPurpose, ScriptHash)>>();
|
|
||||||
|
|
||||||
let wits_rdptrs = tx
|
let wits_redeemer_ptrs: Vec<RedeemerPtr> = tx
|
||||||
.transaction_witness_set
|
.transaction_witness_set
|
||||||
.redeemer
|
.redeemer
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap_or(&MaybeIndefArray::Indef(vec![]))
|
.unwrap_or(&MaybeIndefArray::Indef(vec![]))
|
||||||
.iter()
|
.iter()
|
||||||
.map(|r| {
|
.map(|r| RedeemerPtr {
|
||||||
RedeemerPtr { tag: r.tag.clone(), index: r.index }
|
tag: r.tag.clone(),
|
||||||
|
index: r.index,
|
||||||
})
|
})
|
||||||
.collect::<Vec<RedeemerPtr>>();
|
.collect();
|
||||||
|
|
||||||
let needed_rdptrs = redeemers_needed
|
let needed_redeemer_ptrs: Vec<RedeemerPtr> =
|
||||||
.iter()
|
redeemers_needed.iter().map(|x| x.0.clone()).collect();
|
||||||
.map(|x| x.0.clone())
|
|
||||||
.collect::<Vec<RedeemerPtr>>();
|
|
||||||
|
|
||||||
let missing: Vec<_> = redeemers_needed
|
let missing: Vec<_> = redeemers_needed
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|x| !wits_rdptrs.contains(&x.0))
|
.filter(|x| !wits_redeemer_ptrs.contains(&x.0))
|
||||||
.map(|x| format!(
|
.map(|x| {
|
||||||
"[Missing (rp: {:?}, sp: {:?}, sh: {})]",
|
format!(
|
||||||
|
"[Missing (redeemer_ptr: {:?}, script_purpose: {:?}, script_hash: {})]",
|
||||||
x.0,
|
x.0,
|
||||||
x.1,
|
x.1,
|
||||||
x.2.to_string(),
|
x.2.to_string(),
|
||||||
))
|
)
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let extra: Vec<_> = wits_rdptrs
|
let extra: Vec<_> = wits_redeemer_ptrs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|x| !needed_rdptrs.contains(x))
|
.filter(|x| !needed_redeemer_ptrs.contains(x))
|
||||||
.map(|x| format!(
|
.map(|x| format!("[Extraneous (redeemer_ptr: {:?})]", x))
|
||||||
"[Extraneous (rp: {:?})]",
|
|
||||||
x
|
|
||||||
))
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if missing.len() > 0 || extra.len() > 0 {
|
if missing.len() > 0 || extra.len() > 0 {
|
||||||
let missing_errors = missing.join(" ");
|
let missing_errors = missing.join(" ");
|
||||||
let extra_errors = extra.join(" ");
|
let extra_errors = extra.join(" ");
|
||||||
|
|
||||||
unreachable!("Mismatch in required redeemers: {} {}", missing_errors, extra_errors);
|
Err(Error::RequiredRedeemersMismatch { missing, extra })
|
||||||
}
|
} else {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// builds a redeemer pointer (tag, index) from a script purpose by setting the tag
|
/// builds a redeemer pointer (tag, index) from a script purpose by setting the tag
|
||||||
/// according to the type of the script purpose, and the index according to the
|
/// according to the type of the script purpose, and the index according to the
|
||||||
/// placement of script purpose inside its container.
|
/// placement of script purpose inside its container.
|
||||||
fn rdptr(
|
fn build_redeemer_ptr(
|
||||||
tx: &MintedTx,
|
tx: &MintedTx,
|
||||||
sp: &ScriptPurpose,
|
script_purpose: &ScriptPurpose,
|
||||||
) -> Option<RedeemerPtr> {
|
) -> Result<Option<RedeemerPtr>, Error> {
|
||||||
let txb = tx.transaction_body.clone();
|
let tx_body = tx.transaction_body.clone();
|
||||||
|
|
||||||
match sp {
|
match script_purpose {
|
||||||
ScriptPurpose::Minting(hash) => {
|
ScriptPurpose::Minting(hash) => {
|
||||||
let mut policy_ids = txb.mint
|
let mut policy_ids = tx_body
|
||||||
|
.mint
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap_or(&KeyValuePairs::Indef(vec![]))
|
.unwrap_or(&KeyValuePairs::Indef(vec![]))
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -253,12 +247,15 @@ fn rdptr(
|
||||||
let maybe_idx = policy_ids.iter().position(|x| x == hash);
|
let maybe_idx = policy_ids.iter().position(|x| x == hash);
|
||||||
|
|
||||||
match maybe_idx {
|
match maybe_idx {
|
||||||
Some(idx) => Some(RedeemerPtr { tag: RedeemerTag::Mint, index: idx as u32 }),
|
Some(idx) => Ok(Some(RedeemerPtr {
|
||||||
None => None,
|
tag: RedeemerTag::Mint,
|
||||||
|
index: idx as u32,
|
||||||
|
})),
|
||||||
|
None => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ScriptPurpose::Spending(txin) => {
|
ScriptPurpose::Spending(txin) => {
|
||||||
let mut inputs = txb.inputs.to_vec();
|
let mut inputs = tx_body.inputs.to_vec();
|
||||||
inputs.sort_by(
|
inputs.sort_by(
|
||||||
|i_a, i_b| match i_a.transaction_id.cmp(&i_b.transaction_id) {
|
|i_a, i_b| match i_a.transaction_id.cmp(&i_b.transaction_id) {
|
||||||
std::cmp::Ordering::Less => std::cmp::Ordering::Less,
|
std::cmp::Ordering::Less => std::cmp::Ordering::Less,
|
||||||
|
@ -270,12 +267,16 @@ fn rdptr(
|
||||||
let maybe_idx = inputs.iter().position(|x| x == txin);
|
let maybe_idx = inputs.iter().position(|x| x == txin);
|
||||||
|
|
||||||
match maybe_idx {
|
match maybe_idx {
|
||||||
Some(idx) => Some(RedeemerPtr { tag: RedeemerTag::Spend, index: idx as u32 }),
|
Some(idx) => Ok(Some(RedeemerPtr {
|
||||||
None => None,
|
tag: RedeemerTag::Spend,
|
||||||
|
index: idx as u32,
|
||||||
|
})),
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
ScriptPurpose::Rewarding(racnt) => {
|
ScriptPurpose::Rewarding(racnt) => {
|
||||||
let mut reward_accounts = txb.withdrawals
|
let mut reward_accounts = tx_body
|
||||||
|
.withdrawals
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap_or(&KeyValuePairs::Indef(vec![]))
|
.unwrap_or(&KeyValuePairs::Indef(vec![]))
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -284,42 +285,47 @@ fn rdptr(
|
||||||
|
|
||||||
reward_accounts.sort();
|
reward_accounts.sort();
|
||||||
|
|
||||||
let maybe_idx = reward_accounts.iter().position(|x| {
|
let mut maybe_idx = None;
|
||||||
|
|
||||||
|
for (idx, x) in reward_accounts.iter().enumerate() {
|
||||||
let cred = match Address::from_bytes(x).unwrap() {
|
let cred = match Address::from_bytes(x).unwrap() {
|
||||||
Address::Stake(a) => match a.payload() {
|
Address::Stake(a) => match a.payload() {
|
||||||
StakePayload::Script(sh) => {
|
StakePayload::Script(sh) => StakeCredential::Scripthash(*sh),
|
||||||
StakeCredential::Scripthash(*sh)
|
|
||||||
}
|
|
||||||
StakePayload::Stake(_) => {
|
StakePayload::Stake(_) => {
|
||||||
unreachable!(
|
return Err(Error::ScriptKeyHash);
|
||||||
"This is impossible. A key hash cannot be the hash of a script."
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => unreachable!(
|
_ => return Err(Error::BadWithdrawalAddress),
|
||||||
"This is impossible. Only shelley reward addresses can be a part of withdrawals."
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cred == *racnt
|
if cred == *racnt {
|
||||||
});
|
maybe_idx = Some(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match maybe_idx {
|
match maybe_idx {
|
||||||
Some(idx) => Some(RedeemerPtr { tag: RedeemerTag::Reward, index: idx as u32 }),
|
Some(idx) => Ok(Some(RedeemerPtr {
|
||||||
None => None,
|
tag: RedeemerTag::Reward,
|
||||||
|
index: idx as u32,
|
||||||
|
})),
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
ScriptPurpose::Certifying(d) => {
|
ScriptPurpose::Certifying(d) => {
|
||||||
let maybe_idx = txb.certificates
|
let maybe_idx = tx_body
|
||||||
|
.certificates
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap_or(&MaybeIndefArray::Indef(vec![]))
|
.unwrap_or(&MaybeIndefArray::Indef(vec![]))
|
||||||
.iter()
|
.iter()
|
||||||
.position(|x| x == d);
|
.position(|x| x == d);
|
||||||
|
|
||||||
match maybe_idx {
|
match maybe_idx {
|
||||||
Some(idx) => Some(RedeemerPtr{ tag: RedeemerTag::Cert, index: idx as u32 }),
|
Some(idx) => Ok(Some(RedeemerPtr {
|
||||||
None => None
|
tag: RedeemerTag::Cert,
|
||||||
}
|
index: idx as u32,
|
||||||
},
|
})),
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,16 +1,14 @@
|
||||||
use pallas_addresses::{Address, ShelleyDelegationPart, ShelleyPaymentPart};
|
use pallas_addresses::{Address, ShelleyDelegationPart, ShelleyPaymentPart};
|
||||||
use pallas_primitives::babbage::{AssetName, BigInt, Constr, PlutusData, ScriptRef};
|
|
||||||
|
|
||||||
use pallas_codec::utils::{AnyUInt, Bytes, Int, KeyValuePairs};
|
use pallas_codec::utils::{AnyUInt, Bytes, Int, KeyValuePairs};
|
||||||
use pallas_crypto::hash::Hash;
|
use pallas_crypto::hash::Hash;
|
||||||
|
use pallas_primitives::babbage::{AssetName, BigInt, Constr, PlutusData, ScriptRef};
|
||||||
use pallas_primitives::babbage::{
|
use pallas_primitives::babbage::{
|
||||||
Certificate, DatumOption, PolicyId, Redeemer, Script, StakeCredential, TransactionInput,
|
Certificate, DatumOption, PolicyId, Redeemer, Script, StakeCredential, TransactionInput,
|
||||||
TransactionOutput, Value,
|
TransactionOutput, Value,
|
||||||
};
|
};
|
||||||
use pallas_traverse::ComputeHash;
|
use pallas_traverse::ComputeHash;
|
||||||
use std::vec;
|
|
||||||
|
|
||||||
use super::script_context::{TxOut, TimeRange, TxInInfo, ScriptPurpose, TxInfo, ScriptContext};
|
use super::script_context::{ScriptContext, ScriptPurpose, TimeRange, TxInInfo, TxInfo, TxOut};
|
||||||
|
|
||||||
fn wrap_with_constr(index: u64, data: PlutusData) -> PlutusData {
|
fn wrap_with_constr(index: u64, data: PlutusData) -> PlutusData {
|
||||||
PlutusData::Constr(Constr {
|
PlutusData::Constr(Constr {
|
||||||
|
|
Loading…
Reference in New Issue