Browse Source

Verify refund signatures using bitcoinconsensus

Co-authored-by: Philipp Hoenisch <philipp@hoenisch.at>
bdk-0.11
Lucas Soriano del Pino 3 years ago
committed by Philipp Hoenisch
parent
commit
199b293125
No known key found for this signature in database GPG Key ID: E5F8E74C672BC666
  1. 8
      cfd_protocol/Cargo.toml
  2. 71
      cfd_protocol/src/lib.rs

8
cfd_protocol/Cargo.toml

@ -5,14 +5,10 @@ edition = "2018"
[dependencies] [dependencies]
anyhow = "1" anyhow = "1"
# bdk = { version = "0.10" } bdk = { git = "https://github.com/bitcoindevkit/bdk/", rev = "acf157a99a305226203d2b55a567291a93c64720" }
bdk = { git = "https://github.com/coblox/bdk", rev = "acf157a99a305226203d2b55a567291a93c64720" }
rand = "0.6" rand = "0.6"
rand_chacha = "0.1" rand_chacha = "0.1"
secp256k1-zkp = { version = "0.4", features = ["hashes", "global-context"] } secp256k1-zkp = { version = "0.4", features = ["hashes", "global-context"] }
[dev-dependencies] [dev-dependencies]
bitcoin = { version = "0.27", features = ["rand", "bitcoinconsensus"] }
# bdk = { version = "0.10", features = ["verify"] }
bdk = { git = "https://github.com/coblox/bdk", rev = "acf157a99a305226203d2b55a567291a93c64720", features = ["verify"] }
bitcoin = { version = "0.27", features = ["rand"] }

71
cfd_protocol/src/lib.rs

