Skip to content

Commit

Permalink
Expose onchain balances via BalanceDetails
Browse files Browse the repository at this point in the history
  • Loading branch information
tnull committed Feb 15, 2024
1 parent eeb6861 commit 8495bc7
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ class LibraryTest {
node1.syncWallets()
node2.syncWallets()

val spendableBalance1 = node1.spendableOnchainBalanceSats()
val spendableBalance2 = node2.spendableOnchainBalanceSats()
val totalBalance1 = node1.totalOnchainBalanceSats()
val totalBalance2 = node2.totalOnchainBalanceSats()
val spendableBalance1 = node1.listBalances().spendableOnchainBalanceSats
val spendableBalance2 = node2.listBalances().spendableOnchainBalanceSats
val totalBalance1 = node1.listBalances().totalOnchainBalanceSats
val totalBalance2 = node2.listBalances().totalOnchainBalanceSats
println("Spendable balance 1: $spendableBalance1")
println("Spendable balance 2: $spendableBalance1")
println("Total balance 1: $totalBalance1")
Expand Down Expand Up @@ -199,8 +199,8 @@ class LibraryTest {
node1.syncWallets()
node2.syncWallets()

val spendableBalance1AfterOpen = node1.spendableOnchainBalanceSats()
val spendableBalance2AfterOpen = node2.spendableOnchainBalanceSats()
val spendableBalance1AfterOpen = node1.listBalances().spendableOnchainBalanceSats
val spendableBalance2AfterOpen = node2.listBalances().spendableOnchainBalanceSats
println("Spendable balance 1 after open: $spendableBalance1AfterOpen")
println("Spendable balance 2 after open: $spendableBalance2AfterOpen")
assert(spendableBalance1AfterOpen > 49000u)
Expand Down Expand Up @@ -256,8 +256,8 @@ class LibraryTest {
node1.syncWallets()
node2.syncWallets()

val spendableBalance1AfterClose = node1.spendableOnchainBalanceSats()
val spendableBalance2AfterClose = node2.spendableOnchainBalanceSats()
val spendableBalance1AfterClose = node1.listBalances().spendableOnchainBalanceSats
val spendableBalance2AfterClose = node2.listBalances().spendableOnchainBalanceSats
println("Spendable balance 1 after close: $spendableBalance1AfterClose")
println("Spendable balance 2 after close: $spendableBalance2AfterClose")
assert(spendableBalance1AfterClose > 95000u)
Expand Down
6 changes: 2 additions & 4 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ interface LDKNode {
[Throws=NodeError]
Txid send_all_to_onchain_address([ByRef]Address address);
[Throws=NodeError]
u64 spendable_onchain_balance_sats();
[Throws=NodeError]
u64 total_onchain_balance_sats();
[Throws=NodeError]
void connect(PublicKey node_id, SocketAddress address, boolean persist);
[Throws=NodeError]
void disconnect(PublicKey node_id);
Expand Down Expand Up @@ -239,6 +235,8 @@ interface LightningBalance {
};

dictionary BalanceDetails {
u64 total_onchain_balance_sats;
u64 spendable_onchain_balance_sats;
u64 total_lightning_balance_sats;
sequence<LightningBalance> lightning_balances;
};
Expand Down
12 changes: 6 additions & 6 deletions bindings/python/src/ldk_node/test_ldk_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@ def test_channel_full_cycle(self):
node_1.sync_wallets()
node_2.sync_wallets()

spendable_balance_1 = node_1.spendable_onchain_balance_sats()
spendable_balance_2 = node_2.spendable_onchain_balance_sats()
total_balance_1 = node_1.total_onchain_balance_sats()
total_balance_2 = node_2.total_onchain_balance_sats()
spendable_balance_1 = node_1.list_balances().spendable_onchain_balance_sats
spendable_balance_2 = node_2.list_balances().spendable_onchain_balance_sats
total_balance_1 = node_1.list_balances().total_onchain_balance_sats
total_balance_2 = node_2.list_balances().total_onchain_balance_sats

print("SPENDABLE 1:", spendable_balance_1)
self.assertEqual(spendable_balance_1, 100000)
Expand Down Expand Up @@ -215,10 +215,10 @@ def test_channel_full_cycle(self):
node_1.sync_wallets()
node_2.sync_wallets()

spendable_balance_after_close_1 = node_1.spendable_onchain_balance_sats()
spendable_balance_after_close_1 = node_1.list_balances().spendable_onchain_balance_sats
assert spendable_balance_after_close_1 > 95000
assert spendable_balance_after_close_1 < 100000
spendable_balance_after_close_2 = node_2.spendable_onchain_balance_sats()
spendable_balance_after_close_2 = node_2.list_balances().spendable_onchain_balance_sats
self.assertEqual(spendable_balance_after_close_2, 102500)

# Stop nodes
Expand Down
4 changes: 4 additions & 0 deletions src/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ use lightning::ln::{ChannelId, PaymentHash, PaymentPreimage};
/// [`Node::list_balances`]: crate::Node::list_balances
#[derive(Debug, Clone)]
pub struct BalanceDetails {
/// The total balance of our on-chain wallet.
pub total_onchain_balance_sats: u64,
/// The currently spendable balance of our on-chain wallet.
pub spendable_onchain_balance_sats: u64,
/// The total balance that we would be able to claim across all our Lightning channels.
pub total_lightning_balance_sats: u64,
/// A detailed list of all known Lightning balances.
Expand Down
23 changes: 12 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -853,16 +853,6 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
Ok(funding_address)
}

/// Retrieve the currently spendable on-chain balance in satoshis.
pub fn spendable_onchain_balance_sats(&self) -> Result<u64, Error> {
Ok(self.wallet.get_balance().map(|bal| bal.get_spendable())?)
}

/// Retrieve the current total on-chain balance in satoshis.
pub fn total_onchain_balance_sats(&self) -> Result<u64, Error> {
Ok(self.wallet.get_balance().map(|bal| bal.get_total())?)
}

/// Send an on-chain payment to the given address.
pub fn send_to_onchain_address(
&self, address: &bitcoin::Address, amount_sats: u64,
Expand Down Expand Up @@ -1558,6 +1548,12 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {

/// Retrieves an overview of all known balances.
pub fn list_balances(&self) -> BalanceDetails {
let (total_onchain_balance_sats, spendable_onchain_balance_sats) = self
.wallet
.get_balance()
.map(|bal| (bal.get_total(), bal.get_spendable()))
.unwrap_or((0, 0));

let mut total_lightning_balance_sats = 0;
let mut lightning_balances = Vec::new();
for funding_txo in self.chain_monitor.list_monitors() {
Expand All @@ -1583,7 +1579,12 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
}
}

BalanceDetails { total_lightning_balance_sats, lightning_balances }
BalanceDetails {
total_onchain_balance_sats,
spendable_onchain_balance_sats,
total_lightning_balance_sats,
lightning_balances,
}
}

/// Retrieves all payments that match the given predicate.
Expand Down
19 changes: 11 additions & 8 deletions tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ pub(crate) fn do_channel_full_cycle<K: KVStore + Sync + Send, E: ElectrumApi>(
);
node_a.sync_wallets().unwrap();
node_b.sync_wallets().unwrap();
assert_eq!(node_a.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
assert_eq!(node_b.list_balances().spendable_onchain_balance_sats, premine_amount_sat);

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

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

Expand Down Expand Up @@ -539,10 +539,13 @@ pub(crate) fn do_channel_full_cycle<K: KVStore + Sync + Send, E: ElectrumApi>(
let node_a_upper_bound_sat =
(premine_amount_sat - funding_amount_sat) + (funding_amount_sat - sum_of_all_payments_sat);
let node_a_lower_bound_sat = node_a_upper_bound_sat - onchain_fee_buffer_sat;
assert!(node_a.spendable_onchain_balance_sats().unwrap() > node_a_lower_bound_sat);
assert!(node_a.spendable_onchain_balance_sats().unwrap() < node_a_upper_bound_sat);
assert!(node_a.list_balances().spendable_onchain_balance_sats > node_a_lower_bound_sat);
assert!(node_a.list_balances().spendable_onchain_balance_sats < node_a_upper_bound_sat);
let expected_final_amount_node_b_sat = premine_amount_sat + sum_of_all_payments_sat;
assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), expected_final_amount_node_b_sat);
assert_eq!(
node_b.list_balances().spendable_onchain_balance_sats,
expected_final_amount_node_b_sat
);

// Check we handled all events
assert_eq!(node_a.next_event(), None);
Expand Down
28 changes: 14 additions & 14 deletions tests/integration_tests_rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ fn channel_open_fails_when_funds_insufficient() {
);
node_a.sync_wallets().unwrap();
node_b.sync_wallets().unwrap();
assert_eq!(node_a.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
assert_eq!(node_b.list_balances().spendable_onchain_balance_sats, premine_amount_sat);

println!("\nA -- connect_open_channel -> B");
assert_eq!(
Expand Down Expand Up @@ -88,7 +88,7 @@ fn multi_hop_sending() {

for n in &nodes {
n.sync_wallets().unwrap();
assert_eq!(n.spendable_onchain_balance_sats().unwrap(), premine_amount_sat);
assert_eq!(n.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
assert_eq!(n.next_event(), None);
}

Expand Down Expand Up @@ -168,7 +168,7 @@ fn start_stop_reinit() {

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

assert_eq!(node.total_onchain_balance_sats().unwrap(), 0);
assert_eq!(node.list_balances().total_onchain_balance_sats, 0);

let expected_amount = Amount::from_sat(100000);
premine_and_distribute_funds(
Expand All @@ -179,7 +179,7 @@ fn start_stop_reinit() {
);

node.sync_wallets().unwrap();
assert_eq!(node.spendable_onchain_balance_sats().unwrap(), expected_amount.to_sat());
assert_eq!(node.list_balances().spendable_onchain_balance_sats, expected_amount.to_sat());

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

assert_eq!(
reinitialized_node.spendable_onchain_balance_sats().unwrap(),
reinitialized_node.list_balances().spendable_onchain_balance_sats,
expected_amount.to_sat()
);

reinitialized_node.sync_wallets().unwrap();
assert_eq!(
reinitialized_node.spendable_onchain_balance_sats().unwrap(),
reinitialized_node.list_balances().spendable_onchain_balance_sats,
expected_amount.to_sat()
);

Expand All @@ -232,7 +232,7 @@ fn onchain_spend_receive() {

node_a.sync_wallets().unwrap();
node_b.sync_wallets().unwrap();
assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), 100000);
assert_eq!(node_b.list_balances().spendable_onchain_balance_sats, 100000);

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

Expand All @@ -243,9 +243,9 @@ fn onchain_spend_receive() {
node_a.sync_wallets().unwrap();
node_b.sync_wallets().unwrap();

assert_eq!(node_a.spendable_onchain_balance_sats().unwrap(), 1000);
assert!(node_b.spendable_onchain_balance_sats().unwrap() > 98000);
assert!(node_b.spendable_onchain_balance_sats().unwrap() < 100000);
assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, 1000);
assert!(node_b.list_balances().spendable_onchain_balance_sats > 98000);
assert!(node_b.list_balances().spendable_onchain_balance_sats < 100000);

let addr_b = node_b.new_onchain_address().unwrap();
let txid = node_a.send_all_to_onchain_address(&addr_b).unwrap();
Expand All @@ -255,9 +255,9 @@ fn onchain_spend_receive() {
node_a.sync_wallets().unwrap();
node_b.sync_wallets().unwrap();

assert_eq!(node_a.total_onchain_balance_sats().unwrap(), 0);
assert!(node_b.spendable_onchain_balance_sats().unwrap() > 99000);
assert!(node_b.spendable_onchain_balance_sats().unwrap() < 100000);
assert_eq!(node_a.list_balances().total_onchain_balance_sats, 0);
assert!(node_b.list_balances().spendable_onchain_balance_sats > 99000);
assert!(node_b.list_balances().spendable_onchain_balance_sats < 100000);
}

#[test]
Expand Down

0 comments on commit 8495bc7

Please sign in to comment.