Skip to content

Commit

Permalink
feat(lsp): be able to provide liquitidy to other nodes
Browse files Browse the repository at this point in the history
This commit allows our node to act as a server to provide
liquidity to other nodes.
  • Loading branch information
Harshit933 committed Jul 21, 2024
1 parent bf9692e commit 30a1a42
Show file tree
Hide file tree
Showing 10 changed files with 329 additions and 15 deletions.
56 changes: 56 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lampo-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ crossbeam-channel = "0.5.8"
anyhow = "1.0.70"
colored = "1.9"
log = { version = "0.4", features = ["std"] }
chrono = { version = "0.4", features = ["std"], default-features = false }
chrono = { version = "0.4", features = ["std", "clock"], default-features = false }
serde_json = "1.0"
serde = "1.0"
hex = "0.4.3"
4 changes: 4 additions & 0 deletions lampo-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,7 @@ pub mod btc_rpc {
pub mempoolminfee: f32,
}
}

pub mod chrono {
pub use chrono::*;
}
4 changes: 2 additions & 2 deletions lampo-common/src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::time::SystemTime;
// FIXME: this is not async we should modify it
use std::fs::File;

use chrono::prelude::*;
use crate::chrono::prelude::*;
use colored::*;

pub use log::{Level, Log, Metadata, Record, SetLoggerError};
Expand Down Expand Up @@ -53,7 +53,7 @@ impl Log for Logger {
writeln!(
stream,
"{} {}",
DateTime::from(SystemTime::now())
DateTime::<Utc>::from(SystemTime::now())
.to_rfc3339_opts(SecondsFormat::Millis, true)
.white(),
message,
Expand Down
17 changes: 17 additions & 0 deletions lampod/src/actions/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use lampo_common::event::{Emitter, Event, Subscriber};
use lampo_common::handler::Handler as EventHandler;
use lampo_common::json;
use lampo_common::ldk;
use lampo_common::ldk::ln::peer_handler::CustomMessageHandler;

Check warning on line 13 in lampod/src/actions/handler.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused import: `lampo_common::ldk::ln::peer_handler::CustomMessageHandler`

Check warning on line 13 in lampod/src/actions/handler.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused import: `lampo_common::ldk::ln::peer_handler::CustomMessageHandler`

Check warning on line 13 in lampod/src/actions/handler.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused import: `lampo_common::ldk::ln::peer_handler::CustomMessageHandler`
use lampo_common::ldk::ln::wire::CustomMessageReader;

Check warning on line 14 in lampod/src/actions/handler.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused import: `lampo_common::ldk::ln::wire::CustomMessageReader`

Check warning on line 14 in lampod/src/actions/handler.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused import: `lampo_common::ldk::ln::wire::CustomMessageReader`

Check warning on line 14 in lampod/src/actions/handler.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused import: `lampo_common::ldk::ln::wire::CustomMessageReader`
use lampo_common::model::response::PaymentHop;
use lampo_common::model::response::PaymentState;
use lampo_common::types::ChannelState;
Expand All @@ -19,6 +21,7 @@ use crate::chain::{LampoChainManager, WalletManager};
use crate::command::Command;
use crate::handler::external_handler::ExternalHandler;
use crate::ln::events::PeerEvents;
use crate::ln::liquidity::LampoLiquidityManager;
use crate::ln::{LampoChannelManager, LampoInventoryManager, LampoPeerManager};
use crate::{async_run, LampoDaemon};

Expand All @@ -34,6 +37,7 @@ pub struct LampoHandler {
wallet_manager: Arc<dyn WalletManager>,
chain_manager: Arc<LampoChainManager>,
external_handlers: RefCell<Vec<Arc<dyn ExternalHandler>>>,
liquidity_manager: Option<Arc<LampoLiquidityManager>>,
#[allow(dead_code)]
emitter: Emitter<Event>,
subscriber: Subscriber<Event>,
Expand All @@ -53,6 +57,7 @@ impl LampoHandler {
wallet_manager: lampod.wallet_manager(),
chain_manager: lampod.onchain_manager(),
external_handlers: RefCell::new(Vec::new()),
liquidity_manager: Some(lampod.liquidity()),
emitter,
subscriber,
}
Expand Down Expand Up @@ -142,6 +147,9 @@ impl Handler for LampoHandler {
counterparty_node_id,
channel_type,
} => {
if self.liquidity_manager.is_some() {
self.liquidity_manager.as_ref().unwrap().channel_ready(user_channel_id, &channel_id, &counterparty_node_id)?;
}
log::info!("channel ready with node `{counterparty_node_id}`, and channel type {channel_type}");
self.emit(Event::Lightning(LightningEvent::ChannelReady {
counterparty_node_id,
Expand Down Expand Up @@ -287,6 +295,15 @@ impl Handler for LampoHandler {
self.emit(Event::Lightning(hop));
Ok(())
},
ldk::events::Event::HTLCIntercepted { intercept_id, requested_next_hop_scid, payment_hash, inbound_amount_msat, expected_outbound_amount_msat } => {
log::info!("Intecepted an HTLC");
if self.liquidity_manager.is_some() {
// TODO: Make a new function for self.liquidity_manager.as_ref().unwrap()
self.liquidity_manager.as_ref().unwrap().htlc_intercepted(requested_next_hop_scid, intercept_id, expected_outbound_amount_msat, payment_hash)?;
}

Ok(())
},
_ => Err(error::anyhow!("unexpected ldk event: {:?}", event)),
}
}
Expand Down
3 changes: 2 additions & 1 deletion lampod/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ impl LampoDaemon {

pub fn init_peer_manager(&mut self) -> error::Result<()> {
log::debug!(target: "lampo", "init peer manager ...");
let mut peer_manager = LampoPeerManager::new(&self.conf, self.logger.clone());
// TODO(Harshit): When we want to run as LSP. Configure this!
let mut peer_manager = LampoPeerManager::new(&self.conf, self.logger.clone(), None);
peer_manager.init(
self.onchain_manager(),
self.wallet_manager.clone(),
Expand Down
146 changes: 138 additions & 8 deletions lampod/src/ln/liquidity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use std::time::Duration;

use lampo_common::bitcoin::hashes::sha256;
use lampo_common::bitcoin::hashes::Hash;
use lampo_common::chrono;

Check warning on line 6 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused import: `lampo_common::chrono`

Check warning on line 6 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused import: `lampo_common::chrono`

Check warning on line 6 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused import: `lampo_common::chrono`
use lampo_common::chrono::DateTime;
use lampo_common::chrono::Utc;
use lampo_common::conf::LampoConf;
use lampo_common::error;
use lampo_common::keys::LampoKeysManager;
Expand All @@ -11,8 +14,11 @@ use lampo_common::ldk::invoice::InvoiceBuilder;
use lampo_common::ldk::invoice::RouteHint;
use lampo_common::ldk::invoice::RouteHintHop;
use lampo_common::ldk::invoice::RoutingFees;
use lampo_common::ldk::ln::channelmanager::InterceptId;
use lampo_common::ldk::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA;
use lampo_common::ldk::ln::msgs::SocketAddress;
use lampo_common::ldk::ln::ChannelId;
use lampo_common::ldk::ln::PaymentHash;
use lampo_common::secp256k1::PublicKey;
use lampo_common::secp256k1::Secp256k1;

Expand All @@ -21,6 +27,7 @@ use lightning_liquidity::lsps0::ser::RequestId;
use lightning_liquidity::lsps2::event::LSPS2ClientEvent;
use lightning_liquidity::lsps2::event::LSPS2ServiceEvent;
use lightning_liquidity::lsps2::msgs::OpeningFeeParams;
use lightning_liquidity::lsps2::msgs::RawOpeningFeeParams;
use lightning_liquidity::LiquidityManager;

use crate::chain::LampoChainManager;
Expand Down Expand Up @@ -96,6 +103,46 @@ impl LampoLiquidityManager {
}
}

pub fn liquidity_manager(&self) -> Arc<LampoLiquidity> {
self.lampo_liquidity.clone()
}

pub fn htlc_intercepted(
&self,
intercept_scid: u64,
intercept_id: InterceptId,
expected_outbound_amount_msat: u64,
payment_hash: PaymentHash,
) -> error::Result<()> {
self.liquidity_manager()
.lsps2_service_handler()
.unwrap()
.htlc_intercepted(
intercept_scid,
intercept_id,
expected_outbound_amount_msat,
payment_hash,
)
.map_err(|e| error::anyhow!("Error : {:?}", e))?;

Ok(())
}

pub fn channel_ready(
&self,
user_channel_id: u128,
channel_id: &ChannelId,
counterparty_node_id: &PublicKey,
) -> error::Result<()> {
self.lampo_liquidity
.lsps2_service_handler()
.unwrap()
.channel_ready(user_channel_id, channel_id, counterparty_node_id)
.map_err(|e| error::anyhow!("Error occured : {:?}", e))?;

Ok(())
}

pub fn get_events(&self) -> Vec<Event> {
self.lampo_liquidity.get_and_clear_pending_events()
}
Expand Down Expand Up @@ -138,24 +185,107 @@ impl LampoLiquidityManager {

Ok(())
}
Event::LSPS2Service(LSPS2ServiceEvent::BuyRequest {
request_id,
counterparty_node_id,
opening_fee_params,
payment_size_msat,
}) => todo!(),
Event::LSPS2Service(LSPS2ServiceEvent::GetInfo {
request_id,
counterparty_node_id,
token,

Check warning on line 191 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `token`

Check warning on line 191 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `token`

Check warning on line 191 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `token`
}) => todo!(),
}) => {
let service_handler = self.lampo_liquidity.lsps2_service_handler().unwrap();

let min_fee_msat = 0;
let proportional = 0;
let mut valid_until: DateTime<Utc> = Utc::now();
valid_until += Duration::from_secs_f64(600_f64);
let min_lifetime = 1008;
let max_client_to_self_delay = 144;
let min_payment_size_msat = 1000;
let max_payment_size_msat = 10_000_000_000;

let opening_fee_params = RawOpeningFeeParams {
min_fee_msat,
proportional,
valid_until,
min_lifetime,
max_client_to_self_delay,
min_payment_size_msat,
max_payment_size_msat,
};

let opening_fee_params_menu = vec![opening_fee_params];

service_handler
.opening_fee_params_generated(
&counterparty_node_id,
request_id,
opening_fee_params_menu,
)
.map_err(|e| error::anyhow!("Error : {:?}", e))?;

Ok(())
}
Event::LSPS2Service(LSPS2ServiceEvent::BuyRequest {
request_id,
counterparty_node_id,
opening_fee_params: _,
payment_size_msat: _,
}) => {
let user_channel_id = 0;
let scid = self
.channel_manager
.channeld
.as_ref()
.unwrap()
.get_intercept_scid();
let cltv_expiry_delta = 72;
let client_trusts_lsp = true;

let lsps2_service_handler = self.lampo_liquidity.lsps2_service_handler().unwrap();

lsps2_service_handler
.invoice_parameters_generated(
&counterparty_node_id,
request_id,
scid,
cltv_expiry_delta,
client_trusts_lsp,
user_channel_id,
)
.map_err(|e| error::anyhow!("Error occured: {:?}", e))?;

Ok(())
}
Event::LSPS2Service(LSPS2ServiceEvent::OpenChannel {
their_network_key,
amt_to_forward_msat,
opening_fee_msat,

Check warning on line 260 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `opening_fee_msat`

Check warning on line 260 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `opening_fee_msat`

Check warning on line 260 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `opening_fee_msat`
user_channel_id,
intercept_scid,

Check warning on line 262 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `intercept_scid`

Check warning on line 262 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `intercept_scid`

Check warning on line 262 in lampod/src/ln/liquidity.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `intercept_scid`
}) => todo!(),
}) => {
let channel_size_sats = (amt_to_forward_msat / 1000) * 4;
let mut config = self.lampo_conf.ldk_conf;
config
.channel_handshake_config
.max_inbound_htlc_value_in_flight_percent_of_channel = 100;
config.channel_config.forwarding_fee_base_msat = 0;
config.channel_config.forwarding_fee_proportional_millionths = 0;

// TODO(Harshit): Make a different function to get channeld
self.channel_manager
.channeld
.as_ref()
.unwrap()
.create_channel(
their_network_key,
channel_size_sats,
0,
user_channel_id,
None,
Some(config),
)
.map_err(|e| error::anyhow!("Error occured: {:?}", e))?;

Ok(())
}
}
}

Expand Down
Loading

0 comments on commit 30a1a42

Please sign in to comment.