Skip to content

Commit d9ef3db

Browse files
committed
multi: setup grpc server
1 parent 2952280 commit d9ef3db

File tree

9 files changed

+290
-67
lines changed

9 files changed

+290
-67
lines changed

Cargo.lock

+31-54
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ rand_core = "0.6.4"
2424
log = "0.4.17"
2525
log4rs = { version = "1.2.0", features = ["file_appender"] }
2626
tokio = { version = "1.25.0", features = ["rt", "rt-multi-thread"] }
27-
tonic = "0.8.3"
27+
tonic = "0.11"
2828
tonic_lnd = { git = "https://github.com/orbitalturtle/tonic_lnd", rev="afb0187621bca604f606cacfe3cb2aedf5d2fc89", package="fedimint-tonic-lnd", features = ["lightningrpc", "routerrpc"] }
2929
hex = "0.4.3"
3030
configure_me = "0.4.0"
3131
bytes = "1.4.0"
3232
triggered = "0.1.2"
33+
prost = "0.12"
3334

3435
[dev-dependencies]
3536
bitcoincore-rpc = { package="core-rpc", version = "0.17.0" }
@@ -41,6 +42,7 @@ tempfile = "3.5.0"
4142

4243
[build-dependencies]
4344
configure_me_codegen = "0.4.4"
45+
tonic-build = "0.11"
4446

4547
# The profile that 'cargo dist' will build with
4648
[profile.dist]

build.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1-
fn main() {
2-
configure_me_codegen::build_script_auto().unwrap_or_else(|error| error.report_and_exit())
1+
fn main() -> Result<(), Box<dyn std::error::Error>> {
2+
configure_me_codegen::build_script_auto().unwrap_or_else(|error| error.report_and_exit());
3+
4+
// Compile the protos for our grpc server.
5+
tonic_build::configure()
6+
.protoc_arg("--experimental_allow_proto3_optional")
7+
.compile(&["proto/lndkrpc.proto"], &["proto"])?;
8+
9+
Ok(())
310
}

proto/lndkrpc.proto

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
syntax = "proto3";
2+
package lndkrpc;
3+
4+
service Offers {
5+
rpc PayOffer (PayOfferRequest) returns (PayOfferResponse);
6+
}
7+
8+
message PayOfferRequest {
9+
string offer = 1;
10+
optional uint64 amount = 2;
11+
}
12+
13+
message PayOfferResponse {
14+
string payment_preimage = 2;
15+
}

src/lib.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ pub mod lnd;
44
pub mod lndk_offers;
55
pub mod onion_messenger;
66
mod rate_limit;
7+
pub mod server;
8+
9+
pub mod lndkrpc {
10+
tonic::include_proto!("lndkrpc");
11+
}
712

813
use crate::lnd::{
914
features_support_onion_messages, get_lnd_client, get_network, LndCfg, LndNodeSigner,
@@ -46,6 +51,8 @@ pub fn init_logger(config: LogConfig) {
4651
});
4752
}
4853

