Skip to content
This repository was archived by the owner on Feb 3, 2025. It is now read-only.

Commit e4408b5

Browse files
committed
try to get m2m w/ jeff
1 parent 7884455 commit e4408b5

File tree

6 files changed

+201
-36
lines changed

6 files changed

+201
-36
lines changed

mutiny-core/src/ldkstorage.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ use crate::gossip::PROB_SCORER_KEY;
55
use crate::keymanager::PhantomKeysManager;
66
use crate::logging::MutinyLogger;
77
use crate::multiesplora::MultiEsploraClient;
8+
use crate::node::NetworkGraph;
89
use crate::node::{default_user_config, ChainMonitor};
9-
use crate::node::{NetworkGraph, Router};
1010
use crate::nodemanager::ChannelClosure;
11+
use crate::router::MutinyRouter;
1112
use crate::storage::{MutinyStorage, VersionedValue};
1213
use crate::utils;
1314
use crate::utils::{sleep, spawn};
@@ -53,7 +54,7 @@ pub(crate) type PhantomChannelManager<S: MutinyStorage> = LdkChannelManager<
5354
Arc<PhantomKeysManager<S>>,
5455
Arc<PhantomKeysManager<S>>,
5556
Arc<MutinyFeeEstimator<S>>,
56-
Arc<Router>,
57+
Arc<MutinyRouter>,
5758
Arc<MutinyLogger>,
5859
>;
5960

