Eliminate build_bitcoin_punish_transaction

We reduce indirection by constructing TxPunish directly based off
`State3` and make the type itself more powerful by moving the logic
of completing it with a signature onto it.
This commit is contained in:
Thomas Eizinger 2021-03-16 18:02:31 +11:00
parent dd6c66a594
commit 6beb732e35
No known key found for this signature in database
GPG Key ID: 651AC83A6C6C8B96
5 changed files with 34 additions and 46 deletions

View File

@ -110,6 +110,15 @@ impl From<PublicKey> for Point {
} }
} }
impl From<PublicKey> for ::bitcoin::PublicKey {
fn from(from: PublicKey) -> Self {
::bitcoin::PublicKey {
compressed: true,
key: from.0.into(),
}
}
}
impl From<Point> for PublicKey { impl From<Point> for PublicKey {
fn from(p: Point) -> Self { fn from(p: Point) -> Self {
Self(p) Self(p)

View File

@ -1,12 +1,11 @@
use crate::bitcoin::{Address, PublicKey, PunishTimelock, Transaction, TxCancel}; use crate::bitcoin::{self, Address, PunishTimelock, Transaction, TxCancel};
use ::bitcoin::util::bip143::SigHashCache; use ::bitcoin::util::bip143::SigHashCache;
use ::bitcoin::{SigHash, SigHashType}; use ::bitcoin::{SigHash, SigHashType};
use anyhow::Result; use anyhow::{Context, Result};
use ecdsa_fun::Signature;
use miniscript::{Descriptor, DescriptorTrait}; use miniscript::{Descriptor, DescriptorTrait};
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Debug)] #[derive(Clone, Debug)]
pub struct TxPunish { pub struct TxPunish {
inner: Transaction, inner: Transaction,
digest: SigHash, digest: SigHash,
@ -39,22 +38,20 @@ impl TxPunish {
self.digest self.digest
} }
pub fn add_signatures( pub fn complete(
self, self,
(A, sig_a): (PublicKey, Signature), tx_punish_sig_bob: bitcoin::Signature,
(B, sig_b): (PublicKey, Signature), a: bitcoin::SecretKey,
B: bitcoin::PublicKey,
) -> Result<Transaction> { ) -> Result<Transaction> {
let sig_a = a.sign(self.digest());
let sig_b = tx_punish_sig_bob;
let satisfier = { let satisfier = {
let mut satisfier = HashMap::with_capacity(2); let mut satisfier = HashMap::with_capacity(2);
let A = ::bitcoin::PublicKey { let A = a.public().into();
compressed: true, let B = B.into();
key: A.0.into(),
};
let B = ::bitcoin::PublicKey {
compressed: true,
key: B.0.into(),
};
// The order in which these are inserted doesn't matter // The order in which these are inserted doesn't matter
satisfier.insert(A, (sig_a.into(), ::bitcoin::SigHashType::All)); satisfier.insert(A, (sig_a.into(), ::bitcoin::SigHashType::All));
@ -65,7 +62,8 @@ impl TxPunish {
let mut tx_punish = self.inner; let mut tx_punish = self.inner;
self.cancel_output_descriptor self.cancel_output_descriptor
.satisfy(&mut tx_punish.input[0], satisfier)?; .satisfy(&mut tx_punish.input[0], satisfier)
.context("Failed to satisfy inputs with given signatures")?;
Ok(tx_punish) Ok(tx_punish)
} }

View File

@ -1,6 +1,6 @@
use crate::bitcoin::{ use crate::bitcoin::{
current_epoch, wait_for_cancel_timelock_to_expire, CancelTimelock, ExpiredTimelocks, current_epoch, wait_for_cancel_timelock_to_expire, CancelTimelock, ExpiredTimelocks,
PunishTimelock, TxCancel, TxRefund, PunishTimelock, TxCancel, TxPunish, TxRefund,
}; };
use crate::execution_params::ExecutionParams; use crate::execution_params::ExecutionParams;
use crate::protocol::alice::{Message1, Message3}; use crate::protocol::alice::{Message1, Message3};
@ -343,4 +343,11 @@ impl State3 {
) )
.await .await
} }
pub fn tx_punish(&self) -> TxPunish {
let tx_cancel =
bitcoin::TxCancel::new(&self.tx_lock, self.cancel_timelock, self.a.public(), self.B);
bitcoin::TxPunish::new(&tx_cancel, &self.punish_address, self.punish_timelock)
}
} }

View File

@ -143,25 +143,3 @@ pub fn extract_monero_private_key(
Ok(spend_key) Ok(spend_key)
} }
pub fn build_bitcoin_punish_transaction(
tx_lock: &TxLock,
cancel_timelock: CancelTimelock,
punish_address: &bitcoin::Address,
punish_timelock: PunishTimelock,
tx_punish_sig_bob: bitcoin::Signature,
a: bitcoin::SecretKey,
B: bitcoin::PublicKey,
) -> Result<bitcoin::Transaction> {
let tx_cancel = bitcoin::TxCancel::new(&tx_lock, cancel_timelock, a.public(), B);
let tx_punish = bitcoin::TxPunish::new(&tx_cancel, &punish_address, punish_timelock);
let sig_a = a.sign(tx_punish.digest());
let sig_b = tx_punish_sig_bob;
let signed_tx_punish = tx_punish
.add_signatures((a.public(), sig_a), (B, sig_b))
.expect("sig_{a,b} to be valid signatures for tx_cancel");
Ok(signed_tx_punish)
}

View File

@ -7,8 +7,8 @@ use crate::monero_ext::ScalarExt;
use crate::protocol::alice; use crate::protocol::alice;
use crate::protocol::alice::event_loop::EventLoopHandle; use crate::protocol::alice::event_loop::EventLoopHandle;
use crate::protocol::alice::steps::{ use crate::protocol::alice::steps::{
build_bitcoin_punish_transaction, extract_monero_private_key, lock_xmr, extract_monero_private_key, lock_xmr, publish_cancel_transaction,
publish_cancel_transaction, wait_for_bitcoin_encrypted_signature, wait_for_bitcoin_refund, wait_for_bitcoin_encrypted_signature, wait_for_bitcoin_refund,
}; };
use crate::protocol::alice::AliceState; use crate::protocol::alice::AliceState;
use crate::{bitcoin, database, monero}; use crate::{bitcoin, database, monero};
@ -398,11 +398,7 @@ async fn run_until_internal(
state3, state3,
monero_wallet_restore_blockheight, monero_wallet_restore_blockheight,
} => { } => {
let signed_tx_punish = build_bitcoin_punish_transaction( let signed_tx_punish = state3.tx_punish().complete(
&state3.tx_lock,
state3.cancel_timelock,
&state3.punish_address,
state3.punish_timelock,
state3.tx_punish_sig_bob.clone(), state3.tx_punish_sig_bob.clone(),
state3.a.clone(), state3.a.clone(),
state3.B, state3.B,