Skip to content

Commit

Permalink
try to get m2m w/ jeff
Browse files Browse the repository at this point in the history
  • Loading branch information
benthecarman committed Oct 30, 2023
1 parent 7884455 commit e4408b5
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 36 deletions.
19 changes: 11 additions & 8 deletions mutiny-core/src/ldkstorage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use crate::gossip::PROB_SCORER_KEY;
use crate::keymanager::PhantomKeysManager;
use crate::logging::MutinyLogger;
use crate::multiesplora::MultiEsploraClient;
use crate::node::NetworkGraph;
use crate::node::{default_user_config, ChainMonitor};
use crate::node::{NetworkGraph, Router};
use crate::nodemanager::ChannelClosure;
use crate::router::MutinyRouter;
use crate::storage::{MutinyStorage, VersionedValue};
use crate::utils;
use crate::utils::{sleep, spawn};
Expand Down Expand Up @@ -53,7 +54,7 @@ pub(crate) type PhantomChannelManager<S: MutinyStorage> = LdkChannelManager<
Arc<PhantomKeysManager<S>>,
Arc<PhantomKeysManager<S>>,
Arc<MutinyFeeEstimator<S>>,
Arc<Router>,
Arc<MutinyRouter>,
Arc<MutinyLogger>,
>;

Expand Down Expand Up @@ -202,7 +203,7 @@ impl<S: MutinyStorage> MutinyNodePersister<S> {
fee_estimator: Arc<MutinyFeeEstimator<S>>,
mutiny_logger: Arc<MutinyLogger>,
keys_manager: Arc<PhantomKeysManager<S>>,
router: Arc<Router>,
router: Arc<MutinyRouter>,
channel_monitors: Vec<(BlockHash, ChannelMonitor<InMemorySigner>)>,
esplora: &MultiEsploraClient,
) -> Result<ReadChannelManager<S>, MutinyError> {
Expand Down Expand Up @@ -270,7 +271,7 @@ impl<S: MutinyStorage> MutinyNodePersister<S> {
fee_estimator: Arc<MutinyFeeEstimator<S>>,
mutiny_logger: Arc<MutinyLogger>,
keys_manager: Arc<PhantomKeysManager<S>>,
router: Arc<Router>,
router: Arc<MutinyRouter>,
mut channel_monitors: Vec<(BlockHash, ChannelMonitor<InMemorySigner>)>,
) -> Result<ReadChannelManager<S>, MutinyError> {
let mut channel_monitor_mut_references = Vec::new();
Expand Down Expand Up @@ -312,7 +313,7 @@ impl<S: MutinyStorage> MutinyNodePersister<S> {
fee_estimator: Arc<MutinyFeeEstimator<S>>,
mutiny_logger: Arc<MutinyLogger>,
keys_manager: Arc<PhantomKeysManager<S>>,
router: Arc<Router>,
router: Arc<MutinyRouter>,
channel_monitors: Vec<(BlockHash, ChannelMonitor<InMemorySigner>)>,
esplora: &MultiEsploraClient,
) -> Result<ReadChannelManager<S>, MutinyError> {
Expand Down Expand Up @@ -375,7 +376,7 @@ impl<S: MutinyStorage> MutinyNodePersister<S> {
logger: &MutinyLogger,
) -> Option<PaymentInfo> {
let key = self.get_key(payment_key(inbound, payment_hash).as_str());
log_trace!(logger, "Trace: checking payment key: {key}");
// log_trace!(logger, "Trace: checking payment key: {key}");
let deserialized_value: Result<Option<PaymentInfo>, MutinyError> =
self.storage.get_data(key);
deserialized_value.ok().flatten()
Expand Down Expand Up @@ -619,7 +620,7 @@ impl<S: MutinyStorage>
Arc<PhantomKeysManager<S>>,
Arc<PhantomKeysManager<S>>,
Arc<MutinyFeeEstimator<S>>,
Arc<Router>,
Arc<MutinyRouter>,
Arc<MutinyLogger>,
utils::Mutex<HubPreferentialScorer>,
> for MutinyNodePersister<S>
Expand Down Expand Up @@ -744,6 +745,7 @@ pub(crate) async fn persist_monitor(
#[cfg(test)]
mod test {
use crate::onchain::OnChainWallet;
use crate::router::MutinyRouter;
use crate::storage::MemoryStorage;
use crate::{esplora::EsploraSyncClient, node::scoring_params};
use crate::{
Expand Down Expand Up @@ -967,8 +969,9 @@ mod test {
persister.clone(),
));

let router: Arc<Router> = Arc::new(DefaultRouter::new(
let router: Arc<MutinyRouter> = Arc::new(MutinyRouter::new(
network_graph,
None,
logger.clone(),
km.clone().get_secure_random_bytes(),
Arc::new(utils::Mutex::new(scorer)),
Expand Down
1 change: 1 addition & 0 deletions mutiny-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub mod storage;
mod subscription;
pub mod vss;

mod router;
#[cfg(any(test, feature = "test-utils"))]
pub mod test_utils;
pub mod utils;
Expand Down
51 changes: 23 additions & 28 deletions mutiny-core/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use lightning::{

use crate::multiesplora::MultiEsploraClient;
use crate::peermanager::LspMessageRouter;
use crate::router::MutinyRouter;
use crate::utils::get_monitor_version;
use bitcoin::util::bip32::ExtendedPrivKey;
use futures_util::lock::Mutex;
Expand All @@ -59,7 +60,7 @@ use lightning::{
routing::{
gossip,
gossip::NodeId,
router::{DefaultRouter, PaymentParameters, RouteParameters},
router::{PaymentParameters, RouteParameters},
},
util::{
config::{ChannelHandshakeConfig, ChannelHandshakeLimits, UserConfig},
Expand Down Expand Up @@ -122,14 +123,6 @@ pub(crate) type ChainMonitor<S: MutinyStorage> = chainmonitor::ChainMonitor<
Arc<MutinyNodePersister<S>>,
>;

pub(crate) type Router = DefaultRouter<
Arc<NetworkGraph>,
Arc<MutinyLogger>,
Arc<utils::Mutex<HubPreferentialScorer>>,
ProbabilisticScoringFeeParameters,
HubPreferentialScorer,
>;

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ConnectionType {
Tcp(String),
Expand Down Expand Up @@ -251,8 +244,27 @@ impl<S: MutinyStorage> Node<S> {

let network_graph = gossip_sync.network_graph().clone();

let router: Arc<Router> = Arc::new(DefaultRouter::new(
log_info!(logger, "creating lsp client");
let lsp_client: Option<LspClient> = match node_index.lsp {
None => {
if lsp_clients.is_empty() {
log_info!(logger, "no lsp saved and no lsp clients available");
None
} else {
log_info!(logger, "no lsp saved, picking random one");
// If we don't have an lsp saved we should pick a random
// one from our client list and save it for next time
let rand = rand::random::<usize>() % lsp_clients.len();
Some(lsp_clients[rand].clone())
}
}
Some(ref lsp) => lsp_clients.iter().find(|c| &c.url == lsp).cloned(),
};
let lsp_pubkey = lsp_client.as_ref().map(|l| l.pubkey);

let router: Arc<MutinyRouter> = Arc::new(MutinyRouter::new(
network_graph,
lsp_pubkey,
logger.clone(),
keys_manager.clone().get_secure_random_bytes(),
scorer.clone(),
Expand Down Expand Up @@ -328,24 +340,7 @@ impl<S: MutinyStorage> Node<S> {
logger: logger.clone(),
});

log_info!(logger, "creating lsp client");
let lsp_client: Option<LspClient> = match node_index.lsp {
None => {
if lsp_clients.is_empty() {
log_info!(logger, "no lsp saved and no lsp clients available");
None
} else {
log_info!(logger, "no lsp saved, picking random one");
// If we don't have an lsp saved we should pick a random
// one from our client list and save it for next time
let rand = rand::random::<usize>() % lsp_clients.len();
Some(lsp_clients[rand].clone())
}
}
Some(ref lsp) => lsp_clients.iter().find(|c| &c.url == lsp).cloned(),
};

let message_router = Arc::new(LspMessageRouter::new(lsp_client.as_ref().map(|l| l.pubkey)));
let message_router = Arc::new(LspMessageRouter::new(lsp_pubkey));
let onion_message_handler = Arc::new(OnionMessenger::new(
keys_manager.clone(),
keys_manager.clone(),
Expand Down
2 changes: 2 additions & 0 deletions mutiny-core/src/nodemanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ pub struct MutinyChannel {
pub peer: PublicKey,
pub confirmations_required: Option<u32>,
pub confirmations: u32,
pub scid: Option<u64>,
}

impl From<&ChannelDetails> for MutinyChannel {
Expand All @@ -339,6 +340,7 @@ impl From<&ChannelDetails> for MutinyChannel {
peer: c.counterparty.node_id,
confirmations_required: c.confirmations_required,
confirmations: c.confirmations.unwrap_or(0),
scid: c.inbound_scid_alias,
}
}
}
Expand Down
162 changes: 162 additions & 0 deletions mutiny-core/src/router.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
use crate::logging::MutinyLogger;
use crate::node::NetworkGraph;
use crate::scorer::HubPreferentialScorer;
use crate::utils::Mutex;
use bitcoin::secp256k1::PublicKey;
use lightning::ln::channelmanager::ChannelDetails;
use lightning::ln::features::ChannelFeatures;
use lightning::ln::msgs::LightningError;
use lightning::routing::gossip::NodeId;
use lightning::routing::router::{
BlindedTail, DefaultRouter, InFlightHtlcs, Path, Payee, Route, RouteHop, RouteParameters,
Router,
};
use lightning::routing::scoring::ProbabilisticScoringFeeParameters;
use lightning::util::ser::Writeable;
use log::{info, warn};
use std::sync::Arc;

type LdkRouter = DefaultRouter<
Arc<NetworkGraph>,
Arc<MutinyLogger>,
Arc<Mutex<HubPreferentialScorer>>,
ProbabilisticScoringFeeParameters,
HubPreferentialScorer,
>;

pub struct MutinyRouter {
network_graph: Arc<NetworkGraph>,
lsp_key: Option<PublicKey>,
router: LdkRouter,
}

impl MutinyRouter {
pub fn new(
network_graph: Arc<NetworkGraph>,
lsp_key: Option<PublicKey>,
logger: Arc<MutinyLogger>,
random_seed_bytes: [u8; 32],
scorer: Arc<Mutex<HubPreferentialScorer>>,
score_params: ProbabilisticScoringFeeParameters,
) -> Self {
let router = DefaultRouter::new(
network_graph.clone(),
logger,
random_seed_bytes,
scorer,
score_params,
);

Self {
network_graph,
lsp_key,
router,
}
}
}

impl Router for MutinyRouter {
fn find_route(
&self,
payer: &PublicKey,
route_params: &RouteParameters,
first_hops: Option<&[&ChannelDetails]>,
inflight_htlcs: InFlightHtlcs,
) -> Result<Route, LightningError> {
match &route_params.payment_params.payee {
Payee::Clear { .. } => {
self.router
.find_route(payer, route_params, first_hops, inflight_htlcs)
}
Payee::Blinded {
route_hints,
features: _,
} => {
// if we have no LSP, then handle normally
if self.lsp_key.is_none() {
return self
.router
.find_route(payer, route_params, first_hops, inflight_htlcs);
}

let (blinded_info, blinded_path) = route_hints.first().unwrap();
let graph_lock = self.network_graph.read_only();
let lsp_node_id = NodeId::from_pubkey(&self.lsp_key.unwrap());
let node_info = graph_lock.node(&lsp_node_id).unwrap();

let amt = route_params.final_value_msat;

// first our channel with enough capacity
let first_hops = first_hops.unwrap_or(&[]);
let first = first_hops
.iter()
.find_map(|c| {
if c.outbound_capacity_msat >= amt {
Some(c)
} else {
None
}
})
.unwrap();

let channel_features =
ChannelFeatures::from_be_bytes(first.counterparty.features.encode());

let scid = scid_from_parts(467591, 1, 0);
warn!("scid: {}", scid);

let cltv_expiry_delta = first.config.unwrap().cltv_expiry_delta;
let hops = vec![
RouteHop {
pubkey: self.lsp_key.unwrap(),
node_features: node_info
.announcement_info
.as_ref()
.unwrap()
.features
.clone(),
short_channel_id: first.get_outbound_payment_scid().unwrap(),
channel_features: channel_features.clone(),
fee_msat: 0, // 0 for own channel
cltv_expiry_delta: 0, // 0 for own channel
maybe_announced_channel: false,
},
RouteHop {
pubkey: blinded_path.introduction_node_id,
node_features: node_info
.announcement_info
.as_ref()
.unwrap()
.features
.clone(),
short_channel_id: 17112782831943311000, // fixme
channel_features,
fee_msat: 10_000, // put high value just to try
cltv_expiry_delta: cltv_expiry_delta as u32,
maybe_announced_channel: false,
},
];

let blinded_tail = Some(BlindedTail {
hops: blinded_path.blinded_hops.clone(),
blinding_point: blinded_path.blinding_point,
excess_final_cltv_expiry_delta: blinded_info.cltv_expiry_delta as u32,
final_value_msat: amt,
});

let path = Path { hops, blinded_tail };

Ok(Route {
paths: vec![path],
route_params: Some(route_params.clone()),
})
}
}
}
}

/// Constructs a `short_channel_id` using the components pieces. Results in an error
/// if the block height, tx index, or vout index overflow the maximum sizes.
pub fn scid_from_parts(block: u64, tx_index: u64, vout_index: u64) -> u64 {
(block << 40) | (tx_index << 16) | vout_index
}
2 changes: 2 additions & 0 deletions mutiny-wasm/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ pub struct MutinyChannel {
peer: String,
pub confirmations_required: Option<u32>,
pub confirmations: u32,
pub scid: Option<u64>,
}

#[wasm_bindgen]
Expand Down Expand Up @@ -299,6 +300,7 @@ impl From<nodemanager::MutinyChannel> for MutinyChannel {
peer: m.peer.to_hex(),
confirmations_required: m.confirmations_required,
confirmations: m.confirmations,
scid: m.scid,
}
}
}
Expand Down

0 comments on commit e4408b5

Please sign in to comment.