54+
pub const DEFAULT_SERVER_PORT: u16 = 7000;
55+
4956
#[allow(clippy::result_unit_err)]
5057
pub fn setup_logger(log_level: Option<String>, log_dir: Option<String>) -> Result<(), ()> {
5158
let log_level = match log_level {
@@ -128,7 +135,6 @@ impl LndkOnionMessenger {
128135
offer_handler: Arc<impl OffersMessageHandler>,
129136
) -> Result<(), ()> {
130137
let mut client = get_lnd_client(args.lnd).expect("failed to connect");
131-
132138
let info = client
133139
.lightning()
134140
.get_info(GetInfoRequest {})

src/lnd.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ use log::error;
1616
use std::cell::RefCell;
1717
use std::collections::HashMap;
1818
use std::error::Error;
19-
use std::fmt;
2019
use std::fmt::Display;
2120
use std::path::PathBuf;
21+
use std::{fmt, fs};
2222
use tonic_lnd::lnrpc::{
2323
GetInfoResponse, HtlcAttempt, LightningNode, ListPeersResponse, Payment, QueryRoutesResponse,
2424
Route,
@@ -43,8 +43,8 @@ pub fn get_lnd_client(cfg: LndCfg) -> Result<Client, ConnectError> {
4343
/// LndCfg specifies the configuration required to connect to LND's grpc client.
4444
#[derive(Clone)]
4545
pub struct LndCfg {
46-
address: String,
47-
creds: Creds,
46+
pub address: String,
47+
pub creds: Creds,
4848
}
4949

5050
impl LndCfg {
@@ -161,6 +161,18 @@ pub enum Creds {
161161
String { macaroon: String, cert: String },
162162
}
163163

164+
impl Creds {
165+
#[allow(clippy::result_unit_err)]
166+
pub fn get_certificate_string(&self) -> Result<String, ()> {
167+
let cert = match self {
168+
Creds::Path { macaroon: _, cert } => fs::read_to_string(cert)
169+
.map_err(|e| error!("Error reading tls certificate from file {e:?}"))?,
170+
Creds::String { macaroon: _, cert } => cert.clone(),
171+
};
172+
Ok(cert)
173+
}
174+
}
175+
164176
/// features_support_onion_messages returns a boolean indicating whether a feature set supports onion messaging.
165177
pub fn features_support_onion_messages(features: &HashMap<u32, tonic_lnd::lnrpc::Feature>) -> bool {
166178
features.contains_key(&ONION_MESSAGES_OPTIONAL)

src/main.rs

+54-5
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,18 @@ mod internal {
1010
}
1111

1212
use internal::*;
13-
use lndk::lnd::{validate_lnd_creds, LndCfg};
14-
use lndk::{setup_logger, Cfg, LifecycleSignals, LndkOnionMessenger, OfferHandler};
13+
use lndk::lnd::{get_lnd_client, validate_lnd_creds, LndCfg};
14+
use lndk::server::LNDKServer;
15+
use lndk::{
16+
lndkrpc, setup_logger, Cfg, LifecycleSignals, LndkOnionMessenger, OfferHandler,
17+
DEFAULT_SERVER_PORT,
18+
};
19+
use lndkrpc::offers_server::OffersServer;
20+
use log::{error, info};
1521
use std::sync::Arc;
22+
use tokio::select;
23+
use tonic::transport::Server;
24+
use tonic_lnd::lnrpc::GetInfoRequest;
1625

1726
#[macro_use]
1827
extern crate configure_me;
@@ -32,7 +41,8 @@ async fn main() -> Result<(), ()> {
3241
.map_err(|e| {
3342
println!("Error validating config: {e}.");
3443
})?;
35-
let lnd_args = LndCfg::new(config.address, creds);
44+
let address = config.address.clone();
45+
let lnd_args = LndCfg::new(config.address, creds.clone());
3646

3747
let (shutdown, listener) = triggered::trigger();
3848
let signals = LifecycleSignals { shutdown, listener };
@@ -42,8 +52,47 @@ async fn main() -> Result<(), ()> {
4252
};
4353

4454
let handler = Arc::new(OfferHandler::new());
55+
let messenger = LndkOnionMessenger::new();
4556
setup_logger(config.log_level, config.log_dir)?;
4657

47-
let messenger = LndkOnionMessenger::new();
48-
messenger.run(args, Arc::clone(&handler)).await
58+
let mut client = get_lnd_client(args.lnd.clone()).expect("failed to connect to lnd");
59+
let info = client
60+
.lightning()
61+
.get_info(GetInfoRequest {})
62+
.await
63+
.expect("failed to get info")
64+
.into_inner();
65+
66+
let addr = format!("[::1]:{DEFAULT_SERVER_PORT}")
67+
.parse()
68+
.map_err(|e| {
69+
error!("Error parsing API address: {e}");
70+
})?;
71+
72+
let tls_str = creds.get_certificate_string()?;
73+
let server = LNDKServer::new(
74+
Arc::clone(&handler),
75+
&info.identity_pubkey,
76+
tls_str,
77+
address,
78+
)
79+
.await;
80+
81+
let server_fut = Server::builder()
82+
.add_service(OffersServer::new(server))
83+
.serve(addr);
84+
85+
select! {
86+
_ = messenger.run(args, Arc::clone(&handler)) => {
87+
info!("Onion messenger completed");
88+
},
89+
result2 = server_fut => {
90+
match result2 {
91+
Ok(_) => info!("API completed"),
92+
Err(e) => error!("Error running API: {}", e),
93+
};
94+
},
95+
}
96+
97+
Ok(())
4998
}

0 commit comments

Comments
 (0)