Skip to content
Open
4 changes: 2 additions & 2 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout source code
uses: actions/checkout@v3
uses: actions/checkout@v6
- name: Run security audit
uses: rustsec/audit-check@v1.4.1
uses: rustsec/audit-check@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
6 changes: 3 additions & 3 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ jobs:
TOOLCHAIN: stable
steps:
- name: Checkout source code
uses: actions/checkout@v3
uses: actions/checkout@v6
- name: Install Rust toolchain
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain stable
rustup override set stable
- name: Enable caching for bitcoind
id: cache-bitcoind
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
key: bitcoind-29.0-${{ runner.os }}-${{ runner.arch }}
- name: Enable caching for electrs
id: cache-electrs
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: bin/electrs-${{ runner.os }}-${{ runner.arch }}
key: electrs-${{ runner.os }}-${{ runner.arch }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cln-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Install dependencies
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/cron-weekly-rustfmt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
name: Nightly rustfmt
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt
Expand All @@ -23,7 +23,7 @@ jobs:
- name: Get the current date
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
uses: peter-evans/create-pull-request@v8
with:
author: Fmt Bot <bot@example.com>
title: Automated nightly rustfmt (${{ env.date }})
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/kotlin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up JDK
uses: actions/setup-java@v3
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 11
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lnd-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Check and install CMake if needed
# lnd_grpc_rust (via prost-build v0.10.4) requires CMake >= 3.5 but is incompatible with CMake >= 4.0.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v7
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout source code
uses: actions/checkout@v3
uses: actions/checkout@v6
- name: Install Rust ${{ matrix.toolchain }} toolchain
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain ${{ matrix.toolchain }}
Expand All @@ -50,13 +50,13 @@ jobs:
run: echo "RUSTFLAGS=-D warnings" >> "$GITHUB_ENV"
- name: Enable caching for bitcoind
id: cache-bitcoind
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: bin/bitcoind-${{ runner.os }}-${{ runner.arch }}
key: bitcoind-29.0-${{ runner.os }}-${{ runner.arch }}
- name: Enable caching for electrs
id: cache-electrs
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: bin/electrs-${{ runner.os }}-${{ runner.arch }}
key: electrs-${{ runner.os }}-${{ runner.arch }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/semver.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Check SemVer
uses: obi1kenobi/cargo-semver-checks-action@v2
2 changes: 1 addition & 1 deletion .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set default Rust version to stable
run: rustup default stable
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/vss-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v6
with:
path: ldk-node
- name: Checkout VSS
uses: actions/checkout@v3
uses: actions/checkout@v6
with:
repository: lightningdevkit/vss-server
path: vss-server
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/vss-no-auth-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v6
with:
path: ldk-node
- name: Checkout VSS
uses: actions/checkout@v3
uses: actions/checkout@v6
with:
repository: lightningdevkit/vss-server
path: vss-server
Expand Down
26 changes: 13 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ default = []
#lightning-liquidity = { version = "0.2.0", features = ["std"] }
#lightning-macros = { version = "0.2.0" }

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

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 Down Expand Up @@ -79,13 +79,13 @@ async-trait = { version = "0.1", default-features = false }
vss-client = { package = "vss-client-ng", version = "0.5" }
prost = { version = "0.11.6", default-features = false}
#bitcoin-payment-instructions = { version = "0.6" }
bitcoin-payment-instructions = { git = "https://github.com/joostjager/bitcoin-payment-instructions", branch = "ldk-dcf0c203e166da2348bef12b2e5eff4a250cdec7" }
bitcoin-payment-instructions = { git = "https://github.com/jkczyz/bitcoin-payment-instructions", rev = "a7b32d5fded9bb45f73bf82e6d7187adf705171c" }

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winbase"] }

[dev-dependencies]
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "dcf0c203e166da2348bef12b2e5eff4a250cdec7", features = ["std", "_test_utils"] }
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "38a62c32454d3eac22578144c479dbf9a6d9bff6", features = ["std", "_test_utils"] }
rand = { version = "0.9.2", default-features = false, features = ["std", "thread_rng", "os_rng"] }
proptest = "1.0.0"
regex = "1.5.6"
Expand Down
4 changes: 4 additions & 0 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ interface Node {
[Throws=NodeError]
UserChannelId open_announced_channel_with_all(PublicKey node_id, SocketAddress address, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
[Throws=NodeError]
UserChannelId open_0reserve_channel(PublicKey node_id, SocketAddress address, u64 channel_amount_sats, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
[Throws=NodeError]
UserChannelId open_0reserve_channel_with_all(PublicKey node_id, SocketAddress address, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
[Throws=NodeError]
void splice_in([ByRef]UserChannelId user_channel_id, PublicKey counterparty_node_id, u64 splice_amount_sats);
[Throws=NodeError]
void splice_in_with_all([ByRef]UserChannelId user_channel_id, PublicKey counterparty_node_id);
Expand Down
73 changes: 72 additions & 1 deletion src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ use crate::event::EventQueue;
use crate::fee_estimator::OnchainFeeEstimator;
use crate::gossip::GossipSource;
use crate::io::sqlite_store::SqliteStore;
use crate::io::tier_store::TierStore;
use crate::io::utils::{
read_event_queue, read_external_pathfinding_scores_from_cache, read_network_graph,
read_node_metrics, read_output_sweeper, read_payments, read_peer_info, read_pending_payments,
Expand Down Expand Up @@ -151,6 +152,21 @@ impl std::fmt::Debug for LogWriterConfig {
}
}

#[derive(Default)]
struct TierStoreConfig {
ephemeral: Option<Arc<DynStore>>,
backup: Option<Arc<DynStore>>,
}

impl std::fmt::Debug for TierStoreConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TierStoreConfig")
.field("ephemeral", &self.ephemeral.as_ref().map(|_| "Arc<DynStore>"))
.field("backup", &self.backup.as_ref().map(|_| "Arc<DynStore>"))
.finish()
}
}

/// An error encountered during building a [`Node`].
///
/// [`Node`]: crate::Node
Expand Down Expand Up @@ -278,6 +294,7 @@ pub struct NodeBuilder {
liquidity_source_config: Option<LiquiditySourceConfig>,
log_writer_config: Option<LogWriterConfig>,
async_payments_role: Option<AsyncPaymentsRole>,
tier_store_config: Option<TierStoreConfig>,
runtime_handle: Option<tokio::runtime::Handle>,
pathfinding_scores_sync_config: Option<PathfindingScoresSyncConfig>,
recovery_mode: bool,
Expand All @@ -296,6 +313,7 @@ impl NodeBuilder {
let gossip_source_config = None;
let liquidity_source_config = None;
let log_writer_config = None;
let tier_store_config = None;
let runtime_handle = None;
let pathfinding_scores_sync_config = None;
let recovery_mode = false;
Expand All @@ -305,6 +323,7 @@ impl NodeBuilder {
gossip_source_config,
liquidity_source_config,
log_writer_config,
tier_store_config,
runtime_handle,
async_payments_role: None,
pathfinding_scores_sync_config,
Expand Down Expand Up @@ -614,6 +633,36 @@ impl NodeBuilder {
self
}

/// Configures the backup store for local disaster recovery.
///
/// When building with tiered storage, this store receives a second durable
/// copy of data written to the primary store.
///
/// Writes and removals for primary-backed data only succeed once both the
/// primary and backup stores complete successfully.
///
/// If not set, durable data will be stored only in the primary store.
#[allow(dead_code)] // Used by subsequent FFI/test integration commits.
pub fn set_backup_store(&mut self, backup_store: Arc<DynStore>) -> &mut Self {
let tier_store_config = self.tier_store_config.get_or_insert(TierStoreConfig::default());
tier_store_config.backup = Some(backup_store);
self
}

/// Configures the ephemeral store for non-critical, frequently-accessed data.
///
/// When building with tiered storage, this store is used for ephemeral data like
/// the network graph and scorer data to reduce latency for reads. Data stored here
/// can be rebuilt if lost.
///
/// If not set, non-critical data will be stored in the primary store.
#[allow(dead_code)] // Used by subsequent FFI/test integration commits.
pub fn set_ephemeral_store(&mut self, ephemeral_store: Arc<DynStore>) -> &mut Self {
let tier_store_config = self.tier_store_config.get_or_insert(TierStoreConfig::default());
tier_store_config.ephemeral = Some(ephemeral_store);
self
}

/// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
/// previously configured.
pub fn build(&self, node_entropy: NodeEntropy) -> Result<Node, BuildError> {
Expand Down Expand Up @@ -762,8 +811,23 @@ impl NodeBuilder {
}

/// Builds a [`Node`] instance according to the options previously configured.
///
/// The provided `kv_store` will be used as the primary storage backend. Optionally,
/// an ephemeral store for frequently-accessed non-critical data (e.g., network graph, scorer)
/// and a backup store for local disaster recovery can be configured via
/// [`set_ephemeral_store`] and [`set_backup_store`].
///
/// [`set_ephemeral_store`]: Self::set_ephemeral_store
/// [`set_backup_store`]: Self::set_backup_store
pub fn build_with_store<S: SyncAndAsyncKVStore + Send + Sync + 'static>(
&self, node_entropy: NodeEntropy, kv_store: S,
) -> Result<Node, BuildError> {
let primary_store: Arc<DynStore> = Arc::new(DynStoreWrapper(kv_store));
self.build_with_dynstore(node_entropy, primary_store)
}

fn build_with_dynstore(
&self, node_entropy: NodeEntropy, primary_store: Arc<DynStore>,
) -> Result<Node, BuildError> {
let logger = setup_logger(&self.log_writer_config, &self.config)?;

Expand All @@ -776,6 +840,13 @@ impl NodeBuilder {
})?)
};

let ts_config = self.tier_store_config.as_ref();
let mut tier_store = TierStore::new(primary_store, Arc::clone(&logger));
if let Some(config) = ts_config {
config.ephemeral.as_ref().map(|s| tier_store.set_ephemeral_store(Arc::clone(s)));
config.backup.as_ref().map(|s| tier_store.set_backup_store(Arc::clone(s)));
}

let seed_bytes = node_entropy.to_seed_bytes();
let config = Arc::new(self.config.clone());

Expand All @@ -790,7 +861,7 @@ impl NodeBuilder {
seed_bytes,
runtime,
logger,
Arc::new(DynStoreWrapper(kv_store)),
Arc::new(DynStoreWrapper(tier_store)),
)
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use lightning::events::{
ReplayEvent,
};
use lightning::impl_writeable_tlv_based_enum;
use lightning::ln::channelmanager::PaymentId;
use lightning::ln::channelmanager::{PaymentId, TrustedChannelFeatures};
use lightning::ln::types::ChannelId;
use lightning::routing::gossip::NodeId;
use lightning::sign::EntropySource;
Expand Down Expand Up @@ -1285,10 +1285,11 @@ where
}
}
let res = if allow_0conf {
self.channel_manager.accept_inbound_channel_from_trusted_peer_0conf(
self.channel_manager.accept_inbound_channel_from_trusted_peer(
&temporary_channel_id,
&counterparty_node_id,
user_channel_id,
TrustedChannelFeatures::ZeroConf,
channel_override_config,
)
} else {
Expand Down
Loading