From e4afac8529a6f900298ffb67cf96d8a2bdfc89cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Ludue=C3=B1a?= Date: Wed, 14 Jan 2026 17:57:19 -0300 Subject: [PATCH 1/2] feat: extend u5c ledger definition to allow historical utxos queries --- pallas-utxorpc/src/lib.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/pallas-utxorpc/src/lib.rs b/pallas-utxorpc/src/lib.rs index b3633957..3e0c99aa 100644 --- a/pallas-utxorpc/src/lib.rs +++ b/pallas-utxorpc/src/lib.rs @@ -53,6 +53,7 @@ fn i64_to_bigint(value: i64) -> Option { pub trait LedgerContext: Clone { fn get_utxos(&self, refs: &[TxoRef]) -> Option; fn get_slot_timestamp(&self, slot: u64) -> Option; + fn get_historical_utxos(&self, refs: &[TxoRef], slot_hint: Option) -> Option; } #[derive(Default, Clone)] @@ -635,10 +636,25 @@ impl Mapper { inputs.chain(collateral).chain(reference_inputs).collect() } - pub fn map_tx(&self, tx: &trv::MultiEraTx) -> u5c::Tx { - let resolved = self.ledger.as_ref().and_then(|ctx| { + pub fn map_tx(&self, tx: &trv::MultiEraTx, slot_hint: Option) -> u5c::Tx { + let resolved = self.ledger.as_ref().map(|ctx| { let to_resolve = self.find_related_inputs(tx); - ctx.get_utxos(to_resolve.as_slice()) + + let mut utxos = ctx.get_utxos(to_resolve.as_slice()).unwrap_or_default(); + + let missing_refs: Vec<_> = to_resolve + .iter() + .filter(|r| !utxos.contains_key(r)) + .copied() + .collect(); + + if !missing_refs.is_empty() { + if let Some(historical) = ctx.get_historical_utxos(&missing_refs, slot_hint) { + utxos.extend(historical); + } + } + + utxos }); u5c::Tx { @@ -745,7 +761,11 @@ impl Mapper { } .into(), body: u5c::BlockBody { - tx: block.txs().iter().map(|x| self.map_tx(x)).collect(), + tx: block + .txs() + .iter() + .map(|x| self.map_tx(x, Some(block.slot()))) + .collect(), } .into(), timestamp: self @@ -778,6 +798,10 @@ mod tests { fn get_slot_timestamp(&self, _slot: u64) -> Option { None } + + fn get_historical_utxos(&self, _: &[TxoRef], _: Option) -> Option { + None + } } #[test] From ab27006d0b94acfedae4fb7e852bce30533d90c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Ludue=C3=B1a?= Date: Thu, 15 Jan 2026 11:20:07 -0300 Subject: [PATCH 2/2] chore: remove slot_hint from historical utxos --- pallas-utxorpc/src/lib.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/pallas-utxorpc/src/lib.rs b/pallas-utxorpc/src/lib.rs index 3e0c99aa..a63b1883 100644 --- a/pallas-utxorpc/src/lib.rs +++ b/pallas-utxorpc/src/lib.rs @@ -53,7 +53,7 @@ fn i64_to_bigint(value: i64) -> Option { pub trait LedgerContext: Clone { fn get_utxos(&self, refs: &[TxoRef]) -> Option; fn get_slot_timestamp(&self, slot: u64) -> Option; - fn get_historical_utxos(&self, refs: &[TxoRef], slot_hint: Option) -> Option; + fn get_historical_utxos(&self, refs: &[TxoRef]) -> Option; } #[derive(Default, Clone)] @@ -636,7 +636,7 @@ impl Mapper { inputs.chain(collateral).chain(reference_inputs).collect() } - pub fn map_tx(&self, tx: &trv::MultiEraTx, slot_hint: Option) -> u5c::Tx { + pub fn map_tx(&self, tx: &trv::MultiEraTx) -> u5c::Tx { let resolved = self.ledger.as_ref().map(|ctx| { let to_resolve = self.find_related_inputs(tx); @@ -649,7 +649,7 @@ impl Mapper { .collect(); if !missing_refs.is_empty() { - if let Some(historical) = ctx.get_historical_utxos(&missing_refs, slot_hint) { + if let Some(historical) = ctx.get_historical_utxos(&missing_refs) { utxos.extend(historical); } } @@ -761,11 +761,7 @@ impl Mapper { } .into(), body: u5c::BlockBody { - tx: block - .txs() - .iter() - .map(|x| self.map_tx(x, Some(block.slot()))) - .collect(), + tx: block.txs().iter().map(|x| self.map_tx(x)).collect(), } .into(), timestamp: self @@ -799,7 +795,7 @@ mod tests { None } - fn get_historical_utxos(&self, _: &[TxoRef], _: Option) -> Option { + fn get_historical_utxos(&self, _: &[TxoRef]) -> Option { None } }