Skip to content

Commit

Permalink
chore: Mine block before and after onboarding app
Browse files Browse the repository at this point in the history
It appears broadcasting the funding transaction fails every once in a while as the output transaction has already been spent.

This leads to the following bug #873. Once fixed it should not be required to mine blocks to make that test pass all the time.
  • Loading branch information
holzeis committed Jul 3, 2023
1 parent c31f6b3 commit 9637cf7
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 3 deletions.
65 changes: 65 additions & 0 deletions crates/tests-e2e/src/bitcoind.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use anyhow::bail;
use anyhow::Result;
use reqwest::Client;
use reqwest::Response;
use serde::Deserialize;
use std::time::Duration;

/// A wrapper over the bitcoind HTTP API
///
/// It does not aim to be complete, functionality will be added as needed
pub struct Bitcoind {
client: Client,
host: String,
}

impl Bitcoind {
pub fn new(client: Client) -> Self {
let host = "http://localhost:8080/bitcoin".to_string();
Self { client, host }
}

/// Instructs `bitcoind` to generate to address.
pub async fn mine(&self, n: u16) -> Result<()> {
#[derive(Deserialize, Debug)]
struct BitcoindResponse {
result: String,
}

let response: BitcoindResponse = self
.client
.post(&self.host)
.body(r#"{"jsonrpc": "1.0", "method": "getnewaddress", "params": []}"#.to_string())
.send()
.await?
.json()
.await?;

self.client
.post(&self.host)
.body(format!(
r#"{{"jsonrpc": "1.0", "method": "generatetoaddress", "params": [{}, "{}"]}}"#,
n, response.result
))
.send()
.await?;

// For the mined blocks to be picked up by the subsequent wallet syncs
tokio::time::sleep(Duration::from_secs(5)).await;

Ok(())
}

pub async fn post(&self, endpoint: &str, body: Option<String>) -> Result<Response> {
let mut builder = self.client.post(endpoint.to_string());
if let Some(body) = body {
builder = builder.body(body);
}
let response = builder.send().await?;

if !response.status().is_success() {
bail!(response.text().await?)
}
Ok(response)
}
}
11 changes: 11 additions & 0 deletions crates/tests-e2e/src/coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ impl Coordinator {
Ok(result)
}

pub async fn sync_wallet(&self) -> Result<bool> {
let result = self
.client
.post(&format!("{}/api/admin/sync", self.host))
.send()
.await?
.status()
.is_success();
Ok(result)
}

async fn get(&self, path: &str) -> Result<reqwest::Response> {
self.client
.get(format!("{0}{path}", self.host))
Expand Down
1 change: 1 addition & 0 deletions crates/tests-e2e/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod app;
pub mod bitcoind;
pub mod coordinator;
pub mod fund;
pub mod http;
Expand Down
24 changes: 21 additions & 3 deletions crates/tests-e2e/tests/basic.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use anyhow::Result;
use native::api;
use tests_e2e::app::run_app;
use tests_e2e::bitcoind::Bitcoind;
use tests_e2e::coordinator::Coordinator;
use tests_e2e::fund::fund_app_with_faucet;
use tests_e2e::http::init_reqwest;
Expand All @@ -15,6 +16,8 @@ async fn app_can_be_funded_with_lnd_faucet() -> Result<()> {
let coordinator = Coordinator::new(client.clone());
assert!(coordinator.is_running().await);

let bitcoind = Bitcoind::new(client.clone());

let app = run_app().await;

// this is just to showcase we can retrieve value from a SyncReturn
Expand All @@ -25,14 +28,29 @@ async fn app_can_be_funded_with_lnd_faucet() -> Result<()> {
assert_eq!(app.rx.wallet_info().unwrap().balances.on_chain, 0);
assert_eq!(app.rx.wallet_info().unwrap().balances.lightning, 0);

// TODO: Remove this when fixed. We mine a block before funding the app to ensure that all
// outputs are spendable. This is necessary as the test might otherwise fail due to missing
// or unspendable output when broadcasting the funding transaction.
bitcoind.mine(1).await?;
coordinator.sync_wallet().await?;

let funding_amount = 50_000;
let funding_transaction_fees = 153;
fund_app_with_faucet(&client, funding_amount).await?;

// TODO: Remove this when fixed. We mine a block before funding the app to ensure that all
// outputs are spendable. This is necessary as the test might otherwise fail due to missing
// or unspendable output when broadcasting the funding transaction.
bitcoind.mine(1).await?;
coordinator.sync_wallet().await?;

assert_eq!(app.rx.wallet_info().unwrap().balances.on_chain, 0);
assert_eq!(
app.rx.wallet_info().unwrap().balances.lightning,
funding_amount - funding_transaction_fees

// Asserting here on >= as this test run on the CI can't find a route when trying to pay
// immediately after claiming a received payment.
assert!(
app.rx.wallet_info().unwrap().balances.lightning
>= funding_amount - funding_transaction_fees
);
Ok(())
}

0 comments on commit 9637cf7

Please sign in to comment.