Skip to main content

tx3_resolver/inputs/approximate/
mod.rs

1//! Approximation stage: produces a ranked list of viable UTxO candidates for
2//! each query independently, without cross-query awareness.
3
4use std::collections::HashMap;
5
6use tx3_tir::model::{
7    assets::CanonicalAssets,
8    core::{Utxo, UtxoRef},
9};
10
11use crate::inputs::canonical::CanonicalQuery;
12use crate::job::ResolveJob;
13
14pub mod filter;
15pub mod rank;
16
17use rank::{Rank as _, Ranker};
18
19impl ResolveJob {
20    /// For each query, filter the pool by hard constraints, rank by closeness
21    /// to the target asset composition, then filter by aggregate constraints.
22    pub fn approximate_queries(&mut self) {
23        let pool = self
24            .input_pool
25            .as_ref()
26            .expect("pool must be set before approximate");
27
28        for qr in &mut self.input_queries {
29            qr.candidates = approximate_candidates(pool, &qr.query);
30        }
31    }
32}
33
34fn approximate_candidates(pool: &HashMap<UtxoRef, Utxo>, query: &CanonicalQuery) -> Vec<Utxo> {
35    let target = query.min_amount.clone().unwrap_or(CanonicalAssets::empty());
36
37    let pool_set = pool
38        .values()
39        .filter(|utxo| filter::matches_hard_constraints(query, utxo))
40        .cloned()
41        .collect();
42
43    let ordered = Ranker::sorted_candidates(pool_set, &target);
44
45    ordered
46        .into_iter()
47        .filter(|utxo| filter::matches_aggregate_constraints(query, utxo, &target))
48        .collect()
49}