@ -5,8 +5,10 @@ mod tests {
use bdk::SignOptions; use bdk::SignOptions;
use bdk::{ use bdk::{
bitcoin::{ bitcoin::{
self,
hashes::hex::ToHex, hashes::hex::ToHex,
util::bip143::SigHashCache, util::bip143::SigHashCache,
util::psbt::Global,
util::{bip32::ExtendedPrivKey, psbt::PartiallySignedTransaction}, util::{bip32::ExtendedPrivKey, psbt::PartiallySignedTransaction},
Address, Amount, Network, OutPoint, PrivateKey, PublicKey, Script, SigHash, Address, Amount, Network, OutPoint, PrivateKey, PublicKey, Script, SigHash,
SigHashType, Transaction, TxIn, TxOut, SigHashType, Transaction, TxIn, TxOut,
@ -15,14 +17,15 @@ mod tests {
miniscript::{descriptor::Wsh, DescriptorTrait}, miniscript::{descriptor::Wsh, DescriptorTrait},
wallet::AddressIndex, wallet::AddressIndex,
}; };
use bitcoin::util::psbt::Global;
use rand::RngCore; use rand::RngCore;
use rand::{CryptoRng, SeedableRng}; use rand::{CryptoRng, SeedableRng};
use rand_chacha::ChaChaRng; use rand_chacha::ChaChaRng;
use secp256k1_zkp::{self, schnorrsig}; use secp256k1_zkp::{self, schnorrsig, Signature};
use secp256k1_zkp::{bitcoin_hashes::sha256t_hash_newtype, SECP256K1}; use secp256k1_zkp::{bitcoin_hashes::sha256t_hash_newtype, SECP256K1};
use secp256k1_zkp::{bitcoin_hashes::*, EcdsaAdaptorSignature}; use secp256k1_zkp::{bitcoin_hashes::*, EcdsaAdaptorSignature};
use secp256k1_zkp::{Secp256k1, SecretKey}; use secp256k1_zkp::{Secp256k1, SecretKey};
use std::collections::HashMap;
/// Refund transaction fee. It is paid evenly by the maker and the /// Refund transaction fee. It is paid evenly by the maker and the
/// taker. /// taker.
@ -92,14 +95,9 @@ mod tests {
builder.finish().unwrap() builder.finish().unwrap()
}; };
let lock_tx = LockTransaction::new( let dlc_amount = maker_dlc_amount + taker_dlc_amount;
maker_psbt, let lock_tx =
taker_psbt, LockTransaction::new(maker_psbt, taker_psbt, maker_pk, taker_pk, dlc_amount).unwrap();
maker_pk,
taker_pk,
maker_dlc_amount + taker_dlc_amount,
)
.unwrap();
let refund_tx = RefundTransaction::new( let refund_tx = RefundTransaction::new(
&lock_tx, &lock_tx,
@ -123,6 +121,7 @@ mod tests {
secp.verify(&sighash, &sig, &maker_pk.key) secp.verify(&sighash, &sig, &maker_pk.key)
.expect("valid maker refund sig"); .expect("valid maker refund sig");
sig
}; };
let taker_refund_sig = { let taker_refund_sig = {
@ -131,6 +130,7 @@ mod tests {
secp.verify(&sighash, &sig, &taker_pk.key) secp.verify(&sighash, &sig, &taker_pk.key)
.expect("valid taker refund sig"); .expect("valid taker refund sig");
sig
}; };
let maker_cet_encsigs = cets let maker_cet_encsigs = cets
@ -208,8 +208,20 @@ mod tests {
) )
.unwrap(); .unwrap();
// TODO: Verify validity of all transactions using bitcoinconsensus via bdk let signed_refund_tx = refund_tx
// TODO: Upstream -> Activate rust-bitcoin/bitcoinconsensus feature on bdk .add_signatures((maker_pk, maker_refund_sig), (taker_pk, taker_refund_sig))
.unwrap();
let _ = lock_tx
.descriptor()
.address(Network::Regtest)
.expect("can derive address from descriptor")
.script_pubkey()
.verify(
0,
dlc_amount.as_sat(),
bitcoin::consensus::serialize(&signed_refund_tx).as_slice(),
)
.unwrap();
} }
const BIP340_MIDSTATE: [u8; 32] = [ const BIP340_MIDSTATE: [u8; 32] = [
@ -348,6 +360,7 @@ mod tests {
struct RefundTransaction { struct RefundTransaction {
inner: Transaction, inner: Transaction,
sighash: SigHash, sighash: SigHash,
lock_output_descriptor: Descriptor<PublicKey>,
} }
impl RefundTransaction { impl RefundTransaction {
@ -383,6 +396,8 @@ mod tests {
output: vec![maker_output, taker_output], output: vec![maker_output, taker_output],
}; };
let lock_output_descriptor = lock_tx.dlc_descriptor.clone();
let sighash = SigHashCache::new(&tx).signature_hash( let sighash = SigHashCache::new(&tx).signature_hash(
0, 0,
&lock_tx.dlc_descriptor.script_code(), &lock_tx.dlc_descriptor.script_code(),
@ -390,12 +405,38 @@ mod tests {
SigHashType::All, SigHashType::All,
); );
Self { inner: tx, sighash } Self {
inner: tx,
sighash,
lock_output_descriptor,
}
} }
fn sighash(&self) -> SigHash { fn sighash(&self) -> SigHash {
self.sighash self.sighash
} }
pub fn add_signatures(
self,
(maker_pk, maker_sig): (PublicKey, Signature),
(taker_pk, taker_sig): (PublicKey, Signature),
) -> Result<Transaction> {
let satisfier = {
let mut satisfier = HashMap::with_capacity(2);
// The order in which these are inserted doesn't matter
satisfier.insert(maker_pk, (maker_sig, SigHashType::All));
satisfier.insert(taker_pk, (taker_sig, SigHashType::All));
satisfier
};
let mut tx_refund = self.inner;
self.lock_output_descriptor
.satisfy(&mut tx_refund.input[0], satisfier)?;
Ok(tx_refund)
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -483,6 +524,10 @@ mod tests {
fn to_psbt(&self) -> PartiallySignedTransaction { fn to_psbt(&self) -> PartiallySignedTransaction {
self.inner.clone() self.inner.clone()
} }
fn descriptor(&self) -> Descriptor<PublicKey> {
self.dlc_descriptor.clone()
}
} }
fn build_wallet<R>( fn build_wallet<R>(

Loading…
Cancel
Save