ln_gateway/state_machine/
events.rsuse fedimint_core::core::{ModuleKind, OperationId};
use fedimint_core::Amount;
use fedimint_eventlog::{Event, EventKind, PersistedLogEntry};
use fedimint_ln_common::contracts::outgoing::OutgoingContractAccount;
use fedimint_ln_common::contracts::ContractId;
use serde::{Deserialize, Serialize};
use super::pay::OutgoingPaymentError;
use crate::events::{filter_events, join_events, StructuredPaymentEvents};
#[derive(Serialize, Deserialize, Debug)]
pub struct OutgoingPaymentStarted {
pub contract_id: ContractId,
pub invoice_amount: Amount,
pub operation_id: OperationId,
}
impl Event for OutgoingPaymentStarted {
const MODULE: Option<ModuleKind> = Some(fedimint_ln_common::KIND);
const KIND: EventKind = EventKind::from_static("outgoing-payment-started");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct OutgoingPaymentSucceeded {
pub outgoing_contract: OutgoingContractAccount,
pub contract_id: ContractId,
pub preimage: String,
}
impl Event for OutgoingPaymentSucceeded {
const MODULE: Option<ModuleKind> = Some(fedimint_ln_common::KIND);
const KIND: EventKind = EventKind::from_static("outgoing-payment-succeeded");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct OutgoingPaymentFailed {
pub outgoing_contract: OutgoingContractAccount,
pub contract_id: ContractId,
pub error: OutgoingPaymentError,
}
impl Event for OutgoingPaymentFailed {
const MODULE: Option<ModuleKind> = Some(fedimint_ln_common::KIND);
const KIND: EventKind = EventKind::from_static("outgoing-payment-failed");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct IncomingPaymentStarted {
pub contract_id: ContractId,
pub payment_hash: bitcoin::hashes::sha256::Hash,
pub invoice_amount: Amount,
pub contract_amount: Amount,
pub operation_id: OperationId,
}
impl Event for IncomingPaymentStarted {
const MODULE: Option<ModuleKind> = Some(fedimint_ln_common::KIND);
const KIND: EventKind = EventKind::from_static("incoming-payment-started");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct IncomingPaymentSucceeded {
pub payment_hash: bitcoin::hashes::sha256::Hash,
pub preimage: String,
}
impl Event for IncomingPaymentSucceeded {
const MODULE: Option<ModuleKind> = Some(fedimint_ln_common::KIND);
const KIND: EventKind = EventKind::from_static("incoming-payment-succeeded");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct IncomingPaymentFailed {
pub payment_hash: bitcoin::hashes::sha256::Hash,
pub error: String,
}
impl Event for IncomingPaymentFailed {
const MODULE: Option<ModuleKind> = Some(fedimint_ln_common::KIND);
const KIND: EventKind = EventKind::from_static("incoming-payment-failed");
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CompleteLightningPaymentSucceeded {
pub payment_hash: bitcoin::hashes::sha256::Hash,
}
impl Event for CompleteLightningPaymentSucceeded {
const MODULE: Option<ModuleKind> = Some(fedimint_ln_common::KIND);
const KIND: EventKind = EventKind::from_static("complete-lightning-payment-succeeded");
}
pub fn compute_lnv1_stats(
all_events: &[PersistedLogEntry],
) -> (StructuredPaymentEvents, StructuredPaymentEvents) {
let outgoing_start_events = filter_events(
all_events,
OutgoingPaymentStarted::KIND,
fedimint_ln_common::KIND,
)
.collect::<Vec<_>>();
let outgoing_success_events = filter_events(
all_events,
OutgoingPaymentSucceeded::KIND,
fedimint_ln_common::KIND,
)
.collect::<Vec<_>>();
let outgoing_failure_events = filter_events(
all_events,
OutgoingPaymentFailed::KIND,
fedimint_ln_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.contract_id == success_event.contract_id {
success_event
.outgoing_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.contract_id == fail_event.contract_id {
Some(latency)
} else {
None
}
},
)
.collect::<Vec<_>>();
let incoming_start_events = filter_events(
all_events,
IncomingPaymentStarted::KIND,
fedimint_ln_common::KIND,
)
.collect::<Vec<_>>();
let incoming_success_events = filter_events(
all_events,
IncomingPaymentSucceeded::KIND,
fedimint_ln_common::KIND,
)
.collect::<Vec<_>>();
let incoming_failure_events = filter_events(
all_events,
IncomingPaymentFailed::KIND,
fedimint_ln_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.payment_hash == success_event.payment_hash {
start_event
.contract_amount
.checked_sub(start_event.invoice_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.payment_hash == fail_event.payment_hash {
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)
}