fix(interop): map missing u5c redeemers (#490)
This commit is contained in:
parent
8f74238dc5
commit
60e07e2f00
6 changed files with 95 additions and 14 deletions
|
|
@ -18,6 +18,7 @@ pallas-codec = { version = "=0.28.0", path = "../pallas-codec" }
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
thiserror = "1.0.31"
|
thiserror = "1.0.31"
|
||||||
paste = "1.0.14"
|
paste = "1.0.14"
|
||||||
|
itertools = "0.13.0"
|
||||||
|
|
||||||
# TODO: remove once GenesisValue moves into new genesis crate
|
# TODO: remove once GenesisValue moves into new genesis crate
|
||||||
serde = "1.0.155"
|
serde = "1.0.155"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::{borrow::Cow, collections::HashSet, ops::Deref};
|
use std::{borrow::Cow, collections::HashSet, ops::Deref};
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
use pallas_codec::{minicbor, utils::KeepRaw};
|
use pallas_codec::{minicbor, utils::KeepRaw};
|
||||||
use pallas_crypto::hash::Hash;
|
use pallas_crypto::hash::Hash;
|
||||||
use pallas_primitives::{
|
use pallas_primitives::{
|
||||||
|
|
@ -209,6 +210,27 @@ impl<'b> MultiEraTx<'b> {
|
||||||
raw
|
raw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mints_sorted_set(&self) -> Vec<MultiEraPolicyAssets> {
|
||||||
|
let mut raw = self.mints();
|
||||||
|
|
||||||
|
raw.sort_by_key(|m| *m.policy());
|
||||||
|
|
||||||
|
raw
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn withdrawals_sorted_set(&self) -> Vec<(&[u8], u64)> {
|
||||||
|
match self.withdrawals() {
|
||||||
|
MultiEraWithdrawals::NotApplicable | MultiEraWithdrawals::Empty => {
|
||||||
|
std::iter::empty().collect()
|
||||||
|
}
|
||||||
|
MultiEraWithdrawals::AlonzoCompatible(x) => x
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| (k.as_slice(), *v))
|
||||||
|
.sorted_by_key(|(k, _)| *k)
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the transaction reference inputs
|
/// Return the transaction reference inputs
|
||||||
///
|
///
|
||||||
/// NOTE: It is possible for this to return duplicates. See
|
/// NOTE: It is possible for this to return duplicates. See
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,26 @@ impl<'b> MultiEraTx<'b> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_mint_redeemer(&self, mint_order: u32) -> Option<MultiEraRedeemer> {
|
||||||
|
self.redeemers().into_iter().find(|r| {
|
||||||
|
r.tag() == pallas_primitives::conway::RedeemerTag::Mint && r.index() == mint_order
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_withdrawal_redeemer(&self, withdrawal_order: u32) -> Option<MultiEraRedeemer> {
|
||||||
|
self.redeemers().into_iter().find(|r| {
|
||||||
|
r.tag() == pallas_primitives::conway::RedeemerTag::Reward
|
||||||
|
&& r.index() == withdrawal_order
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_certificate_redeemer(&self, certificate_order: u32) -> Option<MultiEraRedeemer> {
|
||||||
|
self.redeemers().into_iter().find(|r| {
|
||||||
|
r.tag() == pallas_primitives::conway::RedeemerTag::Cert
|
||||||
|
&& r.index() == certificate_order
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn plutus_v2_scripts(&self) -> &[PlutusV2Script] {
|
pub fn plutus_v2_scripts(&self) -> &[PlutusV2Script] {
|
||||||
match self {
|
match self {
|
||||||
Self::Byron(_) => &[],
|
Self::Byron(_) => &[],
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,5 @@ utxorpc-spec = { version = "0.7.0" }
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
serde_json = "1.0.120"
|
serde_json = "1.0.120"
|
||||||
|
pretty_assertions = "1.4.0"
|
||||||
# utxorpc-spec = { path = "../../../utxorpc/spec/gen/rust" }
|
# utxorpc-spec = { path = "../../../utxorpc/spec/gen/rust" }
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,12 @@ impl<C: LedgerContext> Mapper<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_cert(&self, x: &trv::MultiEraCert) -> u5c::Certificate {
|
pub fn map_cert(
|
||||||
|
&self,
|
||||||
|
x: &trv::MultiEraCert,
|
||||||
|
tx: &trv::MultiEraTx,
|
||||||
|
order: u32,
|
||||||
|
) -> u5c::Certificate {
|
||||||
let inner = match x.as_alonzo().unwrap() {
|
let inner = match x.as_alonzo().unwrap() {
|
||||||
babbage::Certificate::StakeRegistration(a) => {
|
babbage::Certificate::StakeRegistration(a) => {
|
||||||
u5c::certificate::Certificate::StakeRegistration(self.map_stake_credential(a))
|
u5c::certificate::Certificate::StakeRegistration(self.map_stake_credential(a))
|
||||||
|
|
@ -279,15 +284,24 @@ impl<C: LedgerContext> Mapper<C> {
|
||||||
|
|
||||||
u5c::Certificate {
|
u5c::Certificate {
|
||||||
certificate: inner.into(),
|
certificate: inner.into(),
|
||||||
redeemer: None, // TODO
|
redeemer: tx
|
||||||
|
.find_certificate_redeemer(order)
|
||||||
|
.map(|r| self.map_redeemer(&r)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_withdrawals(&self, x: &(&[u8], u64)) -> u5c::Withdrawal {
|
pub fn map_withdrawals(
|
||||||
|
&self,
|
||||||
|
x: &(&[u8], u64),
|
||||||
|
tx: &trv::MultiEraTx,
|
||||||
|
order: u32,
|
||||||
|
) -> u5c::Withdrawal {
|
||||||
u5c::Withdrawal {
|
u5c::Withdrawal {
|
||||||
reward_account: Vec::from(x.0).into(),
|
reward_account: Vec::from(x.0).into(),
|
||||||
coin: x.1,
|
coin: x.1,
|
||||||
redeemer: None, // TODO
|
redeemer: tx
|
||||||
|
.find_withdrawal_redeemer(order)
|
||||||
|
.map(|x| self.map_redeemer(&x)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -303,7 +317,7 @@ impl<C: LedgerContext> Mapper<C> {
|
||||||
u5c::Multiasset {
|
u5c::Multiasset {
|
||||||
policy_id: x.policy().to_vec().into(),
|
policy_id: x.policy().to_vec().into(),
|
||||||
assets: x.assets().iter().map(|x| self.map_asset(x)).collect(),
|
assets: x.assets().iter().map(|x| self.map_asset(x)).collect(),
|
||||||
redeemer: None, // TODO
|
redeemer: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -534,17 +548,31 @@ impl<C: LedgerContext> Mapper<C> {
|
||||||
.map(|(order, i)| self.map_tx_input(i, tx, order as u32, &resolved))
|
.map(|(order, i)| self.map_tx_input(i, tx, order as u32, &resolved))
|
||||||
.collect(),
|
.collect(),
|
||||||
outputs: tx.outputs().iter().map(|x| self.map_tx_output(x)).collect(),
|
outputs: tx.outputs().iter().map(|x| self.map_tx_output(x)).collect(),
|
||||||
certificates: tx.certs().iter().map(|x| self.map_cert(x)).collect(),
|
certificates: tx
|
||||||
withdrawals: tx
|
.certs()
|
||||||
.withdrawals()
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| self.map_withdrawals(x))
|
.enumerate()
|
||||||
|
.map(|(order, x)| self.map_cert(x, tx, order as u32))
|
||||||
|
.collect(),
|
||||||
|
withdrawals: tx
|
||||||
|
.withdrawals_sorted_set()
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(order, x)| self.map_withdrawals(x, tx, order as u32))
|
||||||
.collect(),
|
.collect(),
|
||||||
mint: tx
|
mint: tx
|
||||||
.mints()
|
.mints_sorted_set()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| self.map_policy_assets(x))
|
.enumerate()
|
||||||
|
.map(|(order, x)| {
|
||||||
|
let mut ma = self.map_policy_assets(x);
|
||||||
|
|
||||||
|
ma.redeemer = tx
|
||||||
|
.find_mint_redeemer(order as u32)
|
||||||
|
.map(|r| self.map_redeemer(&r));
|
||||||
|
|
||||||
|
ma
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
reference_inputs: tx
|
reference_inputs: tx
|
||||||
.reference_inputs()
|
.reference_inputs()
|
||||||
|
|
@ -619,6 +647,7 @@ impl<C: LedgerContext> Mapper<C> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct NoLedger;
|
struct NoLedger;
|
||||||
|
|
@ -642,7 +671,7 @@ mod tests {
|
||||||
let current = serde_json::json!(mapper.map_block(&block));
|
let current = serde_json::json!(mapper.map_block(&block));
|
||||||
let expected: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
let expected: serde_json::Value = serde_json::from_str(&json_str).unwrap();
|
||||||
|
|
||||||
assert_eq!(current, expected)
|
assert_eq!(expected, current)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1341,7 +1341,15 @@
|
||||||
"mint": [
|
"mint": [
|
||||||
{
|
{
|
||||||
"assets": [{ "mintCoin": "5000000000", "name": "VFVOQQ==" }],
|
"assets": [{ "mintCoin": "5000000000", "name": "VFVOQQ==" }],
|
||||||
"policyId": "J5+ELDPu2QVLnjxwzWo7MimCWcJLeLiVy0HZGg=="
|
"policyId": "J5+ELDPu2QVLnjxwzWo7MimCWcJLeLiVy0HZGg==",
|
||||||
|
"redeemer": {
|
||||||
|
"datum": {
|
||||||
|
"constr": {
|
||||||
|
"tag": 121
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"purpose": "REDEEMER_PURPOSE_MINT"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue