Skip to content

Upgrade to LDK 0.2 #462

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 22 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
562bbf2
WIP: Upgrade to LDK 0.2
tnull Feb 6, 2025
b0e0332
f Add `lightning-macros` to alt `Cargo.toml` sources
tnull Jun 12, 2025
becf364
f Account for renamed `lightning-liquidity` types
tnull May 16, 2025
f558435
f Move `uniffi` LSPS1PaymentInfo types next to the pre-existing ones
tnull May 16, 2025
3e3b988
f Account for `ChannelMonitors` being tracked by `ChannelId`
tnull May 16, 2025
b274128
f Account for `HTLCHandlingFailureType`
tnull May 16, 2025
d30ed43
f Account for signer changes
tnull May 16, 2025
7b78e61
f Account for `PaymentClaimable` API changes
tnull May 16, 2025
31cbcc8
f Account for `get_counterparty_node_id` returning `PublicKey`
tnull May 21, 2025
8479012
f Account for BP taking Sweeper and LiqMan as arguments now
tnull May 21, 2025
befad49
f Account for `accept_inbound_channel` allowing override params
tnull May 21, 2025
9f7abda
f Account for `CMH` using `LengthLimitedRead`
tnull May 21, 2025
dd8c3ab
f Account for `get_current_default_config` changes
tnull May 21, 2025
d8b32b9
f Account for BOLT12 methods taking `RouteParamsConfig` arg
tnull May 21, 2025
b42393b
f Account for `async`'ified `ChangeDestinationSource`
tnull May 21, 2025
198f319
f Account for `PeerStorage` changes
tnull Jun 12, 2025
e92582c
f Account for Async bumping changes
tnull Jun 12, 2025
8a10706
f Reuse the same esplora-client again
tnull Jun 12, 2025
cb488ae
f Reuse `electrum-client`
tnull Jun 12, 2025
f5d36c3
f Account for changes in BOLT11 interface
tnull May 21, 2025
d5277f3
f Account for `CurrencyCode` changes
tnull Jun 23, 2025
3232202
f Account for `lightning::util::string` re-exports being dropped
tnull Jul 9, 2025
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
51 changes: 31 additions & 20 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,53 @@ panic = 'abort' # Abort on panic
default = []

[dependencies]
lightning = { version = "0.1.0", features = ["std"] }
lightning-types = { version = "0.2.0" }
lightning-invoice = { version = "0.33.0", features = ["std"] }
lightning-net-tokio = { version = "0.1.0" }
lightning-persister = { version = "0.1.0" }
lightning-background-processor = { version = "0.1.0", features = ["futures"] }
lightning-rapid-gossip-sync = { version = "0.1.0" }
lightning-block-sync = { version = "0.1.0", features = ["rpc-client", "rest-client", "tokio"] }
lightning-transaction-sync = { version = "0.1.0", features = ["esplora-async-https", "time", "electrum"] }
lightning-liquidity = { version = "0.1.0", features = ["std"] }
#lightning = { version = "0.1.0", features = ["std"] }
#lightning-types = { version = "0.2.0" }
#lightning-invoice = { version = "0.33.0", features = ["std"] }
#lightning-net-tokio = { version = "0.1.0" }
#lightning-persister = { version = "0.1.0" }
#lightning-background-processor = { version = "0.1.0" }
#lightning-rapid-gossip-sync = { version = "0.1.0" }
#lightning-block-sync = { version = "0.1.0", features = ["rest-client", "rpc-client", "tokio"] }
#lightning-transaction-sync = { version = "0.1.0", features = ["esplora-async-https", "time", "electrum"] }
#lightning-liquidity = { version = "0.1.0", features = ["std"] }
#lightning-macros = { version = "0.1.0" }

#lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["std"] }
#lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }
#lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["std"] }
#lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }
#lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }
#lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["futures"] }
#lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }
#lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }
#lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["rpc-client", "tokio"] }
#lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["rest-client", "rpc-client", "tokio"] }
#lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["esplora-async-https", "electrum", "time"] }
#lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }
#lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }

lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6", features = ["std"] }
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6" }
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6", features = ["std"] }
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6" }
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6" }
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6" }
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6" }
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6", features = ["rest-client", "rpc-client", "tokio"] }
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6", features = ["esplora-async-https", "electrum", "time"] }
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6" }
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6" }

