Skip to content

Commit

Permalink
fix: Create invoice route hint on app side
Browse files Browse the repository at this point in the history
The route hint can actually get created entirely on the app side, we do not need to ping the coordinator if we already have a channel. Correspondingly we have to switch to the inbound_payment_scid.
  • Loading branch information
holzeis committed Oct 23, 2023
1 parent 17ee8ab commit 7c77036
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 77 deletions.
31 changes: 0 additions & 31 deletions coordinator/src/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,6 @@ pub fn router(
"/api/prepare_onboarding_payment",
post(prepare_onboarding_payment),
)
.route(
"/api/prepare_regular_payment/:peer_id",
post(prepare_regular_payment),
)
.route("/api/newaddress", get(get_unused_address))
.route("/api/node", get(get_node_info))
.route("/api/invoice", get(get_invoice))
Expand Down Expand Up @@ -261,33 +257,6 @@ pub async fn prepare_onboarding_payment(
Ok(Json(route_hint_hop.into()))
}

pub async fn prepare_regular_payment(
peer_id: Path<String>,
State(app_state): State<Arc<AppState>>,
) -> Result<Json<RouteHintHop>, AppError> {
let peer_id = peer_id.0;
let peer_id: PublicKey = peer_id.parse().map_err(|e| {
AppError::BadRequest(format!(
"Provided public key {peer_id} was not valid: {e:#}"
))
})?;

let route_hint_hop = spawn_blocking({
let app_state = app_state.clone();
move || {
app_state
.node
.inner
.prepare_payment_with_route_hint(peer_id)
}
})
.await
.expect("task to complete")
.map_err(|e| AppError::InternalServerError(format!("Could not prepare payment: {e:#}")))?;

Ok(Json(route_hint_hop.into()))
}

pub async fn get_unused_address(State(app_state): State<Arc<AppState>>) -> impl IntoResponse {
app_state.node.inner.get_unused_address().to_string()
}
Expand Down
3 changes: 1 addition & 2 deletions crates/ln-dlc-node/src/ln/channel_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ pub struct ChannelConfig {

impl From<lightning::ln::channelmanager::ChannelDetails> for ChannelDetails {
fn from(cd: lightning::ln::channelmanager::ChannelDetails) -> Self {
let scid = cd.get_outbound_payment_scid();
ChannelDetails {
channel_id: cd.channel_id,
counterparty: cd.counterparty.node_id,
Expand Down Expand Up @@ -76,7 +75,7 @@ impl From<lightning::ln::channelmanager::ChannelDetails> for ChannelDetails {
max_dust_htlc_exposure_msat: c.max_dust_htlc_exposure_msat,
force_close_avoidance_max_fee_satoshis: c.force_close_avoidance_max_fee_satoshis,
}),
scid,
scid: cd.short_channel_id,
}
}
}
Expand Down
28 changes: 15 additions & 13 deletions crates/ln-dlc-node/src/node/invoice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,38 +181,40 @@ where
Ok(route_hint_hop)
}

pub fn prepare_payment_with_route_hint(&self, target_node: PublicKey) -> Result<RouteHintHop> {
pub fn prepare_payment_with_route_hint(&self, hop_node_id: PublicKey) -> Result<RouteHintHop> {
let channels = self.channel_manager.list_channels();
let channel = channels
.iter()
.find(|channel| channel.counterparty.node_id == target_node)
.with_context(|| format!("Couldn't find channel for {target_node}"))?;
.find(|channel| channel.counterparty.node_id == hop_node_id)
.with_context(|| format!("Couldn't find channel for {hop_node_id}"))?;

let short_channel_id = channel.get_outbound_payment_scid().with_context(|| {
let short_channel_id = channel.get_inbound_payment_scid().with_context(|| {
format!(
"Couldn't find short channel id for channel: {}, trader_id={target_node}",
"Couldn't find short channel id for channel: {}, hop_node_id={hop_node_id}",
channel.channel_id.to_hex()
)
})?;

let ldk_config = self.ldk_config.read();
let counterparty_forwarding_info = channel
.clone()
.counterparty
.forwarding_info
.context("Couldn't find forwarding info")?;

let route_hint_hop = RouteHintHop {
src_node_id: self.info.pubkey,
src_node_id: hop_node_id,
short_channel_id,
fees: RoutingFees {
base_msat: ldk_config.channel_config.forwarding_fee_base_msat,
proportional_millionths: ldk_config
.channel_config
.forwarding_fee_proportional_millionths,
base_msat: counterparty_forwarding_info.fee_base_msat,
proportional_millionths: counterparty_forwarding_info.fee_proportional_millionths,
},
cltv_expiry_delta: MIN_CLTV_EXPIRY_DELTA,
cltv_expiry_delta: counterparty_forwarding_info.cltv_expiry_delta,
htlc_minimum_msat: None,
htlc_maximum_msat: None,
};

tracing::info!(
peer_id = %target_node,
peer_id = %hop_node_id,
route_hint_hop = ?route_hint_hop,
"Created route hint for payment to private channel"
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ pub(crate) async fn send_payment(
let coordinator_balance_before = coordinator.get_ldk_balance();
let payee_balance_before = payee.get_ldk_balance();

let route_hint_hop = coordinator.prepare_payment_with_route_hint(payee.info.pubkey)?;
let route_hint_hop = payee.prepare_payment_with_route_hint(coordinator.info.pubkey)?;

let invoice = payee.create_invoice_with_route_hint(
Some(invoice_amount_sat),
Expand Down
2 changes: 1 addition & 1 deletion crates/ln-dlc-node/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ async fn wait_for_n_usable_channels(
.channel_manager
.list_usable_channels()
.iter()
.all(|c| c.get_outbound_payment_scid().is_some());
.all(|c| c.get_inbound_payment_scid().is_some());

Ok((usable_channels_length == channel_count && scids_set).then_some(()))
})
Expand Down
40 changes: 11 additions & 29 deletions mobile/native/src/ln_dlc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -970,36 +970,18 @@ pub fn create_onboarding_invoice(amount_sats: u64, liquidity_option_id: i32) ->
}

pub fn create_invoice(amount_sats: Option<u64>) -> Result<Invoice> {
let runtime = get_or_create_tokio_runtime()?;

runtime.block_on(async {
let node = NODE.get();
let client = reqwest_client();

let response = client
.post(format!(
"http://{}/api/prepare_regular_payment/{}",
config::get_http_endpoint(),
node.inner.info.pubkey
))
.send()
.await?;

if !response.status().is_success() {
let text = response.text().await?;
bail!("Failed to fetch route hint from coordinator for regular payment: {text}")
}

let final_route_hint_hop: RouteHintHop = response.json().await?;
let final_route_hint_hop = final_route_hint_hop.into();
let node = NODE.get();

node.inner.create_invoice_with_route_hint(
amount_sats,
None,
"".to_string(),
final_route_hint_hop,
)
})
let final_route_hint_hop = node
.inner
.prepare_payment_with_route_hint(config::get_coordinator_info().pubkey)?;

node.inner.create_invoice_with_route_hint(
amount_sats,
None,
"".to_string(),
final_route_hint_hop,
)
}

pub fn send_payment(payment: SendPayment) -> Result<()> {
Expand Down

0 comments on commit 7c77036

Please sign in to comment.