@@ -202,7 +203,7 @@ impl<S: MutinyStorage> MutinyNodePersister<S> {
202203
fee_estimator: Arc<MutinyFeeEstimator<S>>,
203204
mutiny_logger: Arc<MutinyLogger>,
204205
keys_manager: Arc<PhantomKeysManager<S>>,
205-
router: Arc<Router>,
206+
router: Arc<MutinyRouter>,
206207
channel_monitors: Vec<(BlockHash, ChannelMonitor<InMemorySigner>)>,
207208
esplora: &MultiEsploraClient,
208209
) -> Result<ReadChannelManager<S>, MutinyError> {
@@ -270,7 +271,7 @@ impl<S: MutinyStorage> MutinyNodePersister<S> {
270271
fee_estimator: Arc<MutinyFeeEstimator<S>>,
271272
mutiny_logger: Arc<MutinyLogger>,
272273
keys_manager: Arc<PhantomKeysManager<S>>,
273-
router: Arc<Router>,
274+
router: Arc<MutinyRouter>,
274275
mut channel_monitors: Vec<(BlockHash, ChannelMonitor<InMemorySigner>)>,
275276
) -> Result<ReadChannelManager<S>, MutinyError> {
276277
let mut channel_monitor_mut_references = Vec::new();
@@ -312,7 +313,7 @@ impl<S: MutinyStorage> MutinyNodePersister<S> {
312313
fee_estimator: Arc<MutinyFeeEstimator<S>>,
313314
mutiny_logger: Arc<MutinyLogger>,
314315
keys_manager: Arc<PhantomKeysManager<S>>,
315-
router: Arc<Router>,
316+
router: Arc<MutinyRouter>,
316317
channel_monitors: Vec<(BlockHash, ChannelMonitor<InMemorySigner>)>,
317318
esplora: &MultiEsploraClient,
318319
) -> Result<ReadChannelManager<S>, MutinyError> {
@@ -375,7 +376,7 @@ impl<S: MutinyStorage> MutinyNodePersister<S> {
375376
logger: &MutinyLogger,
376377
) -> Option<PaymentInfo> {
377378
let key = self.get_key(payment_key(inbound, payment_hash).as_str());
378-
log_trace!(logger, "Trace: checking payment key: {key}");
379+
// log_trace!(logger, "Trace: checking payment key: {key}");
379380
let deserialized_value: Result<Option<PaymentInfo>, MutinyError> =
380381
self.storage.get_data(key);
381382
deserialized_value.ok().flatten()
@@ -619,7 +620,7 @@ impl<S: MutinyStorage>
619620
Arc<PhantomKeysManager<S>>,
620621
Arc<PhantomKeysManager<S>>,
621622
Arc<MutinyFeeEstimator<S>>,
622-
Arc<Router>,
623+
Arc<MutinyRouter>,
623624
Arc<MutinyLogger>,
624625
utils::Mutex<HubPreferentialScorer>,
625626
> for MutinyNodePersister<S>
@@ -744,6 +745,7 @@ pub(crate) async fn persist_monitor(
744745
#[cfg(test)]
745746
mod test {
746747
use crate::onchain::OnChainWallet;
748+
use crate::router::MutinyRouter;
747749
use crate::storage::MemoryStorage;
748750
use crate::{esplora::EsploraSyncClient, node::scoring_params};
749751
use crate::{
@@ -967,8 +969,9 @@ mod test {
967969
persister.clone(),
968970
));
969971

970-
let router: Arc<Router> = Arc::new(DefaultRouter::new(
972+
let router: Arc<MutinyRouter> = Arc::new(MutinyRouter::new(
971973
network_graph,
974+
None,
972975
logger.clone(),
973976
km.clone().get_secure_random_bytes(),
974977
Arc::new(utils::Mutex::new(scorer)),

mutiny-core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub mod storage;
4040
mod subscription;
4141
pub mod vss;
4242

43+
mod router;
4344
#[cfg(any(test, feature = "test-utils"))]
4445
pub mod test_utils;
4546
pub mod utils;

mutiny-core/src/node.rs

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use lightning::{
3939

4040
use crate::multiesplora::MultiEsploraClient;
4141
use crate::peermanager::LspMessageRouter;
42+
use crate::router::MutinyRouter;
4243
use crate::utils::get_monitor_version;
4344
use bitcoin::util::bip32::ExtendedPrivKey;
4445
use futures_util::lock::Mutex;
@@ -59,7 +60,7 @@ use lightning::{
5960
routing::{
6061
gossip,
6162
gossip::NodeId,
62-
router::{DefaultRouter, PaymentParameters, RouteParameters},
63+
router::{PaymentParameters, RouteParameters},
6364
},
6465
util::{
6566
config::{ChannelHandshakeConfig, ChannelHandshakeLimits, UserConfig},
@@ -122,14 +123,6 @@ pub(crate) type ChainMonitor<S: MutinyStorage> = chainmonitor::ChainMonitor<
122123
Arc<MutinyNodePersister<S>>,
123124
>;
124125

125-
pub(crate) type Router = DefaultRouter<
126-
Arc<NetworkGraph>,
127-
Arc<MutinyLogger>,
128-
Arc<utils::Mutex<HubPreferentialScorer>>,
129-
ProbabilisticScoringFeeParameters,
130-
HubPreferentialScorer,
131-
>;
132-
133126
#[derive(Clone, Debug, Eq, PartialEq)]
134127
pub enum ConnectionType {
135128
Tcp(String),
@@ -251,8 +244,27 @@ impl<S: MutinyStorage> Node<S> {
251244

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

254-
let router: Arc<Router> = Arc::new(DefaultRouter::new(
247+
log_info!(logger, "creating lsp client");
248+
let lsp_client: Option<LspClient> = match node_index.lsp {
249+
None => {
250+
if lsp_clients.is_empty() {
251+
log_info!(logger, "no lsp saved and no lsp clients available");
252+
None
253+
} else {
254+
log_info!(logger, "no lsp saved, picking random one");
255+
// If we don't have an lsp saved we should pick a random
256+
// one from our client list and save it for next time
257+
let rand = rand::random::<usize>() % lsp_clients.len();
258+
Some(lsp_clients[rand].clone())
259+
}
260+
}
261+
Some(ref lsp) => lsp_clients.iter().find(|c| &c.url == lsp).cloned(),
262+
};
263+
let lsp_pubkey = lsp_client.as_ref().map(|l| l.pubkey);
264+
265+
let router: Arc<MutinyRouter> = Arc::new(MutinyRouter::new(
255266
network_graph,
267+
lsp_pubkey,
256268
logger.clone(),
257269
keys_manager.clone().get_secure_random_bytes(),
258270
scorer.clone(),
@@ -328,24 +340,7 @@ impl<S: MutinyStorage> Node<S> {
328340
logger: logger.clone(),
329341
});
330342

331-
log_info!(logger, "creating lsp client");
332-
let lsp_client: Option<LspClient> = match node_index.lsp {
333-
None => {
334-
if lsp_clients.is_empty() {
335-
log_info!(logger, "no lsp saved and no lsp clients available");
336-
None
337-
} else {
338-
log_info!(logger, "no lsp saved, picking random one");
339-
// If we don't have an lsp saved we should pick a random
340-
// one from our client list and save it for next time
341-
let rand = rand::random::<usize>() % lsp_clients.len();
342-
Some(lsp_clients[rand].clone())
343-
}
344-
}
345-
Some(ref lsp) => lsp_clients.iter().find(|c| &c.url == lsp).cloned(),
346-
};
347-
348-
let message_router = Arc::new(LspMessageRouter::new(lsp_client.as_ref().map(|l| l.pubkey)));
343+
let message_router = Arc::new(LspMessageRouter::new(lsp_pubkey));
349344
let onion_message_handler = Arc::new(OnionMessenger::new(
350345
keys_manager.clone(),
351346
keys_manager.clone(),

mutiny-core/src/nodemanager.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ pub struct MutinyChannel {
326326
pub peer: PublicKey,
327327
pub confirmations_required: Option<u32>,
328328
pub confirmations: u32,
329+
pub scid: Option<u64>,
329330
}
330331

331332
impl From<&ChannelDetails> for MutinyChannel {
@@ -339,6 +340,7 @@ impl From<&ChannelDetails> for MutinyChannel {
339340
peer: c.counterparty.node_id,
340341
confirmations_required: c.confirmations_required,
341342
confirmations: c.confirmations.unwrap_or(0),
343+
scid: c.inbound_scid_alias,
342344
}
343345
}
344346
}

mutiny-core/src/router.rs

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
use crate::logging::MutinyLogger;
2+
use crate::node::NetworkGraph;
3+
use crate::scorer::HubPreferentialScorer;
4+
use crate::utils::Mutex;
5+
use bitcoin::secp256k1::PublicKey;
6+
use lightning::ln::channelmanager::ChannelDetails;
7+
use lightning::ln::features::ChannelFeatures;
8+
use lightning::ln::msgs::LightningError;
9+
use lightning::routing::gossip::NodeId;
10+
use lightning::routing::router::{
11+
BlindedTail, DefaultRouter, InFlightHtlcs, Path, Payee, Route, RouteHop, RouteParameters,
12+
Router,
13+
};
14+
use lightning::routing::scoring::ProbabilisticScoringFeeParameters;
15+
use lightning::util::ser::Writeable;
16+
use log::{info, warn};
17+
use std::sync::Arc;
18+
19+
type LdkRouter = DefaultRouter<
20+
Arc<NetworkGraph>,
21+
Arc<MutinyLogger>,
22+
Arc<Mutex<HubPreferentialScorer>>,
23+
ProbabilisticScoringFeeParameters,
24+
HubPreferentialScorer,
25+
>;
26+
27+
pub struct MutinyRouter {
28+
network_graph: Arc<NetworkGraph>,
29+
lsp_key: Option<PublicKey>,
30+
router: LdkRouter,
31+
}
32+
33+
impl MutinyRouter {
34+
pub fn new(
35+
network_graph: Arc<NetworkGraph>,
36+
lsp_key: Option<PublicKey>,
37+
logger: Arc<MutinyLogger>,
38+
random_seed_bytes: [u8; 32],
39+
scorer: Arc<Mutex<HubPreferentialScorer>>,
40+
score_params: ProbabilisticScoringFeeParameters,
41+
) -> Self {
42+
let router = DefaultRouter::new(
43+
network_graph.clone(),
44+
logger,
45+
random_seed_bytes,
46+
scorer,
47+
score_params,
48+
);
49+
50+
Self {
51+
network_graph,
52+
lsp_key,
53+
router,
54+
}
55+
}
56+
}
57+
58+
impl Router for MutinyRouter {
59+
fn find_route(
60+
&self,
61+
payer: &PublicKey,
62+
route_params: &RouteParameters,
63+
first_hops: Option<&[&ChannelDetails]>,
64+
inflight_htlcs: InFlightHtlcs,
65+
) -> Result<Route, LightningError> {
66+
match &route_params.payment_params.payee {
67+
Payee::Clear { .. } => {
68+
self.router
69+
.find_route(payer, route_params, first_hops, inflight_htlcs)
70+
}
71+
Payee::Blinded {
72+
route_hints,
73+
features: _,
74+
} => {
75+
// if we have no LSP, then handle normally
76+
if self.lsp_key.is_none() {
77+
return self
78+
.router
79+
.find_route(payer, route_params, first_hops, inflight_htlcs);
80+
}
81+
82+
let (blinded_info, blinded_path) = route_hints.first().unwrap();
83+
let graph_lock = self.network_graph.read_only();
84+
let lsp_node_id = NodeId::from_pubkey(&self.lsp_key.unwrap());
85+
let node_info = graph_lock.node(&lsp_node_id).unwrap();
86+
87+
let amt = route_params.final_value_msat;
88+
89+
// first our channel with enough capacity
90+
let first_hops = first_hops.unwrap_or(&[]);
91+
let first = first_hops
92+
.iter()
93+
.find_map(|c| {
94+
if c.outbound_capacity_msat >= amt {
95+
Some(c)
96+
} else {
97+
None
98+
}
99+
})
100+
.unwrap();
101+
102+
let channel_features =
103+
ChannelFeatures::from_be_bytes(first.counterparty.features.encode());
104+
105+
let scid = scid_from_parts(467591, 1, 0);
106+
warn!("scid: {}", scid);
107+
108+
let cltv_expiry_delta = first.config.unwrap().cltv_expiry_delta;
109+
let hops = vec![
110+
RouteHop {
111+
pubkey: self.lsp_key.unwrap(),
112+
node_features: node_info
113+
.announcement_info
114+
.as_ref()
115+
.unwrap()
116+
.features
117+
.clone(),
118+
short_channel_id: first.get_outbound_payment_scid().unwrap(),
119+
channel_features: channel_features.clone(),
120+
fee_msat: 0, // 0 for own channel
121+
cltv_expiry_delta: 0, // 0 for own channel
122+
maybe_announced_channel: false,
123+
},
124+
RouteHop {
125+
pubkey: blinded_path.introduction_node_id,
126+
node_features: node_info
127+
.announcement_info
128+
.as_ref()
129+
.unwrap()
130+
.features
131+
.clone(),
132+
short_channel_id: 17112782831943311000, // fixme
133+
channel_features,
134+
fee_msat: 10_000, // put high value just to try
135+
cltv_expiry_delta: cltv_expiry_delta as u32,
136+
maybe_announced_channel: false,
137+
},
138+
];
139+
140+
let blinded_tail = Some(BlindedTail {
141+
hops: blinded_path.blinded_hops.clone(),
142+
blinding_point: blinded_path.blinding_point,
143+
excess_final_cltv_expiry_delta: blinded_info.cltv_expiry_delta as u32,
144+
final_value_msat: amt,
145+
});
146+
147+
let path = Path { hops, blinded_tail };
148+
149+
Ok(Route {
150+
paths: vec![path],
151+
route_params: Some(route_params.clone()),
152+
})
153+
}
154+
}
155+
}
156+
}
157+
158+
/// Constructs a `short_channel_id` using the components pieces. Results in an error
159+
/// if the block height, tx index, or vout index overflow the maximum sizes.
160+
pub fn scid_from_parts(block: u64, tx_index: u64, vout_index: u64) -> u64 {
161+
(block << 40) | (tx_index << 16) | vout_index
162+
}

mutiny-wasm/src/models.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ pub struct MutinyChannel {
261261
peer: String,
262262
pub confirmations_required: Option<u32>,
263263
pub confirmations: u32,
264+
pub scid: Option<u64>,
264265
}
265266

266267
#[wasm_bindgen]
@@ -299,6 +300,7 @@ impl From<nodemanager::MutinyChannel> for MutinyChannel {
299300
peer: m.peer.to_hex(),
300301
confirmations_required: m.confirmations_required,
301302
confirmations: m.confirmations,
303+
scid: m.scid,
302304
}
303305
}
304306
}

0 commit comments

Comments
 (0)