Skip to content

Commit cf2c657

Browse files
committed
Have tests use esplora syncing
1 parent cd130ab commit cf2c657

6 files changed

Lines changed: 200 additions & 77 deletions

File tree

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ codegen-units = 1 # Reduce number of codegen units to increase optimizations.
1616
panic = 'abort' # Abort on panic
1717

1818
[workspace.dependencies]
19-
bitcoin-payment-instructions = { git = "https://github.com/benthecarman/bitcoin-payment-instructions.git", branch = "orange-fork2", features = ["http"] }
20-
lightning = { version = "0.2.0-rc1" }
21-
lightning-invoice = { version = "0.34.0-rc1" }
19+
bitcoin-payment-instructions = { version = "0.6.0" }
20+
lightning = { version = "0.2.0" }
21+
lightning-invoice = { version = "0.34.0" }
2222

2323
[profile.release]
2424
panic = "abort"

orange-sdk/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ default = ["spark"]
1717
uniffi = ["dep:uniffi", "spark", "cashu"]
1818
spark = ["breez-sdk-spark", "uuid", "serde_json"]
1919
cashu = ["cdk", "serde_json"]
20-
_test-utils = ["corepc-node", "cashu", "uuid/v7", "rand"]
20+
_test-utils = ["corepc-node", 'electrsd', "cashu", "uuid/v7", "rand"]
2121
_cashu-tests = ["_test-utils", "cdk-ldk-node", "cdk/mint", "cdk-sqlite", "cdk-axum", "axum"]
2222

2323
[dependencies]
@@ -36,7 +36,8 @@ serde_json = { version = "1.0", optional = true }
3636
async-trait = "0.1"
3737
log = "0.4.28"
3838

39-
corepc-node = { version = "0.8.0", features = ["29_0", "download"], optional = true }
39+
corepc-node = { version = "0.10.1", features = ["27_2", "download"], optional = true }
40+
electrsd = { version = "0.36.1", default-features = false, features = ["esplora_a33e97e1", "corepc-node_27_2"], optional = true }
4041
cdk-ldk-node = { version = "0.14.2", optional = true }
4142
cdk-sqlite = { version = "0.14.2", optional = true }
4243
cdk-axum = { version = "0.14.2", optional = true }