#lightning = { path = "../rust-lightning/lightning", features = ["std"] }
#lightning-types = { path = "../rust-lightning/lightning-types" }
#lightning-invoice = { path = "../rust-lightning/lightning-invoice", features = ["std"] }
#lightning-net-tokio = { path = "../rust-lightning/lightning-net-tokio" }
#lightning-persister = { path = "../rust-lightning/lightning-persister" }
#lightning-background-processor = { path = "../rust-lightning/lightning-background-processor", features = ["futures"] }
#lightning-background-processor = { path = "../rust-lightning/lightning-background-processor" }
#lightning-rapid-gossip-sync = { path = "../rust-lightning/lightning-rapid-gossip-sync" }
#lightning-block-sync = { path = "../rust-lightning/lightning-block-sync", features = ["rpc-client", "tokio"] }
#lightning-block-sync = { path = "../rust-lightning/lightning-block-sync", features = ["rest-client", "rpc-client", "tokio"] }
#lightning-transaction-sync = { path = "../rust-lightning/lightning-transaction-sync", features = ["esplora-async-https", "electrum", "time"] }
#lightning-liquidity = { path = "../rust-lightning/lightning-liquidity", features = ["std"] }
#lightning-macros = { path = "../rust-lightning/lightning-macros" }

bdk_chain = { version = "0.23.0", default-features = false, features = ["std"] }
bdk_esplora = { version = "0.22.0", default-features = false, features = ["async-https-rustls", "tokio"]}
Expand All @@ -77,11 +92,6 @@ rand = "0.8.5"
chrono = { version = "0.4", default-features = false, features = ["clock"] }
tokio = { version = "1.37", default-features = false, features = [ "rt-multi-thread", "time", "sync", "macros" ] }
esplora-client = { version = "0.12", default-features = false, features = ["tokio", "async-https-rustls"] }

# FIXME: This was introduced to decouple the `bdk_esplora` and
# `lightning-transaction-sync` APIs. We should drop it as part of the upgrade
# to LDK 0.2.
esplora-client_0_11 = { package = "esplora-client", version = "0.11", default-features = false, features = ["tokio", "async-https-rustls"] }
electrum-client = { version = "0.23.1", default-features = true }
libc = "0.2"
uniffi = { version = "0.28.3", features = ["build"], optional = true }
Expand All @@ -96,8 +106,9 @@ prost = { version = "0.11.6", default-features = false}
winapi = { version = "0.3", features = ["winbase"] }

[dev-dependencies]
lightning = { version = "0.1.0", features = ["std", "_test_utils"] }
#lightning = { version = "0.1.0", features = ["std", "_test_utils"] }
#lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main", features = ["std", "_test_utils"] }
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "d67bd0fa4b62f80cd3d354e7db0ebe9f5d6954f6", features = ["std", "_test_utils"] }
#lightning = { path = "../rust-lightning/lightning", features = ["std", "_test_utils"] }
proptest = "1.0.0"
regex = "1.5.6"
Expand Down
76 changes: 35 additions & 41 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ dictionary Config {
sequence<PublicKey> trusted_peers_0conf;
u64 probing_liquidity_limit_multiplier;
AnchorChannelsConfig? anchor_channels_config;
SendingParameters? sending_parameters;
RouteParametersConfig? route_parameters;
};

