mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-12-29 09:26:30 -05:00
Merge #119
119: Remember the block-height before XMR lock for generated monero wallet r=da-kami a=da-kami The first approach https://github.com/comit-network/xmr-btc-swap/pull/121 was using `get_transfer_by_txid` that allows extrancting the exact tx-lock 1st confirmation block height. But that introduced an additional error scenario, and I actually ran into that error scenario (`transaction not found`) once I ran it on `stagenet`. Might be that `get_transfer_by_txid` requires running the node in a specific way (like `txindex` on bitcoin). I am not sure at this stage and don't want to invest more time. Long story short: I opted for just recording the height before watching for XMR locked. This means that we record a height right after sending the Bitcoin lock tx. (Because we start watching for XMR lock right after that.) Bob's new wallet unnecessarily scans an additional 7+ blocks (assuming inclusion in the next Bitcoin block and one confirmation for Monero lock) every time which is a matter of milliseconds. Not worth optimising this further at this stage. This solution is more resilient as well, because it does not add another error scenario. Co-authored-by: Daniel Karzel <daniel@comit.network>
This commit is contained in:
commit
2790dec6dc
@ -186,7 +186,7 @@ impl Client {
|
||||
}
|
||||
|
||||
/// Get wallet block height, this might be behind monerod height.
|
||||
pub(crate) async fn block_height(&self) -> Result<BlockHeight> {
|
||||
pub async fn block_height(&self) -> Result<BlockHeight> {
|
||||
let request = Request::new("get_height", "");
|
||||
|
||||
let response = self
|
||||
@ -238,9 +238,16 @@ impl Client {
|
||||
address: &str,
|
||||
spend_key: &str,
|
||||
view_key: &str,
|
||||
restore_height: Option<u32>,
|
||||
) -> Result<GenerateFromKeys> {
|
||||
let restore_height = if let Some(restore_height) = restore_height {
|
||||
restore_height
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let params = GenerateFromKeysParams {
|
||||
restore_height: 0,
|
||||
restore_height,
|
||||
filename: view_key.into(),
|
||||
address: address.into(),
|
||||
spendkey: spend_key.into(),
|
||||
|
@ -210,6 +210,7 @@ pub trait CreateWalletForOutput {
|
||||
&self,
|
||||
private_spend_key: PrivateKey,
|
||||
private_view_key: PrivateViewKey,
|
||||
restore_height: Option<u32>,
|
||||
) -> anyhow::Result<()>;
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,7 @@ impl CreateWalletForOutput for Wallet {
|
||||
&self,
|
||||
private_spend_key: PrivateKey,
|
||||
private_view_key: PrivateViewKey,
|
||||
restore_height: Option<u32>,
|
||||
) -> Result<()> {
|
||||
let public_spend_key = PublicKey::from_private_key(&private_spend_key);
|
||||
let public_view_key = PublicKey::from_private_key(&private_view_key.into());
|
||||
@ -80,6 +81,7 @@ impl CreateWalletForOutput for Wallet {
|
||||
&address.to_string(),
|
||||
&private_spend_key.to_string(),
|
||||
&PrivateKey::from(private_view_key).to_string(),
|
||||
restore_height,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
@ -538,10 +538,11 @@ impl State5 {
|
||||
|
||||
let s = s_b.scalar + self.s_a.into_ed25519();
|
||||
|
||||
// TODO: Optimized rescan height should be passed for refund as well.
|
||||
// NOTE: This actually generates and opens a new wallet, closing the currently
|
||||
// open one.
|
||||
monero_wallet
|
||||
.create_and_load_wallet_for_output(monero::PrivateKey::from_scalar(s), self.v)
|
||||
.create_and_load_wallet_for_output(monero::PrivateKey::from_scalar(s), self.v, None)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
|
@ -405,7 +405,7 @@ pub async fn run_until(
|
||||
let view_key = state3.v;
|
||||
|
||||
monero_wallet
|
||||
.create_and_load_wallet_for_output(spend_key, view_key)
|
||||
.create_and_load_wallet_for_output(spend_key, view_key, None)
|
||||
.await?;
|
||||
|
||||
let state = AliceState::XmrRefunded;
|
||||
|
@ -304,7 +304,12 @@ pub struct State3 {
|
||||
}
|
||||
|
||||
impl State3 {
|
||||
pub async fn watch_for_lock_xmr<W>(self, xmr_wallet: &W, msg: alice::Message2) -> Result<State4>
|
||||
pub async fn watch_for_lock_xmr<W>(
|
||||
self,
|
||||
xmr_wallet: &W,
|
||||
msg: alice::Message2,
|
||||
monero_wallet_restore_blockheight: u32,
|
||||
) -> Result<State4>
|
||||
where
|
||||
W: monero::WatchForTransfer,
|
||||
{
|
||||
@ -340,6 +345,7 @@ impl State3 {
|
||||
tx_lock: self.tx_lock,
|
||||
tx_cancel_sig_a: self.tx_cancel_sig_a,
|
||||
tx_refund_encsig: self.tx_refund_encsig,
|
||||
monero_wallet_restore_blockheight,
|
||||
})
|
||||
}
|
||||
|
||||
@ -373,6 +379,7 @@ impl State3 {
|
||||
tx_lock: self.tx_lock.clone(),
|
||||
tx_cancel_sig_a: self.tx_cancel_sig_a.clone(),
|
||||
tx_refund_encsig: self.tx_refund_encsig.clone(),
|
||||
monero_wallet_restore_blockheight: 0u32,
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,6 +420,7 @@ pub struct State4 {
|
||||
pub tx_lock: bitcoin::TxLock,
|
||||
pub tx_cancel_sig_a: Signature,
|
||||
pub tx_refund_encsig: EncryptedSignature,
|
||||
pub monero_wallet_restore_blockheight: u32,
|
||||
}
|
||||
|
||||
impl State4 {
|
||||
@ -509,6 +517,7 @@ impl State4 {
|
||||
tx_lock: self.tx_lock.clone(),
|
||||
tx_refund_encsig: self.tx_refund_encsig.clone(),
|
||||
tx_cancel_sig: self.tx_cancel_sig_a.clone(),
|
||||
monero_wallet_restore_blockheight: self.monero_wallet_restore_blockheight,
|
||||
})
|
||||
}
|
||||
|
||||
@ -606,6 +615,7 @@ pub struct State5 {
|
||||
pub tx_lock: bitcoin::TxLock,
|
||||
tx_refund_encsig: EncryptedSignature,
|
||||
tx_cancel_sig: Signature,
|
||||
pub monero_wallet_restore_blockheight: u32,
|
||||
}
|
||||
|
||||
impl State5 {
|
||||
@ -622,7 +632,11 @@ impl State5 {
|
||||
// NOTE: This actually generates and opens a new wallet, closing the currently
|
||||
// open one.
|
||||
monero_wallet
|
||||
.create_and_load_wallet_for_output(s, self.v)
|
||||
.create_and_load_wallet_for_output(
|
||||
s,
|
||||
self.v,
|
||||
Some(self.monero_wallet_restore_blockheight),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
|
@ -142,11 +142,19 @@ where
|
||||
let cancel_timelock_expires =
|
||||
state3.wait_for_cancel_timelock_to_expire(bitcoin_wallet.as_ref());
|
||||
|
||||
// Record the current monero wallet block height so we don't have to scan from
|
||||
// block 0 once we create the redeem wallet.
|
||||
// TODO: This can be optimized further by extracting the block height when
|
||||
// tx-lock was included. However, scanning a few more blocks won't do any harm
|
||||
// and is simpler.
|
||||
let monero_wallet_restore_blockheight =
|
||||
monero_wallet.inner.block_height().await?;
|
||||
|
||||
select! {
|
||||
msg2 = msg2_watcher => {
|
||||
|
||||
let xmr_lock_watcher = state3.clone()
|
||||
.watch_for_lock_xmr(monero_wallet.as_ref(), msg2?);
|
||||
.watch_for_lock_xmr(monero_wallet.as_ref(), msg2?, monero_wallet_restore_blockheight.height);
|
||||
let cancel_timelock_expires = state3.wait_for_cancel_timelock_to_expire(bitcoin_wallet.as_ref());
|
||||
|
||||
select! {
|
||||
|
Loading…
Reference in New Issue
Block a user