Merge pull request #90 from spacebudz/sorting

This commit is contained in:
Lucas 2022-11-04 13:30:25 -04:00 committed by GitHub
commit 6cfc75d9ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 109 additions and 17 deletions

View File

@ -2,6 +2,8 @@
## [next] - 2022-MM-DD ## [next] - 2022-MM-DD
- **uplc**: Sorted remaining structured in the ScriptContext (Value, Wdrl, (Ref) Inputs, Mint, Required signers, Data, Redeemers)
## [v0.0.23] - 2022-11-03 ## [v0.0.23] - 2022-11-03
### Changed ### Changed

1
Cargo.lock generated
View File

@ -1217,6 +1217,7 @@ dependencies = [
"cryptoxide", "cryptoxide",
"flat-rs", "flat-rs",
"hex", "hex",
"itertools",
"pallas-addresses", "pallas-addresses",
"pallas-codec", "pallas-codec",
"pallas-crypto", "pallas-crypto",

View File

@ -29,6 +29,7 @@ serde = { version = "1.0.144", features = ["derive"] }
serde_json = "1.0.85" serde_json = "1.0.85"
strum = "0.24.1" strum = "0.24.1"
strum_macros = "0.24.3" strum_macros = "0.24.3"
itertools = "0.10.5"
[dev-dependencies] [dev-dependencies]
hex = "0.4.3" hex = "0.4.3"

View File

@ -22,6 +22,7 @@ use super::{
to_plutus_data::{MintValue, ToPlutusData}, to_plutus_data::{MintValue, ToPlutusData},
Error, Error,
}; };
use itertools::Itertools;
fn slot_to_begin_posix_time(slot: u64, sc: &SlotConfig) -> u64 { fn slot_to_begin_posix_time(slot: u64, sc: &SlotConfig) -> u64 {
let ms_after_begin = (slot - sc.zero_slot) * sc.slot_length as u64; let ms_after_begin = (slot - sc.zero_slot) * sc.slot_length as u64;
@ -48,6 +49,54 @@ fn redeemer_tag_to_string(redeemer_tag: &RedeemerTag) -> String {
} }
} }
fn sort_mint(mint: &Mint) -> Mint {
let mut mint_vec = vec![];
for m in mint.deref().iter().sorted() {
mint_vec.push((
m.0,
KeyValuePairs::Indef(m.1.deref().clone().into_iter().sorted().clone().collect()),
));
}
KeyValuePairs::Indef(mint_vec)
}
fn sort_value(value: &Value) -> Value {
match value {
Value::Coin(_) => value.clone(),
Value::Multiasset(coin, ma) => {
let mut ma_vec = vec![];
for m in ma.deref().iter().sorted() {
ma_vec.push((
m.0,
KeyValuePairs::Indef(
m.1.deref().clone().into_iter().sorted().clone().collect(),
),
));
}
Value::Multiasset(*coin, KeyValuePairs::Indef(ma_vec))
}
}
}
fn sort_tx_out_value(tx_output: &TransactionOutput) -> TransactionOutput {
match tx_output {
TransactionOutput::Legacy(output) => {
let mut new_output = output.clone();
new_output.amount = sort_value(&output.amount);
TransactionOutput::Legacy(new_output)
}
TransactionOutput::PostAlonzo(output) => {
let mut new_output = output.clone();
new_output.value = sort_value(&output.value);
TransactionOutput::PostAlonzo(new_output)
}
}
}
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum ScriptVersion { pub enum ScriptVersion {
Native(NativeScript), Native(NativeScript),
@ -78,6 +127,7 @@ pub fn get_tx_in_info_v1(
) -> Result<Vec<TxInInfo>, Error> { ) -> Result<Vec<TxInInfo>, Error> {
inputs inputs
.iter() .iter()
.sorted()
.map(|input| { .map(|input| {
let utxo = match utxos.iter().find(|utxo| utxo.input == *input) { let utxo = match utxos.iter().find(|utxo| utxo.input == *input) {
Some(resolved) => resolved, Some(resolved) => resolved,
@ -114,7 +164,7 @@ pub fn get_tx_in_info_v1(
Ok(TxInInfo { Ok(TxInInfo {
out_ref: utxo.input.clone(), out_ref: utxo.input.clone(),
resolved: TxOut::V1(utxo.output.clone()), resolved: TxOut::V1(sort_tx_out_value(&utxo.output)),
}) })
}) })
.collect() .collect()
@ -126,6 +176,7 @@ fn get_tx_in_info_v2(
) -> Result<Vec<TxInInfo>, Error> { ) -> Result<Vec<TxInInfo>, Error> {
inputs inputs
.iter() .iter()
.sorted()
.map(|input| { .map(|input| {
let utxo = match utxos.iter().find(|utxo| utxo.input == *input) { let utxo = match utxos.iter().find(|utxo| utxo.input == *input) {
Some(resolved) => resolved, Some(resolved) => resolved,
@ -149,7 +200,7 @@ fn get_tx_in_info_v2(
Ok(TxInInfo { Ok(TxInInfo {
out_ref: utxo.input.clone(), out_ref: utxo.input.clone(),
resolved: TxOut::V2(utxo.output.clone()), resolved: TxOut::V2(sort_tx_out_value(&utxo.output)),
}) })
}) })
.collect() .collect()
@ -239,23 +290,29 @@ fn get_tx_info_v1(
return Err(Error::ScriptAndInputRefNotAllowed); return Err(Error::ScriptAndInputRefNotAllowed);
} }
let mut inputs = get_tx_in_info_v1(&body.inputs, utxos)?; let inputs = get_tx_in_info_v1(&body.inputs, utxos)?;
inputs.sort_by(|x, y| x.out_ref.cmp(&y.out_ref));
let outputs = body let outputs = body
.outputs .outputs
.iter() .iter()
.map(|output| TxOut::V1(output.clone())) .map(|output| TxOut::V1(sort_tx_out_value(output)))
.collect(); .collect();
let fee = Value::Coin(body.fee); let fee = Value::Coin(body.fee);
let mint = body.mint.clone().unwrap_or(KeyValuePairs::Indef(vec![]));
let mint = sort_mint(&body.mint.clone().unwrap_or(KeyValuePairs::Indef(vec![])));
let dcert = body.certificates.clone().unwrap_or_default(); let dcert = body.certificates.clone().unwrap_or_default();
let wdrl = body let wdrl = body
.withdrawals .withdrawals
.clone() .clone()
.unwrap_or(KeyValuePairs::Indef(vec![])) .unwrap_or(KeyValuePairs::Indef(vec![]))
.deref() .deref()
.clone(); .clone()
.into_iter()
.sorted()
.collect();
let valid_range = slot_range_to_posix_time_range( let valid_range = slot_range_to_posix_time_range(
TimeRange { TimeRange {
@ -264,7 +321,14 @@ fn get_tx_info_v1(
}, },
slot_config, slot_config,
); );
let signatories = body.required_signers.clone().unwrap_or_default();
let signatories = body
.required_signers
.clone()
.unwrap_or_default()
.into_iter()
.sorted()
.collect();
let data = tx let data = tx
.transaction_witness_set .transaction_witness_set
@ -273,6 +337,7 @@ fn get_tx_info_v1(
.unwrap_or(&vec![]) .unwrap_or(&vec![])
.iter() .iter()
.map(|d| (d.original_hash(), d.clone().unwrap())) .map(|d| (d.original_hash(), d.clone().unwrap()))
.sorted()
.collect(); .collect();
let id = tx.transaction_body.compute_hash(); let id = tx.transaction_body.compute_hash();
@ -298,23 +363,34 @@ fn get_tx_info_v2(
) -> Result<TxInfo, Error> { ) -> Result<TxInfo, Error> {
let body = tx.transaction_body.clone(); let body = tx.transaction_body.clone();
let mut inputs = get_tx_in_info_v2(&body.inputs, utxos)?; let inputs = get_tx_in_info_v2(&body.inputs, utxos)?;
inputs.sort_by(|x, y| x.out_ref.cmp(&y.out_ref));
let reference_inputs = let reference_inputs =
get_tx_in_info_v2(&body.reference_inputs.clone().unwrap_or_default(), utxos)?; get_tx_in_info_v2(&body.reference_inputs.clone().unwrap_or_default(), utxos)?;
let outputs = body let outputs = body
.outputs .outputs
.iter() .iter()
.map(|output| TxOut::V2(output.clone())) .map(|output| TxOut::V2(sort_tx_out_value(output)))
.collect(); .collect();
let fee = Value::Coin(body.fee); let fee = Value::Coin(body.fee);
let mint = body.mint.clone().unwrap_or(KeyValuePairs::Indef(vec![]));
let mint = sort_mint(&body.mint.clone().unwrap_or(KeyValuePairs::Indef(vec![])));
let dcert = body.certificates.clone().unwrap_or_default(); let dcert = body.certificates.clone().unwrap_or_default();
let wdrl = body
.withdrawals let wdrl = KeyValuePairs::Indef(
body.withdrawals
.clone() .clone()
.unwrap_or(KeyValuePairs::Indef(vec![])); .unwrap_or(KeyValuePairs::Indef(vec![]))
.deref()
.clone()
.into_iter()
.sorted()
.collect(),
);
let valid_range = slot_range_to_posix_time_range( let valid_range = slot_range_to_posix_time_range(
TimeRange { TimeRange {
lower_bound: body.validity_interval_start, lower_bound: body.validity_interval_start,
@ -322,13 +398,22 @@ fn get_tx_info_v2(
}, },
slot_config, slot_config,
); );
let signatories = body.required_signers.clone().unwrap_or_default();
let signatories = body
.required_signers
.clone()
.unwrap_or_default()
.into_iter()
.sorted()
.collect();
let redeemers = KeyValuePairs::Indef( let redeemers = KeyValuePairs::Indef(
tx.transaction_witness_set tx.transaction_witness_set
.redeemer .redeemer
.as_ref() .as_ref()
.unwrap_or(&MaybeIndefArray::Indef(vec![])) .unwrap_or(&MaybeIndefArray::Indef(vec![]))
.iter() .iter()
.sorted_by(|a, b| a.data.compute_hash().cmp(&b.data.compute_hash()))
.map(|r| { .map(|r| {
( (
get_script_purpose( get_script_purpose(
@ -344,6 +429,7 @@ fn get_tx_info_v2(
}) })
.collect(), .collect(),
); );
let data = KeyValuePairs::Indef( let data = KeyValuePairs::Indef(
tx.transaction_witness_set tx.transaction_witness_set
.plutus_data .plutus_data
@ -351,8 +437,10 @@ fn get_tx_info_v2(
.unwrap_or(&vec![]) .unwrap_or(&vec![])
.iter() .iter()
.map(|d| (d.original_hash(), d.clone().unwrap())) .map(|d| (d.original_hash(), d.clone().unwrap()))
.sorted()
.collect(), .collect(),
); );
let id = tx.transaction_body.compute_hash(); let id = tx.transaction_body.compute_hash();
Ok(TxInfo::V2(TxInfoV2 { Ok(TxInfo::V2(TxInfoV2 {