implement a strict subset of PlutusV3 transaction info
More specifically, that is simply mimicking the script context from v2, minus the new governance features.
This commit is contained in:
parent
c454dc72eb
commit
fdf7a81288
|
@ -96,7 +96,8 @@ pub fn eval_phase_two_raw(
|
|||
run_phase_one: bool,
|
||||
with_redeemer: fn(&Redeemer) -> (),
|
||||
) -> Result<Vec<Vec<u8>>, Error> {
|
||||
let multi_era_tx = MultiEraTx::decode_for_era(Era::Babbage, tx_bytes)
|
||||
let multi_era_tx = MultiEraTx::decode_for_era(Era::Conway, tx_bytes)
|
||||
.or_else(|_| MultiEraTx::decode_for_era(Era::Babbage, tx_bytes))
|
||||
.or_else(|_| MultiEraTx::decode_for_era(Era::Alonzo, tx_bytes))?;
|
||||
|
||||
let cost_mdls = CostMdls::decode_fragment(cost_mdls_bytes)?;
|
||||
|
|
|
@ -6,7 +6,7 @@ use super::{
|
|||
use crate::{
|
||||
ast::{FakeNamedDeBruijn, NamedDeBruijn, Program},
|
||||
machine::cost_model::ExBudget,
|
||||
tx::script_context::{DataLookupTable, ScriptVersion, TxInfoV1, TxInfoV2},
|
||||
tx::script_context::{DataLookupTable, ScriptVersion, TxInfoV1, TxInfoV2, TxInfoV3},
|
||||
PlutusData,
|
||||
};
|
||||
use pallas_codec::utils::Bytes;
|
||||
|
@ -116,7 +116,22 @@ pub fn eval_redeemer(
|
|||
program(script.0)?,
|
||||
),
|
||||
|
||||
(ScriptVersion::V3(_script), _datum) => todo!(),
|
||||
(ScriptVersion::V3(script), datum) => do_eval_redeemer(
|
||||
cost_mdls_opt
|
||||
.map(|cost_mdls| {
|
||||
cost_mdls
|
||||
.plutus_v3
|
||||
.as_ref()
|
||||
.ok_or(Error::CostModelNotFound(Language::PlutusV3))
|
||||
})
|
||||
.transpose()?,
|
||||
initial_budget,
|
||||
&Language::PlutusV3,
|
||||
datum,
|
||||
redeemer,
|
||||
TxInfoV3::from_transaction(tx, utxos, slot_config)?,
|
||||
program(script.0)?,
|
||||
),
|
||||
}
|
||||
.map_err(|err| Error::RedeemerError {
|
||||
tag: redeemer_tag_to_string(&redeemer.tag),
|
||||
|
|
|
@ -10,7 +10,7 @@ use pallas_primitives::conway::{
|
|||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
type AlonzoScriptsNeeded = Vec<(ScriptPurpose, ScriptHash)>;
|
||||
type ScriptsNeeded = Vec<(ScriptPurpose, ScriptHash)>;
|
||||
|
||||
// subset of phase-1 ledger checks related to scripts
|
||||
pub fn eval_phase_one(
|
||||
|
@ -28,7 +28,7 @@ pub fn eval_phase_one(
|
|||
}
|
||||
|
||||
pub fn validate_missing_scripts(
|
||||
needed: &AlonzoScriptsNeeded,
|
||||
needed: &ScriptsNeeded,
|
||||
txscripts: HashMap<ScriptHash, ScriptVersion>,
|
||||
) -> Result<(), Error> {
|
||||
let received_hashes = txscripts.keys().copied().collect::<Vec<ScriptHash>>();
|
||||
|
@ -61,10 +61,7 @@ pub fn validate_missing_scripts(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn scripts_needed(
|
||||
tx: &MintedTx,
|
||||
utxos: &[ResolvedInput],
|
||||
) -> Result<AlonzoScriptsNeeded, Error> {
|
||||
pub fn scripts_needed(tx: &MintedTx, utxos: &[ResolvedInput]) -> Result<ScriptsNeeded, Error> {
|
||||
let mut needed = Vec::new();
|
||||
|
||||
let txb = tx.transaction_body.clone();
|
||||
|
@ -106,7 +103,7 @@ pub fn scripts_needed(
|
|||
|
||||
None
|
||||
})
|
||||
.collect::<AlonzoScriptsNeeded>()
|
||||
.collect::<ScriptsNeeded>()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
|
@ -127,7 +124,7 @@ pub fn scripts_needed(
|
|||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect::<AlonzoScriptsNeeded>()
|
||||
.collect::<ScriptsNeeded>()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
|
@ -137,7 +134,7 @@ pub fn scripts_needed(
|
|||
.map(|m| {
|
||||
m.iter()
|
||||
.map(|(policy_id, _)| (ScriptPurpose::Minting(*policy_id), *policy_id))
|
||||
.collect::<AlonzoScriptsNeeded>()
|
||||
.collect::<ScriptsNeeded>()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
|
@ -156,7 +153,7 @@ pub fn scripts_needed(
|
|||
/// hasExactSetOfRedeemers in Ledger Spec, but we pass `txscripts` directly
|
||||
pub fn has_exact_set_of_redeemers(
|
||||
tx: &MintedTx,
|
||||
needed: &AlonzoScriptsNeeded,
|
||||
needed: &ScriptsNeeded,
|
||||
tx_scripts: HashMap<ScriptHash, ScriptVersion>,
|
||||
) -> Result<(), Error> {
|
||||
let mut redeemers_needed = Vec::new();
|
||||
|
|
|
@ -27,6 +27,7 @@ pub struct TxInInfo {
|
|||
pub out_ref: TransactionInput,
|
||||
pub resolved: TxOut,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum TxOut {
|
||||
V1(TransactionOutput),
|
||||
|
@ -290,15 +291,51 @@ impl TxInfoV2 {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct TxInfoV3 {}
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct TxInfoV3 {
|
||||
pub inputs: Vec<TxInInfo>,
|
||||
pub reference_inputs: Vec<TxInInfo>,
|
||||
pub outputs: Vec<TxOut>,
|
||||
pub fee: Value,
|
||||
pub mint: MintValue,
|
||||
pub certificates: Vec<Certificate>,
|
||||
pub withdrawals: KeyValuePairs<Address, Coin>,
|
||||
pub valid_range: TimeRange,
|
||||
pub signatories: Vec<AddrKeyhash>,
|
||||
pub redeemers: KeyValuePairs<ScriptPurpose, Redeemer>,
|
||||
pub data: KeyValuePairs<DatumHash, PlutusData>,
|
||||
// TODO:
|
||||
// votes : KeyValuePairs<Voter, KeyValuePairs<GovernanceActionId, Vote>>
|
||||
// proposalProcedures : Vec<ProposalProcedure>
|
||||
// currentTreasuryAmount : Option<Coin>
|
||||
// treasuryDonation : Option<Coin>
|
||||
pub id: Hash<32>,
|
||||
}
|
||||
|
||||
impl TxInfoV3 {
|
||||
pub fn from_transaction(
|
||||
_tx: &MintedTx,
|
||||
_utxos: &[ResolvedInput],
|
||||
_slot_config: &SlotConfig,
|
||||
tx: &MintedTx,
|
||||
utxos: &[ResolvedInput],
|
||||
slot_config: &SlotConfig,
|
||||
) -> Result<TxInfo, Error> {
|
||||
todo!("TxInfoV3")
|
||||
if let TxInfo::V2(tx_info_v2) = TxInfoV2::from_transaction(tx, utxos, slot_config)? {
|
||||
Ok(TxInfo::V3(TxInfoV3 {
|
||||
inputs: tx_info_v2.inputs,
|
||||
reference_inputs: tx_info_v2.reference_inputs,
|
||||
outputs: tx_info_v2.outputs,
|
||||
fee: tx_info_v2.fee,
|
||||
mint: tx_info_v2.mint,
|
||||
certificates: tx_info_v2.certificates,
|
||||
withdrawals: tx_info_v2.withdrawals,
|
||||
valid_range: tx_info_v2.valid_range,
|
||||
signatories: tx_info_v2.signatories,
|
||||
redeemers: tx_info_v2.redeemers,
|
||||
data: tx_info_v2.data,
|
||||
id: tx_info_v2.id,
|
||||
}))
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,12 +343,15 @@ impl TxInfoV3 {
|
|||
pub enum TxInfo {
|
||||
V1(TxInfoV1),
|
||||
V2(TxInfoV2),
|
||||
V3(TxInfoV3),
|
||||
}
|
||||
|
||||
impl TxInfo {
|
||||
pub fn purpose(&self, needle: &Redeemer) -> Option<ScriptPurpose> {
|
||||
match self {
|
||||
TxInfo::V1(TxInfoV1 { redeemers, .. }) | TxInfo::V2(TxInfoV2 { redeemers, .. }) => {
|
||||
TxInfo::V1(TxInfoV1 { redeemers, .. })
|
||||
| TxInfo::V2(TxInfoV2 { redeemers, .. })
|
||||
| TxInfo::V3(TxInfoV3 { redeemers, .. }) => {
|
||||
redeemers.iter().find_map(|(purpose, redeemer)| {
|
||||
if redeemer == needle {
|
||||
Some(purpose.clone())
|
||||
|
@ -327,6 +367,7 @@ impl TxInfo {
|
|||
match self {
|
||||
TxInfo::V1(info) => &info.inputs,
|
||||
TxInfo::V2(info) => &info.inputs,
|
||||
TxInfo::V3(info) => &info.inputs,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,6 +375,7 @@ impl TxInfo {
|
|||
match self {
|
||||
TxInfo::V1(info) => &info.mint,
|
||||
TxInfo::V2(info) => &info.mint,
|
||||
TxInfo::V3(info) => &info.mint,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,6 +383,7 @@ impl TxInfo {
|
|||
match self {
|
||||
TxInfo::V1(info) => &info.withdrawals[..],
|
||||
TxInfo::V2(info) => &info.withdrawals[..],
|
||||
TxInfo::V3(info) => &info.withdrawals[..],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,6 +391,7 @@ impl TxInfo {
|
|||
match self {
|
||||
TxInfo::V1(info) => &info.certificates[..],
|
||||
TxInfo::V2(info) => &info.certificates[..],
|
||||
TxInfo::V3(info) => &info.certificates[..],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ fn empty_constr(index: u64) -> PlutusData {
|
|||
})
|
||||
}
|
||||
|
||||
struct WithWrappedTransactionId<'a, T>(&'a T);
|
||||
|
||||
pub trait ToPlutusData {
|
||||
fn to_plutus_data(&self) -> PlutusData;
|
||||
}
|
||||
|
@ -98,12 +100,24 @@ impl ToPlutusData for Address {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ToPlutusData for WithWrappedTransactionId<'a, TransactionInput> {
|
||||
fn to_plutus_data(&self) -> PlutusData {
|
||||
wrap_multiple_with_constr(
|
||||
0,
|
||||
vec![
|
||||
wrap_with_constr(0, self.0.transaction_id.to_plutus_data()),
|
||||
PlutusData::BigInt(BigInt::Int((self.0.index as i128).try_into().unwrap())),
|
||||
],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToPlutusData for TransactionInput {
|
||||
fn to_plutus_data(&self) -> PlutusData {
|
||||
wrap_multiple_with_constr(
|
||||
0,
|
||||
vec![
|
||||
wrap_with_constr(0, self.transaction_id.to_plutus_data()),
|
||||
self.transaction_id.to_plutus_data(),
|
||||
PlutusData::BigInt(BigInt::Int((self.index as i128).try_into().unwrap())),
|
||||
],
|
||||
)
|
||||
|
@ -299,7 +313,7 @@ impl ToPlutusData for TxOut {
|
|||
// legacy_output.datum_hash.to_plutus_data(),
|
||||
// ],
|
||||
// ),
|
||||
TransactionOutput::Legacy(..) => todo!("TransactionOutput::Legacy"),
|
||||
TransactionOutput::Legacy(..) => unimplemented!("TransactionOutput::Legacy"),
|
||||
TransactionOutput::PostAlonzo(post_alonzo_output) => wrap_multiple_with_constr(
|
||||
0,
|
||||
vec![
|
||||
|
@ -329,7 +343,7 @@ impl ToPlutusData for TxOut {
|
|||
// None::<ScriptRef>.to_plutus_data(),
|
||||
// ],
|
||||
// ),
|
||||
TransactionOutput::Legacy(..) => todo!("TransactionOutput::Legacy"),
|
||||
TransactionOutput::Legacy(..) => unimplemented!("TransactionOutput::Legacy"),
|
||||
TransactionOutput::PostAlonzo(post_alonzo_output) => wrap_multiple_with_constr(
|
||||
0,
|
||||
vec![
|
||||
|
@ -556,6 +570,29 @@ impl ToPlutusData for TimeRange {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ToPlutusData for WithWrappedTransactionId<'a, Vec<TxInInfo>> {
|
||||
fn to_plutus_data(&self) -> PlutusData {
|
||||
PlutusData::Array(
|
||||
self.0
|
||||
.iter()
|
||||
.map(|p| WithWrappedTransactionId(p).to_plutus_data())
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToPlutusData for WithWrappedTransactionId<'a, TxInInfo> {
|
||||
fn to_plutus_data(&self) -> PlutusData {
|
||||
wrap_multiple_with_constr(
|
||||
0,
|
||||
vec![
|
||||
WithWrappedTransactionId(&self.0.out_ref).to_plutus_data(),
|
||||
self.0.resolved.to_plutus_data(),
|
||||
],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToPlutusData for TxInInfo {
|
||||
fn to_plutus_data(&self) -> PlutusData {
|
||||
wrap_multiple_with_constr(
|
||||
|
@ -587,7 +624,7 @@ impl ToPlutusData for TxInfo {
|
|||
TxInfo::V1(tx_info) => wrap_multiple_with_constr(
|
||||
0,
|
||||
vec![
|
||||
tx_info.inputs.to_plutus_data(),
|
||||
WithWrappedTransactionId(&tx_info.inputs).to_plutus_data(),
|
||||
tx_info.outputs.to_plutus_data(),
|
||||
tx_info.fee.to_plutus_data(),
|
||||
tx_info.mint.to_plutus_data(),
|
||||
|
@ -600,6 +637,23 @@ impl ToPlutusData for TxInfo {
|
|||
],
|
||||
),
|
||||
TxInfo::V2(tx_info) => wrap_multiple_with_constr(
|
||||
0,
|
||||
vec![
|
||||
WithWrappedTransactionId(&tx_info.inputs).to_plutus_data(),
|
||||
WithWrappedTransactionId(&tx_info.reference_inputs).to_plutus_data(),
|
||||
tx_info.outputs.to_plutus_data(),
|
||||
tx_info.fee.to_plutus_data(),
|
||||
tx_info.mint.to_plutus_data(),
|
||||
tx_info.certificates.to_plutus_data(),
|
||||
tx_info.withdrawals.to_plutus_data(),
|
||||
tx_info.valid_range.to_plutus_data(),
|
||||
tx_info.signatories.to_plutus_data(),
|
||||
tx_info.redeemers.to_plutus_data(),
|
||||
tx_info.data.to_plutus_data(),
|
||||
wrap_with_constr(0, tx_info.id.to_plutus_data()),
|
||||
],
|
||||
),
|
||||
TxInfo::V3(tx_info) => wrap_multiple_with_constr(
|
||||
0,
|
||||
vec![
|
||||
tx_info.inputs.to_plutus_data(),
|
||||
|
@ -613,7 +667,7 @@ impl ToPlutusData for TxInfo {
|
|||
tx_info.signatories.to_plutus_data(),
|
||||
tx_info.redeemers.to_plutus_data(),
|
||||
tx_info.data.to_plutus_data(),
|
||||
wrap_with_constr(0, tx_info.id.to_plutus_data()),
|
||||
tx_info.id.to_plutus_data(),
|
||||
],
|
||||
),
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue