diff --git a/ark-client/src/lib.rs b/ark-client/src/lib.rs index ab81622..25480a4 100644 --- a/ark-client/src/lib.rs +++ b/ark-client/src/lib.rs @@ -127,7 +127,6 @@ pub use error::Error; /// # &self, /// # server_pk: XOnlyPublicKey, /// # exit_delay: bitcoin::Sequence, -/// # descriptor_template: &str, /// # network: Network, /// # ) -> Result { /// # unimplemented!() diff --git a/ark-client/src/round.rs b/ark-client/src/round.rs index f260315..5cfef74 100644 --- a/ark-client/src/round.rs +++ b/ark-client/src/round.rs @@ -43,16 +43,34 @@ where { /// Lift all pending VTXOs and boarding outputs into the Ark, converting them into new, /// confirmed VTXOs. We do this by "joining the next round". - pub async fn board(&self, rng: &mut R) -> Result<(), Error> + pub async fn settle_all(&self, rng: &mut R) -> Result<(), Error> where R: Rng + CryptoRng + Clone, { - // Get off-chain address and send all funds to this address, no change output 🦄 - let (to_address, _) = self.get_offchain_address()?; - let (boarding_inputs, vtxo_inputs, total_amount) = self.fetch_round_transaction_inputs().await?; + self.settle(rng, boarding_inputs, vtxo_inputs, total_amount) + .await?; + + Ok(()) + } + + /// Lift all pending VTXOs and boarding outputs into the Ark, converting them into new, + /// confirmed VTXOs. We do this by "joining the next round". + pub async fn settle( + &self, + rng: &mut R, + boarding_inputs: Vec, + vtxo_inputs: Vec, + total_amount: Amount, + ) -> Result<(), Error> + where + R: Rng + CryptoRng + Clone, + { + // Get off-chain address and send all funds to this address, no change output 🦄 + let (to_address, _) = self.get_offchain_address()?; + tracing::debug!( offchain_adress = %to_address.encode(), ?boarding_inputs, @@ -153,11 +171,8 @@ where Ok(txid) } - /// Get all the [`round::OnChainInput`]s and [`round::VtxoInput`]s that can be used to join an - /// upcoming round. - async fn fetch_round_transaction_inputs( - &self, - ) -> Result<(Vec, Vec, Amount), Error> { + /// Get all the [`round::OnChainInput`]s that can be used to join an upcoming round. + pub async fn fetch_boarding_inputs(&self) -> Result<(Vec, Amount), Error> { // Get all known boarding outputs. let boarding_outputs = self.inner.wallet.get_boarding_outputs()?; @@ -194,6 +209,13 @@ where } } + Ok((boarding_inputs, total_amount)) + } + + /// Get all [`round::VtxoInput`]s that can be used to join an upcoming round. + pub async fn fetch_pending_vtxos(&self) -> Result<(Vec, Amount), Error> { + let mut total_amount = Amount::ZERO; + let spendable_vtxos = self.spendable_vtxos().await?; for (vtxo_outpoints, _) in spendable_vtxos.iter() { @@ -218,7 +240,22 @@ where }) .collect::>(); - Ok((boarding_inputs, vtxo_inputs, total_amount)) + Ok((vtxo_inputs, total_amount)) + } + + /// Get all the [`round::OnChainInput`]s and [`round::VtxoInput`]s that can be used to join an + /// upcoming round. + async fn fetch_round_transaction_inputs( + &self, + ) -> Result<(Vec, Vec, Amount), Error> { + let (boarding_inputs, boarding_input_amount) = self.fetch_boarding_inputs().await?; + let (vtxo_inputs, vtxo_input_amount) = self.fetch_pending_vtxos().await?; + + Ok(( + boarding_inputs, + vtxo_inputs, + boarding_input_amount + vtxo_input_amount, + )) } async fn join_next_ark_round( diff --git a/e2e-tests/tests/e2e_concurrent_boarding.rs b/e2e-tests/tests/e2e_concurrent_boarding.rs index b09d6b1..d1f78cb 100644 --- a/e2e-tests/tests/e2e_concurrent_boarding.rs +++ b/e2e-tests/tests/e2e_concurrent_boarding.rs @@ -62,20 +62,20 @@ pub async fn concurrent_boarding() { let alice_task = tokio::spawn({ async move { let mut rng = StdRng::from_entropy(); - alice.board(&mut rng).await.unwrap(); + alice.settle_all(&mut rng).await.unwrap(); alice } }); let bob_task = tokio::spawn(async move { let mut rng = StdRng::from_entropy(); - bob.board(&mut rng).await.unwrap(); + bob.settle_all(&mut rng).await.unwrap(); bob }); let claire_task = tokio::spawn(async move { let mut rng = StdRng::from_entropy(); - claire.board(&mut rng).await.unwrap(); + claire.settle_all(&mut rng).await.unwrap(); claire }); @@ -144,20 +144,20 @@ pub async fn concurrent_boarding() { let alice_task = tokio::spawn({ async move { let mut rng = StdRng::from_entropy(); - alice.board(&mut rng).await.unwrap(); + alice.settle_all(&mut rng).await.unwrap(); alice } }); let bob_task = tokio::spawn(async move { let mut rng = StdRng::from_entropy(); - bob.board(&mut rng).await.unwrap(); + bob.settle_all(&mut rng).await.unwrap(); bob }); let claire_task = tokio::spawn(async move { let mut rng = StdRng::from_entropy(); - claire.board(&mut rng).await.unwrap(); + claire.settle_all(&mut rng).await.unwrap(); claire }); diff --git a/e2e-tests/tests/e2e_send_onchain_vtxo_and_boarding_output.rs b/e2e-tests/tests/e2e_send_onchain_vtxo_and_boarding_output.rs index 689c3a6..2becdcf 100644 --- a/e2e-tests/tests/e2e_send_onchain_vtxo_and_boarding_output.rs +++ b/e2e-tests/tests/e2e_send_onchain_vtxo_and_boarding_output.rs @@ -43,7 +43,7 @@ pub async fn send_onchain_vtxo_and_boarding_output() { assert_eq!(offchain_balance.total(), Amount::ZERO); - alice.board(&mut rng).await.unwrap(); + alice.settle_all(&mut rng).await.unwrap(); wait_until_balance(&alice, fund_amount, Amount::ZERO).await; alice.commit_vtxos_on_chain().await.unwrap(); diff --git a/e2e-tests/tests/e2e_two_party.rs b/e2e-tests/tests/e2e_two_party.rs index c6cec88..de3b03f 100644 --- a/e2e-tests/tests/e2e_two_party.rs +++ b/e2e-tests/tests/e2e_two_party.rs @@ -55,7 +55,15 @@ pub async fn e2e() { assert_eq!(alice_offchain_balance.total(), Amount::ZERO); assert_eq!(bob_offchain_balance.total(), Amount::ZERO); - alice.board(&mut rng).await.unwrap(); + { + let (boarding_inputs, amount) = alice.fetch_boarding_inputs().await.unwrap(); + tracing::debug!(?boarding_inputs, ?amount, "Settling boarding inputs"); + alice + .settle(&mut rng, boarding_inputs, vec![], amount) + .await + .unwrap(); + } + tokio::time::sleep(std::time::Duration::from_secs(2)).await; let alice_offchain_balance = alice.offchain_balance().await.unwrap(); @@ -107,7 +115,14 @@ pub async fn e2e() { assert_eq!(bob_offchain_balance.confirmed(), Amount::ZERO); assert_eq!(bob_offchain_balance.pending(), send_to_bob_vtxo_amount); - bob.board(&mut rng).await.unwrap(); + { + let (pending_vtxos, amount) = bob.fetch_pending_vtxos().await.unwrap(); + tracing::debug!(?pending_vtxos, ?amount, "Settling bob's vtxo"); + bob.settle(&mut rng, vec![], pending_vtxos, amount) + .await + .unwrap(); + } + tokio::time::sleep(std::time::Duration::from_secs(2)).await; let alice_offchain_balance = alice.offchain_balance().await.unwrap(); @@ -127,7 +142,7 @@ pub async fn e2e() { assert_eq!(bob_offchain_balance.confirmed(), send_to_bob_vtxo_amount); assert_eq!(bob_offchain_balance.pending(), Amount::ZERO); - alice.board(&mut rng).await.unwrap(); + alice.settle_all(&mut rng).await.unwrap(); tokio::time::sleep(std::time::Duration::from_secs(2)).await; let alice_offchain_balance = alice.offchain_balance().await.unwrap();