style: cargo fmt for v1.7.99-alpha release gate
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
144c4a2872
commit
83bb589ea6
@@ -489,8 +489,12 @@ pub async fn swap_between_mints(
|
||||
// The pay leg never completed — record the route failure so future
|
||||
// payments can prefer a route with a track record.
|
||||
record_swap_failure(data_dir, from_mint, to_mint).await;
|
||||
return Err(e)
|
||||
.with_context(|| format!("melting source proofs at {} to pay target invoice", from_mint));
|
||||
return Err(e).with_context(|| {
|
||||
format!(
|
||||
"melting source proofs at {} to pay target invoice",
|
||||
from_mint
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
// Persist the spend BEFORE claiming so a crash can't double-spend, and
|
||||
@@ -533,7 +537,10 @@ pub async fn swap_between_mints(
|
||||
wallet.record_tx(
|
||||
TransactionType::Mint,
|
||||
minted,
|
||||
&format!("Cross-mint swap {}→{}: claimed {} sats", from_mint, to_mint, minted),
|
||||
&format!(
|
||||
"Cross-mint swap {}→{}: claimed {} sats",
|
||||
from_mint, to_mint, minted
|
||||
),
|
||||
to_mint,
|
||||
from_mint,
|
||||
);
|
||||
@@ -680,7 +687,11 @@ pub enum PaymentPlan {
|
||||
/// Pure and synchronous so it can be unit-tested without a live mint. It does
|
||||
/// not know swap fees; `swap_between_mints` enforces the fee cap and bails (→
|
||||
/// origin fallback) if the chosen source can't cover amount + fee.
|
||||
fn plan_payment(holdings: &[(String, u64)], accepted: &[(String, bool)], amount: u64) -> PaymentPlan {
|
||||
fn plan_payment(
|
||||
holdings: &[(String, u64)],
|
||||
accepted: &[(String, bool)],
|
||||
amount: u64,
|
||||
) -> PaymentPlan {
|
||||
let norm = |s: &str| s.trim_end_matches('/').to_string();
|
||||
let home = norm(&default_mint_url());
|
||||
let held = |mint: &str| -> u64 {
|
||||
@@ -692,10 +703,8 @@ fn plan_payment(holdings: &[(String, u64)], accepted: &[(String, bool)], amount:
|
||||
};
|
||||
|
||||
// 1. Direct: any accepted mint we already hold enough on. Prefer home.
|
||||
let mut direct: Vec<&(String, bool)> = accepted
|
||||
.iter()
|
||||
.filter(|(m, _)| held(m) >= amount)
|
||||
.collect();
|
||||
let mut direct: Vec<&(String, bool)> =
|
||||
accepted.iter().filter(|(m, _)| held(m) >= amount).collect();
|
||||
direct.sort_by_key(|(m, _)| norm(m) != home); // home (false) sorts first
|
||||
if let Some((mint, _)) = direct.first() {
|
||||
return PaymentPlan::Direct {
|
||||
@@ -761,7 +770,10 @@ pub async fn build_payment_token(
|
||||
|
||||
match plan_payment(&holdings, &accepted, amount_sats) {
|
||||
PaymentPlan::Direct { mint_url } => {
|
||||
debug!("Payment plan: direct from {} for {} sats", mint_url, amount_sats);
|
||||
debug!(
|
||||
"Payment plan: direct from {} for {} sats",
|
||||
mint_url, amount_sats
|
||||
);
|
||||
send_token_at(data_dir, &mint_url, amount_sats).await
|
||||
}
|
||||
PaymentPlan::Swap { from_mint, to_mint } => {
|
||||
@@ -844,7 +856,10 @@ pub async fn resume_pending_swaps(data_dir: &Path) -> Result<u64> {
|
||||
let to = match MintClient::new(&swap.to_mint) {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
warn!("resume_pending_swaps: bad target mint {}: {}", swap.to_mint, e);
|
||||
warn!(
|
||||
"resume_pending_swaps: bad target mint {}: {}",
|
||||
swap.to_mint, e
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
@@ -883,7 +898,10 @@ pub async fn resume_pending_swaps(data_dir: &Path) -> Result<u64> {
|
||||
swap.from_mint, swap.to_mint, minted
|
||||
);
|
||||
}
|
||||
Err(e) => warn!("resume_pending_swaps: claim failed for {}: {}", swap.mint_quote_id, e),
|
||||
Err(e) => warn!(
|
||||
"resume_pending_swaps: claim failed for {}: {}",
|
||||
swap.mint_quote_id, e
|
||||
),
|
||||
},
|
||||
"ISSUED" => {
|
||||
// Already claimed on a previous run — drop the journal entry.
|
||||
@@ -940,14 +958,20 @@ async fn save_swap_liquidity(data_dir: &Path, liq: &SwapLiquidity) {
|
||||
/// Record that a swap route succeeded (best-effort; never fails the caller).
|
||||
async fn record_swap_success(data_dir: &Path, from_mint: &str, to_mint: &str) {
|
||||
let mut liq = load_swap_liquidity(data_dir).await;
|
||||
liq.routes.entry(route_key(from_mint, to_mint)).or_default().successes += 1;
|
||||
liq.routes
|
||||
.entry(route_key(from_mint, to_mint))
|
||||
.or_default()
|
||||
.successes += 1;
|
||||
save_swap_liquidity(data_dir, &liq).await;
|
||||
}
|
||||
|
||||
/// Record that a swap route failed (best-effort; never fails the caller).
|
||||
async fn record_swap_failure(data_dir: &Path, from_mint: &str, to_mint: &str) {
|
||||
let mut liq = load_swap_liquidity(data_dir).await;
|
||||
liq.routes.entry(route_key(from_mint, to_mint)).or_default().failures += 1;
|
||||
liq.routes
|
||||
.entry(route_key(from_mint, to_mint))
|
||||
.or_default()
|
||||
.failures += 1;
|
||||
save_swap_liquidity(data_dir, &liq).await;
|
||||
}
|
||||
|
||||
@@ -1574,17 +1598,38 @@ mod tests {
|
||||
wallet.add_proofs(
|
||||
"http://mint-a",
|
||||
vec![
|
||||
Proof { amount: 10, id: "k".into(), secret: "s1".into(), c: "c".into() },
|
||||
Proof { amount: 5, id: "k".into(), secret: "s2".into(), c: "c".into() },
|
||||
Proof {
|
||||
amount: 10,
|
||||
id: "k".into(),
|
||||
secret: "s1".into(),
|
||||
c: "c".into(),
|
||||
},
|
||||
Proof {
|
||||
amount: 5,
|
||||
id: "k".into(),
|
||||
secret: "s2".into(),
|
||||
c: "c".into(),
|
||||
},
|
||||
],
|
||||
);
|
||||
wallet.add_proofs(
|
||||
"http://mint-b",
|
||||
vec![Proof { amount: 7, id: "k".into(), secret: "s3".into(), c: "c".into() }],
|
||||
vec![Proof {
|
||||
amount: 7,
|
||||
id: "k".into(),
|
||||
secret: "s3".into(),
|
||||
c: "c".into(),
|
||||
}],
|
||||
);
|
||||
wallet.proofs[1].spent = true; // exclude the 5 on mint-a
|
||||
let by_mint = wallet.spendable_by_mint();
|
||||
assert_eq!(by_mint, vec![("http://mint-a".to_string(), 10), ("http://mint-b".to_string(), 7)]);
|
||||
assert_eq!(
|
||||
by_mint,
|
||||
vec![
|
||||
("http://mint-a".to_string(), 10),
|
||||
("http://mint-b".to_string(), 7)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1606,7 +1651,9 @@ mod tests {
|
||||
let accepted = vec![("https://b".into(), true)];
|
||||
assert_eq!(
|
||||
plan_payment(&holdings, &accepted, 50),
|
||||
PaymentPlan::Direct { mint_url: "https://b".into() }
|
||||
PaymentPlan::Direct {
|
||||
mint_url: "https://b".into()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1617,7 +1664,10 @@ mod tests {
|
||||
let accepted = vec![("https://b".into(), true)];
|
||||
assert_eq!(
|
||||
plan_payment(&holdings, &accepted, 50),
|
||||
PaymentPlan::Swap { from_mint: "https://a".into(), to_mint: "https://b".into() }
|
||||
PaymentPlan::Swap {
|
||||
from_mint: "https://a".into(),
|
||||
to_mint: "https://b".into()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1626,7 +1676,10 @@ mod tests {
|
||||
// Seeder accepts only B, but B is not trusted → no swap, insufficient.
|
||||
let holdings = vec![("https://a".into(), 100)];
|
||||
let accepted = vec![("https://b".into(), false)];
|
||||
assert_eq!(plan_payment(&holdings, &accepted, 50), PaymentPlan::Insufficient);
|
||||
assert_eq!(
|
||||
plan_payment(&holdings, &accepted, 50),
|
||||
PaymentPlan::Insufficient
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1635,7 +1688,10 @@ mod tests {
|
||||
// we hold neither accepted mint directly.
|
||||
let holdings = vec![("https://a".into(), 30), ("https://c".into(), 30)];
|
||||
let accepted = vec![("https://b".into(), true)];
|
||||
assert_eq!(plan_payment(&holdings, &accepted, 50), PaymentPlan::Insufficient);
|
||||
assert_eq!(
|
||||
plan_payment(&holdings, &accepted, 50),
|
||||
PaymentPlan::Insufficient
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1646,7 +1702,9 @@ mod tests {
|
||||
let accepted = vec![("https://b".into(), true)];
|
||||
assert_eq!(
|
||||
plan_payment(&holdings, &accepted, 50),
|
||||
PaymentPlan::Direct { mint_url: "https://b".into() }
|
||||
PaymentPlan::Direct {
|
||||
mint_url: "https://b".into()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1744,7 +1802,10 @@ mod tests {
|
||||
record_swap_success(tmp.path(), "https://src", "https://liquid").await;
|
||||
|
||||
// Seeder accepts both non-home mints; we only hold "https://src".
|
||||
let accepted = vec![("https://dry".into(), true), ("https://liquid".into(), true)];
|
||||
let accepted = vec![
|
||||
("https://dry".into(), true),
|
||||
("https://liquid".into(), true),
|
||||
];
|
||||
let holdings = vec![("https://src".to_string(), 1000u64)];
|
||||
|
||||
// Mirror build_payment_token's ordering step, then plan.
|
||||
|
||||
@@ -88,7 +88,11 @@ pub async fn ensure_default_federation(data_dir: &Path) -> Result<()> {
|
||||
}
|
||||
};
|
||||
let mut reg = load_registry(data_dir).await?;
|
||||
if !reg.federations.iter().any(|f| f.federation_id == federation_id) {
|
||||
if !reg
|
||||
.federations
|
||||
.iter()
|
||||
.any(|f| f.federation_id == federation_id)
|
||||
{
|
||||
reg.federations.push(JoinedFederation {
|
||||
federation_id,
|
||||
name: None,
|
||||
|
||||
Reference in New Issue
Block a user