Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 50 additions & 3 deletions libs/gl-plugin/src/node/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::config::Config;
use crate::pb::{self, node_server::Node};
use crate::storage::StateStore;
use crate::storage::{JitRequestMeta, StateStore};
use crate::{messages, Event};
use crate::{stager, tramp};
use anyhow::{Context, Error, Result};
use anyhow::{anyhow, Context, Error, Result};
use base64::{engine::general_purpose, Engine as _};
use bytes::BufMut;
use cln_rpc::Notification;
use cln_rpc::{ClnRpc, Notification};
use gl_client::metrics::{savings_percent, signer_state_request_wire_bytes};
use gl_client::persist::{State, StateSketch};
use governor::{
Expand Down Expand Up @@ -323,6 +323,9 @@ impl Node for PluginNodeServer {
.div_ceil(1_000_000);
std::cmp::max(min_fee, proportional_fee)
};

let requested_amount_msat = req.amount_msat.clone();
let invoice_label = req.label.clone();

// Use the new RPC method name for versions > v25.05gl1
let mut res = if *version > *"v25.05gl1" {
Expand All @@ -340,6 +343,23 @@ impl Node for PluginNodeServer {
};

res.opening_fee_msat = opening_fee_msat;

// A JIT channel has now been negotiated with the LSP for this
// invoice. So, we're storing some data with the original requested
// amount.
let meta = JitRequestMeta {
label: invoice_label.clone(),
payment_hash: res.payment_hash.clone(),
requested_amount_msat,
expected_amount_msat: requested_amount_msat.saturating_sub(opening_fee_msat),
bolt11: res.bolt11.clone(),
lsp_id,
};

if let Err(e) = write_lsp_invoice_meta(&mut rpc, meta).await {
warn!("Failed to write LSP invoice meta: {}", e);
}

Ok(Response::new(res.into()))
}

Expand Down Expand Up @@ -834,6 +854,33 @@ impl Node for PluginNodeServer {
}
}

/// Writes `LspInvoiceMeta` using datastore request. `LspInvoiceMeta` is useful for defining
/// some additional information regarding invoice being requested trough Greenlight.
async fn write_lsp_invoice_meta(rpc: &mut ClnRpc, meta: JitRequestMeta)
-> Result<()> {
let record_serialized =
serde_json::to_string(&meta).context("failed to serialize LspInvoiceMeta")?;

let datastore_req = cln_rpc::model::requests::DatastoreRequest {
key: vec![
"gl".to_string(),
"jit_channels".to_string(),
meta.label,
],
Comment thread
nepet marked this conversation as resolved.
string: Some(record_serialized),
hex: None,
mode: Some(cln_rpc::model::requests::DatastoreMode::CREATE_OR_REPLACE),
generation: None,
};

rpc.call_typed(&datastore_req).await.map_err(
|e|
anyhow!("Failed to store JIT channel negotiation data in datastore: {}", e)
)?;

Ok(())
}

use cln_grpc::pb::node_server::NodeServer;

#[derive(Clone, Debug)]
Expand Down
29 changes: 29 additions & 0 deletions libs/gl-plugin/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

pub use gl_client::persist::State;
use log::debug;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use tonic::async_trait;

Expand Down Expand Up @@ -66,3 +67,31 @@ impl StateStore for SledStateStore {
.map_err(|e| e.into())
}
}

/// A structure that is used for storing JIT channel requests metadata that is
/// requested through [Node::lsp_invoice](pb::node_server::Node::lsp_invoice)
/// RPC call.
///
/// This structure is stored in CLN datastore. The reason of why do we need this
/// structure instead of querying invoices table is that we want to distinguish
/// incomming payments whether they were for JIT channel opening or just a simple
/// payment. Currently, CLN does not allow this, that's why this workaround
/// exists.
#[derive(Serialize, Deserialize)]
pub struct JitRequestMeta {
/// A label of the requested invoice.
pub label: String,
/// Payment hash of the requested invoice.
pub payment_hash: String,
/// The requested amount of msats.
pub requested_amount_msat: u64,
/// The expected (reduced) amount if msats.
///
/// Note that expected_amount_msat <= requested_amount_msat since
/// expected_amount_msat = requested_amount_msat + lsp_fee.
pub expected_amount_msat: u64,
/// Original Bolt11 invoice which includes requested_amount_msat.
pub bolt11: String,
Comment thread
nepet marked this conversation as resolved.
/// ID of the LSP through which the invoice was requested.
pub lsp_id: String,
}
Loading