From ae470e84efd1d3b925a473d55f4e74fc0a84e095 Mon Sep 17 00:00:00 2001
From: DanGould <d@ngould.dev>
Date: Tue, 3 Dec 2024 12:55:41 -0500
Subject: [PATCH 1/2] Expose test fixtures and fns at payjoin-test-utils

This new crate also provides an opportunity to create downstream test
fixtures in payjoin-ffi and language bindings downstream of it.
---
 Cargo-minimal.lock            |  17 ++++++
 Cargo-recent.lock             |  17 ++++++
 Cargo.toml                    |   2 +-
 payjoin-cli/Cargo.toml        |   1 +
 payjoin-cli/tests/e2e.rs      | 111 ++++++----------------------------
 payjoin-test-utils/Cargo.toml |  18 ++++++
 payjoin-test-utils/src/lib.rs |  77 +++++++++++++++++++++++
 payjoin/Cargo.toml            |   1 +
 payjoin/tests/integration.rs  |  70 +--------------------
 9 files changed, 155 insertions(+), 159 deletions(-)
 create mode 100644 payjoin-test-utils/Cargo.toml
 create mode 100644 payjoin-test-utils/src/lib.rs

diff --git a/Cargo-minimal.lock b/Cargo-minimal.lock
index cc0da7a5..d8e9abd9 100644
--- a/Cargo-minimal.lock
+++ b/Cargo-minimal.lock
@@ -1590,6 +1590,7 @@ dependencies = [
  "ohttp-relay",
  "once_cell",
  "payjoin-directory",
+ "payjoin-test-utils",
  "rcgen",
  "reqwest",
  "rustls 0.22.4",
@@ -1624,6 +1625,7 @@ dependencies = [
  "once_cell",
  "payjoin",
  "payjoin-directory",
+ "payjoin-test-utils",
  "rcgen",
  "reqwest",
  "rustls 0.22.4",
@@ -1659,6 +1661,21 @@ dependencies = [
  "tracing-subscriber",
 ]
 
+[[package]]
+name = "payjoin-test-utils"
+version = "0.1.0"
+dependencies = [
+ "bitcoincore-rpc",
+ "bitcoind",
+ "http",
+ "log",
+ "ohttp-relay",
+ "payjoin-directory",
+ "rcgen",
+ "testcontainers",
+ "testcontainers-modules",
+]
+
 [[package]]
 name = "pbkdf2"
 version = "0.11.0"
diff --git a/Cargo-recent.lock b/Cargo-recent.lock
index cc0da7a5..d8e9abd9 100644
--- a/Cargo-recent.lock
+++ b/Cargo-recent.lock
@@ -1590,6 +1590,7 @@ dependencies = [
  "ohttp-relay",
  "once_cell",
  "payjoin-directory",
+ "payjoin-test-utils",
  "rcgen",
  "reqwest",
  "rustls 0.22.4",
@@ -1624,6 +1625,7 @@ dependencies = [
  "once_cell",
  "payjoin",
  "payjoin-directory",
+ "payjoin-test-utils",
  "rcgen",
  "reqwest",
  "rustls 0.22.4",
@@ -1659,6 +1661,21 @@ dependencies = [
  "tracing-subscriber",
 ]
 
+[[package]]
+name = "payjoin-test-utils"
+version = "0.1.0"
+dependencies = [
+ "bitcoincore-rpc",
+ "bitcoind",
+ "http",
+ "log",
+ "ohttp-relay",
+ "payjoin-directory",
+ "rcgen",
+ "testcontainers",
+ "testcontainers-modules",
+]
+
 [[package]]
 name = "pbkdf2"
 version = "0.11.0"
diff --git a/Cargo.toml b/Cargo.toml
index 532c7cda..0efa8fd2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,5 @@
 [workspace]
-members = ["payjoin", "payjoin-cli", "payjoin-directory"]
+members = ["payjoin", "payjoin-cli", "payjoin-directory", "payjoin-test-utils"]
 resolver = "2"
 
 [patch.crates-io.payjoin]
diff --git a/payjoin-cli/Cargo.toml b/payjoin-cli/Cargo.toml
index 3e1937cc..543d0d93 100644
--- a/payjoin-cli/Cargo.toml
+++ b/payjoin-cli/Cargo.toml
@@ -53,6 +53,7 @@ http = "1"
 ohttp-relay = "0.0.8"
 once_cell = "1"
 payjoin-directory = { path = "../payjoin-directory", features = ["_danger-local-https"] }
+payjoin-test-utils = { path = "../payjoin-test-utils" }
 testcontainers = "0.15.0"
 testcontainers-modules = { version = "0.1.3", features = ["redis"] }
 tokio = { version = "1.12.0", features = ["full"] }
diff --git a/payjoin-cli/tests/e2e.rs b/payjoin-cli/tests/e2e.rs
index e9caa23c..91a7bfe6 100644
--- a/payjoin-cli/tests/e2e.rs
+++ b/payjoin-cli/tests/e2e.rs
@@ -4,45 +4,24 @@ mod e2e {
     use std::process::Stdio;
 
     use bitcoincore_rpc::json::AddressType;
-    use bitcoind::bitcoincore_rpc::RpcApi;
-    use log::{log_enabled, Level};
-    use payjoin::bitcoin::Amount;
+    use payjoin_test_utils::*;
     use tokio::fs;
     use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
     use tokio::process::Command;
 
     const RECEIVE_SATS: &str = "54321";
 
+    type Error = Box<dyn std::error::Error + 'static>;
+    type Result<T> = std::result::Result<T, Error>;
+
     #[cfg(not(feature = "v2"))]
     #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
-    async fn send_receive_payjoin() {
-        let bitcoind_exe = env::var("BITCOIND_EXE")
-            .ok()
-            .or_else(|| bitcoind::downloaded_exe_path().ok())
-            .expect("version feature or env BITCOIND_EXE is required for tests");
-        let mut conf = bitcoind::Conf::default();
-        conf.view_stdout = log_enabled!(Level::Debug);
-        let bitcoind = bitcoind::BitcoinD::with_conf(bitcoind_exe, &conf).unwrap();
-        let receiver = bitcoind.create_wallet("receiver").unwrap();
-        let receiver_address =
-            receiver.get_new_address(None, Some(AddressType::Bech32)).unwrap().assume_checked();
-        let sender = bitcoind.create_wallet("sender").unwrap();
-        let sender_address =
-            sender.get_new_address(None, Some(AddressType::Bech32)).unwrap().assume_checked();
-        bitcoind.client.generate_to_address(1, &receiver_address).unwrap();
-        bitcoind.client.generate_to_address(101, &sender_address).unwrap();
-
-        assert_eq!(
-            Amount::from_btc(50.0).unwrap(),
-            receiver.get_balances().unwrap().mine.trusted,
-            "receiver doesn't own bitcoin"
-        );
-
-        assert_eq!(
-            Amount::from_btc(50.0).unwrap(),
-            sender.get_balances().unwrap().mine.trusted,
-            "sender doesn't own bitcoin"
-        );
+    async fn send_receive_payjoin() -> Result<()> {
+        // _sender and _receiver are called by the payjoin-cli using RPC directly
+        let (bitcoind, _sender, _receiver) = payjoin_test_utils::init_bitcoind_sender_receiver(
+            Some(AddressType::Bech32),
+            Some(AddressType::Bech32),
+        )?;
 
         let temp_dir = env::temp_dir();
         let receiver_db_path = temp_dir.join("receiver_db");
@@ -151,6 +130,7 @@ mod e2e {
             payjoin_sent.unwrap().unwrap_or(Some(false)).unwrap(),
             "Payjoin send was not detected"
         );
+        Ok(())
     }
 
     #[cfg(feature = "v2")]
@@ -164,20 +144,15 @@ mod e2e {
         use http::StatusCode;
         use once_cell::sync::{Lazy, OnceCell};
         use reqwest::{Client, ClientBuilder};
-        use testcontainers::clients::Cli;
-        use testcontainers_modules::redis::Redis;
         use tokio::process::Child;
         use url::Url;
 
-        type Error = Box<dyn std::error::Error + 'static>;
-        type Result<T> = std::result::Result<T, Error>;
-
         static INIT_TRACING: OnceCell<()> = OnceCell::new();
         static TESTS_TIMEOUT: Lazy<Duration> = Lazy::new(|| Duration::from_secs(20));
         static WAIT_SERVICE_INTERVAL: Lazy<Duration> = Lazy::new(|| Duration::from_secs(3));
 
         init_tracing();
-        let (cert, key) = local_cert_key();
+        let (cert, key) = payjoin_test_utils::local_cert_key();
         let ohttp_relay_port = find_free_port();
         let ohttp_relay = Url::parse(&format!("http://localhost:{}", ohttp_relay_port)).unwrap();
         let directory_port = find_free_port();
@@ -189,7 +164,7 @@ mod e2e {
         let sender_db_path = temp_dir.join("sender_db");
         let result: Result<()> = tokio::select! {
             res = ohttp_relay::listen_tcp(ohttp_relay_port, gateway_origin) => Err(format!("Ohttp relay is long running: {:?}", res).into()),
-            res = init_directory(directory_port, (cert.clone(), key)) => Err(format!("Directory server is long running: {:?}", res).into()),
+            res = payjoin_test_utils::init_directory(directory_port, (cert.clone(), key)) => Err(format!("Directory server is long running: {:?}", res).into()),
             res = send_receive_cli_async(ohttp_relay, directory, cert, receiver_db_path.clone(), sender_db_path.clone()) => res.map_err(|e| format!("send_receive failed: {:?}", e).into()),
         };
 
@@ -204,33 +179,13 @@ mod e2e {
             receiver_db_path: PathBuf,
             sender_db_path: PathBuf,
         ) -> Result<()> {
-            let bitcoind_exe = env::var("BITCOIND_EXE")
-                .ok()
-                .or_else(|| bitcoind::downloaded_exe_path().ok())
-                .expect("version feature or env BITCOIND_EXE is required for tests");
-            let mut conf = bitcoind::Conf::default();
-            conf.view_stdout = log_enabled!(Level::Debug);
-            let bitcoind = bitcoind::BitcoinD::with_conf(bitcoind_exe, &conf)?;
-            let receiver = bitcoind.create_wallet("receiver")?;
-            let receiver_address =
-                receiver.get_new_address(None, Some(AddressType::Bech32))?.assume_checked();
-            let sender = bitcoind.create_wallet("sender")?;
-            let sender_address =
-                sender.get_new_address(None, Some(AddressType::Bech32))?.assume_checked();
-            bitcoind.client.generate_to_address(1, &receiver_address)?;
-            bitcoind.client.generate_to_address(101, &sender_address)?;
-
-            assert_eq!(
-                Amount::from_btc(50.0)?,
-                receiver.get_balances()?.mine.trusted,
-                "receiver doesn't own bitcoin"
-            );
-
-            assert_eq!(
-                Amount::from_btc(50.0)?,
-                sender.get_balances()?.mine.trusted,
-                "sender doesn't own bitcoin"
-            );
+            // _sender and _receiver are called by the payjoin-cli using RPC directly
+            let (bitcoind, _sender, _receiver) = payjoin_test_utils::init_bitcoind_sender_receiver(
+                Some(AddressType::Bech32),
+                Some(AddressType::Bech32),
+            )
+            .unwrap();
+
             let temp_dir = env::temp_dir();
             let cert_path = temp_dir.join("localhost.der");
             tokio::fs::write(&cert_path, cert.clone()).await?;
@@ -476,27 +431,6 @@ mod e2e {
             Err("Timeout waiting for service to be ready".into())
         }
 
-        async fn init_directory(port: u16, local_cert_key: (Vec<u8>, Vec<u8>)) -> Result<()> {
-            let docker: Cli = Cli::default();
-            let timeout = Duration::from_secs(2);
-            let db = docker.run(Redis);
-            let db_host = format!("127.0.0.1:{}", db.get_host_port_ipv4(6379));
-            println!("Database running on {}", db.get_host_port_ipv4(6379));
-            payjoin_directory::listen_tcp_with_tls(port, db_host, timeout, local_cert_key).await
-        }
-
-        // generates or gets a DER encoded localhost cert and key.
-        fn local_cert_key() -> (Vec<u8>, Vec<u8>) {
-            let cert = rcgen::generate_simple_self_signed(vec![
-                "0.0.0.0".to_string(),
-                "localhost".to_string(),
-            ])
-            .expect("Failed to generate cert");
-            let cert_der = cert.serialize_der().expect("Failed to serialize cert");
-            let key_der = cert.serialize_private_key_der();
-            (cert_der, key_der)
-        }
-
         fn http_agent(cert_der: Vec<u8>) -> Result<Client> {
             Ok(http_agent_builder(cert_der)?.build()?)
         }
@@ -521,11 +455,6 @@ mod e2e {
         }
     }
 
-    fn find_free_port() -> u16 {
-        let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
-        listener.local_addr().unwrap().port()
-    }
-
     async fn cleanup_temp_file(path: &std::path::Path) {
         if let Err(e) = fs::remove_dir_all(path).await {
             eprintln!("Failed to remove {:?}: {}", path, e);
diff --git a/payjoin-test-utils/Cargo.toml b/payjoin-test-utils/Cargo.toml
new file mode 100644
index 00000000..c8f0c0ea
--- /dev/null
+++ b/payjoin-test-utils/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "payjoin-test-utils"
+version = "0.1.0"
+edition = "2021"
+authors = ["Dan Gould <d@ngould.dev>"]
+rust-version = "1.63"
+license = "MIT"
+
+[dependencies]
+bitcoincore-rpc = "0.19.0"
+bitcoind = { version = "0.36.0", features = ["0_21_2"] }
+http = "1"
+log = "0.4.7"
+ohttp-relay = "0.0.8"
+payjoin-directory = { path = "../payjoin-directory", features = ["_danger-local-https"] }
+rcgen = "0.11"
+testcontainers = "0.15.0"
+testcontainers-modules = { version = "0.1.3", features = ["redis"] }
diff --git a/payjoin-test-utils/src/lib.rs b/payjoin-test-utils/src/lib.rs
new file mode 100644
index 00000000..984de1df
--- /dev/null
+++ b/payjoin-test-utils/src/lib.rs
@@ -0,0 +1,77 @@
+use std::time::Duration;
+
+use bitcoincore_rpc::bitcoin::Amount;
+use bitcoincore_rpc::json::AddressType;
+use bitcoincore_rpc::RpcApi;
+use testcontainers::clients::Cli;
+use testcontainers_modules::redis::Redis;
+
+type Error = Box<dyn std::error::Error + 'static>;
+
+pub fn init_bitcoind() -> Result<bitcoind::BitcoinD, Error> {
+    let bitcoind_exe = std::env::var("BITCOIND_EXE")
+        .ok()
+        .or_else(|| bitcoind::downloaded_exe_path().ok())
+        .unwrap();
+    let mut conf = bitcoind::Conf::default();
+    conf.view_stdout = log::log_enabled!(log::Level::Debug);
+    let bitcoind = bitcoind::BitcoinD::with_conf(bitcoind_exe, &conf)?;
+    Ok(bitcoind)
+}
+
+pub fn init_bitcoind_sender_receiver(
+    sender_address_type: Option<AddressType>,
+    receiver_address_type: Option<AddressType>,
+) -> Result<(bitcoind::BitcoinD, bitcoincore_rpc::Client, bitcoincore_rpc::Client), Error> {
+    let bitcoind = init_bitcoind()?;
+    let receiver = bitcoind.create_wallet("receiver")?;
+    let receiver_address = receiver.get_new_address(None, receiver_address_type)?.assume_checked();
+    let sender = bitcoind.create_wallet("sender")?;
+    let sender_address = sender.get_new_address(None, sender_address_type)?.assume_checked();
+    bitcoind.client.generate_to_address(1, &receiver_address)?;
+    bitcoind.client.generate_to_address(101, &sender_address)?;
+
+    assert_eq!(
+        Amount::from_btc(50.0)?,
+        receiver.get_balances()?.mine.trusted,
+        "receiver doesn't own bitcoin"
+    );
+
+    assert_eq!(
+        Amount::from_btc(50.0)?,
+        sender.get_balances()?.mine.trusted,
+        "sender doesn't own bitcoin"
+    );
+    Ok((bitcoind, sender, receiver))
+}
+
+pub async fn init_directory(port: u16, local_cert_key: (Vec<u8>, Vec<u8>)) -> Result<(), Error> {
+    let docker: Cli = Cli::default();
+    let timeout = Duration::from_secs(2);
+    let db = docker.run(Redis);
+    let db_host = format!("127.0.0.1:{}", db.get_host_port_ipv4(6379));
+    println!("Database running on {}", db.get_host_port_ipv4(6379));
+    payjoin_directory::listen_tcp_with_tls(port, db_host, timeout, local_cert_key).await
+}
+
+pub async fn init_ohttp_relay(
+    port: u16,
+    gateway_origin: http::Uri,
+) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
+    ohttp_relay::listen_tcp(port, gateway_origin).await
+}
+
+// generates or gets a DER encoded localhost cert and key.
+pub fn local_cert_key() -> (Vec<u8>, Vec<u8>) {
+    let cert =
+        rcgen::generate_simple_self_signed(vec!["0.0.0.0".to_string(), "localhost".to_string()])
+            .expect("Failed to generate cert");
+    let cert_der = cert.serialize_der().expect("Failed to serialize cert");
+    let key_der = cert.serialize_private_key_der();
+    (cert_der, key_der)
+}
+
+pub fn find_free_port() -> u16 {
+    let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
+    listener.local_addr().unwrap().port()
+}
diff --git a/payjoin/Cargo.toml b/payjoin/Cargo.toml
index 2fd573fd..3a973759 100644
--- a/payjoin/Cargo.toml
+++ b/payjoin/Cargo.toml
@@ -41,6 +41,7 @@ serde_json = "1.0.108"
 bitcoind = { version = "0.36.0", features = ["0_21_2"] }
 http = "1"
 payjoin-directory = { path = "../payjoin-directory", features = ["_danger-local-https"] }
+payjoin-test-utils = { path = "../payjoin-test-utils" }
 ohttp-relay = "0.0.8"
 once_cell = "1"
 rcgen = { version = "0.11" }
diff --git a/payjoin/tests/integration.rs b/payjoin/tests/integration.rs
index a82e581a..c53e1ebc 100644
--- a/payjoin/tests/integration.rs
+++ b/payjoin/tests/integration.rs
@@ -1,7 +1,6 @@
 #[cfg(all(feature = "send", feature = "receive"))]
 mod integration {
     use std::collections::HashMap;
-    use std::env;
     use std::str::FromStr;
 
     use bitcoin::policy::DEFAULT_MIN_RELAY_TX_FEE;
@@ -10,11 +9,11 @@ mod integration {
     use bitcoin::{Amount, FeeRate, OutPoint, TxIn, TxOut, Weight};
     use bitcoind::bitcoincore_rpc::json::{AddressType, WalletProcessPsbtResult};
     use bitcoind::bitcoincore_rpc::{self, RpcApi};
-    use log::{log_enabled, Level};
     use once_cell::sync::{Lazy, OnceCell};
     use payjoin::receive::InputPair;
     use payjoin::send::SenderBuilder;
     use payjoin::{PjUri, PjUriBuilder, Request, Uri};
+    use payjoin_test_utils::*;
     use tracing_subscriber::{EnvFilter, FmtSubscriber};
     use url::Url;
 
@@ -182,8 +181,6 @@ mod integration {
         use payjoin::receive::v2::{PayjoinProposal, Receiver, UncheckedProposal};
         use payjoin::{HpkeKeyPair, OhttpKeys, PjUri, UriExt};
         use reqwest::{Client, ClientBuilder, Error, Response};
-        use testcontainers_modules::redis::Redis;
-        use testcontainers_modules::testcontainers::clients::Cli;
 
         use super::*;
 
@@ -307,8 +304,8 @@ mod integration {
             let directory = Url::parse(&format!("https://localhost:{}", directory_port)).unwrap();
             let gateway_origin = http::Uri::from_str(directory.as_str()).unwrap();
             tokio::select!(
-            _ = ohttp_relay::listen_tcp(ohttp_relay_port, gateway_origin) => panic!("Ohttp relay is long running"),
-            _ = init_directory(directory_port, (cert.clone(), key)) => panic!("Directory server is long running"),
+            _ = payjoin_test_utils::init_ohttp_relay(ohttp_relay_port, gateway_origin) => panic!("Ohttp relay is long running"),
+            _ = payjoin_test_utils::init_directory(directory_port, (cert.clone(), key)) => panic!("Directory server is long running"),
             res = do_v2_send_receive(ohttp_relay, directory, cert) => assert!(res.is_ok(), "v2 send receive failed: {:#?}", res)
             );
 
@@ -770,30 +767,6 @@ mod integration {
             }
         }
 
-        async fn init_directory(
-            port: u16,
-            local_cert_key: (Vec<u8>, Vec<u8>),
-        ) -> Result<(), BoxError> {
-            let docker: Cli = Cli::default();
-            let timeout = Duration::from_secs(2);
-            let db = docker.run(Redis);
-            let db_host = format!("127.0.0.1:{}", db.get_host_port_ipv4(6379));
-            println!("Database running on {}", db.get_host_port_ipv4(6379));
-            payjoin_directory::listen_tcp_with_tls(port, db_host, timeout, local_cert_key).await
-        }
-
-        // generates or gets a DER encoded localhost cert and key.
-        fn local_cert_key() -> (Vec<u8>, Vec<u8>) {
-            let cert = rcgen::generate_simple_self_signed(vec![
-                "0.0.0.0".to_string(),
-                "localhost".to_string(),
-            ])
-            .expect("Failed to generate cert");
-            let cert_der = cert.serialize_der().expect("Failed to serialize cert");
-            let key_der = cert.serialize_private_key_der();
-            (cert_der, key_der)
-        }
-
         fn initialize_session(
             address: Address,
             directory: Url,
@@ -905,11 +878,6 @@ mod integration {
                 ))
         }
 
-        fn find_free_port() -> u16 {
-            let listener = std::net::TcpListener::bind("0.0.0.0:0").unwrap();
-            listener.local_addr().unwrap().port()
-        }
-
         async fn wait_for_service_ready(
             service_url: Url,
             agent: Arc<Client>,
@@ -1152,38 +1120,6 @@ mod integration {
         });
     }
 
-    fn init_bitcoind_sender_receiver(
-        sender_address_type: Option<AddressType>,
-        receiver_address_type: Option<AddressType>,
-    ) -> Result<(bitcoind::BitcoinD, bitcoincore_rpc::Client, bitcoincore_rpc::Client), BoxError>
-    {
-        let bitcoind_exe =
-            env::var("BITCOIND_EXE").ok().or_else(|| bitcoind::downloaded_exe_path().ok()).unwrap();
-        let mut conf = bitcoind::Conf::default();
-        conf.view_stdout = log_enabled!(Level::Debug);
-        let bitcoind = bitcoind::BitcoinD::with_conf(bitcoind_exe, &conf)?;
-        let receiver = bitcoind.create_wallet("receiver")?;
-        let receiver_address =
-            receiver.get_new_address(None, receiver_address_type)?.assume_checked();
-        let sender = bitcoind.create_wallet("sender")?;
-        let sender_address = sender.get_new_address(None, sender_address_type)?.assume_checked();
-        bitcoind.client.generate_to_address(1, &receiver_address)?;
-        bitcoind.client.generate_to_address(101, &sender_address)?;
-
-        assert_eq!(
-            Amount::from_btc(50.0)?,
-            receiver.get_balances()?.mine.trusted,
-            "receiver doesn't own bitcoin"
-        );
-
-        assert_eq!(
-            Amount::from_btc(50.0)?,
-            sender.get_balances()?.mine.trusted,
-            "sender doesn't own bitcoin"
-        );
-        Ok((bitcoind, sender, receiver))
-    }
-
     fn build_original_psbt(
         sender: &bitcoincore_rpc::Client,
         pj_uri: &PjUri,

From 71ce2016c5368d302979a481631b16b35aa4520b Mon Sep 17 00:00:00 2001
From: DanGould <d@ngould.dev>
Date: Tue, 3 Dec 2024 13:29:36 -0500
Subject: [PATCH 2/2] Ignore unused test, don't just TODO it

---
 payjoin/tests/integration.rs | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/payjoin/tests/integration.rs b/payjoin/tests/integration.rs
index c53e1ebc..317d0aa3 100644
--- a/payjoin/tests/integration.rs
+++ b/payjoin/tests/integration.rs
@@ -60,16 +60,16 @@ mod integration {
             do_v1_to_v1(sender, receiver, false)
         }
 
-        // TODO: Not supported by bitcoind 0_21_2. Later versions fail for unknown reasons
-        //#[test]
-        //fn v1_to_v1_taproot() -> Result<(), BoxError> {
-        //    init_tracing();
-        //    let (_bitcoind, sender, receiver) = init_bitcoind_sender_receiver(
-        //        Some(AddressType::Bech32m),
-        //        Some(AddressType::Bech32m),
-        //    )?;
-        //    do_v1_to_v1(sender, receiver, false)
-        //}
+        #[ignore] // TODO: Not supported by bitcoind 0_21_2. Later versions fail for unknown reasons
+        #[test]
+        fn v1_to_v1_taproot() -> Result<(), BoxError> {
+            init_tracing();
+            let (_bitcoind, sender, receiver) = init_bitcoind_sender_receiver(
+                Some(AddressType::Bech32m),
+                Some(AddressType::Bech32m),
+            )?;
+            do_v1_to_v1(sender, receiver, false)
+        }
 
         fn do_v1_to_v1(
             sender: bitcoincore_rpc::Client,