use std::fmt;
use std::sync::{Arc, Mutex};
use bitcoin::secp256k1::PublicKey;
use bitcoin::OutPoint;
use lightning::chain::chainmonitor;
use lightning::impl_writeable_tlv_based;
use lightning::ln::channel_state::ChannelDetails as LdkChannelDetails;
use lightning::ln::msgs::{RoutingMessageHandler, SocketAddress};
use lightning::ln::peer_handler::IgnoringMessageHandler;
use lightning::ln::types::ChannelId;
use lightning::routing::gossip;
use lightning::routing::router::DefaultRouter;
use lightning::routing::scoring::{CombinedScorer, ProbabilisticScoringFeeParameters};
use lightning::sign::InMemorySigner;
use lightning::util::persist::{KVStore, KVStoreSync, MonitorUpdatingPersister};
use lightning::util::ser::{Readable, Writeable, Writer};
use lightning::util::sweep::OutputSweeper;
use lightning_block_sync::gossip::{GossipVerifier, UtxoSource};
use lightning_liquidity::utils::time::DefaultTimeProvider;
use lightning_net_tokio::SocketDescriptor;
use crate::chain::ChainSource;
use crate::config::ChannelConfig;
use crate::data_store::DataStore;
use crate::fee_estimator::OnchainFeeEstimator;
use crate::gossip::RuntimeSpawner;
use crate::logger::Logger;
use crate::message_handler::NodeCustomMessageHandler;
use crate::payment::PaymentDetails;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WordCount {
Words12,
Words15,
Words18,
Words21,
Words24,
}
impl WordCount {
pub fn word_count(&self) -> usize {
match self {
WordCount::Words12 => 12,
WordCount::Words15 => 15,
WordCount::Words18 => 18,
WordCount::Words21 => 21,
WordCount::Words24 => 24,
}
}
}
pub trait SyncAndAsyncKVStore: KVStore + KVStoreSync {}
impl<T> SyncAndAsyncKVStore for T
where
T: KVStore,
T: KVStoreSync,
{
}
pub type DynStore = dyn SyncAndAsyncKVStore + Sync + Send;
pub type Persister = MonitorUpdatingPersister<
Arc<DynStore>,
Arc<Logger>,
Arc<KeysManager>,
Arc<KeysManager>,
Arc<Broadcaster>,
Arc<OnchainFeeEstimator>,
>;
pub(crate) type ChainMonitor = chainmonitor::ChainMonitor<
InMemorySigner,
Arc<ChainSource>,
Arc<Broadcaster>,
Arc<OnchainFeeEstimator>,
Arc<Logger>,
Arc<Persister>,
Arc<KeysManager>,
>;
pub(crate) type PeerManager = lightning::ln::peer_handler::PeerManager<
SocketDescriptor,
Arc<ChannelManager>,
Arc<dyn RoutingMessageHandler + Send + Sync>,
Arc<OnionMessenger>,
Arc<Logger>,
Arc<NodeCustomMessageHandler<Arc<Logger>>>,
Arc<KeysManager>,
Arc<ChainMonitor>,
>;
pub(crate) type LiquidityManager = lightning_liquidity::LiquidityManager<
Arc<KeysManager>,
Arc<KeysManager>,
Arc<ChannelManager>,
Arc<ChainSource>,
Arc<DynStore>,
DefaultTimeProvider,
Arc<Broadcaster>,
>;
pub(crate) type ChannelManager = lightning::ln::channelmanager::ChannelManager<
Arc<ChainMonitor>,
Arc<Broadcaster>,
Arc<KeysManager>,
Arc<KeysManager>,
Arc<KeysManager>,
Arc<OnchainFeeEstimator>,
Arc<Router>,
Arc<MessageRouter>,
Arc<Logger>,
>;
pub(crate) type Broadcaster = crate::tx_broadcaster::TransactionBroadcaster<Arc<Logger>>;
pub(crate) type Wallet = crate::wallet::Wallet;
pub(crate) type KeysManager = crate::wallet::WalletKeysManager;
pub(crate) type Router = DefaultRouter<
Arc<Graph>,
Arc<Logger>,
Arc<KeysManager>,
Arc<Mutex<Scorer>>,
ProbabilisticScoringFeeParameters,
Scorer,
>;
pub(crate) type Scorer = CombinedScorer<Arc<Graph>, Arc<Logger>>;
pub(crate) type Graph = gossip::NetworkGraph<Arc<Logger>>;
pub(crate) type UtxoLookup = GossipVerifier<RuntimeSpawner, Arc<dyn UtxoSource>, Arc<Logger>>;
pub(crate) type P2PGossipSync =
lightning::routing::gossip::P2PGossipSync<Arc<Graph>, Arc<UtxoLookup>, Arc<Logger>>;
pub(crate) type RapidGossipSync =
lightning_rapid_gossip_sync::RapidGossipSync<Arc<Graph>, Arc<Logger>>;
pub(crate) type GossipSync = lightning_background_processor::GossipSync<
Arc<P2PGossipSync>,
Arc<RapidGossipSync>,
Arc<Graph>,
Arc<UtxoLookup>,
Arc<Logger>,
>;
pub(crate) type OnionMessenger = lightning::onion_message::messenger::OnionMessenger<
Arc<KeysManager>,
Arc<KeysManager>,
Arc<Logger>,
Arc<ChannelManager>,
Arc<MessageRouter>,
Arc<ChannelManager>,
Arc<ChannelManager>,
IgnoringMessageHandler,
IgnoringMessageHandler,
>;
pub(crate) type MessageRouter = lightning::onion_message::messenger::DefaultMessageRouter<
Arc<Graph>,
Arc<Logger>,
Arc<KeysManager>,
>;
pub(crate) type Sweeper = OutputSweeper<
Arc<Broadcaster>,
Arc<KeysManager>,
Arc<OnchainFeeEstimator>,
Arc<ChainSource>,
Arc<DynStore>,
Arc<Logger>,
Arc<KeysManager>,
>;
pub(crate) type BumpTransactionEventHandler =
lightning::events::bump_transaction::BumpTransactionEventHandler<
Arc<Broadcaster>,
Arc<lightning::events::bump_transaction::Wallet<Arc<Wallet>, Arc<Logger>>>,
Arc<KeysManager>,
Arc<Logger>,
>;
pub(crate) type PaymentStore = DataStore<PaymentDetails, Arc<Logger>>;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct UserChannelId(pub u128);
impl Writeable for UserChannelId {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
Ok(self.0.write(writer)?)
}
}
impl Readable for UserChannelId {
fn read<R: lightning::io::Read>(
reader: &mut R,
) -> Result<Self, lightning::ln::msgs::DecodeError> {
Ok(Self(Readable::read(reader)?))
}
}
impl fmt::Display for UserChannelId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "UserChannelId({})", self.0)
}
}
#[derive(Debug, Clone)]
pub struct ChannelDetails {
pub channel_id: ChannelId,
pub counterparty_node_id: PublicKey,
pub funding_txo: Option<OutPoint>,
pub short_channel_id: Option<u64>,
pub outbound_scid_alias: Option<u64>,
pub inbound_scid_alias: Option<u64>,
pub channel_value_sats: u64,
pub unspendable_punishment_reserve: Option<u64>,
pub user_channel_id: UserChannelId,
pub feerate_sat_per_1000_weight: u32,
pub outbound_capacity_msat: u64,
pub inbound_capacity_msat: u64,
pub confirmations_required: Option<u32>,
pub confirmations: Option<u32>,
pub is_outbound: bool,
pub is_channel_ready: bool,
pub is_usable: bool,
pub is_announced: bool,
pub cltv_expiry_delta: Option<u16>,
pub counterparty_unspendable_punishment_reserve: u64,
pub counterparty_outbound_htlc_minimum_msat: Option<u64>,
pub counterparty_outbound_htlc_maximum_msat: Option<u64>,
pub counterparty_forwarding_info_fee_base_msat: Option<u32>,
pub counterparty_forwarding_info_fee_proportional_millionths: Option<u32>,
pub counterparty_forwarding_info_cltv_expiry_delta: Option<u16>,
pub next_outbound_htlc_limit_msat: u64,
pub next_outbound_htlc_minimum_msat: u64,
pub force_close_spend_delay: Option<u16>,
pub inbound_htlc_minimum_msat: u64,
pub inbound_htlc_maximum_msat: Option<u64>,
pub config: ChannelConfig,
}
impl From<LdkChannelDetails> for ChannelDetails {
fn from(value: LdkChannelDetails) -> Self {
ChannelDetails {
channel_id: value.channel_id,
counterparty_node_id: value.counterparty.node_id,
funding_txo: value.funding_txo.map(|o| o.into_bitcoin_outpoint()),
short_channel_id: value.short_channel_id,
outbound_scid_alias: value.outbound_scid_alias,
inbound_scid_alias: value.inbound_scid_alias,
channel_value_sats: value.channel_value_satoshis,
unspendable_punishment_reserve: value.unspendable_punishment_reserve,
user_channel_id: UserChannelId(value.user_channel_id),
feerate_sat_per_1000_weight: value.feerate_sat_per_1000_weight.unwrap(),
outbound_capacity_msat: value.outbound_capacity_msat,
inbound_capacity_msat: value.inbound_capacity_msat,
confirmations_required: value.confirmations_required,
confirmations: value.confirmations,
is_outbound: value.is_outbound,
is_channel_ready: value.is_channel_ready,
is_usable: value.is_usable,
is_announced: value.is_announced,
cltv_expiry_delta: value.config.map(|c| c.cltv_expiry_delta),
counterparty_unspendable_punishment_reserve: value
.counterparty
.unspendable_punishment_reserve,
counterparty_outbound_htlc_minimum_msat: value.counterparty.outbound_htlc_minimum_msat,
counterparty_outbound_htlc_maximum_msat: value.counterparty.outbound_htlc_maximum_msat,
counterparty_forwarding_info_fee_base_msat: value
.counterparty
.forwarding_info
.as_ref()
.map(|f| f.fee_base_msat),
counterparty_forwarding_info_fee_proportional_millionths: value
.counterparty
.forwarding_info
.as_ref()
.map(|f| f.fee_proportional_millionths),
counterparty_forwarding_info_cltv_expiry_delta: value
.counterparty
.forwarding_info
.as_ref()
.map(|f| f.cltv_expiry_delta),
next_outbound_htlc_limit_msat: value.next_outbound_htlc_limit_msat,
next_outbound_htlc_minimum_msat: value.next_outbound_htlc_minimum_msat,
force_close_spend_delay: value.force_close_spend_delay,
inbound_htlc_minimum_msat: value.inbound_htlc_minimum_msat.unwrap_or(0),
inbound_htlc_maximum_msat: value.inbound_htlc_maximum_msat,
config: value.config.map(|c| c.into()).unwrap(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PeerDetails {
pub node_id: PublicKey,
pub address: SocketAddress,
pub is_persisted: bool,
pub is_connected: bool,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CustomTlvRecord {
pub type_num: u64,
pub value: Vec<u8>,
}
impl_writeable_tlv_based!(CustomTlvRecord, {
(0, type_num, required),
(2, value, required),
});
impl From<&(u64, Vec<u8>)> for CustomTlvRecord {
fn from(tlv: &(u64, Vec<u8>)) -> Self {
CustomTlvRecord { type_num: tlv.0, value: tlv.1.clone() }
}
}