currencyrate: expose get_median_rate and do conversion in front-end for currencyconvert.
What changed, and why it matters
This is a small internal code refactor in Core Lightning's currency-rate plugin. It moves the constant 'MSAT_PER_BTC' and the final arithmetic from the back-end oracle into the front-end handler, exposing a new 'get_median_rate' helper. The actual conversion formula is unchanged. There is no security issue visible in the diff.
No security action required; treat as a normal refactor review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors the currency conversion path in plugins/currencyrate-plugin. It removes the public MSAT_PER_BTC constant from oracle.rs, adds it locally in main.rs, renames oracle::convert to oracle::get_median_rate, and renames get_median_rate to get_median. The caller now performs (amount * MSAT_PER_BTC / rate).round() as u64 itself. No logic, trust model, input validation, or network behavior changes are introduced.
Changed components
plugins/currencyrate-plugin/src/main.rsplugins/currencyrate-plugin/src/oracle.rsInspect captured patch +8 / −10
diff --git a/plugins/currencyrate-plugin/src/main.rs b/plugins/currencyrate-plugin/src/main.rs
index 8dc85651..d0d3f475 100644
--- a/plugins/currencyrate-plugin/src/main.rs
+++ b/plugins/currencyrate-plugin/src/main.rs
@@ -10,11 +10,12 @@ use std::sync::Arc;
use std::vec;
use tokio::sync::Mutex;
-use crate::oracle::{BtcPriceOracle, Source, MSAT_PER_BTC};
+use crate::oracle::{BtcPriceOracle, Source};
mod oracle;
const DEFAULT_PROXY_PORT: u16 = 9050;
+const MSAT_PER_BTC: f64 = 1e11;
#[derive(Debug, Clone)]
pub struct SourceResult {
@@ -129,9 +130,9 @@ async fn currencyconvert(plugin: Plugin<PluginState>, args: Value) -> Result<Val
let oracle = plugin.state().oracle.lock().await;
oracle.currency_requested(¤cy).await;
- match oracle.convert(amount, ¤cy).await {
- Ok(result) => Ok(json!({
- "msat": result,
+ match oracle.get_median_rate(¤cy).await {
+ Ok(rate) => Ok(json!({
+ "msat": (amount * MSAT_PER_BTC / rate).round() as u64,
})),
Err(e) => Err(anyhow!("Error converting currency: {e}")),
}
diff --git a/plugins/currencyrate-plugin/src/oracle.rs b/plugins/currencyrate-plugin/src/oracle.rs
index 0098c943..7145c4ff 100644
--- a/plugins/currencyrate-plugin/src/oracle.rs
+++ b/plugins/currencyrate-plugin/src/oracle.rs
@@ -20,8 +20,6 @@ const DRIFT_THRESHOLD: f64 = 0.01;
const INITIAL_BACKOFF: Duration = Duration::from_secs(30);
const MAX_BACKOFF: Duration = Duration::from_secs(3_600);
-pub const MSAT_PER_BTC: f64 = 1e11;
-
#[derive(Debug, Clone)]
pub struct Source {
name: String,
@@ -312,7 +310,7 @@ impl BtcPriceOracle {
Ok(results)
}
- pub async fn convert(&self, amount: f64, currency: &str) -> Result<u64, anyhow::Error> {
+ pub async fn get_median_rate(&self, currency: &str) -> Result<f64, anyhow::Error> {
let inner = self.inner.lock().await;
let source_results = if let Some(currency_cache) = inner.currencies.get(currency) {
let prices = currency_cache.fresh_prices();
@@ -328,8 +326,7 @@ impl BtcPriceOracle {
self.get_all_rates(currency).await?
};
- let median_currency_per_btc = get_median_rate(source_results);
- Ok((amount * MSAT_PER_BTC / median_currency_per_btc).round() as u64)
+ Ok(get_median(source_results))
}
async fn refresh_currency(&self, currency: &str) -> Result<(), anyhow::Error> {
@@ -528,7 +525,7 @@ impl BtcPriceOracle {
}
}
-fn get_median_rate(source_results: Vec<SourceResult>) -> f64 {
+fn get_median(source_results: Vec<SourceResult>) -> f64 {
let mut prices: Vec<f64> = source_results.iter().map(|r| r.price).collect();
prices.sort_by(|a, b| a.partial_cmp(b).unwrap());
let mid = prices.len() / 2;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.