Browse Source

Merge pull request #51 from comit-network/verify-transactions

Taker verifies all transactions
no-contract-setup-message
Philipp Hoenisch 3 years ago
committed by GitHub
parent
commit
1ebd042329
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 139
      daemon/src/taker_cfd_actor.rs

139
daemon/src/taker_cfd_actor.rs

@ -5,14 +5,15 @@ use crate::db::{
use crate::model::cfd::{Cfd, CfdOffer, CfdOfferId, CfdState, CfdStateCommon, FinalizedCfd};
use crate::model::Usd;
use crate::wire;
use crate::wire::{Msg0, Msg1, SetupMsg};
use bdk::bitcoin::secp256k1::{schnorrsig, SecretKey};
use bdk::bitcoin::{self, Amount};
use crate::wire::{AdaptorSignature, Msg0, Msg1, SetupMsg};
use anyhow::{Context, Result};
use bdk::bitcoin::secp256k1::{schnorrsig, SecretKey, Signature, SECP256K1};
use bdk::bitcoin::{self, Amount, PublicKey, Transaction, Txid};
use bdk::database::BatchDatabase;
use bdk::descriptor::Descriptor;
use cfd_protocol::{
commit_descriptor, create_cfd_transactions, lock_descriptor, PartyParams, PunishParams,
WalletExt,
commit_descriptor, compute_signature_point, create_cfd_transactions, lock_descriptor,
spending_tx_sighash, EcdsaAdaptorSignature, PartyParams, PunishParams, WalletExt,
};
use core::panic;
use futures::Future;
@ -201,10 +202,11 @@ fn setup_contract(
send_to_maker(SetupMsg::Msg1(Msg1::from(taker_cfd_txs.clone())));
let msg1 = receiver.recv().await.unwrap().try_into_msg1().unwrap();
let _lock_desc = lock_descriptor(maker.identity_pk, taker.identity_pk);
// let lock_amount = maker_lock_amount + taker_lock_amount;
let lock_desc = lock_descriptor(maker.identity_pk, taker.identity_pk);
let lock_amount = maker.lock_amount + taker.lock_amount;
let _commit_desc = commit_descriptor(
let commit_desc = commit_descriptor(
(
maker.identity_pk,
maker_punish.revocation_pk,
@ -212,17 +214,45 @@ fn setup_contract(
),
(taker.identity_pk, rev_pk, publish_pk),
);
let commit_tx = taker_cfd_txs.commit.0;
let _commit_amount = Amount::from_sat(commit_tx.output[0].value);
let taker_cets = taker_cfd_txs.cets;
let commit_tx = taker_cfd_txs.commit.0.clone();
let commit_amount = Amount::from_sat(commit_tx.output[0].value);
verify_adaptor_signature(
&commit_tx,
&lock_desc,
lock_amount,
&msg1.commit,
&taker_punish.publish_pk,
&maker.identity_pk,
)
.unwrap();
// TODO: Verify all signatures from the maker here
verify_cets(
&oracle_pk,
&maker,
&taker_cets,
&msg1.cets,
&commit_desc,
commit_amount,
)
.unwrap();
let lock_tx = taker_cfd_txs.lock;
let refund_tx = taker_cfd_txs.refund.0;
let mut cet_by_id = taker_cfd_txs
.cets
verify_signature(
&refund_tx,
&commit_desc,
commit_amount,
&msg1.refund,
&maker.identity_pk,
)
.unwrap();
let mut cet_by_id = taker_cets
.into_iter()
.map(|(tx, _, msg, _)| (tx.txid(), (tx, msg)))
.collect::<HashMap<_, _>>();
@ -248,3 +278,84 @@ fn setup_contract(
(actor, sender)
}
fn verify_cets(
oracle_pk: &schnorrsig::PublicKey,
maker: &PartyParams,
taker_cets: &[(
Transaction,
EcdsaAdaptorSignature,
Vec<u8>,
schnorrsig::PublicKey,
)],
cets: &[(Txid, AdaptorSignature)],
commit_desc: &Descriptor<PublicKey>,
commit_amount: Amount,
) -> Result<()> {
for (tx, _, msg, nonce_pk) in taker_cets.iter() {
let maker_encsig = cets
.iter()
.find_map(|(txid, encsig)| (txid == &tx.txid()).then(|| encsig))
.expect("one encsig per cet, per party");
verify_cet_encsig(
tx,
maker_encsig,
msg,
&maker.identity_pk,
(oracle_pk, nonce_pk),
commit_desc,
commit_amount,
)
.expect("valid maker cet encsig")
}
Ok(())
}
fn verify_adaptor_signature(
tx: &Transaction,
spent_descriptor: &Descriptor<PublicKey>,
spent_amount: Amount,
encsig: &AdaptorSignature,
encryption_point: &PublicKey,
pk: &PublicKey,
) -> Result<()> {
let sighash = spending_tx_sighash(tx, spent_descriptor, spent_amount);
encsig
.verify(SECP256K1, &sighash, &pk.key, &encryption_point.key)
.context("failed to verify encsig spend tx")
}
fn verify_signature(
tx: &Transaction,
spent_descriptor: &Descriptor<PublicKey>,
spent_amount: Amount,
sig: &Signature,
pk: &PublicKey,
) -> Result<()> {
let sighash = spending_tx_sighash(tx, spent_descriptor, spent_amount);
SECP256K1.verify(&sighash, sig, &pk.key)?;
Ok(())
}
fn verify_cet_encsig(
tx: &Transaction,
encsig: &AdaptorSignature,
msg: &[u8],
pk: &PublicKey,
(oracle_pk, nonce_pk): (&schnorrsig::PublicKey, &schnorrsig::PublicKey),
spent_descriptor: &Descriptor<PublicKey>,
spent_amount: Amount,
) -> Result<()> {
let sig_point = compute_signature_point(oracle_pk, nonce_pk, msg)
.context("could not calculate signature point")?;
verify_adaptor_signature(
tx,
spent_descriptor,
spent_amount,
encsig,
&PublicKey::new(sig_point),
pk,
)
}

Loading…
Cancel
Save