Skip to content

Commit

Permalink
fix(test-e2e): Wait for app outbound payment after opening channel
Browse files Browse the repository at this point in the history
Fixes #1087.

We fix two issues here:

- We no longer assume that the order-matching fee is constant. It
actually depends on the state of the blockchain, which can change as
we run the e2e tests (even if run sequentially!).
- We wait for the app to confirm the payment before continuing with
test assertions. Otherwise these tests can be flaky.

The fact that the test needs to know about certain implementation
details (e.g. that the order-matching fee is paid via a payment after
the JIT channel is open) is not great, but it's pretty hard to know
what fee will be charged from within the test before it is actually
paid.

This test will probably have to change when we address
#843.
  • Loading branch information
luckysori committed Aug 18, 2023
1 parent 61cb7ab commit 9d15865
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 27 deletions.
72 changes: 60 additions & 12 deletions crates/tests-e2e/src/fund.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,77 @@
use crate::app::AppHandle;
use crate::wait_until;
use anyhow::bail;
use anyhow::Result;
use native::api;
use native::api::PaymentFlow;
use native::api::Status;
use native::api::WalletHistoryItem;
use reqwest::Client;
use serde::Deserialize;
use tokio::task::spawn_blocking;

// TODO: Fetch these from the app
pub const FUNDING_TRANSACTION_FEES: u64 = 153;

/// Pay a lightning invoice using an LND faucet
///
/// Returns the funded amount (in satoshis)
pub async fn fund_app_with_faucet(client: &Client, funding_amount: u64) -> Result<u64> {
let invoice = spawn_blocking(move || {
api::create_invoice_with_amount(funding_amount).expect("to succeed")
})
.await?;
/// Instruct the LND faucet to pay an invoice generated with the purpose of opening a JIT channel
/// between the coordinator and an app.
pub async fn fund_app_with_faucet(
app: &AppHandle,
client: &Client,
fund_amount: u64,
) -> Result<()> {
let invoice =
spawn_blocking(move || api::create_invoice_with_amount(fund_amount).expect("to succeed"))
.await?;
api::decode_invoice(invoice.clone()).expect("to decode invoice we created");

pay_with_faucet(client, invoice).await?;

// Ensure we sync the wallet info after funding
spawn_blocking(move || api::refresh_wallet_info().expect("to succeed")).await?;

Ok(funding_amount - FUNDING_TRANSACTION_FEES)
// Wait until the app has an outbound payment which should correspond to the channel-opening fee
wait_until!(app
.rx
.wallet_info()
.expect("to have wallet info")
.history
.iter()
.any(|item| matches!(
item,
WalletHistoryItem {
flow: PaymentFlow::Outbound,
status: Status::Confirmed,
..
}
)));

let order_matching_fee = app
.rx
.wallet_info()
.expect("to have wallet info")
.history
.iter()
.find_map(|item| match item {
WalletHistoryItem {
flow: PaymentFlow::Outbound,
status: Status::Confirmed,
amount_sats,
..
} => Some(amount_sats),
_ => None,
})
.copied()
.expect("to have an order-matching fee");

tracing::info!(%fund_amount, %order_matching_fee, "Successfully funded app with faucet");
assert_eq!(
app.rx
.wallet_info()
.expect("to have wallet info")
.balances
.lightning,
fund_amount - order_matching_fee
);

Ok(())
}

async fn pay_with_faucet(client: &Client, invoice: String) -> Result<()> {
Expand Down
9 changes: 3 additions & 6 deletions crates/tests-e2e/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ impl TestSetup {
"App should start with empty wallet"
);

let funded_amount = fund_app_with_faucet(&client, 50_000)
let fund_amount = 50_000;
fund_app_with_faucet(&app, &client, fund_amount)
.await
.expect("to be able to fund");

Expand All @@ -71,11 +72,7 @@ impl TestSetup {
.expect("to have wallet info")
.balances
.lightning;
tracing::info!(%funded_amount, %ln_balance, "Successfully funded app with faucet");

if funded_amount != ln_balance {
tracing::warn!("Expected funded amount does not match ln balance!");
}
tracing::info!(%fund_amount, %ln_balance, "Successfully funded app with faucet");

assert!(ln_balance > 0, "App wallet should be funded");

Expand Down
11 changes: 2 additions & 9 deletions crates/tests-e2e/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,10 @@ async fn app_can_be_funded_with_lnd_faucet() -> Result<()> {
let app = run_app().await;

// Unfunded wallet should be empty
assert_eq!(app.rx.wallet_info().unwrap().balances.on_chain, 0);
assert_eq!(app.rx.wallet_info().unwrap().balances.lightning, 0);

let funded_amount = fund_app_with_faucet(&client, 50_000).await?;
let fund_amount = 50_000;
fund_app_with_faucet(&app, &client, fund_amount).await?;

assert_eq!(app.rx.wallet_info().unwrap().balances.on_chain, 0);

tracing::info!(%funded_amount, "Successfully funded app with faucet");
assert_eq!(
app.rx.wallet_info().unwrap().balances.lightning,
funded_amount
);
Ok(())
}

0 comments on commit 9d15865

Please sign in to comment.