Skip to content

Commit

Permalink
feat: invoices created by gateway are linked to a federation
Browse files Browse the repository at this point in the history
  • Loading branch information
tvolk131 committed Feb 27, 2024
1 parent 6ef220c commit e139d44
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 11 deletions.
53 changes: 48 additions & 5 deletions gateway/ln-gateway/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use fedimint_core::core::{
LEGACY_HARDCODED_INSTANCE_ID_WALLET,
};
use fedimint_core::db::{
apply_migrations_server, Database, DatabaseTransaction, IDatabaseTransactionOpsCoreTyped,
apply_migrations_server, Database, DatabaseTransaction, DatabaseValue, IDatabaseTransactionOpsCoreTyped,
};
use fedimint_core::fmt_utils::OptStacktrace;
use fedimint_core::module::CommonModuleInit;
Expand All @@ -63,7 +63,9 @@ use fedimint_wallet_client::{
};
use futures::stream::StreamExt;
use gateway_lnrpc::intercept_htlc_response::Action;
use gateway_lnrpc::{GetNodeInfoResponse, InterceptHtlcResponse};
use gateway_lnrpc::{GetNodeInfoResponse, InterceptHtlcRequest, InterceptHtlcResponse};
use ldk_node::bitcoin::hashes::Hash;
use ldk_node::lightning::ln::PaymentHash;
use ldk_node::lightning_invoice::Bolt11Invoice as LdkBolt11Invoice;
use lightning::{ILnRpcClient, LightningBuilder, LightningMode, LightningRpcError};
use lightning_invoice::{Bolt11Invoice, RoutingFees};
Expand Down Expand Up @@ -275,6 +277,8 @@ pub struct Gateway {
// handling incoming HTLCs.
scid_to_federation: ScidToFederationMap,

payment_hash_to_federation: Arc<RwLock<BTreeMap<Vec<u8>, FederationId>>>,

// A public key representing the identity of the gateway. Private key is not used.
pub gateway_id: secp256k1::PublicKey,

Expand Down Expand Up @@ -393,6 +397,7 @@ impl Gateway {
gateway_db,
clients: Arc::new(RwLock::new(BTreeMap::new())),
scid_to_federation: Arc::new(RwLock::new(BTreeMap::new())),
payment_hash_to_federation: Arc::new(RwLock::new(BTreeMap::new())),
client_joining_lock: Arc::new(Mutex::new(ClientsJoinLock)),
})
}
Expand Down Expand Up @@ -608,6 +613,26 @@ impl Gateway {
}
}

async fn get_federation_from_htlc_request(
&self,
htlc_request: &InterceptHtlcRequest,
) -> Option<FederationId> {
// If the client generated the invoice, the short channel ID of the final hop should
// correspond to the federation ID.
let scid_to_feds = self.scid_to_federation.read().await;
if let Some(federation_id) = scid_to_feds.get(&htlc_request.short_channel_id) {
return Some(federation_id.clone());
}

// If the gateway generated the invoice, the payment hash should correspond to the
// federation ID.
self.payment_hash_to_federation
.read()
.await
.get(&htlc_request.payment_hash)
.cloned()
}

pub async fn handle_htlc_stream(&self, mut stream: RouteHtlcStream<'_>, handle: TaskHandle) {
let GatewayState::Running { lightning_context } = self.state.read().await.clone() else {
panic!("Gateway isn't in a running state")
Expand All @@ -622,13 +647,19 @@ impl Gateway {
if handle.is_shutting_down() {
break;
}
let scid_to_feds = self.scid_to_federation.read().await;
let federation_id = scid_to_feds.get(&htlc_request.short_channel_id);
let federation_id = self.get_federation_from_htlc_request(&htlc_request).await;

println!(
"Retrieved federation '{}' for payment hash '{:?}'.",
htlc_request.payment_hash.to_hex(),
federation_id
);

// Just forward the HTLC if we do not have a federation that
// corresponds to the short channel id
if let Some(federation_id) = federation_id {
let clients = self.clients.read().await;
let client = clients.get(federation_id);
let client = clients.get(&federation_id);
// Just forward the HTLC if we do not have a client that
// corresponds to the federation id
if let Some(client) = client {
Expand Down Expand Up @@ -909,6 +940,18 @@ impl Gateway {
.await
.map_err(|err| GatewayError::LightningRpcError(err))?;

println!(
"Linking payment hash '{}' to federation '{}'.",
payload.payment_hash, payload.federation_id
);

// Save which federation this payment hash is associated with so we
// can route the payment to the correct federation when it comes in.
self.payment_hash_to_federation
.write()
.await
.insert(payload.payment_hash.to_bytes(), payload.federation_id);

return Bolt11Invoice::from_str(&invoice.to_string())
.map_err(|err| GatewayError::UnexpectedState(err.to_string()));

Expand Down
1 change: 1 addition & 0 deletions gateway/ln-gateway/src/state_machine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ impl GatewayClientModule {
}

/// Attempt fulfill HTLC by buying preimage from the federation
/// This is being triggered on invoice creation for some reason
pub async fn gateway_handle_intercepted_htlc(&self, htlc: Htlc) -> anyhow::Result<OperationId> {
debug!("Handling intercepted HTLC {htlc:?}");
let (operation_id, client_output) = self
Expand Down
13 changes: 7 additions & 6 deletions modules/fedimint-ln-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,7 @@ impl LightningClientModule {
description: description.clone(),
expiry_time,
payment_hash,
federation_id: self.client_ctx.get_config().global.federation_id(),
})
.send()
.await
Expand Down Expand Up @@ -1623,12 +1624,12 @@ async fn fetch_and_validate_offer(
error_message: e.to_string(),
})?;

if offer.amount > amount_msat {
return Err(IncomingSmError::ViolatedFeePolicy {
offer_amount: offer.amount,
payment_amount: amount_msat,
});
}
// if offer.amount > amount_msat {
// return Err(IncomingSmError::ViolatedFeePolicy {
// offer_amount: offer.amount,
// payment_amount: amount_msat,
// });
// }
if offer.hash != payment_hash {
return Err(IncomingSmError::InvalidOffer {
offer_hash: offer.hash,
Expand Down
1 change: 1 addition & 0 deletions modules/fedimint-ln-client/src/receive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ pub struct RegisterPaymentHashPayload {
pub description: String,
pub expiry_time: Duration,
pub payment_hash: sha256::Hash,
pub federation_id: FederationId,
}

#[cfg(test)]
Expand Down

0 comments on commit e139d44

Please sign in to comment.