Skip to content

Commit 32d3675

Browse files
committed
Generate UniFFI scaffolding
We generate the scaffolding from an UDL file and include it in `lib.rs`. Furthermore, we add a bindings generation shell script for convenience.
1 parent e530c86 commit 32d3675

File tree

9 files changed

+270
-38
lines changed

9 files changed

+270
-38
lines changed

Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ description = "A ready-to-go node implementation based on LDK."
88

99
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1010

11+
[lib]
12+
crate-type = ["staticlib", "cdylib"]
13+
name = "ldk_node"
14+
1115
[dependencies]
1216
#lightning = { version = "0.0.112", features = ["max_level_trace", "std"] }
1317
#lightning-invoice = { version = "0.20" }
@@ -47,12 +51,17 @@ chrono = "0.4"
4751
futures = "0.3"
4852
serde_json = { version = "1.0" }
4953
tokio = { version = "1", features = [ "full" ] }
54+
uniffi = { version = "0.21.0", features = ["builtin-bindgen"] }
55+
uniffi_macros = { version = "0.21.0", features = ["builtin-bindgen"] }
5056

5157
[dev-dependencies]
5258
electrsd = { version = "0.22.0", features = ["legacy", "esplora_a33e97e1", "bitcoind_23_0"] }
5359
electrum-client = "0.12.0"
5460
once_cell = "1.16.0"
5561

62+
[build-dependencies]
63+
uniffi_build = "0.21.0"
64+
5665
[profile.release]
5766
panic = "abort"
5867

build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
uniffi_build::generate_scaffolding("uniffi/ldk_node.udl").unwrap();
3+
}

