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 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..5a5d3f3 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)] @@ -22,49 +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: ForwardEventNotification = serde_json::from_value(v)?; - plugin - .state() - .counters - .forward_events_total - .with_label_values(&[&n.forward_event.status]) - .inc(); + let n: ForwardEventNotificationWrapper = serde_json::from_value(v)?; + 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(); + // CLN hook - must return {"result": "continue"} or the HTLC will be rejected by the node 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..ba1b50f 100644 --- a/metrics-plugin/src/metrics.rs +++ b/metrics-plugin/src/metrics.rs @@ -5,6 +5,7 @@ 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}, @@ -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.