orange-sdk/src/lib.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -785,13 +785,17 @@ impl Wallet {
785785
},
786786
_ => None,
787787
};
788-
let fee = match payment.fee_paid_msat {
789-
None => lightning_receive_fee,
790-
Some(fee) => Some(
791-
Amount::from_milli_sats(fee)
792-
.unwrap()
793-
.saturating_add(lightning_receive_fee.unwrap_or(Amount::ZERO)),
794-
),
788+
let fee = if payment.direction == PaymentDirection::Outbound {
789+
match payment.fee_paid_msat {
790+
None => Some(lightning_receive_fee.unwrap_or(Amount::ZERO)),
791+
Some(fee) => Some(
792+
Amount::from_milli_sats(fee)
793+
.unwrap()
794+
.saturating_add(lightning_receive_fee.unwrap_or(Amount::ZERO)),
795+
),
796+
}
797+
} else {
798+
Some(lightning_receive_fee.unwrap_or(Amount::ZERO))
795799
};
796800
if let Some(tx_metadata) = tx_metadata.get(&PaymentId::SelfCustodial(payment.id.0)) {
797801
match &tx_metadata.ty {
@@ -1357,4 +1361,13 @@ impl Wallet {
13571361
// Wait until non-cancellable background tasks (mod LDK's background processor) are done.
13581362
self.inner.runtime.wait_on_background_tasks();
13591363
}
1364+
1365+
/// Manually sync the LDK and BDK wallets with the current chain state and update the fee rate cache.
1366+
///
1367+
/// This is done automatically in the background, but can be triggered manually if needed. Often useful for
1368+
/// testing purposes.
1369+
pub fn sync_ln_wallet(&self) -> Result<(), WalletError> {
1370+
self.inner.ln_wallet.inner.ldk_node.sync_wallets()?;
1371+
Ok(())
1372+
}
13601373
}

orange-sdk/src/lightning_wallet.rs

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,42 @@ impl LightningWallet {
110110
let (lsp_socket_addr, lsp_node_id, lsp_token) = config.lsp;
111111
builder.set_liquidity_source_lsps2(lsp_node_id, lsp_socket_addr.clone(), lsp_token);
112112
match config.chain_source {
113-
ChainSource::Esplora { url, username, password } => match (&username, &password) {
114-
(Some(username), Some(password)) => {
115-
let mut headers = HashMap::with_capacity(1);
116-
headers.insert(
117-
"Authorization".to_string(),
118-
format!(
119-
"Basic {}",
120-
BASE64_STANDARD.encode(format!("{}:{}", username, password))
121-
),
122-
);
123-
builder.set_chain_source_esplora_with_headers(url, headers, None)
124-
},
125-
(None, None) => builder.set_chain_source_esplora(url, None),
126-
_ => {
127-
return Err(InitFailure::LdkNodeStartFailure(NodeError::WalletOperationFailed));
128-
},
113+
ChainSource::Esplora { url, username, password } => {
114+
let sync_config = if config.network == Network::Regtest {
115+
ldk_node::config::EsploraSyncConfig {
116+
background_sync_config: Some(BackgroundSyncConfig {
117+
onchain_wallet_sync_interval_secs: 2,
118+
lightning_wallet_sync_interval_secs: 2,
119+
fee_rate_cache_update_interval_secs: 30,
120+
}),
121+
}
122+
} else {
123+
ldk_node::config::EsploraSyncConfig::default()
124+
};
125+
126+
match (&username, &password) {
127+
(Some(username), Some(password)) => {
128+
let mut headers = HashMap::with_capacity(1);
129+
headers.insert(
130+
"Authorization".to_string(),
131+
format!(
132+
"Basic {}",
133+
BASE64_STANDARD.encode(format!("{username}:{password}"))
134+
),
135+
);
136+
builder.set_chain_source_esplora_with_headers(
137+
url,
138+
headers,
139+
Some(sync_config),
140+
)
141+
},
142+
(None, None) => builder.set_chain_source_esplora(url, Some(sync_config)),
143+
_ => {
144+
return Err(InitFailure::LdkNodeStartFailure(
145+
NodeError::WalletOperationFailed,
146+
));
147+
},
148+
}
129149
},
130150
ChainSource::Electrum(url) => builder.set_chain_source_electrum(url, None),
131151
ChainSource::BitcoindRPC { host, port, user, password } => {

orange-sdk/tests/integration_tests.rs

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![cfg(feature = "_test-utils")]
22

3-
use crate::test_utils::{generate_blocks, open_channel_from_lsp, wait_next_event};
3+
use crate::test_utils::{generate_blocks, open_channel_from_lsp, wait_for_tx, wait_next_event};
44
use bitcoin_payment_instructions::amount::Amount;
55
use bitcoin_payment_instructions::http_resolver::HTTPHrnResolver;
66
use bitcoin_payment_instructions::{ParseError, PaymentInstructions};
@@ -370,12 +370,14 @@ async fn test_receive_to_ln() {
370370
}
371371

372372
#[tokio::test(flavor = "multi_thread")]
373-
async fn test_receive_to_onchain() {
373+
#[test_log::test]
374+
async fn test_receive_onchain() {
374375
test_utils::run_test(|params| async move {
375376
let wallet = Arc::clone(&params.wallet);
376377
let lsp = Arc::clone(&params.lsp);
377378
let bitcoind = Arc::clone(&params.bitcoind);
378379
let third_party = Arc::clone(&params.third_party);
380+
let electrsd = Arc::clone(&params.electrsd);
379381

380382
let starting_bal = wallet.get_balance().await.unwrap();
381383
assert_eq!(starting_bal.available_balance(), Amount::ZERO);
@@ -389,8 +391,10 @@ async fn test_receive_to_onchain() {
389391
.send_to_address(&uri.address.unwrap(), recv_amt.sats().unwrap(), None)
390392
.unwrap();
391393

394+
wait_for_tx(&electrsd.client, sent_txid).await;
395+
392396
// confirm transaction
393-
generate_blocks(&bitcoind, 6);
397+
generate_blocks(&bitcoind, &electrsd, 6).await;
394398

395399
// check we received on-chain, should be pending
396400
// wait for payment success
@@ -435,9 +439,9 @@ async fn test_receive_to_onchain() {
435439

436440
// a rebalance should be initiated, we need to mine the channel opening transaction
437441
// for it to be confirmed and reflected in the wallet's history
438-
generate_blocks(&bitcoind, 6);
442+
generate_blocks(&bitcoind, &electrsd, 6).await;
439443
tokio::time::sleep(Duration::from_secs(5)).await; // wait for sync
440-
generate_blocks(&bitcoind, 6); // confirm the channel opening transaction
444+
generate_blocks(&bitcoind, &electrsd, 6).await; // confirm the channel opening transaction
441445
tokio::time::sleep(Duration::from_secs(5)).await; // wait for sync
442446

443447
// wait for rebalance to be initiated
@@ -482,13 +486,14 @@ async fn test_receive_to_onchain() {
482486
}
483487

484488
#[tokio::test(flavor = "multi_thread")]
485-
// #[test_log::test]
489+
#[test_log::test]
486490
async fn test_receive_to_onchain_with_channel() {
487491
test_utils::run_test(|params| async move {
488492
let wallet = Arc::clone(&params.wallet);
489493
let lsp = Arc::clone(&params.lsp);
490494
let bitcoind = Arc::clone(&params.bitcoind);
491495
let third_party = Arc::clone(&params.third_party);
496+
let electrsd = Arc::clone(&params.electrsd);
492497

493498
let start = open_channel_from_lsp(&wallet, Arc::clone(&third_party)).await;
494499

@@ -508,10 +513,13 @@ async fn test_receive_to_onchain_with_channel() {
508513
.send_to_address(&uri.address.unwrap(), recv_amt.sats().unwrap(), None)
509514
.unwrap();
510515

511-
println!("Sent txid: {}", sent_txid);
516+
println!("Sent txid: {sent_txid}");
517+
518+
wait_for_tx(&electrsd.client, sent_txid).await;
512519

513520
// confirm transaction
514-
generate_blocks(&bitcoind, 6);
521+
generate_blocks(&bitcoind, &electrsd, 6).await;
522+
wallet.sync_ln_wallet().unwrap();
515523

516524
// check we received on-chain, should be pending
517525
// wait for payment success
@@ -521,6 +529,7 @@ async fn test_receive_to_onchain_with_channel() {
521529
})
522530
.await;
523531

532+
println!("waiting for onchain recv event");
524533
let event = wait_next_event(&wallet).await;
525534
match event {
526535
Event::OnchainPaymentReceived { txid, amount_sat, status, .. } => {
@@ -531,6 +540,7 @@ async fn test_receive_to_onchain_with_channel() {
531540
ev => panic!("Expected OnchainPaymentReceived event, got {ev:?}"),
532541
}
533542

543+
println!("waiting for splice pending event");
534544
let event = wait_next_event(&wallet).await;
535545
match event {
536546
Event::SplicePending { counterparty_node_id, .. } => {
@@ -540,7 +550,7 @@ async fn test_receive_to_onchain_with_channel() {
540550
}
541551

542552
// confirm splice
543-
generate_blocks(&bitcoind, 6);
553+
generate_blocks(&bitcoind, &electrsd, 6).await;
544554
tokio::time::sleep(Duration::from_secs(5)).await;
545555

546556
let event = wait_next_event(&wallet).await;
@@ -589,12 +599,13 @@ async fn run_test_pay_lightning_from_self_custody(amountless: bool) {
589599
let wallet = Arc::clone(&params.wallet);
590600
let bitcoind = Arc::clone(&params.bitcoind);
591601
let third_party = Arc::clone(&params.third_party);
602+
let electrsd = Arc::clone(&params.electrsd);
592603

593604
// get a channel so we can make a payment
594605
open_channel_from_lsp(&wallet, Arc::clone(&third_party)).await;
595606

596607
// wait for sync
597-
generate_blocks(&bitcoind, 6);
608+
generate_blocks(&bitcoind, &electrsd, 6).await;
598609
test_utils::wait_for_condition("wallet sync after channel open", || async {
599610
wallet.channels().iter().any(|a| a.confirmations.is_some_and(|c| c > 0) && a.is_usable)
600611
&& third_party
@@ -692,12 +703,13 @@ async fn run_test_pay_bolt12_from_self_custody(amountless: bool) {
692703
let wallet = Arc::clone(&params.wallet);
693704
let bitcoind = Arc::clone(&params.bitcoind);
694705
let third_party = Arc::clone(&params.third_party);
706+
let electrsd = Arc::clone(&params.electrsd);
695707

696708
// get a channel so we can make a payment
697709
open_channel_from_lsp(&wallet, Arc::clone(&third_party)).await;
698710

699711
// wait for sync
700-
generate_blocks(&bitcoind, 6);
712+
generate_blocks(&bitcoind, &electrsd, 6).await;
701713
test_utils::wait_for_condition("wallet sync after channel open", || async {
702714
wallet.channels().iter().any(|a| a.confirmations.is_some_and(|c| c > 0) && a.is_usable)
703715
&& third_party
@@ -786,6 +798,7 @@ async fn test_pay_onchain_from_self_custody() {
786798
let wallet = Arc::clone(&params.wallet);
787799
let bitcoind = Arc::clone(&params.bitcoind);
788800
let third_party = Arc::clone(&params.third_party);
801+
let electrsd = Arc::clone(&params.electrsd);
789802

790803
// disable rebalancing so we have on-chain funds
791804
wallet.set_rebalance_enabled(false);
@@ -806,7 +819,7 @@ async fn test_pay_onchain_from_self_custody() {
806819
.unwrap();
807820

808821
// confirm tx
809-
generate_blocks(&bitcoind, 6);
822+
generate_blocks(&bitcoind, &electrsd, 6).await;
810823

811824
// wait for node to sync and see the balance update
812825
test_utils::wait_for_condition("wallet sync after on-chain receive", || async {
@@ -826,7 +839,7 @@ async fn test_pay_onchain_from_self_custody() {
826839
tokio::time::sleep(Duration::from_secs(1)).await;
827840

828841
// confirm the tx
829-
generate_blocks(&bitcoind, 6);
842+
generate_blocks(&bitcoind, &electrsd, 6).await;
830843

831844
// sleep for a second to wait for sync
832845
tokio::time::sleep(Duration::from_secs(1)).await;
@@ -901,6 +914,7 @@ async fn test_pay_onchain_from_channel() {
901914
let wallet = Arc::clone(&params.wallet);
902915
let bitcoind = Arc::clone(&params.bitcoind);
903916
let third_party = Arc::clone(&params.third_party);
917+
let electrsd = Arc::clone(&params.electrsd);
904918

905919
// get a channel so we can make a payment
906920
let recv = open_channel_from_lsp(&wallet, Arc::clone(&third_party)).await;
@@ -913,7 +927,7 @@ async fn test_pay_onchain_from_channel() {
913927
assert_eq!(starting_bal.pending_balance, Amount::ZERO);
914928

915929
// wait for sync
916-
generate_blocks(&bitcoind, 6);
930+
generate_blocks(&bitcoind, &electrsd, 6).await;
917931
test_utils::wait_for_condition("wallet sync after channel open", || async {
918932
wallet.channels().iter().any(|a| a.confirmations.is_some_and(|c| c > 0) && a.is_usable)
919933
})
@@ -931,7 +945,7 @@ async fn test_pay_onchain_from_channel() {
931945
tokio::time::sleep(Duration::from_secs(1)).await;
932946

933947
// confirm the tx
934-
generate_blocks(&bitcoind, 6);
948+
generate_blocks(&bitcoind, &electrsd, 6).await;
935949

936950
// sleep for a second to wait for sync
937951
tokio::time::sleep(Duration::from_secs(1)).await;
@@ -1010,6 +1024,7 @@ async fn test_force_close_handling() {
10101024
let lsp = Arc::clone(&params.lsp);
10111025
let bitcoind = Arc::clone(&params.bitcoind);
10121026
let third_party = Arc::clone(&params.third_party);
1027+
let electrsd = Arc::clone(&params.electrsd);
10131028

10141029
let starting_bal = wallet.get_balance().await.unwrap();
10151030
assert_eq!(starting_bal.available_balance(), Amount::ZERO);
@@ -1022,7 +1037,7 @@ async fn test_force_close_handling() {
10221037
open_channel_from_lsp(&wallet, Arc::clone(&third_party)).await;
10231038

10241039
// mine some blocks to ensure the channel is confirmed
1025-
generate_blocks(&bitcoind, 6);
1040+
generate_blocks(&bitcoind, &electrsd, 6).await;
10261041

10271042
// get channel details
10281043
let channel = lsp
@@ -1058,6 +1073,7 @@ async fn test_close_all_channels() {
10581073
let lsp = Arc::clone(&params.lsp);
10591074
let bitcoind = Arc::clone(&params.bitcoind);
10601075
let third_party = Arc::clone(&params.third_party);
1076+
let electrsd = Arc::clone(&params.electrsd);
10611077

10621078
let starting_bal = wallet.get_balance().await.unwrap();
10631079
assert_eq!(starting_bal.available_balance(), Amount::ZERO);
@@ -1070,7 +1086,7 @@ async fn test_close_all_channels() {
10701086
open_channel_from_lsp(&wallet, Arc::clone(&third_party)).await;
10711087

10721088
// mine some blocks to ensure the channel is confirmed
1073-
generate_blocks(&bitcoind, 6);
1089+
generate_blocks(&bitcoind, &electrsd, 6).await;
10741090

10751091
// init closing all channels
10761092
wallet.close_channels().unwrap();
@@ -1489,6 +1505,7 @@ async fn test_payment_network_mismatch() {
14891505
test_utils::run_test(|params| async move {
14901506
let wallet = Arc::clone(&params.wallet);
14911507
let bitcoind = Arc::clone(&params.bitcoind);
1508+
let electrsd = Arc::clone(&params.electrsd);
14921509

14931510
// disable rebalancing so we have on-chain funds
14941511
wallet.set_rebalance_enabled(false);
@@ -1505,7 +1522,7 @@ async fn test_payment_network_mismatch() {
15051522
.unwrap();
15061523

15071524
// confirm tx
1508-
generate_blocks(&bitcoind, 6);
1525+
generate_blocks(&bitcoind, &electrsd, 6).await;
15091526
test_utils::wait_for_condition("wallet sync after on-chain receive", || async {
15101527
wallet.get_balance().await.unwrap().pending_balance >= recv_amount
15111528
})
@@ -1550,13 +1567,14 @@ async fn test_concurrent_payments() {
15501567
test_utils::run_test(|params| async move {
15511568
let wallet = Arc::clone(&params.wallet);
15521569
let bitcoind = Arc::clone(&params.bitcoind);
1570+
let electrsd = Arc::clone(&params.electrsd);
15531571
let third_party = Arc::clone(&params.third_party);
15541572

15551573
// First, build up sufficient balance for concurrent sending
15561574
let _channel_amount = open_channel_from_lsp(&wallet, Arc::clone(&third_party)).await;
15571575

15581576
// Wait for sync
1559-
generate_blocks(&bitcoind, 6);
1577+
generate_blocks(&bitcoind, &electrsd, 6).await;
15601578
test_utils::wait_for_condition("wallet sync after channel open", || async {
15611579
wallet.channels().iter().any(|a| a.confirmations.is_some_and(|c| c > 0) && a.is_usable)
15621580
&& third_party
@@ -2145,13 +2163,14 @@ async fn test_lsp_connectivity_fallback() {
21452163
let wallet = Arc::clone(&params.wallet);
21462164
let lsp = Arc::clone(&params.lsp);
21472165
let bitcoind = Arc::clone(&params.bitcoind);
2166+
let electrsd = Arc::clone(&params.electrsd);
21482167
let third_party = Arc::clone(&params.third_party);
21492168

21502169
// open a channel with the LSP
21512170
open_channel_from_lsp(&wallet, Arc::clone(&third_party)).await;
21522171

21532172
// confirm channel
2154-
generate_blocks(&bitcoind, 6);
2173+
generate_blocks(&bitcoind, &electrsd, 6).await;
21552174
test_utils::wait_for_condition("wallet sync after channel open", || async {
21562175
wallet.channels().iter().any(|a| a.confirmations.is_some_and(|c| c > 0) && a.is_usable)
21572176
&& third_party

0 commit comments

Comments
 (0)