Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions simln-lib/src/cln.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ use cln_grpc::pb::{
};
use lightning::ln::features::NodeFeatures;
use lightning::ln::PaymentHash;

use serde::{Deserialize, Serialize};
use tokio::fs::File;
use tokio::io::{AsyncReadExt, Error};
use tokio::sync::Mutex;
use tokio::time::{self, Duration};
use tonic::transport::{Certificate, Channel, ClientTlsConfig, Identity};
use triggered::Listener;
Expand All @@ -38,7 +38,7 @@ pub struct ClnConnection {
}

pub struct ClnNode {
pub client: NodeClient<Channel>,
pub client: Mutex<NodeClient<Channel>>,
info: NodeInfo,
}

Expand All @@ -60,7 +60,7 @@ impl ClnNode {
})?,
));

let mut client = NodeClient::new(
let client = Mutex::new(NodeClient::new(
Channel::from_shared(connection.address)
.map_err(|err| LightningError::ConnectionError(err.to_string()))?
.tls_config(tls)
Expand All @@ -72,9 +72,11 @@ impl ClnNode {
.map_err(|_| {
LightningError::ConnectionError("Cannot connect to gRPC server".to_string())
})?,
);
));

let (id, mut alias, our_features) = client
.lock()
.await
.getinfo(GetinfoRequest {})
.await
.map(|r| {
Expand Down Expand Up @@ -110,7 +112,7 @@ impl ClnNode {
/// Fetch channels belonging to the local node, initiated locally if is_source is true, and initiated remotely if
/// is_source is false. Introduced as a helper function because CLN doesn't have a single API to list all of our
/// node's channels.
async fn node_channels(&mut self, is_source: bool) -> Result<Vec<u64>, LightningError> {
async fn node_channels(&self, is_source: bool) -> Result<Vec<u64>, LightningError> {
let req = if is_source {
ListchannelsRequest {
source: Some(self.info.pubkey.serialize().to_vec()),
Expand All @@ -125,6 +127,8 @@ impl ClnNode {

let resp = self
.client
.lock()
.await
.list_channels(req)
.await
.map_err(|err| LightningError::ListChannelsError(err.to_string()))?
Expand All @@ -144,9 +148,9 @@ impl LightningNode for ClnNode {
&self.info
}

async fn get_network(&mut self) -> Result<Network, LightningError> {
let info = self
.client
async fn get_network(&self) -> Result<Network, LightningError> {
let mut client = self.client.lock().await;
let info = client
.getinfo(GetinfoRequest {})
.await
.map_err(|err| LightningError::GetInfoError(err.to_string()))?
Expand All @@ -157,12 +161,12 @@ impl LightningNode for ClnNode {
}

async fn send_payment(
&mut self,
&self,
dest: PublicKey,
amount_msat: u64,
) -> Result<PaymentHash, LightningError> {
let KeysendResponse { payment_hash, .. } = self
.client
let mut client = self.client.lock().await;
let KeysendResponse { payment_hash, .. } = client
.key_send(KeysendRequest {
destination: dest.serialize().to_vec(),
amount_msat: Some(Amount { msat: amount_msat }),
Expand Down Expand Up @@ -191,7 +195,7 @@ impl LightningNode for ClnNode {
}

async fn track_payment(
&mut self,
&self,
hash: &PaymentHash,
shutdown: Listener,
) -> Result<PaymentResult, LightningError> {
Expand All @@ -202,8 +206,8 @@ impl LightningNode for ClnNode {
return Err(LightningError::TrackPaymentError("Shutdown before tracking results".to_string()));
},
_ = time::sleep(Duration::from_millis(500)) => {
let ListpaysResponse { pays } = self
.client
let mut client = self.client.lock().await;
let ListpaysResponse { pays } = client
.list_pays(ListpaysRequest {
payment_hash: Some(hash.0.to_vec()),
..Default::default()
Expand Down Expand Up @@ -233,9 +237,9 @@ impl LightningNode for ClnNode {
}
}

async fn get_node_info(&mut self, node_id: &PublicKey) -> Result<NodeInfo, LightningError> {
let mut nodes: Vec<cln_grpc::pb::ListnodesNodes> = self
.client
async fn get_node_info(&self, node_id: &PublicKey) -> Result<NodeInfo, LightningError> {
let mut client = self.client.lock().await;
let mut nodes: Vec<cln_grpc::pb::ListnodesNodes> = client
.list_nodes(ListnodesRequest {
id: Some(node_id.serialize().to_vec()),
})
Expand All @@ -261,15 +265,15 @@ impl LightningNode for ClnNode {
}
}

async fn list_channels(&mut self) -> Result<Vec<u64>, LightningError> {
async fn list_channels(&self) -> Result<Vec<u64>, LightningError> {
let mut node_channels = self.node_channels(true).await?;
node_channels.extend(self.node_channels(false).await?);
Ok(node_channels)
}

async fn get_graph(&mut self) -> Result<Graph, LightningError> {
let nodes: Vec<cln_grpc::pb::ListnodesNodes> = self
.client
async fn get_graph(&self) -> Result<Graph, LightningError> {
let mut client = self.client.lock().await;
let nodes: Vec<cln_grpc::pb::ListnodesNodes> = client
.list_nodes(ListnodesRequest { id: None })
.await
.map_err(|err| LightningError::GetNodeInfoError(err.to_string()))?
Expand Down
40 changes: 20 additions & 20 deletions simln-lib/src/eclair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use std::collections::HashMap;
use std::error::Error;
use std::str::FromStr;
use std::time::Duration;
use tokio::sync::Mutex;
use tokio::time;
use triggered::Listener;

Expand Down Expand Up @@ -83,7 +84,7 @@ impl TryInto<EclairClient> for EclairConnection {
}

pub struct EclairNode {
client: EclairClient,
client: Mutex<EclairClient>,
info: NodeInfo,
network: Network,
}
Expand All @@ -110,7 +111,7 @@ impl EclairNode {
let features = parse_json_to_node_features(&info.features);

Ok(Self {
client,
client: Mutex::new(client),
info: NodeInfo {
pubkey,
alias: info.alias,
Expand All @@ -127,31 +128,30 @@ impl LightningNode for EclairNode {
&self.info
}

async fn get_network(&mut self) -> Result<Network, LightningError> {
async fn get_network(&self) -> Result<Network, LightningError> {
Ok(self.network)
}

async fn send_payment(
&mut self,
&self,
dest: PublicKey,
amount_msat: u64,
) -> Result<PaymentHash, LightningError> {
let client = self.client.lock().await;
let preimage = PaymentPreimage(rand::random()).0;
let mut params = HashMap::new();
params.insert("nodeId".to_string(), hex::encode(dest.serialize()));
params.insert("amountMsat".to_string(), amount_msat.to_string());
params.insert("paymentHash".to_string(), hex::encode(preimage));
let uuid: String = self
.client
let uuid: String = client
.request("sendtonode", Some(params))
.await
.map_err(|err| LightningError::SendPaymentError(err.to_string()))?;

let mut params = HashMap::new();
params.insert("paymentHash".to_string(), hex::encode(preimage));
params.insert("id".to_string(), uuid);
let payment_parts: PaymentInfoResponse = self
.client
let payment_parts: PaymentInfoResponse = client
.request("getsentinfo", Some(params))
.await
.map_err(|_| LightningError::InvalidPaymentHash)?;
Expand All @@ -164,7 +164,7 @@ impl LightningNode for EclairNode {
}

async fn track_payment(
&mut self,
&self,
hash: &PaymentHash,
shutdown: Listener,
) -> Result<PaymentResult, LightningError> {
Expand All @@ -175,11 +175,11 @@ impl LightningNode for EclairNode {
return Err(LightningError::TrackPaymentError("Shutdown before tracking results".to_string()));
},
_ = time::sleep(Duration::from_millis(500)) => {
let client = self.client.lock().await;
let mut params = HashMap::new();
params.insert("paymentHash".to_string(), hex::encode(hash.0));

let payment_parts: PaymentInfoResponse = self
.client
let payment_parts: PaymentInfoResponse = client
.request("getsentinfo", Some(params))
.await
.map_err(|err| LightningError::TrackPaymentError(err.to_string()))?;
Expand All @@ -204,12 +204,12 @@ impl LightningNode for EclairNode {
}
}

async fn get_node_info(&mut self, node_id: &PublicKey) -> Result<NodeInfo, LightningError> {
async fn get_node_info(&self, node_id: &PublicKey) -> Result<NodeInfo, LightningError> {
let mut params = HashMap::new();
params.insert("nodeId".to_string(), hex::encode(node_id.serialize()));

let node_info: NodeResponse = self
.client
let client = self.client.lock().await;
let node_info: NodeResponse = client
.request("node", Some(params))
.await
.map_err(|err| LightningError::GetNodeInfoError(err.to_string()))?;
Expand All @@ -222,9 +222,9 @@ impl LightningNode for EclairNode {
})
}

async fn list_channels(&mut self) -> Result<Vec<u64>, LightningError> {
let channels: ChannelsResponse = self
.client
async fn list_channels(&self) -> Result<Vec<u64>, LightningError> {
let client = self.client.lock().await;
let channels: ChannelsResponse = client
.request("channels", None)
.await
.map_err(|err| LightningError::ListChannelsError(err.to_string()))?;
Expand All @@ -245,9 +245,9 @@ impl LightningNode for EclairNode {
Ok(capacities_msat)
}

async fn get_graph(&mut self) -> Result<Graph, LightningError> {
let nodes: NodesResponse = self
.client
async fn get_graph(&self) -> Result<Graph, LightningError> {
let client = self.client.lock().await;
let nodes: NodesResponse = client
.request("nodes", None)
.await
.map_err(|err| LightningError::GetNodeInfoError(err.to_string()))?;
Expand Down
16 changes: 8 additions & 8 deletions simln-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,26 +324,26 @@ pub trait LightningNode: Send {
/// Get information about the node.
fn get_info(&self) -> &NodeInfo;
/// Get the network this node is running at.
async fn get_network(&mut self) -> Result<Network, LightningError>;
async fn get_network(&self) -> Result<Network, LightningError>;
/// Keysend payment worth `amount_msat` from a source node to the destination node.
async fn send_payment(
&mut self,
&self,
dest: PublicKey,
amount_msat: u64,
) -> Result<PaymentHash, LightningError>;
/// Track a payment with the specified hash.
async fn track_payment(
&mut self,
&self,
hash: &PaymentHash,
shutdown: Listener,
) -> Result<PaymentResult, LightningError>;
/// Gets information on a specific node.
async fn get_node_info(&mut self, node_id: &PublicKey) -> Result<NodeInfo, LightningError>;
async fn get_node_info(&self, node_id: &PublicKey) -> Result<NodeInfo, LightningError>;
/// Lists all channels, at present only returns a vector of channel capacities in msat because no further
/// information is required.
async fn list_channels(&mut self) -> Result<Vec<u64>, LightningError>;
async fn list_channels(&self) -> Result<Vec<u64>, LightningError>;
/// Get the network graph from the point of view of a given node.
async fn get_graph(&mut self) -> Result<Graph, LightningError>;
async fn get_graph(&self) -> Result<Graph, LightningError>;
}

/// Represents an error that occurs when generating a destination for a payment.
Expand Down Expand Up @@ -1149,7 +1149,7 @@ async fn consume_events(
if let Some(event) = simulation_event {
match event {
SimulationEvent::SendPayment(dest, amt_msat) => {
let mut node = node.lock().await;
let node = node.lock().await;

let mut payment = Payment {
source: node.get_info().pubkey,
Expand Down Expand Up @@ -1501,7 +1501,7 @@ async fn track_payment_result(
) -> Result<(), SimulationError> {
log::trace!("Payment result tracker starting.");

let mut node = node.lock().await;
let node = node.lock().await;

let res = match payment.hash {
Some(hash) => {
Expand Down
Loading