Skip to content

Commit 122fd00

Browse files
committed
Expose onchain balances via BalanceDetails
1 parent 28d5d6b commit 122fd00

File tree

7 files changed

+57
-51
lines changed

7 files changed

+57
-51
lines changed

bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt

+8-8
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,10 @@ class LibraryTest {
162162
node1.syncWallets()
163163
node2.syncWallets()
164164

165-
val spendableBalance1 = node1.spendableOnchainBalanceSats()
166-
val spendableBalance2 = node2.spendableOnchainBalanceSats()
167-
val totalBalance1 = node1.totalOnchainBalanceSats()
168-
val totalBalance2 = node2.totalOnchainBalanceSats()
165+
val spendableBalance1 = node1.listBalances().spendableOnchainBalanceSats
166+
val spendableBalance2 = node2.listBalances().spendableOnchainBalanceSats
167+
val totalBalance1 = node1.listBalances().totalOnchainBalanceSats
168+
val totalBalance2 = node2.listBalances().totalOnchainBalanceSats
169169
println("Spendable balance 1: $spendableBalance1")
170170
println("Spendable balance 2: $spendableBalance1")
171171
println("Total balance 1: $totalBalance1")
@@ -199,8 +199,8 @@ class LibraryTest {
199199
node1.syncWallets()
200200
node2.syncWallets()
201201

202-
val spendableBalance1AfterOpen = node1.spendableOnchainBalanceSats()
203-
val spendableBalance2AfterOpen = node2.spendableOnchainBalanceSats()
202+
val spendableBalance1AfterOpen = node1.listBalances().spendableOnchainBalanceSats
203+
val spendableBalance2AfterOpen = node2.listBalances().spendableOnchainBalanceSats
204204
println("Spendable balance 1 after open: $spendableBalance1AfterOpen")
205205
println("Spendable balance 2 after open: $spendableBalance2AfterOpen")
206206
assert(spendableBalance1AfterOpen > 49000u)
@@ -256,8 +256,8 @@ class LibraryTest {
256256
node1.syncWallets()
257257
node2.syncWallets()
258258

259-
val spendableBalance1AfterClose = node1.spendableOnchainBalanceSats()
260-
val spendableBalance2AfterClose = node2.spendableOnchainBalanceSats()
259+
val spendableBalance1AfterClose = node1.listBalances().spendableOnchainBalanceSats
260+
val spendableBalance2AfterClose = node2.listBalances().spendableOnchainBalanceSats
261261
println("Spendable balance 1 after close: $spendableBalance1AfterClose")
262262
println("Spendable balance 2 after close: $spendableBalance2AfterClose")
263263
assert(spendableBalance1AfterClose > 95000u)

bindings/ldk_node.udl

+2-4
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@ interface LDKNode {
5353
[Throws=NodeError]
5454
Txid send_all_to_onchain_address([ByRef]Address address);
5555
[Throws=NodeError]
56-
u64 spendable_onchain_balance_sats();
57-
[Throws=NodeError]
58-
u64 total_onchain_balance_sats();
59-
[Throws=NodeError]
6056
void connect(PublicKey node_id, SocketAddress address, boolean persist);
6157
[Throws=NodeError]
6258
void disconnect(PublicKey node_id);
@@ -239,6 +235,8 @@ interface LightningBalance {
239235
};
240236

241237
dictionary BalanceDetails {
238+
u64 total_onchain_balance_sats;
239+
u64 spendable_onchain_balance_sats;
242240
u64 total_lightning_balance_sats;
243241
sequence<LightningBalance> lightning_balances;
244242
};

bindings/python/src/ldk_node/test_ldk_node.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ def test_channel_full_cycle(self):
138138
node_1.sync_wallets()
139139
node_2.sync_wallets()
140140

141-
spendable_balance_1 = node_1.spendable_onchain_balance_sats()
142-
spendable_balance_2 = node_2.spendable_onchain_balance_sats()
143-
total_balance_1 = node_1.total_onchain_balance_sats()
144-
total_balance_2 = node_2.total_onchain_balance_sats()
141+
spendable_balance_1 = node_1.list_balances().spendable_onchain_balance_sats
142+
spendable_balance_2 = node_2.list_balances().spendable_onchain_balance_sats
143+
total_balance_1 = node_1.list_balances().total_onchain_balance_sats
144+
total_balance_2 = node_2.list_balances().total_onchain_balance_sats
145145

146146
print("SPENDABLE 1:", spendable_balance_1)
147147
self.assertEqual(spendable_balance_1, 100000)
@@ -215,10 +215,10 @@ def test_channel_full_cycle(self):
215215
node_1.sync_wallets()
216216
node_2.sync_wallets()
217217

218-
spendable_balance_after_close_1 = node_1.spendable_onchain_balance_sats()
218+
spendable_balance_after_close_1 = node_1.list_balances().spendable_onchain_balance_sats
219219
assert spendable_balance_after_close_1 > 95000
220220
assert spendable_balance_after_close_1 < 100000
221-
spendable_balance_after_close_2 = node_2.spendable_onchain_balance_sats()
221+
spendable_balance_after_close_2 = node_2.list_balances().spendable_onchain_balance_sats
222222
self.assertEqual(spendable_balance_after_close_2, 102500)
223223

224224
# Stop nodes

src/balance.rs

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ use lightning::ln::{ChannelId, PaymentHash, PaymentPreimage};
77
/// [`Node::list_balances`]: crate::Node::list_balances
88
#[derive(Debug, Clone)]
99
pub struct BalanceDetails {
10+
/// The total balance of our on-chain wallet.
11+
pub total_onchain_balance_sats: u64,
12+
/// The currently spendable balance of our on-chain wallet.
13+
pub spendable_onchain_balance_sats: u64,
1014
/// The total balance that we would be able to claim across all our Lightning channels.
1115
pub total_lightning_balance_sats: u64,
1216
/// A detailed list of all known balances.

src/lib.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -853,16 +853,6 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
853853
Ok(funding_address)
854854
}
855855

856-
/// Retrieve the currently spendable on-chain balance in satoshis.
857-
pub fn spendable_onchain_balance_sats(&self) -> Result<u64, Error> {
858-
Ok(self.wallet.get_balance().map(|bal| bal.get_spendable())?)
859-
}
860-
861-
/// Retrieve the current total on-chain balance in satoshis.
862-
pub fn total_onchain_balance_sats(&self) -> Result<u64, Error> {
863-
Ok(self.wallet.get_balance().map(|bal| bal.get_total())?)
864-
}
865-
866856
/// Send an on-chain payment to the given address.
867857
pub fn send_to_onchain_address(
868858
&self, address: &bitcoin::Address, amount_sats: u64,
@@ -1558,6 +1548,12 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
15581548

15591549
/// Retrieves an overview of all known balances.
15601550
pub fn list_balances(&self) -> BalanceDetails {
1551+
let (total_onchain_balance_sats, spendable_onchain_balance_sats) = self
1552+
.wallet
1553+
.get_balance()
1554+
.map(|bal| (bal.get_total(), bal.get_spendable()))
1555+
.unwrap_or((0, 0));
1556+
15611557
let mut total_lightning_balance_sats = 0;
15621558
let mut lightning_balances = Vec::new();
15631559
for funding_txo in self.chain_monitor.list_monitors() {
@@ -1583,7 +1579,12 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
15831579
}
15841580
}
15851581

1586-
BalanceDetails { total_lightning_balance_sats, lightning_balances }
1582+
BalanceDetails {
1583+
total_onchain_balance_sats,
1584+
spendable_onchain_balance_sats,
1585+
total_lightning_balance_sats,
1586+
lightning_balances,
1587+
}
15871588
}
15881589

15891590
/// Retrieves all payments that match the given predicate.

tests/common.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,8 @@ pub(crate) fn do_channel_full_cycle<K: KVStore + Sync + Send, E: ElectrumApi>(
333333
);
334334
node_a.sync_wallets().unwrap();
335335
node_b.sync_wallets().unwrap();
336-
assert_eq!(node_a.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
337-
assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
336+
assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
337+
assert_eq!(node_b.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
338338

339339
// Check we haven't got any events yet
340340
assert_eq!(node_a.next_event(), None);
@@ -371,9 +371,9 @@ pub(crate) fn do_channel_full_cycle<K: KVStore + Sync + Send, E: ElectrumApi>(
371371
let onchain_fee_buffer_sat = 1500;
372372
let node_a_upper_bound_sat = premine_amount_sat - funding_amount_sat;
373373
let node_a_lower_bound_sat = premine_amount_sat - funding_amount_sat - onchain_fee_buffer_sat;
374-
assert!(node_a.spendable_onchain_balance_sats().unwrap() < node_a_upper_bound_sat);
375-
assert!(node_a.spendable_onchain_balance_sats().unwrap() > node_a_lower_bound_sat);
376-
assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
374+
assert!(node_a.list_balances().spendable_onchain_balance_sats < node_a_upper_bound_sat);
375+
assert!(node_a.list_balances().spendable_onchain_balance_sats > node_a_lower_bound_sat);
376+
assert_eq!(node_b.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
377377

378378
expect_channel_ready_event!(node_a, node_b.node_id());
379379

@@ -539,10 +539,13 @@ pub(crate) fn do_channel_full_cycle<K: KVStore + Sync + Send, E: ElectrumApi>(
539539
let node_a_upper_bound_sat =
540540
(premine_amount_sat - funding_amount_sat) + (funding_amount_sat - sum_of_all_payments_sat);
541541
let node_a_lower_bound_sat = node_a_upper_bound_sat - onchain_fee_buffer_sat;
542-
assert!(node_a.spendable_onchain_balance_sats().unwrap() > node_a_lower_bound_sat);
543-
assert!(node_a.spendable_onchain_balance_sats().unwrap() < node_a_upper_bound_sat);
542+
assert!(node_a.list_balances().spendable_onchain_balance_sats > node_a_lower_bound_sat);
543+
assert!(node_a.list_balances().spendable_onchain_balance_sats < node_a_upper_bound_sat);
544544
let expected_final_amount_node_b_sat = premine_amount_sat + sum_of_all_payments_sat;
545-
assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), expected_final_amount_node_b_sat);
545+
assert_eq!(
546+
node_b.list_balances().spendable_onchain_balance_sats,
547+
expected_final_amount_node_b_sat
548+
);
546549

547550
// Check we handled all events
548551
assert_eq!(node_a.next_event(), None);

tests/integration_tests_rust.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ fn channel_open_fails_when_funds_insufficient() {
4444
);
4545
node_a.sync_wallets().unwrap();
4646
node_b.sync_wallets().unwrap();
47-
assert_eq!(node_a.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
48-
assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
47+
assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
48+
assert_eq!(node_b.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
4949

5050
println!("\nA -- connect_open_channel -> B");
5151
assert_eq!(
@@ -88,7 +88,7 @@ fn multi_hop_sending() {
8888

8989
for n in &nodes {
9090
n.sync_wallets().unwrap();
91-
assert_eq!(n.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
91+
assert_eq!(n.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
9292
assert_eq!(n.next_event(), None);
9393
}
9494

@@ -168,7 +168,7 @@ fn start_stop_reinit() {
168168

169169
let funding_address = node.new_onchain_address().unwrap();
170170

171-
assert_eq!(node.total_onchain_balance_sats().unwrap(), 0);
171+
assert_eq!(node.list_balances().total_onchain_balance_sats, 0);
172172

173173
let expected_amount = Amount::from_sat(100000);
174174
premine_and_distribute_funds(
@@ -179,7 +179,7 @@ fn start_stop_reinit() {
179179
);
180180

181181
node.sync_wallets().unwrap();
182-
assert_eq!(node.spendable_onchain_balance_sats().unwrap(), expected_amount.to_sat());
182+
assert_eq!(node.list_balances().spendable_onchain_balance_sats, expected_amount.to_sat());
183183

184184
let log_file_symlink = format!("{}/logs/ldk_node_latest.log", config.clone().storage_dir_path);
185185
assert!(std::path::Path::new(&log_file_symlink).is_symlink());
@@ -202,13 +202,13 @@ fn start_stop_reinit() {
202202
assert_eq!(reinitialized_node.node_id(), expected_node_id);
203203

204204
assert_eq!(
205-
reinitialized_node.spendable_onchain_balance_sats().unwrap(),
205+
reinitialized_node.list_balances().spendable_onchain_balance_sats,
206206
expected_amount.to_sat()
207207
);
208208

209209
reinitialized_node.sync_wallets().unwrap();
210210
assert_eq!(
211-
reinitialized_node.spendable_onchain_balance_sats().unwrap(),
211+
reinitialized_node.list_balances().spendable_onchain_balance_sats,
212212
expected_amount.to_sat()
213213
);
214214

@@ -232,7 +232,7 @@ fn onchain_spend_receive() {
232232

233233
node_a.sync_wallets().unwrap();
234234
node_b.sync_wallets().unwrap();
235-
assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), 100000);
235+
assert_eq!(node_b.list_balances().spendable_onchain_balance_sats, 100000);
236236

237237
assert_eq!(Err(NodeError::InsufficientFunds), node_a.send_to_onchain_address(&addr_b, 1000));
238238

@@ -243,9 +243,9 @@ fn onchain_spend_receive() {
243243
node_a.sync_wallets().unwrap();
244244
node_b.sync_wallets().unwrap();
245245

246-
assert_eq!(node_a.spendable_onchain_balance_sats().unwrap(), 1000);
247-
assert!(node_b.spendable_onchain_balance_sats().unwrap() > 98000);
248-
assert!(node_b.spendable_onchain_balance_sats().unwrap() < 100000);
246+
assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, 1000);
247+
assert!(node_b.list_balances().spendable_onchain_balance_sats > 98000);
248+
assert!(node_b.list_balances().spendable_onchain_balance_sats < 100000);
249249

250250
let addr_b = node_b.new_onchain_address().unwrap();
251251
let txid = node_a.send_all_to_onchain_address(&addr_b).unwrap();
@@ -255,9 +255,9 @@ fn onchain_spend_receive() {
255255
node_a.sync_wallets().unwrap();
256256
node_b.sync_wallets().unwrap();
257257

258-
assert_eq!(node_a.total_onchain_balance_sats().unwrap(), 0);
259-
assert!(node_b.spendable_onchain_balance_sats().unwrap() > 99000);
260-
assert!(node_b.spendable_onchain_balance_sats().unwrap() < 100000);
258+
assert_eq!(node_a.list_balances().total_onchain_balance_sats, 0);
259+
assert!(node_b.list_balances().spendable_onchain_balance_sats > 99000);
260+
assert!(node_b.list_balances().spendable_onchain_balance_sats < 100000);
261261
}
262262

263263
#[test]

0 commit comments

Comments
 (0)