dictionary AnchorChannelsConfig {
Expand Down Expand Up @@ -161,19 +161,19 @@ interface Node {

[Enum]
interface Bolt11InvoiceDescription {
Hash(string hash);
Direct(string description);
Hash(string hash);
Direct(string description);
};

interface Bolt11Payment {
[Throws=NodeError]
PaymentId send([ByRef]Bolt11Invoice invoice, SendingParameters? sending_parameters);
PaymentId send([ByRef]Bolt11Invoice invoice, RouteParametersConfig? route_parameters);
[Throws=NodeError]
PaymentId send_using_amount([ByRef]Bolt11Invoice invoice, u64 amount_msat, SendingParameters? sending_parameters);
PaymentId send_using_amount([ByRef]Bolt11Invoice invoice, u64 amount_msat, RouteParametersConfig? route_parameters);
[Throws=NodeError]
void send_probes([ByRef]Bolt11Invoice invoice);
void send_probes([ByRef]Bolt11Invoice invoice, RouteParametersConfig? route_parameters);
[Throws=NodeError]
void send_probes_using_amount([ByRef]Bolt11Invoice invoice, u64 amount_msat);
void send_probes_using_amount([ByRef]Bolt11Invoice invoice, u64 amount_msat, RouteParametersConfig? route_parameters);
[Throws=NodeError]
void claim_for_hash(PaymentHash payment_hash, u64 claimable_amount_msat, PaymentPreimage preimage);
[Throws=NodeError]
Expand Down Expand Up @@ -209,9 +209,9 @@ interface Bolt12Payment {

interface SpontaneousPayment {
[Throws=NodeError]
PaymentId send(u64 amount_msat, PublicKey node_id, SendingParameters? sending_parameters);
PaymentId send(u64 amount_msat, PublicKey node_id, RouteParametersConfig? route_parameters);
[Throws=NodeError]
PaymentId send_with_custom_tlvs(u64 amount_msat, PublicKey node_id, SendingParameters? sending_parameters, sequence<CustomTlvRecord> custom_tlvs);
PaymentId send_with_custom_tlvs(u64 amount_msat, PublicKey node_id, RouteParametersConfig? route_parameters, sequence<CustomTlvRecord> custom_tlvs);
[Throws=NodeError]
void send_probes(u64 amount_msat, PublicKey node_id);
};
Expand Down Expand Up @@ -246,7 +246,7 @@ interface LSPS1Liquidity {
[Throws=NodeError]
LSPS1OrderStatus request_channel(u64 lsp_balance_sat, u64 client_balance_sat, u32 channel_expiry_blocks, boolean announce_channel);
[Throws=NodeError]
LSPS1OrderStatus check_order_status(OrderId order_id);
LSPS1OrderStatus check_order_status(LSPS1OrderId order_id);
};

[Error]
Expand Down Expand Up @@ -447,11 +447,11 @@ dictionary PaymentDetails {
u64 latest_update_timestamp;
};

dictionary SendingParameters {
MaxTotalRoutingFeeLimit? max_total_routing_fee_msat;
u32? max_total_cltv_expiry_delta;
u8? max_path_count;
u8? max_channel_saturation_power_of_half;
dictionary RouteParametersConfig {
u64? max_total_routing_fee_msat;
u32 max_total_cltv_expiry_delta;
u8 max_path_count;
u8 max_channel_saturation_power_of_half;
};

dictionary CustomTlvRecord {
Expand All @@ -460,13 +460,13 @@ dictionary CustomTlvRecord {
};

dictionary LSPS1OrderStatus {
OrderId order_id;
OrderParameters order_params;
PaymentInfo payment_options;
ChannelOrderInfo? channel_state;
LSPS1OrderId order_id;
LSPS1OrderParams order_params;
LSPS1PaymentInfo payment_options;
LSPS1ChannelInfo? channel_state;
};

dictionary OrderParameters {
dictionary LSPS1OrderParams {
u64 lsp_balance_sat;
u64 client_balance_sat;
u16 required_channel_confirmations;
Expand All @@ -476,22 +476,22 @@ dictionary OrderParameters {
boolean announce_channel;
};

dictionary PaymentInfo {
Bolt11PaymentInfo? bolt11;
OnchainPaymentInfo? onchain;
dictionary LSPS1PaymentInfo {
LSPS1Bolt11PaymentInfo? bolt11;
LSPS1OnchainPaymentInfo? onchain;
};

dictionary Bolt11PaymentInfo {
PaymentState state;
DateTime expires_at;
dictionary LSPS1Bolt11PaymentInfo {
LSPS1PaymentState state;
LSPSDateTime expires_at;
u64 fee_total_sat;
u64 order_total_sat;
Bolt11Invoice invoice;
};

dictionary OnchainPaymentInfo {
PaymentState state;
DateTime expires_at;
dictionary LSPS1OnchainPaymentInfo {
LSPS1PaymentState state;
LSPSDateTime expires_at;
u64 fee_total_sat;
u64 order_total_sat;
Address address;
Expand All @@ -500,24 +500,18 @@ dictionary OnchainPaymentInfo {
Address? refund_onchain_address;
};

dictionary ChannelOrderInfo {
DateTime funded_at;
dictionary LSPS1ChannelInfo {
LSPSDateTime funded_at;
OutPoint funding_outpoint;
DateTime expires_at;
LSPSDateTime expires_at;
};

enum PaymentState {
enum LSPS1PaymentState {
"ExpectPayment",
"Paid",
"Refunded",
};

[Enum]
interface MaxTotalRoutingFeeLimit {
None ();
Some ( u64 amount_msat );
};

[NonExhaustive]
enum Network {
"Bitcoin",
Expand Down Expand Up @@ -852,7 +846,7 @@ typedef string UntrustedString;
typedef string NodeAlias;

[Custom]
typedef string OrderId;
typedef string LSPS1OrderId;

[Custom]
typedef string DateTime;
typedef string LSPSDateTime;
41 changes: 18 additions & 23 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use lightning::routing::router::DefaultRouter;
use lightning::routing::scoring::{
ProbabilisticScorer, ProbabilisticScoringDecayParameters, ProbabilisticScoringFeeParameters,
};
use lightning::sign::EntropySource;
use lightning::sign::{EntropySource, NodeSigner};

use lightning::util::persist::{
read_channel_monitors, CHANNEL_MANAGER_PERSISTENCE_KEY,
Expand Down Expand Up @@ -1201,15 +1201,6 @@ fn build_with_store_internal(

let runtime = Arc::new(RwLock::new(None));

// Initialize the ChainMonitor
let chain_monitor: Arc<ChainMonitor> = Arc::new(chainmonitor::ChainMonitor::new(
Some(Arc::clone(&chain_source)),
Arc::clone(&tx_broadcaster),
Arc::clone(&logger),
Arc::clone(&fee_estimator),
Arc::clone(&kv_store),
));

// Initialize the KeysManager
let cur_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).map_err(|e| {
log_error!(logger, "Failed to get current time: {}", e);
Expand All @@ -1225,6 +1216,19 @@ fn build_with_store_internal(
Arc::clone(&logger),
));

let peer_storage_key = keys_manager.get_peer_storage_key();

// Initialize the ChainMonitor
let chain_monitor: Arc<ChainMonitor> = Arc::new(chainmonitor::ChainMonitor::new(
Some(Arc::clone(&chain_source)),
Arc::clone(&tx_broadcaster),
Arc::clone(&logger),
Arc::clone(&fee_estimator),
Arc::clone(&kv_store),
Arc::clone(&keys_manager),
peer_storage_key,
));

// Initialize the network graph, scorer, and router
let network_graph =
match io::utils::read_network_graph(Arc::clone(&kv_store), Arc::clone(&logger)) {
Expand Down Expand Up @@ -1285,17 +1289,6 @@ fn build_with_store_internal(
};

let mut user_config = default_user_config(&config);
if liquidity_source_config.and_then(|lsc| lsc.lsps2_client.as_ref()).is_some() {
// Generally allow claiming underpaying HTLCs as the LSP will skim off some fee. We'll
// check that they don't take too much before claiming.
user_config.channel_config.accept_underpaying_htlcs = true;

// FIXME: When we're an LSPS2 client, set maximum allowed inbound HTLC value in flight
// to 100%. We should eventually be able to set this on a per-channel basis, but for
// now we just bump the default for all channels.
user_config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel =
100;
}

if liquidity_source_config.and_then(|lsc| lsc.lsps2_service.as_ref()).is_some() {
// If we act as an LSPS2 service, we need to to be able to intercept HTLCs and forward the
Expand Down Expand Up @@ -1373,8 +1366,8 @@ fn build_with_store_internal(

// Give ChannelMonitors to ChainMonitor
for (_blockhash, channel_monitor) in channel_monitors.into_iter() {
let funding_outpoint = channel_monitor.get_funding_txo().0;
chain_monitor.watch_channel(funding_outpoint, channel_monitor).map_err(|e| {
let channel_id = channel_monitor.channel_id();
chain_monitor.watch_channel(channel_id, channel_monitor).map_err(|e| {
log_error!(logger, "Failed to watch channel monitor: {:?}", e);
BuildError::InvalidChannelMonitor
})?;
Expand Down Expand Up @@ -1486,13 +1479,15 @@ fn build_with_store_internal(
as Arc<dyn RoutingMessageHandler + Sync + Send>,
onion_message_handler: Arc::clone(&onion_messenger),
custom_message_handler,
send_only_message_handler: Arc::clone(&chain_monitor),
},
GossipSync::Rapid(_) => MessageHandler {
chan_handler: Arc::clone(&channel_manager),
route_handler: Arc::new(IgnoringMessageHandler {})
as Arc<dyn RoutingMessageHandler + Sync + Send>,
onion_message_handler: Arc::clone(&onion_messenger),
custom_message_handler,
send_only_message_handler: Arc::clone(&chain_monitor),
},
GossipSync::None => {
unreachable!("We must always have a gossip sync!");
Expand Down
9 changes: 2 additions & 7 deletions src/chain/electrum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const ELECTRUM_CLIENT_TIMEOUT_SECS: u8 = 20;

pub(crate) struct ElectrumRuntimeClient {
electrum_client: Arc<ElectrumClient>,
bdk_electrum_client: Arc<BdkElectrumClient<ElectrumClient>>,
bdk_electrum_client: Arc<BdkElectrumClient<Arc<ElectrumClient>>>,
tx_sync: Arc<ElectrumSyncClient<Arc<Logger>>>,
runtime: Arc<tokio::runtime::Runtime>,
config: Arc<Config>,
Expand All @@ -67,12 +67,7 @@ impl ElectrumRuntimeClient {
Error::ConnectionFailed
})?,
);
let electrum_client_2 =
ElectrumClient::from_config(&server_url, electrum_config).map_err(|e| {
log_error!(logger, "Failed to connect to electrum server: {}", e);
Error::ConnectionFailed
})?;
let bdk_electrum_client = Arc::new(BdkElectrumClient::new(electrum_client_2));
let bdk_electrum_client = Arc::new(BdkElectrumClient::new(Arc::clone(&electrum_client)));
let tx_sync = Arc::new(
ElectrumSyncClient::new(server_url.clone(), Arc::clone(&logger)).map_err(|e| {
log_error!(logger, "Failed to connect to electrum server: {}", e);
Expand Down
12 changes: 3 additions & 9 deletions src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,17 +238,11 @@ impl ChainSource {
kv_store: Arc<DynStore>, config: Arc<Config>, logger: Arc<Logger>,
node_metrics: Arc<RwLock<NodeMetrics>>,
) -> Self {
// FIXME / TODO: We introduced this to make `bdk_esplora` work separately without updating
// `lightning-transaction-sync`. We should revert this as part of of the upgrade to LDK 0.2.
let mut client_builder_0_11 = esplora_client_0_11::Builder::new(&server_url);
client_builder_0_11 = client_builder_0_11.timeout(DEFAULT_ESPLORA_CLIENT_TIMEOUT_SECS);
let esplora_client_0_11 = client_builder_0_11.build_async().unwrap();
let tx_sync =
Arc::new(EsploraSyncClient::from_client(esplora_client_0_11, Arc::clone(&logger)));

let mut client_builder = esplora_client::Builder::new(&server_url);
client_builder = client_builder.timeout(DEFAULT_ESPLORA_CLIENT_TIMEOUT_SECS);
let esplora_client = client_builder.build_async().unwrap();
let tx_sync =
Arc::new(EsploraSyncClient::from_client(esplora_client.clone(), Arc::clone(&logger)));

let onchain_wallet_sync_status = Mutex::new(WalletSyncStatus::Completed);
let lightning_wallet_sync_status = Mutex::new(WalletSyncStatus::Completed);
Expand Down Expand Up @@ -496,7 +490,7 @@ impl ChainSource {
if let Some(worst_channel_monitor_block_hash) = chain_monitor
.list_monitors()
.iter()
.flat_map(|(txo, _)| chain_monitor.get_monitor(*txo))
.flat_map(|channel_id| chain_monitor.get_monitor(*channel_id))
.map(|m| m.current_best_block())
.min_by_key(|b| b.height)
.map(|b| b.block_hash)
Expand Down
Loading
Loading