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
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 0.7.0-rc.13 (Synonym Fork)
# 0.7.0-rc.14 (Synonym Fork)

## Bug Fixes
- Fixed duplicate payment events (`PaymentReceived`, `PaymentSuccessful`, `PaymentFailed`) being
Expand All @@ -13,10 +13,11 @@
- `RuntimeSyncIntervals::battery_saving()` preset (5min onchain, 2min lightning, 30min fees)
- Minimum 10-second interval enforced for all values
- Returns `BackgroundSyncNotEnabled` error if manual sync mode was configured at build time
- Optimized startup performance by parallelizing VSS reads:
- Optimized startup performance by parallelizing VSS reads and caching network graph locally:
- Parallelized early reads (node_metrics, payments, wallet)
- Parallelized channel monitors and scorer reads
- Parallelized tail reads (output_sweeper, event_queue, peer_store)
- Added local caching for network graph to avoid slow VSS reads on startup
- Added `claimable_on_close_sats` field to `ChannelDetails` struct. This field contains the
amount (in satoshis) that would be claimable if the channel were force-closed now, computed
from the channel monitor's `ClaimableOnChannelClose` balance. Returns `None` if no monitor
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ldk-node"
version = "0.7.0-rc.13"
version = "0.7.0-rc.14"
authors = ["Elias Rohrer <dev@tnull.de>"]
homepage = "https://lightningdevkit.org/"
license = "MIT OR Apache-2.0"
Expand Down
9 changes: 5 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

import PackageDescription

let tag = "v0.7.0-rc.13"
let checksum = "31d9d85d9a5d48fa47cebaf24aad3710432ea3368b35ba19efda582768d48265"
let tag = "v0.7.0-rc.14"
let checksum = "117aa66af8e95212856be9aa0a99c1b59afc87e2b798a5e2ec3d33f8c6105cab"
let url = "https://github.com/synonymdev/ldk-node/releases/download/\(tag)/LDKNodeFFI.xcframework.zip"

let package = Package(
Expand All @@ -27,8 +27,9 @@ let package = Package(
),
.binaryTarget(
name: "LDKNodeFFI",
url: url,
checksum: checksum
// url: url,
// checksum: checksum
path: "./bindings/swift/LDKNodeFFI.xcframework"
)
]
)
2 changes: 1 addition & 1 deletion bindings/kotlin/ldk-node-android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx1536m
android.useAndroidX=true
android.enableJetifier=true
kotlin.code.style=official
libraryVersion=0.7.0-rc.13
libraryVersion=0.7.0-rc.14
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion bindings/kotlin/ldk-node-jvm/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
org.gradle.jvmargs=-Xmx1536m
kotlin.code.style=official
libraryVersion=0.7.0-rc.13
libraryVersion=0.7.0-rc.14
2 changes: 1 addition & 1 deletion bindings/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "ldk_node"
version = "0.7.0-rc.13"
version = "0.7.0-rc.14"
authors = [
{ name="Elias Rohrer", email="dev@tnull.de" },
]
Expand Down
84 changes: 62 additions & 22 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::collections::HashMap;
use std::convert::TryInto;
use std::default::Default;
use std::path::PathBuf;
use std::sync::atomic::AtomicU32;
use std::sync::{Arc, Mutex, Once, RwLock};
use std::time::SystemTime;
use std::{fmt, fs};
Expand Down Expand Up @@ -56,9 +57,10 @@ use crate::connection::ConnectionManager;
use crate::event::EventQueue;
use crate::fee_estimator::OnchainFeeEstimator;
use crate::gossip::GossipSource;
use crate::io::local_graph_store::read_local_graph_cache;
use crate::io::sqlite_store::SqliteStore;
use crate::io::utils::{
read_node_metrics, read_payments_async, write_node_metrics,
read_network_graph, read_node_metrics, read_payments_async, write_node_metrics,
EXTERNAL_PATHFINDING_SCORES_CACHE_KEY,
};
use crate::io::vss_store::VssStore;
Expand Down Expand Up @@ -1528,18 +1530,60 @@ fn build_with_store_internal(
);
}