src/error.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,20 @@ pub enum Error {
1111
FundingTxCreationFailed,
1212
/// A network connection has been closed.
1313
ConnectionFailed,
14+
/// The given address is invalid.
15+
AddressInvalid,
16+
/// The given public key is invalid.
17+
PublicKeyInvalid,
18+
/// The given payment hash is invalid.
19+
PaymentHashInvalid,
1420
/// Payment of the given invoice has already been intiated.
1521
NonUniquePaymentHash,
1622
/// The given invoice is invalid.
1723
InvoiceInvalid,
1824
/// Invoice creation failed.
1925
InvoiceCreationFailed,
26+
/// The given channel ID is invalid.
27+
ChannelIdInvalid,
2028
/// No route for the given target could be found.
2129
RoutingFailed,
2230
/// A given peer info could not be parsed.
@@ -40,13 +48,15 @@ impl fmt::Display for Error {
4048
match *self {
4149
Self::AlreadyRunning => write!(f, "Node is already running."),
4250
Self::NotRunning => write!(f, "Node is not running."),
43-
Self::FundingTxCreationFailed => {
44-
write!(f, "Funding transaction could not be created.")
45-
}
51+
Self::FundingTxCreationFailed => write!(f, "Funding transaction could not be created."),
4652
Self::ConnectionFailed => write!(f, "Network connection closed."),
53+
Self::AddressInvalid => write!(f, "The given address is invalid."),
54+
Self::PublicKeyInvalid => write!(f, "The given public key is invalid."),
55+
Self::PaymentHashInvalid => write!(f, "The given payment hash is invalid."),
4756
Self::NonUniquePaymentHash => write!(f, "An invoice must not get payed twice."),
4857
Self::InvoiceInvalid => write!(f, "The given invoice is invalid."),
4958
Self::InvoiceCreationFailed => write!(f, "Failed to create invoice."),
59+
Self::ChannelIdInvalid => write!(f, "The given channel ID is invalid."),
5060
Self::RoutingFailed => write!(f, "Failed to find route."),
5161
Self::PeerInfoParseFailed => write!(f, "Failed to parse the given peer information."),
5262
Self::ChannelCreationFailed => write!(f, "Failed to create channel."),

src/event.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
2-
hex_utils, ChannelManager, Config, Error, KeysManager, NetworkGraph, PaymentInfo,
3-
PaymentInfoStorage, PaymentStatus, Wallet,
2+
hex_utils, ChannelId, ChannelManager, Config, Error, KeysManager, NetworkGraph, PaymentInfo,
3+
PaymentInfoStorage, PaymentStatus, UserChannelId, Wallet,
44
};
55

66
use crate::logger::{log_error, log_given_level, log_info, log_internal, Logger};
@@ -50,16 +50,16 @@ pub enum Event {
5050
/// A channel is ready to be used.
5151
ChannelReady {
5252
/// The `channel_id` of the channel.
53-
channel_id: [u8; 32],
53+
channel_id: ChannelId,
5454
/// The `user_channel_id` of the channel.
55-
user_channel_id: u128,
55+
user_channel_id: UserChannelId,
5656
},
5757
/// A channel has been closed.
5858
ChannelClosed {
5959
/// The `channel_id` of the channel.
60-
channel_id: [u8; 32],
60+
channel_id: ChannelId,
6161
/// The `user_channel_id` of the channel.
62-
user_channel_id: u128,
62+
user_channel_id: UserChannelId,
6363
},
6464
}
6565

@@ -83,13 +83,13 @@ impl Readable for Event {
8383
Ok(Self::PaymentReceived { payment_hash, amount_msat })
8484
}
8585
3u8 => {
86-
let channel_id: [u8; 32] = Readable::read(reader)?;
87-
let user_channel_id: u128 = Readable::read(reader)?;
86+
let channel_id = ChannelId(Readable::read(reader)?);
87+
let user_channel_id = UserChannelId(Readable::read(reader)?);
8888
Ok(Self::ChannelReady { channel_id, user_channel_id })
8989
}
9090
4u8 => {
91-
let channel_id: [u8; 32] = Readable::read(reader)?;
92-
let user_channel_id: u128 = Readable::read(reader)?;
91+
let channel_id = ChannelId(Readable::read(reader)?);
92+
let user_channel_id = UserChannelId(Readable::read(reader)?);
9393
Ok(Self::ChannelClosed { channel_id, user_channel_id })
9494
}
9595
_ => Err(lightning::ln::msgs::DecodeError::InvalidValue),
@@ -118,14 +118,14 @@ impl Writeable for Event {
118118
}
119119
Self::ChannelReady { channel_id, user_channel_id } => {
120120
3u8.write(writer)?;
121-
channel_id.write(writer)?;
122-
user_channel_id.write(writer)?;
121+
channel_id.0.write(writer)?;
122+
user_channel_id.0.write(writer)?;
123123
Ok(())
124124
}
125125
Self::ChannelClosed { channel_id, user_channel_id } => {
126126
4u8.write(writer)?;
127-
channel_id.write(writer)?;
128-
user_channel_id.write(writer)?;
127+
channel_id.0.write(writer)?;
128+
user_channel_id.0.write(writer)?;
129129
Ok(())
130130
}
131131
}
@@ -562,7 +562,10 @@ where
562562
counterparty_node_id,
563563
);
564564
self.event_queue
565-
.add_event(Event::ChannelReady { channel_id, user_channel_id })
565+
.add_event(Event::ChannelReady {
566+
channel_id: ChannelId(channel_id),
567+
user_channel_id: UserChannelId(user_channel_id),
568+
})
566569
.expect("Failed to push to event queue");
567570
}
568571
LdkEvent::ChannelClosed { channel_id, reason, user_channel_id } => {
@@ -573,7 +576,10 @@ where
573576
reason
574577
);
575578
self.event_queue
576-
.add_event(Event::ChannelClosed { channel_id, user_channel_id })
579+
.add_event(Event::ChannelClosed {
580+
channel_id: ChannelId(channel_id),
581+
user_channel_id: UserChannelId(user_channel_id),
582+
})
577583
.expect("Failed to push to event queue");
578584
}
579585
LdkEvent::DiscardFunding { .. } => {}
@@ -592,7 +598,10 @@ mod tests {
592598
let test_persister = Arc::new(TestPersister::new());
593599
let event_queue = EventQueue::new(Arc::clone(&test_persister));
594600

595-
let expected_event = Event::ChannelReady { channel_id: [23u8; 32], user_channel_id: 2323 };
601+
let expected_event = Event::ChannelReady {
602+
channel_id: ChannelId([23u8; 32]),
603+
user_channel_id: UserChannelId(2323),
604+
};
596605
event_queue.add_event(expected_event.clone()).unwrap();
597606
assert!(test_persister.get_and_clear_pending_persist());
598607

src/lib.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
//! - Wallet and channel states are persisted to disk.
1818
//! - Gossip is retrieved over the P2P network.
1919
20-
#![deny(missing_docs)]
2120
#![deny(broken_intra_doc_links)]
2221
#![deny(private_intra_doc_links)]
2322
#![allow(bare_trait_objects)]
@@ -35,15 +34,16 @@ mod tests;
3534
mod types;
3635
mod wallet;
3736

38-
pub use error::Error;
37+
pub use error::Error as NodeError;
38+
use error::Error;
3939
pub use event::Event;
4040
use event::{EventHandler, EventQueue};
4141
use peer_store::{PeerInfo, PeerInfoStorage};
4242
use types::{
4343
ChainMonitor, ChannelManager, GossipSync, InvoicePayer, KeysManager, NetworkGraph,
4444
OnionMessenger, PaymentInfoStorage, PeerManager, Router, Scorer,
4545
};
46-
pub use types::{PaymentInfo, PaymentStatus};
46+
pub use types::{ChannelId, PaymentInfo, PaymentStatus, UserChannelId};
4747
use wallet::Wallet;
4848

4949
use logger::{log_error, log_given_level, log_info, log_internal, FilesystemLogger, Logger};
@@ -76,7 +76,7 @@ use bdk::template::Bip84;
7676
use bitcoin::hashes::sha256::Hash as Sha256;
7777
use bitcoin::hashes::Hash;
7878
use bitcoin::secp256k1::PublicKey;
79-
use bitcoin::BlockHash;
79+
use bitcoin::{Address, BlockHash};
8080

8181
use rand::Rng;
8282

@@ -89,6 +89,8 @@ use std::sync::atomic::{AtomicBool, Ordering};
8989
use std::sync::{Arc, Mutex, RwLock};
9090
use std::time::{Duration, Instant, SystemTime};
9191

92+
uniffi_macros::include_scaffolding!("ldk_node");
93+
9294
// The used 'stop gap' parameter used by BDK's wallet sync. This seems to configure the threshold
9395
// number of blocks after which BDK stops looking for scripts belonging to the wallet.
9496
const BDK_CLIENT_STOP_GAP: usize = 20;
@@ -195,8 +197,8 @@ impl Builder {
195197
self
196198
}
197199

198-
/// Builds an [`Node`] instance according to the options previously configured.
199-
pub fn build(&self) -> Node {
200+
/// Builds a [`Node`] instance according to the options previously configured.
201+
pub fn build(&self) -> Arc<Node> {
200202
let config = Arc::new(self.config.clone());
201203

202204
let ldk_data_dir = format!("{}/ldk", &config.storage_dir_path.clone());
@@ -410,7 +412,7 @@ impl Builder {
410412

411413
let running = RwLock::new(None);
412414

413-
Node {
415+
Arc::new(Node {
414416
running,
415417
config,
416418
wallet,
@@ -429,7 +431,7 @@ impl Builder {
429431
inbound_payments,
430432
outbound_payments,
431433
peer_store,
432-
}
434+
})
433435
}
434436
}
435437

@@ -472,7 +474,7 @@ impl Node {
472474
/// Starts the necessary background tasks, such as handling events coming from user input,
473475
/// LDK/BDK, and the peer-to-peer network. After this returns, the [`Node`] instance can be
474476
/// controlled via the provided API methods in a thread-safe manner.
475-
pub fn start(&mut self) -> Result<(), Error> {
477+
pub fn start(&self) -> Result<(), Error> {
476478
// Acquire a run lock and hold it until we're setup.
477479
let mut run_lock = self.running.write().unwrap();
478480
if run_lock.is_some() {
@@ -486,7 +488,7 @@ impl Node {
486488
}
487489

488490
/// Disconnects all peers, stops all running background tasks, and shuts down [`Node`].
489-
pub fn stop(&mut self) -> Result<(), Error> {
491+
pub fn stop(&self) -> Result<(), Error> {
490492
let mut run_lock = self.running.write().unwrap();
491493
if run_lock.is_none() {
492494
return Err(Error::NotRunning);
@@ -704,15 +706,15 @@ impl Node {
704706
}
705707

706708
/// Retrieve a new on-chain/funding address.
707-
pub fn new_funding_address(&mut self) -> Result<bitcoin::Address, Error> {
709+
pub fn new_funding_address(&self) -> Result<Address, Error> {
708710
let funding_address = self.wallet.get_new_address()?;
709711
log_info!(self.logger, "Generated new funding address: {}", funding_address);
710712
Ok(funding_address)
711713
}
712714

713715
#[cfg(test)]
714716
/// Retrieve the current on-chain balance.
715-
pub fn on_chain_balance(&mut self) -> Result<bdk::Balance, Error> {
717+
pub fn on_chain_balance(&self) -> Result<bdk::Balance, Error> {
716718
self.wallet.get_balance()
717719
}
718720

src/tests/functional_tests.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,13 @@ fn rand_config() -> Config {
124124
fn channel_full_cycle() {
125125
println!("== Node A ==");
126126
let config_a = rand_config();
127-
let mut node_a = Builder::from_config(config_a).build();
127+
let node_a = Builder::from_config(config_a).build();
128128
node_a.start().unwrap();
129129
let addr_a = node_a.new_funding_address().unwrap();
130130

131131
println!("\n== Node B ==");
132132
let config_b = rand_config();
133-
let mut node_b = Builder::from_config(config_b).build();
133+
let node_b = Builder::from_config(config_b).build();
134134
node_b.start().unwrap();
135135
let addr_b = node_b.new_funding_address().unwrap();
136136

@@ -161,10 +161,10 @@ fn channel_full_cycle() {
161161
expect_event!(node_a, ChannelReady);
162162

163163
let channel_id = match node_b.next_event() {
164-
ref e @ Event::ChannelReady { channel_id, .. } => {
164+
ref e @ Event::ChannelReady { ref channel_id, .. } => {
165165
println!("{} got event {:?}", std::stringify!(node_b), e);
166166
node_b.event_handled();
167-
channel_id
167+
channel_id.clone()
168168
}
169169
ref e => {
170170
panic!("{} got unexpected event!: {:?}", std::stringify!(node_b), e);
@@ -180,7 +180,7 @@ fn channel_full_cycle() {
180180
expect_event!(node_a, PaymentSuccessful);
181181
expect_event!(node_b, PaymentReceived);
182182

183-
node_b.close_channel(&channel_id, &node_a.node_id().unwrap()).unwrap();
183+
node_b.close_channel(&channel_id.0, &node_a.node_id().unwrap()).unwrap();
184184
expect_event!(node_a, ChannelClosed);
185185
expect_event!(node_b, ChannelClosed);
186186

0 commit comments

Comments
 (0)