From d6f74c82e0cb9ec0b9165c892067b902207e858d Mon Sep 17 00:00:00 2001 From: Oleh Fomenko Date: Thu, 23 Jul 2026 01:17:10 +0300 Subject: [PATCH 1/5] [metrics] Bump cln_rpc crate to 0.7. Using ForwardEventNotification from cln_rpc, instead of defining the custom one. Co-authored-by: Oleg Fomenko --- Cargo.lock | 4 ++-- metrics-plugin/Cargo.toml | 2 +- metrics-plugin/src/events.rs | 16 ++++++---------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b3fcfd..80c83dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,9 +525,9 @@ dependencies = [ [[package]] name = "cln-rpc" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c63eb175d58f0212e35e427237cf3e4f856f47ec7b8ad95110484d292fc819" +checksum = "5d9f5e26f0a2713ea1393eb3117c148295fa4c5f7db529713b20323ca7cc37aa" dependencies = [ "anyhow", "bitcoin", diff --git a/metrics-plugin/Cargo.toml b/metrics-plugin/Cargo.toml index c4a79f0..2ba1cc4 100644 --- a/metrics-plugin/Cargo.toml +++ b/metrics-plugin/Cargo.toml @@ -11,7 +11,7 @@ path = "src/main.rs" [dependencies] cln-plugin = { version = "0.7" } -cln-rpc = { version = "0.6" } +cln-rpc = { version = "0.7" } prometheus = { version = "0.14" } axum = { version = "0.8" } tokio = { version = "1", features = ["full"] } diff --git a/metrics-plugin/src/events.rs b/metrics-plugin/src/events.rs index c55c81f..5546cbf 100644 --- a/metrics-plugin/src/events.rs +++ b/metrics-plugin/src/events.rs @@ -1,19 +1,14 @@ use anyhow::Result; use cln_plugin::Plugin; -use cln_rpc::notifications::ChannelStateChangedNotification; +use cln_rpc::notifications::{ChannelStateChangedNotification, ForwardEventNotification}; use serde::Deserialize; use serde_json::{Value, json}; use crate::PluginState; #[derive(Deserialize)] -struct ForwardEventNotification { - forward_event: ForwardEvent, -} - -#[derive(Deserialize)] -struct ForwardEvent { - status: String, +struct ForwardEventNotificationWrapper { + forward_event: ForwardEventNotification, } #[derive(Deserialize)] @@ -27,12 +22,13 @@ pub async fn on_channel_opened(plugin: Plugin, _v: Value) -> Result } pub async fn on_forward_event(plugin: Plugin, v: Value) -> Result<()> { - let n: ForwardEventNotification = serde_json::from_value(v)?; + let n: ForwardEventNotificationWrapper = serde_json::from_value(v)?; + plugin .state() .counters .forward_events_total - .with_label_values(&[&n.forward_event.status]) + .with_label_values(&[serde_json::to_string(&n.forward_event.status)?]) .inc(); Ok(()) } From 5a2d091d145718a9f2076a1f86b2c4fd1bf5a498 Mon Sep 17 00:00:00 2001 From: Oleh Fomenko Date: Thu, 23 Jul 2026 01:20:31 +0300 Subject: [PATCH 2/5] [metrics] Move the logic for incrementing the counter into the counter itself, instead of executing it in hook handlers. Co-authored-by: Oleg Fomenko --- metrics-plugin/src/events.rs | 31 ++++--------------------------- metrics-plugin/src/metrics.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/metrics-plugin/src/events.rs b/metrics-plugin/src/events.rs index 5546cbf..dcf07a3 100644 --- a/metrics-plugin/src/events.rs +++ b/metrics-plugin/src/events.rs @@ -17,50 +17,27 @@ struct ChannelStateChangedWrapper { } pub async fn on_channel_opened(plugin: Plugin, _v: Value) -> Result<()> { - plugin.state().counters.channel_opened_total.inc(); + plugin.state().counters.on_channel_opened(); Ok(()) } pub async fn on_forward_event(plugin: Plugin, v: Value) -> Result<()> { let n: ForwardEventNotificationWrapper = serde_json::from_value(v)?; - - plugin - .state() - .counters - .forward_events_total - .with_label_values(&[serde_json::to_string(&n.forward_event.status)?]) - .inc(); + plugin.state().counters.on_forward_event(&n.forward_event); Ok(()) } // CLN hook - must return {"result": "continue"} or the HTLC will be rejected by the node pub async fn hook_htlc_accepted(plugin: Plugin, _v: Value) -> Result { - plugin.state().counters.htlc_accepted_total.inc(); + plugin.state().counters.on_htlc_accepted(); Ok(json!({ "result": "continue" })) } pub async fn on_channel_state_changed(plugin: Plugin, v: Value) -> Result<()> { let n: ChannelStateChangedWrapper = serde_json::from_value(v)?; - let c = n.channel_state_changed; - - let old = c - .old_state - .map(|s| s.to_string()) - .unwrap_or_else(|| "unknown".to_string()); - let new = c.new_state.to_string(); - plugin .state() .counters - .channel_state_changes_total - .with_label_values(&[&old, &new]) - .inc(); - - tracing::info!( - peer = %c.peer_id, - old_state = old, - new_state = new, - "channel_state_changed" - ); + .on_channel_state_changed(&n.channel_state_changed); Ok(()) } diff --git a/metrics-plugin/src/metrics.rs b/metrics-plugin/src/metrics.rs index e1bc7ee..ba713ae 100644 --- a/metrics-plugin/src/metrics.rs +++ b/metrics-plugin/src/metrics.rs @@ -11,6 +11,7 @@ use prometheus::{ proto::MetricFamily, }; use std::sync::{Arc, RwLock}; +use cln_rpc::notifications::{ChannelStateChangedNotification, ForwardEventNotification}; use tokio::net::TcpListener; use tracing::error; @@ -85,6 +86,39 @@ impl EventCounters { )?)?, }) } + + pub fn on_forward_event(&self, event: &ForwardEventNotification) { + self.forward_events_total + .with_label_values(&[event.status.to_string()]) + .inc(); + } + + pub fn on_channel_opened(&self) { + self.channel_opened_total.inc() + } + + pub fn on_channel_state_changed(&self, event: &ChannelStateChangedNotification) { + let old = event + .old_state + .map(|s| s.to_string()) + .unwrap_or_else(|| "unknown".to_string()); + let new = event.new_state.to_string(); + + self.channel_state_changes_total + .with_label_values(&[&old, &new]) + .inc(); + + tracing::info!( + peer = %event.peer_id, + old_state = old, + new_state = new, + "channel_state_changed" + ); + } + + pub fn on_htlc_accepted(&self) { + self.htlc_accepted_total.inc(); + } } /// Registers the build_info gauge with the global registry and pins it to 1.0. From 1a89503f68e14e9972056770799c12a391fabda3 Mon Sep 17 00:00:00 2001 From: Oleh Fomenko Date: Thu, 23 Jul 2026 01:20:48 +0300 Subject: [PATCH 3/5] [metrics] Small ref Co-authored-by: Oleg Fomenko --- metrics-plugin/src/events.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics-plugin/src/events.rs b/metrics-plugin/src/events.rs index dcf07a3..5a5d3f3 100644 --- a/metrics-plugin/src/events.rs +++ b/metrics-plugin/src/events.rs @@ -27,9 +27,9 @@ pub async fn on_forward_event(plugin: Plugin, v: Value) -> Result<( Ok(()) } -// CLN hook - must return {"result": "continue"} or the HTLC will be rejected by the node pub async fn hook_htlc_accepted(plugin: Plugin, _v: Value) -> Result { plugin.state().counters.on_htlc_accepted(); + // CLN hook - must return {"result": "continue"} or the HTLC will be rejected by the node Ok(json!({ "result": "continue" })) } From 06cd2a57ccab06b9c4cbb73f3c1db7ea9b2afb53 Mon Sep 17 00:00:00 2001 From: Oleh Fomenko Date: Thu, 23 Jul 2026 15:10:14 +0300 Subject: [PATCH 4/5] [events] cargo fmt Co-authored-by: Oleg Fomenko --- metrics-plugin/src/metrics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics-plugin/src/metrics.rs b/metrics-plugin/src/metrics.rs index ba713ae..ba1b50f 100644 --- a/metrics-plugin/src/metrics.rs +++ b/metrics-plugin/src/metrics.rs @@ -5,13 +5,13 @@ use axum::{ response::{IntoResponse, Response}, routing::get, }; +use cln_rpc::notifications::{ChannelStateChangedNotification, ForwardEventNotification}; use prometheus::{ Encoder, Gauge, GaugeVec, IntCounter, IntCounterVec, Opts, TextEncoder, core::{Collector, Desc}, proto::MetricFamily, }; use std::sync::{Arc, RwLock}; -use cln_rpc::notifications::{ChannelStateChangedNotification, ForwardEventNotification}; use tokio::net::TcpListener; use tracing::error; From ec0f6f3f562d343183fe2937296ce0e074dee82d Mon Sep 17 00:00:00 2001 From: Nazarevsky Date: Sat, 25 Jul 2026 16:15:58 +0200 Subject: [PATCH 5/5] (ci): add basic workflow for linting Rust code This workflow includes: - pulling rust-toolchain commands - caching the compiled dependencies and cargo registry after a run - calling cargo fmt - calling cargo clippy --- .github/workflows/code.yaml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/code.yaml diff --git a/.github/workflows/code.yaml b/.github/workflows/code.yaml new file mode 100644 index 0000000..a8abd16 --- /dev/null +++ b/.github/workflows/code.yaml @@ -0,0 +1,29 @@ +name: CI + +on: + pull_request: + branches: [master] + +jobs: + build-lint: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - name: Install protoc + uses: arduino/setup-protoc@v3 + + - name: Cache cargo + uses: Swatinem/rust-cache@v2 + + - name: Check formatting + run: cargo fmt --all --check + + - name: Run clippy + run: cargo clippy --all-targets --all-features -- -D warnings \ No newline at end of file