// Initialize the network graph
let network_graph =
match io::utils::read_network_graph(Arc::clone(&kv_store), Arc::clone(&logger)) {
Ok(graph) => Arc::new(graph),
Err(e) => {
if e.kind() == std::io::ErrorKind::NotFound {
Arc::new(Graph::new(config.network.into(), Arc::clone(&logger)))
} else {
log_error!(logger, "Failed to read network graph from store: {}", e);
return Err(BuildError::ReadFailed);
// Initialize the network graph from local cache, with VSS fallback for migration.
let (network_graph, local_rgs_timestamp) =
match read_local_graph_cache(&config.storage_dir_path, Arc::clone(&logger)) {
Ok(cache_data) => {
log_trace!(
logger,
"Loaded network graph from local cache with RGS timestamp {}",
cache_data.rgs_timestamp
);
(Arc::new(cache_data.graph), Arc::new(AtomicU32::new(cache_data.rgs_timestamp)))
},
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
// Local cache doesn't exist, try VSS as fallback for migration.
log_trace!(
logger,
"Local graph cache not found, trying VSS fallback for migration"
);
match read_network_graph(Arc::clone(&kv_store), Arc::clone(&logger)) {
Ok(graph) => {
let timestamp =
node_metrics.read().unwrap().latest_rgs_snapshot_timestamp.unwrap_or(0);
log_info!(
logger,
"Migrated network graph from VSS to local cache (RGS timestamp: {})",
timestamp
);
(Arc::new(graph), Arc::new(AtomicU32::new(timestamp)))
},
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
// New user, create empty graph. RGS will download full snapshot.
log_trace!(logger, "No network graph found, creating empty graph");
(
Arc::new(Graph::new(config.network.into(), Arc::clone(&logger))),
Arc::new(AtomicU32::new(0)),
)
},
Err(e) => {
log_error!(logger, "Failed to read network graph from VSS: {}", e);
return Err(BuildError::ReadFailed);
},
}
},
Err(e) => {
// Local cache is invalid. Start fresh to avoid graph/timestamp mismatch.
log_error!(
logger,
"Local graph cache invalid: {}, starting fresh with empty graph",
e
);
(
Arc::new(Graph::new(config.network.into(), Arc::clone(&logger))),
Arc::new(AtomicU32::new(0)),
)
},
};

// Read channel monitors and scorer data in parallel
Expand Down Expand Up @@ -1804,17 +1848,12 @@ fn build_with_store_internal(
}
p2p_source
},
GossipSourceConfig::RapidGossipSync(rgs_server) => {
let latest_sync_timestamp =
node_metrics.read().unwrap().latest_rgs_snapshot_timestamp.unwrap_or(0);

Arc::new(GossipSource::new_rgs(
rgs_server.clone(),
latest_sync_timestamp,
Arc::clone(&network_graph),
Arc::clone(&logger),
))
},
GossipSourceConfig::RapidGossipSync(rgs_server) => Arc::new(GossipSource::new_rgs(
rgs_server.clone(),
Arc::clone(&local_rgs_timestamp),
Arc::clone(&network_graph),
Arc::clone(&logger),
)),
};

let (liquidity_source, custom_message_handler) =
Expand Down Expand Up @@ -2075,6 +2114,7 @@ fn build_with_store_internal(
om_mailbox,
async_payments_role,
runtime_sync_intervals: Arc::new(RwLock::new(RuntimeSyncIntervals::default())),
local_rgs_timestamp,
})
}

Expand Down
5 changes: 2 additions & 3 deletions src/gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub(crate) enum GossipSource {
RapidGossipSync {
gossip_sync: Arc<RapidGossipSync>,
server_url: String,
latest_sync_timestamp: AtomicU32,
latest_sync_timestamp: Arc<AtomicU32>,
logger: Arc<Logger>,
},
}
Expand All @@ -43,11 +43,10 @@ impl GossipSource {
}

pub fn new_rgs(
server_url: String, latest_sync_timestamp: u32, network_graph: Arc<Graph>,
server_url: String, latest_sync_timestamp: Arc<AtomicU32>, network_graph: Arc<Graph>,
logger: Arc<Logger>,
) -> Self {
let gossip_sync = Arc::new(RapidGossipSync::new(network_graph, Arc::clone(&logger)));
let latest_sync_timestamp = AtomicU32::new(latest_sync_timestamp);
Self::RapidGossipSync { gossip_sync, server_url, latest_sync_timestamp, logger }
}

Expand Down
Loading