Remove traits in favor of using the wallet struct directly

Abstracting over the individual bits of functionality of the wallet
does have its place, especially if one wants to keep a separation
of an abstract protocol library that other people can use with their
own wallets.

However, at the moment, the traits only cause unnecessary friction.
We can always add such abstraction layers again once we need them.
This commit is contained in:
Thomas Eizinger 2021-03-02 12:22:23 +11:00
parent 8c0df23647
commit 45cff81ea5
No known key found for this signature in database
GPG Key ID: 651AC83A6C6C8B96
6 changed files with 96 additions and 203 deletions

View File

@ -19,13 +19,11 @@ pub use ::bitcoin::{util::amount::Amount, Address, Network, Transaction, Txid};
pub use ecdsa_fun::{adaptor::EncryptedSignature, fun::Scalar, Signature}; pub use ecdsa_fun::{adaptor::EncryptedSignature, fun::Scalar, Signature};
pub use wallet::Wallet; pub use wallet::Wallet;
use crate::execution_params::ExecutionParams;
use ::bitcoin::{ use ::bitcoin::{
hashes::{hex::ToHex, Hash}, hashes::{hex::ToHex, Hash},
secp256k1, SigHash, secp256k1, SigHash,
}; };
use anyhow::{anyhow, bail, Result}; use anyhow::{anyhow, bail, Result};
use async_trait::async_trait;
use ecdsa_fun::{ use ecdsa_fun::{
adaptor::{Adaptor, HashTranscript}, adaptor::{Adaptor, HashTranscript},
fun::Point, fun::Point,
@ -201,45 +199,6 @@ pub fn build_shared_output_descriptor(A: Point, B: Point) -> Descriptor<bitcoin:
Descriptor::Wsh(Wsh::new(miniscript).expect("a valid descriptor")) Descriptor::Wsh(Wsh::new(miniscript).expect("a valid descriptor"))
} }
#[async_trait]
pub trait SignTxLock {
async fn sign_tx_lock(&self, tx_lock: TxLock) -> Result<Transaction>;
}
#[async_trait]
pub trait BroadcastSignedTransaction {
async fn broadcast_signed_transaction(&self, transaction: Transaction) -> Result<Txid>;
}
#[async_trait]
pub trait WatchForRawTransaction {
async fn watch_for_raw_transaction(&self, txid: Txid) -> Result<Transaction>;
}
#[async_trait]
pub trait WaitForTransactionFinality {
async fn wait_for_transaction_finality(
&self,
txid: Txid,
execution_params: ExecutionParams,
) -> Result<()>;
}
#[async_trait]
pub trait GetBlockHeight {
async fn get_block_height(&self) -> Result<BlockHeight>;
}
#[async_trait]
pub trait TransactionBlockHeight {
async fn transaction_block_height(&self, txid: Txid) -> Result<BlockHeight>;
}
#[async_trait]
pub trait GetRawTransaction {
async fn get_raw_transaction(&self, txid: Txid) -> Result<Transaction>;
}
pub fn recover(S: PublicKey, sig: Signature, encsig: EncryptedSignature) -> Result<SecretKey> { pub fn recover(S: PublicKey, sig: Signature, encsig: EncryptedSignature) -> Result<SecretKey> {
let adaptor = Adaptor::<HashTranscript<Sha256>, Deterministic<Sha256>>::default(); let adaptor = Adaptor::<HashTranscript<Sha256>, Deterministic<Sha256>>::default();
@ -251,25 +210,22 @@ pub fn recover(S: PublicKey, sig: Signature, encsig: EncryptedSignature) -> Resu
Ok(s) Ok(s)
} }
pub async fn poll_until_block_height_is_gte<B>(client: &B, target: BlockHeight) -> Result<()> pub async fn poll_until_block_height_is_gte(
where client: &crate::bitcoin::Wallet,
B: GetBlockHeight, target: BlockHeight,
{ ) -> Result<()> {
while client.get_block_height().await? < target { while client.get_block_height().await? < target {
tokio::time::sleep(std::time::Duration::from_secs(1)).await; tokio::time::sleep(std::time::Duration::from_secs(1)).await;
} }
Ok(()) Ok(())
} }
pub async fn current_epoch<W>( pub async fn current_epoch(
bitcoin_wallet: &W, bitcoin_wallet: &crate::bitcoin::Wallet,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
lock_tx_id: ::bitcoin::Txid, lock_tx_id: ::bitcoin::Txid,
) -> Result<ExpiredTimelocks> ) -> Result<ExpiredTimelocks> {
where
W: WatchForRawTransaction + TransactionBlockHeight + GetBlockHeight,
{
let current_block_height = bitcoin_wallet.get_block_height().await?; let current_block_height = bitcoin_wallet.get_block_height().await?;
let lock_tx_height = bitcoin_wallet.transaction_block_height(lock_tx_id).await?; let lock_tx_height = bitcoin_wallet.transaction_block_height(lock_tx_id).await?;
let cancel_timelock_height = lock_tx_height + cancel_timelock; let cancel_timelock_height = lock_tx_height + cancel_timelock;
@ -285,14 +241,11 @@ where
} }
} }
pub async fn wait_for_cancel_timelock_to_expire<W>( pub async fn wait_for_cancel_timelock_to_expire(
bitcoin_wallet: &W, bitcoin_wallet: &crate::bitcoin::Wallet,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
lock_tx_id: ::bitcoin::Txid, lock_tx_id: ::bitcoin::Txid,
) -> Result<()> ) -> Result<()> {
where
W: WatchForRawTransaction + TransactionBlockHeight + GetBlockHeight,
{
let tx_lock_height = bitcoin_wallet.transaction_block_height(lock_tx_id).await?; let tx_lock_height = bitcoin_wallet.transaction_block_height(lock_tx_id).await?;
poll_until_block_height_is_gte(bitcoin_wallet, tx_lock_height + cancel_timelock).await?; poll_until_block_height_is_gte(bitcoin_wallet, tx_lock_height + cancel_timelock).await?;

View File

@ -1,14 +1,9 @@
use crate::{ use crate::{
bitcoin::{ bitcoin::{timelocks::BlockHeight, Address, Amount, Transaction, TxLock},
timelocks::BlockHeight, Address, Amount, BroadcastSignedTransaction, GetBlockHeight,
GetRawTransaction, SignTxLock, Transaction, TransactionBlockHeight, TxLock,
WaitForTransactionFinality, WatchForRawTransaction,
},
execution_params::ExecutionParams, execution_params::ExecutionParams,
}; };
use ::bitcoin::{util::psbt::PartiallySignedTransaction, Txid}; use ::bitcoin::{util::psbt::PartiallySignedTransaction, Txid};
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use async_trait::async_trait;
use backoff::{backoff::Constant as ConstantBackoff, future::retry}; use backoff::{backoff::Constant as ConstantBackoff, future::retry};
use bdk::{ use bdk::{
blockchain::{noop_progress, Blockchain, ElectrumBlockchain}, blockchain::{noop_progress, Blockchain, ElectrumBlockchain},
@ -152,17 +147,19 @@ impl Wallet {
self.inner.lock().await.network() self.inner.lock().await.network()
} }
/// Selects an appropriate [`FeeRate`] to be used for getting transactions pub async fn broadcast_signed_transaction(&self, transaction: Transaction) -> Result<Txid> {
/// confirmed within a reasonable amount of time. let txid = transaction.txid();
fn select_feerate(&self) -> FeeRate {
// TODO: This should obviously not be a const :) self.inner
FeeRate::from_sat_per_vb(5.0) .lock()
} .await
.broadcast(transaction)
.with_context(|| format!("failed to broadcast transaction {}", txid))?;
Ok(txid)
} }
#[async_trait] pub async fn sign_tx_lock(&self, tx_lock: TxLock) -> Result<Transaction> {
impl SignTxLock for Wallet {
async fn sign_tx_lock(&self, tx_lock: TxLock) -> Result<Transaction> {
let txid = tx_lock.txid(); let txid = tx_lock.txid();
tracing::debug!("signing tx lock: {}", txid); tracing::debug!("signing tx lock: {}", txid);
let psbt = PartiallySignedTransaction::from(tx_lock); let psbt = PartiallySignedTransaction::from(tx_lock);
@ -174,26 +171,14 @@ impl SignTxLock for Wallet {
tracing::debug!("signed tx lock: {}", txid); tracing::debug!("signed tx lock: {}", txid);
Ok(tx) Ok(tx)
} }
pub async fn get_raw_transaction(&self, txid: Txid) -> Result<Transaction> {
self.get_tx(txid)
.await?
.ok_or_else(|| anyhow!("Could not get raw tx with id: {}", txid))
} }
#[async_trait] pub async fn watch_for_raw_transaction(&self, txid: Txid) -> Result<Transaction> {
impl BroadcastSignedTransaction for Wallet {
async fn broadcast_signed_transaction(&self, transaction: Transaction) -> Result<Txid> {
let txid = transaction.txid();
self.inner
.lock()
.await
.broadcast(transaction)
.with_context(|| format!("failed to broadcast transaction {}", txid))?;
Ok(txid)
}
}
#[async_trait]
impl WatchForRawTransaction for Wallet {
async fn watch_for_raw_transaction(&self, txid: Txid) -> Result<Transaction> {
tracing::debug!("watching for tx: {}", txid); tracing::debug!("watching for tx: {}", txid);
let tx = retry(ConstantBackoff::new(Duration::from_secs(1)), || async { let tx = retry(ConstantBackoff::new(Duration::from_secs(1)), || async {
let client = Client::new(self.rpc_url.as_ref()) let client = Client::new(self.rpc_url.as_ref())
@ -214,20 +199,8 @@ impl WatchForRawTransaction for Wallet {
Ok(tx) Ok(tx)
} }
}
#[async_trait] pub async fn get_block_height(&self) -> Result<BlockHeight> {
impl GetRawTransaction for Wallet {
async fn get_raw_transaction(&self, txid: Txid) -> Result<Transaction> {
self.get_tx(txid)
.await?
.ok_or_else(|| anyhow!("Could not get raw tx with id: {}", txid))
}
}
#[async_trait]
impl GetBlockHeight for Wallet {
async fn get_block_height(&self) -> Result<BlockHeight> {
let url = blocks_tip_height_url(&self.http_url)?; let url = blocks_tip_height_url(&self.http_url)?;
let height = retry(ConstantBackoff::new(Duration::from_secs(1)), || async { let height = retry(ConstantBackoff::new(Duration::from_secs(1)), || async {
let height = reqwest::Client::new() let height = reqwest::Client::new()
@ -247,11 +220,8 @@ impl GetBlockHeight for Wallet {
Ok(BlockHeight::new(height)) Ok(BlockHeight::new(height))
} }
}
#[async_trait] pub async fn transaction_block_height(&self, txid: Txid) -> Result<BlockHeight> {
impl TransactionBlockHeight for Wallet {
async fn transaction_block_height(&self, txid: Txid) -> Result<BlockHeight> {
let url = tx_status_url(txid, &self.http_url)?; let url = tx_status_url(txid, &self.http_url)?;
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
struct TransactionStatus { struct TransactionStatus {
@ -281,11 +251,8 @@ impl TransactionBlockHeight for Wallet {
Ok(BlockHeight::new(height)) Ok(BlockHeight::new(height))
} }
}
#[async_trait] pub async fn wait_for_transaction_finality(
impl WaitForTransactionFinality for Wallet {
async fn wait_for_transaction_finality(
&self, &self,
txid: Txid, txid: Txid,
execution_params: ExecutionParams, execution_params: ExecutionParams,
@ -315,6 +282,13 @@ impl WaitForTransactionFinality for Wallet {
Ok(()) Ok(())
} }
/// Selects an appropriate [`FeeRate`] to be used for getting transactions
/// confirmed within a reasonable amount of time.
fn select_feerate(&self) -> FeeRate {
// TODO: This should obviously not be a const :)
FeeRate::from_sat_per_vb(5.0)
}
} }
fn tx_status_url(txid: Txid, base_url: &Url) -> Result<Url> { fn tx_status_url(txid: Txid, base_url: &Url) -> Result<Url> {

View File

@ -2,8 +2,7 @@ use crate::{
bitcoin, bitcoin,
bitcoin::{ bitcoin::{
current_epoch, wait_for_cancel_timelock_to_expire, CancelTimelock, ExpiredTimelocks, current_epoch, wait_for_cancel_timelock_to_expire, CancelTimelock, ExpiredTimelocks,
GetBlockHeight, PunishTimelock, TransactionBlockHeight, TxCancel, TxRefund, PunishTimelock, TxCancel, TxRefund,
WatchForRawTransaction,
}, },
execution_params::ExecutionParams, execution_params::ExecutionParams,
monero, monero,
@ -325,10 +324,10 @@ pub struct State3 {
} }
impl State3 { impl State3 {
pub async fn wait_for_cancel_timelock_to_expire<W>(&self, bitcoin_wallet: &W) -> Result<()> pub async fn wait_for_cancel_timelock_to_expire(
where &self,
W: WatchForRawTransaction + TransactionBlockHeight + GetBlockHeight, bitcoin_wallet: &bitcoin::Wallet,
{ ) -> Result<()> {
wait_for_cancel_timelock_to_expire( wait_for_cancel_timelock_to_expire(
bitcoin_wallet, bitcoin_wallet,
self.cancel_timelock, self.cancel_timelock,
@ -337,10 +336,10 @@ impl State3 {
.await .await
} }
pub async fn expired_timelocks<W>(&self, bitcoin_wallet: &W) -> Result<ExpiredTimelocks> pub async fn expired_timelocks(
where &self,
W: WatchForRawTransaction + TransactionBlockHeight + GetBlockHeight, bitcoin_wallet: &bitcoin::Wallet,
{ ) -> Result<ExpiredTimelocks> {
current_epoch( current_epoch(
bitcoin_wallet, bitcoin_wallet,
self.cancel_timelock, self.cancel_timelock,

View File

@ -1,10 +1,8 @@
use crate::{ use crate::{
bitcoin, bitcoin,
bitcoin::{ bitcoin::{
poll_until_block_height_is_gte, BlockHeight, BroadcastSignedTransaction, CancelTimelock, poll_until_block_height_is_gte, BlockHeight, CancelTimelock, EncryptedSignature,
EncryptedSignature, GetBlockHeight, GetRawTransaction, PunishTimelock, PunishTimelock, TxCancel, TxLock, TxRefund,
TransactionBlockHeight, TxCancel, TxLock, TxRefund, WaitForTransactionFinality,
WatchForRawTransaction,
}, },
execution_params::ExecutionParams, execution_params::ExecutionParams,
monero, monero,
@ -31,14 +29,11 @@ use tracing::info;
// TODO(Franck): Use helper functions from xmr-btc instead of re-writing them // TODO(Franck): Use helper functions from xmr-btc instead of re-writing them
// here // here
pub async fn wait_for_locked_bitcoin<W>( pub async fn wait_for_locked_bitcoin(
lock_bitcoin_txid: bitcoin::Txid, lock_bitcoin_txid: bitcoin::Txid,
bitcoin_wallet: Arc<W>, bitcoin_wallet: &bitcoin::Wallet,
execution_params: ExecutionParams, execution_params: ExecutionParams,
) -> Result<()> ) -> Result<()> {
where
W: WatchForRawTransaction + WaitForTransactionFinality,
{
// We assume we will see Bob's transaction in the mempool first. // We assume we will see Bob's transaction in the mempool first.
timeout( timeout(
execution_params.bob_time_to_act, execution_params.bob_time_to_act,
@ -130,13 +125,10 @@ pub fn build_bitcoin_redeem_transaction(
Ok(tx) Ok(tx)
} }
pub async fn publish_bitcoin_redeem_transaction<W>( pub async fn publish_bitcoin_redeem_transaction(
redeem_tx: bitcoin::Transaction, redeem_tx: bitcoin::Transaction,
bitcoin_wallet: Arc<W>, bitcoin_wallet: Arc<bitcoin::Wallet>,
) -> Result<::bitcoin::Txid> ) -> Result<::bitcoin::Txid> {
where
W: BroadcastSignedTransaction + WaitForTransactionFinality,
{
info!("Attempting to publish bitcoin redeem txn"); info!("Attempting to publish bitcoin redeem txn");
let txid = bitcoin_wallet let txid = bitcoin_wallet
.broadcast_signed_transaction(redeem_tx) .broadcast_signed_transaction(redeem_tx)
@ -145,17 +137,14 @@ where
Ok(txid) Ok(txid)
} }
pub async fn publish_cancel_transaction<W>( pub async fn publish_cancel_transaction(
tx_lock: TxLock, tx_lock: TxLock,
a: bitcoin::SecretKey, a: bitcoin::SecretKey,
B: bitcoin::PublicKey, B: bitcoin::PublicKey,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
tx_cancel_sig_bob: bitcoin::Signature, tx_cancel_sig_bob: bitcoin::Signature,
bitcoin_wallet: Arc<W>, bitcoin_wallet: Arc<bitcoin::Wallet>,
) -> Result<bitcoin::TxCancel> ) -> Result<bitcoin::TxCancel> {
where
W: GetRawTransaction + TransactionBlockHeight + GetBlockHeight + BroadcastSignedTransaction,
{
// First wait for cancel timelock to expire // First wait for cancel timelock to expire
let tx_lock_height = bitcoin_wallet let tx_lock_height = bitcoin_wallet
.transaction_block_height(tx_lock.txid()) .transaction_block_height(tx_lock.txid())
@ -194,18 +183,15 @@ where
Ok(tx_cancel) Ok(tx_cancel)
} }
pub async fn wait_for_bitcoin_refund<W>( pub async fn wait_for_bitcoin_refund(
tx_cancel: &TxCancel, tx_cancel: &TxCancel,
cancel_tx_height: BlockHeight, cancel_tx_height: BlockHeight,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
refund_address: &bitcoin::Address, refund_address: &bitcoin::Address,
bitcoin_wallet: Arc<W>, bitcoin_wallet: &bitcoin::Wallet,
) -> Result<(bitcoin::TxRefund, Option<bitcoin::Transaction>)> ) -> Result<(bitcoin::TxRefund, Option<bitcoin::Transaction>)> {
where
W: GetBlockHeight + WatchForRawTransaction,
{
let punish_timelock_expired = let punish_timelock_expired =
poll_until_block_height_is_gte(bitcoin_wallet.as_ref(), cancel_tx_height + punish_timelock); poll_until_block_height_is_gte(bitcoin_wallet, cancel_tx_height + punish_timelock);
let tx_refund = bitcoin::TxRefund::new(tx_cancel, refund_address); let tx_refund = bitcoin::TxRefund::new(tx_cancel, refund_address);
@ -267,14 +253,11 @@ pub fn build_bitcoin_punish_transaction(
Ok(signed_tx_punish) Ok(signed_tx_punish)
} }
pub async fn publish_bitcoin_punish_transaction<W>( pub async fn publish_bitcoin_punish_transaction(
punish_tx: bitcoin::Transaction, punish_tx: bitcoin::Transaction,
bitcoin_wallet: Arc<W>, bitcoin_wallet: Arc<bitcoin::Wallet>,
execution_params: ExecutionParams, execution_params: ExecutionParams,
) -> Result<bitcoin::Txid> ) -> Result<bitcoin::Txid> {
where
W: BroadcastSignedTransaction + WaitForTransactionFinality,
{
let txid = bitcoin_wallet let txid = bitcoin_wallet
.broadcast_signed_transaction(punish_tx) .broadcast_signed_transaction(punish_tx)
.await?; .await?;

View File

@ -2,10 +2,7 @@
//! Alice holds XMR and wishes receive BTC. //! Alice holds XMR and wishes receive BTC.
use crate::{ use crate::{
bitcoin, bitcoin,
bitcoin::{ bitcoin::ExpiredTimelocks,
ExpiredTimelocks, TransactionBlockHeight, WaitForTransactionFinality,
WatchForRawTransaction,
},
database, database,
database::Database, database::Database,
execution_params::ExecutionParams, execution_params::ExecutionParams,
@ -98,7 +95,7 @@ async fn run_until_internal(
} => { } => {
let _ = wait_for_locked_bitcoin( let _ = wait_for_locked_bitcoin(
state3.tx_lock.txid(), state3.tx_lock.txid(),
bitcoin_wallet.clone(), &bitcoin_wallet,
execution_params, execution_params,
) )
.await?; .await?;
@ -335,7 +332,7 @@ async fn run_until_internal(
tx_cancel_height, tx_cancel_height,
state3.punish_timelock, state3.punish_timelock,
&state3.refund_address, &state3.refund_address,
bitcoin_wallet.clone(), &bitcoin_wallet,
) )
.await?; .await?;

View File

@ -1,8 +1,7 @@
use crate::{ use crate::{
bitcoin::{ bitcoin::{
self, current_epoch, wait_for_cancel_timelock_to_expire, BroadcastSignedTransaction, self, current_epoch, wait_for_cancel_timelock_to_expire, CancelTimelock, ExpiredTimelocks,
CancelTimelock, ExpiredTimelocks, GetBlockHeight, GetRawTransaction, PunishTimelock, PunishTimelock, Transaction, TxCancel, Txid,
Transaction, TransactionBlockHeight, TxCancel, Txid, WatchForRawTransaction,
}, },
execution_params::ExecutionParams, execution_params::ExecutionParams,
monero, monero,
@ -269,10 +268,7 @@ impl State2 {
} }
} }
pub async fn lock_btc<W>(self, bitcoin_wallet: &W) -> Result<State3> pub async fn lock_btc(self, bitcoin_wallet: &bitcoin::Wallet) -> Result<State3> {
where
W: bitcoin::SignTxLock + bitcoin::BroadcastSignedTransaction,
{
let signed_tx_lock = bitcoin_wallet.sign_tx_lock(self.tx_lock.clone()).await?; let signed_tx_lock = bitcoin_wallet.sign_tx_lock(self.tx_lock.clone()).await?;
tracing::debug!("locking BTC in transaction {}", self.tx_lock.txid()); tracing::debug!("locking BTC in transaction {}", self.tx_lock.txid());
@ -363,10 +359,10 @@ impl State3 {
})) }))
} }
pub async fn wait_for_cancel_timelock_to_expire<W>(&self, bitcoin_wallet: &W) -> Result<()> pub async fn wait_for_cancel_timelock_to_expire(
where &self,
W: WatchForRawTransaction + TransactionBlockHeight + GetBlockHeight, bitcoin_wallet: &bitcoin::Wallet,
{ ) -> Result<()> {
wait_for_cancel_timelock_to_expire( wait_for_cancel_timelock_to_expire(
bitcoin_wallet, bitcoin_wallet,
self.cancel_timelock, self.cancel_timelock,
@ -399,10 +395,10 @@ impl State3 {
self.tx_lock.txid() self.tx_lock.txid()
} }
pub async fn current_epoch<W>(&self, bitcoin_wallet: &W) -> Result<ExpiredTimelocks> pub async fn current_epoch(
where &self,
W: WatchForRawTransaction + TransactionBlockHeight + GetBlockHeight, bitcoin_wallet: &bitcoin::Wallet,
{ ) -> Result<ExpiredTimelocks> {
current_epoch( current_epoch(
bitcoin_wallet, bitcoin_wallet,
self.cancel_timelock, self.cancel_timelock,
@ -443,10 +439,10 @@ impl State4 {
self.b.encsign(self.S_a_bitcoin, tx_redeem.digest()) self.b.encsign(self.S_a_bitcoin, tx_redeem.digest())
} }
pub async fn check_for_tx_cancel<W>(&self, bitcoin_wallet: &W) -> Result<Transaction> pub async fn check_for_tx_cancel(
where &self,
W: GetRawTransaction, bitcoin_wallet: &bitcoin::Wallet,
{ ) -> Result<Transaction> {
let tx_cancel = let tx_cancel =
bitcoin::TxCancel::new(&self.tx_lock, self.cancel_timelock, self.A, self.b.public()); bitcoin::TxCancel::new(&self.tx_lock, self.cancel_timelock, self.A, self.b.public());
@ -466,10 +462,7 @@ impl State4 {
Ok(tx) Ok(tx)
} }
pub async fn submit_tx_cancel<W>(&self, bitcoin_wallet: &W) -> Result<Txid> pub async fn submit_tx_cancel(&self, bitcoin_wallet: &bitcoin::Wallet) -> Result<Txid> {
where
W: BroadcastSignedTransaction,
{
let tx_cancel = let tx_cancel =
bitcoin::TxCancel::new(&self.tx_lock, self.cancel_timelock, self.A, self.b.public()); bitcoin::TxCancel::new(&self.tx_lock, self.cancel_timelock, self.A, self.b.public());
@ -490,10 +483,7 @@ impl State4 {
Ok(tx_id) Ok(tx_id)
} }
pub async fn watch_for_redeem_btc<W>(&self, bitcoin_wallet: &W) -> Result<State5> pub async fn watch_for_redeem_btc(&self, bitcoin_wallet: &bitcoin::Wallet) -> Result<State5> {
where
W: WatchForRawTransaction,
{
let tx_redeem = bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address); let tx_redeem = bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address);
let tx_redeem_encsig = self.b.encsign(self.S_a_bitcoin, tx_redeem.digest()); let tx_redeem_encsig = self.b.encsign(self.S_a_bitcoin, tx_redeem.digest());
@ -515,10 +505,10 @@ impl State4 {
}) })
} }
pub async fn wait_for_cancel_timelock_to_expire<W>(&self, bitcoin_wallet: &W) -> Result<()> pub async fn wait_for_cancel_timelock_to_expire(
where &self,
W: WatchForRawTransaction + TransactionBlockHeight + GetBlockHeight, bitcoin_wallet: &bitcoin::Wallet,
{ ) -> Result<()> {
wait_for_cancel_timelock_to_expire( wait_for_cancel_timelock_to_expire(
bitcoin_wallet, bitcoin_wallet,
self.cancel_timelock, self.cancel_timelock,
@ -527,10 +517,10 @@ impl State4 {
.await .await
} }
pub async fn expired_timelock<W>(&self, bitcoin_wallet: &W) -> Result<ExpiredTimelocks> pub async fn expired_timelock(
where &self,
W: WatchForRawTransaction + TransactionBlockHeight + GetBlockHeight, bitcoin_wallet: &bitcoin::Wallet,
{ ) -> Result<ExpiredTimelocks> {
current_epoch( current_epoch(
bitcoin_wallet, bitcoin_wallet,
self.cancel_timelock, self.cancel_timelock,
@ -540,14 +530,11 @@ impl State4 {
.await .await
} }
pub async fn refund_btc<W>( pub async fn refund_btc(
&self, &self,
bitcoin_wallet: &W, bitcoin_wallet: &bitcoin::Wallet,
execution_params: ExecutionParams, execution_params: ExecutionParams,
) -> Result<()> ) -> Result<()> {
where
W: bitcoin::BroadcastSignedTransaction + bitcoin::WaitForTransactionFinality,
{
let tx_cancel = let tx_cancel =
bitcoin::TxCancel::new(&self.tx_lock, self.cancel_timelock, self.A, self.b.public()); bitcoin::TxCancel::new(&self.tx_lock, self.cancel_timelock, self.A, self.b.public());
let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &self.refund_address); let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &self.refund_address);