ln_gateway/gateway_module_v2/
events.rsuse std::time::SystemTime;
use fedimint_core::config::FederationId;
use fedimint_core::core::ModuleKind;
use fedimint_core::Amount;
use fedimint_eventlog::{Event, EventKind, PersistedLogEntry};
use fedimint_lnv2_common::contracts::{Commitment, OutgoingContract, PaymentImage};
use serde::{Deserialize, Serialize};
use serde_millis;
use super::send_sm::Cancelled;
use crate::events::{filter_events, join_events, StructuredPaymentEvents};
#[derive(Serialize, Deserialize, Debug)]
pub struct OutgoingPaymentStarted {
#[serde(with = "serde_millis")]
pub operation_start: SystemTime,
pub outgoing_contract: OutgoingContract,
pub min_contract_amount: Amount,
pub invoice_amount: Amount,
pub max_delay: u64,
}
impl Event for OutgoingPaymentStarted {
const MODULE: Option<ModuleKind> = Some(fedimint_lnv2_common::KIND);
const KIND: EventKind = EventKind::from_static("outgoing-payment-started");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct OutgoingPaymentSucceeded {
pub payment_image: PaymentImage,
pub target_federation: Option<FederationId>,
}
impl Event for OutgoingPaymentSucceeded {
const MODULE: Option<ModuleKind> = Some(fedimint_lnv2_common::KIND);
const KIND: EventKind = EventKind::from_static("outgoing-payment-succeeded");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct OutgoingPaymentFailed {
pub payment_image: PaymentImage,
pub error: Cancelled,
}
impl Event for OutgoingPaymentFailed {
const MODULE: Option<ModuleKind> = Some(fedimint_lnv2_common::KIND);
const KIND: EventKind = EventKind::from_static("outgoing-payment-failed");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct IncomingPaymentStarted {
#[serde(with = "serde_millis")]
pub operation_start: SystemTime,
pub incoming_contract_commitment: Commitment,
pub invoice_amount: Amount,
}
impl Event for IncomingPaymentStarted {
const MODULE: Option<ModuleKind> = Some(fedimint_lnv2_common::KIND);
const KIND: EventKind = EventKind::from_static("incoming-payment-started");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct IncomingPaymentSucceeded {
pub payment_image: PaymentImage,
}
impl Event for IncomingPaymentSucceeded {
const MODULE: Option<ModuleKind> = Some(fedimint_lnv2_common::KIND);
const KIND: EventKind = EventKind::from_static("incoming-payment-succeeded");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct IncomingPaymentFailed {
pub payment_image: PaymentImage,
pub error: String,
}
impl Event for IncomingPaymentFailed {
const MODULE: Option<ModuleKind> = Some(fedimint_lnv2_common::KIND);
const KIND: EventKind = EventKind::from_static("incoming-payment-failed");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CompleteLightningPaymentSucceeded {
pub payment_image: PaymentImage,
}
impl Event for CompleteLightningPaymentSucceeded {
const MODULE: Option<ModuleKind> = Some(fedimint_lnv2_common::KIND);
const KIND: EventKind = EventKind::from_static("complete-lightning-payment-succeeded");
}
pub fn compute_lnv2_stats(
all_events: &[PersistedLogEntry],
) -> (StructuredPaymentEvents, StructuredPaymentEvents) {
let outgoing_start_events = filter_events(
all_events,
OutgoingPaymentStarted::KIND,
fedimint_lnv2_common::KIND,
)
.collect::<Vec<_>>();
let outgoing_success_events = filter_events(
all_events,
OutgoingPaymentSucceeded::KIND,
fedimint_lnv2_common::KIND,
)
.collect::<Vec<_>>();
let outgoing_failure_events = filter_events(
all_events,
OutgoingPaymentFailed::KIND,
fedimint_lnv2_common::KIND,
)
.collect::<Vec<_>>();
let outgoing_success_stats =
join_events::<OutgoingPaymentStarted, OutgoingPaymentSucceeded, (u64, Amount)>(
&outgoing_start_events,
&outgoing_success_events,
|start_event, success_event, latency| {
if start_event.outgoing_contract.payment_image == success_event.payment_image {
start_event
.min_contract_amount
.checked_sub(start_event.invoice_amount)
.map(|fee| (latency, fee))
} else {
None
}
},
)
.collect::<Vec<_>>();
let outgoing_failure_stats = join_events::<OutgoingPaymentStarted, OutgoingPaymentFailed, u64>(
&outgoing_start_events,
&outgoing_failure_events,
|start_event, fail_event, latency| {
if start_event.outgoing_contract.payment_image == fail_event.payment_image {
Some(latency)
} else {
None
}
},
)
.collect::<Vec<_>>();
let incoming_start_events = filter_events(
all_events,
IncomingPaymentStarted::KIND,
fedimint_lnv2_common::KIND,
)
.collect::<Vec<_>>();
let incoming_success_events = filter_events(
all_events,
IncomingPaymentSucceeded::KIND,
fedimint_lnv2_common::KIND,
)
.collect::<Vec<_>>();
let incoming_failure_events = filter_events(
all_events,
IncomingPaymentFailed::KIND,
fedimint_lnv2_common::KIND,
)
.collect::<Vec<_>>();
let incoming_success_stats =
join_events::<IncomingPaymentStarted, IncomingPaymentSucceeded, (u64, Amount)>(
&incoming_start_events,
&incoming_success_events,
|start_event, success_event, latency| {
if start_event.incoming_contract_commitment.payment_image
== success_event.payment_image
{
start_event
.invoice_amount
.checked_sub(start_event.incoming_contract_commitment.amount)
.map(|fee| (latency, fee))
} else {
None
}
},
)
.collect::<Vec<_>>();
let incoming_failure_stats = join_events::<IncomingPaymentStarted, IncomingPaymentFailed, u64>(
&incoming_start_events,
&incoming_failure_events,
|start_event, fail_event, latency| {
if start_event.incoming_contract_commitment.payment_image == fail_event.payment_image {
Some(latency)
} else {
None
}
},
)
.collect::<Vec<_>>();
let outgoing = StructuredPaymentEvents::new(&outgoing_success_stats, outgoing_failure_stats);
let incoming = StructuredPaymentEvents::new(&incoming_success_stats, incoming_failure_stats);
(outgoing, incoming)
}