Skip to content

Improving currencyrate plugin#9011

Open
enaples wants to merge 5 commits intoElementsProject:masterfrom
enaples:improve-currencyrate-plugin
Open

Improving currencyrate plugin#9011
enaples wants to merge 5 commits intoElementsProject:masterfrom
enaples:improve-currencyrate-plugin

Conversation

@enaples
Copy link
Copy Markdown
Collaborator

@enaples enaples commented Mar 31, 2026

Important

26.04 FREEZE March 11th: Non-bugfix PRs not ready by this date will wait for 26.06.

RC1 is scheduled on March 23rd

The final release is scheduled for April 15th.

Checklist

Before submitting the PR, ensure the following tasks are completed. If an item is not applicable to your PR, please mark it as checked:

  • The changelog has been updated in the relevant commit(s) according to the guidelines.
  • Tests have been added or modified to reflect the changes.
  • Documentation has been reviewed and updated as needed.
  • Related issues have been listed and linked, including any that this PR closes.
  • Important All PRs must consider how to reverse any persistent changes for tools/lightning-downgrade

Currencyrate plugin changes

As mentioned in #9010,

  1. Check on RPC argument number added
  2. Show max three decimal digits
  3. Added source argument to the currencyrate RPC call
  4. Added "Example" on RPC documentation

Info Needed

I would personally suggest to add a README.md file in the currencyrate plugin folder reporting how to configure new sources in the config file, plus some best practice using reckless to add and disable sources without restarting the node.

@enaples enaples requested a review from daywalker90 March 31, 2026 15:11
@enaples enaples added this to the 26.06 milestone Mar 31, 2026
@enaples enaples changed the title plugin: round to the tird digit and adding source argument to `curren… Improving currencyrate plugin Mar 31, 2026
@enaples enaples linked an issue Mar 31, 2026 that may be closed by this pull request
@madelinevibes madelinevibes added the 26.04 RC This PR needs to go into the next release candidate for 26.04 label Mar 31, 2026
@sangbida sangbida removed the 26.04 RC This PR needs to go into the next release candidate for 26.04 label Apr 1, 2026
const MSAT_PER_BTC: f64 = 1e11;

fn round_to_3dp(price: f64) -> f64 {
format!("{:.3}", price).parse::<f64>().unwrap_or(price)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of moving from f64 to a string and then back again to f64, it would be better to do some purely mathematical operation.
eg. output = (input*1000.0).round() / 1000.0;

Copy link
Copy Markdown
Collaborator

@daywalker90 daywalker90 Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to always get 3 decimal places you must return a String:

fn round_to_3dp(price: f64) -> String {
    format!("{:.3}", (price * 1000.0).round() / 1000.0)
}

Copy link
Copy Markdown
Collaborator Author

@enaples enaples Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is not that reliable. See here the comment for very large number. That's why I opted for the f64 --> String --> f64 solution.

I need to return again f64 since the price is used to compute the median, so it is better to return f64 again in my opinion.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, the linked issue said to always have 3 decimal places not at most 3. So this is fine then if we can live with always rounding toward 0.

@daywalker90 daywalker90 force-pushed the improve-currencyrate-plugin branch from 1f75db1 to 3ef67e3 Compare April 2, 2026 08:15
@daywalker90 daywalker90 requested a review from cdecker as a code owner April 2, 2026 08:15
@daywalker90 daywalker90 force-pushed the improve-currencyrate-plugin branch from 3ef67e3 to d945873 Compare April 2, 2026 08:16
@daywalker90 daywalker90 force-pushed the improve-currencyrate-plugin branch from d945873 to 1a74aaa Compare April 2, 2026 08:27
@daywalker90
Copy link
Copy Markdown
Collaborator

I would personally suggest to add a README.md file in the currencyrate plugin folder reporting how to configure new sources in the config file

We can do that, but personally i go to https://docs.corelightning.org/reference/lightningd-config first to see documentation on config options and we have the currencyrate options with instructions on how they need to be written included there.

, plus some best practice using reckless to add and disable sources without restarting the node.

No sure if it can be done with reckless but it can be done with just the plugin command e.g.:

lightning-cli plugin stop cln-currencyrate

then to add a source:

lightning-cli plugin -k subcommand=start plugin=/media/addonssd/dev/lightning/plugins/cln-currencyrate currencyrate-add-source="test,https://test.com/{currency},rate"

But keep in mind that afaik any events happening while the plugin is stopped will have their currencyrate missing.

Value::Array(values) => {
if values.len() > 2 {
return Err(anyhow!(
"Too many arguments: expected at most 2 (amount currency), got {}",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: change this to expected 2.

.to_owned();
(amount, currency.to_uppercase())
}
Value::Object(map) => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should then also do the same check for object based queries here aswell.

let source = values.get(1).and_then(|v| v.as_str()).map(str::to_owned);
(currency, source)
}
Value::Object(map) => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should then also do the same check for object based queries here aswell.

Value::Array(values) => {
if values.len() > 1 {
return Err(anyhow!(
"Too many arguments: expected at most 1 (currency), got {}",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "expected 1"

.to_owned();
currency.to_uppercase()
}
Value::Object(map) => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should then also do the same check for object based queries here aswell.

.to_owned();
currency.to_uppercase()
.to_uppercase();
let source = values.get(1).and_then(|v| v.as_str()).map(str::to_owned);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do allow sources to be named as numbers only and this would then cause currencyrate to silently ignore the sourrce and return a median result. I suggest changing this to:

let source = values.get(1).and_then(|v| {
                v.as_str()
                    .map(str::to_owned)
                    .or_else(|| v.as_number().map(std::string::ToString::to_string))
            });

.to_owned();
currency.to_uppercase()
.to_uppercase();
let source = map.get("source").and_then(|v| v.as_str()).map(str::to_owned);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above:

let source = map.get("source").and_then(|v| {
                v.as_str()
                    .map(str::to_owned)
                    .or_else(|| v.as_number().map(std::string::ToString::to_string))
            });

@daywalker90
Copy link
Copy Markdown
Collaborator

Usually we would use setconfig to change options dynamically but since here we have multi options it's not possible until something like #8751. Then we could change sources without restarting the plugin or node or extra rpc methods(yikes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

currencyrate plugin UI improvement proposals

5 participants