Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Psbt satisfy #142

Merged
merged 2 commits into from Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/psbt/finalizer.rs
Expand Up @@ -21,7 +21,7 @@

use super::super::Error as MsError;
use super::{sanity_check, Psbt};
use super::{Error, InputError};
use super::{Error, InputError, PsbtInputSatisfier};
use bitcoin::secp256k1;
use bitcoin::util::bip143::SigHashCache;
use bitcoin::{self, PublicKey, Script, SigHashType};
Expand Down Expand Up @@ -301,13 +301,13 @@ pub fn finalize(psbt: &mut Psbt) -> Result<(), super::Error> {
for index in 0..psbt.inputs.len() {
// Get a descriptor for this input
let desc = get_descriptor(&psbt, index).map_err(|e| Error::InputError(e, index))?;
let input = &mut psbt.inputs[index];

//generate the satisfaction witness and scriptsig
let (witness, script_sig) = desc
.get_satisfication(&input)
.get_satisfication(PsbtInputSatisfier::new(&psbt, index))
.map_err(|e| Error::InputError(InputError::MiniscriptError(e), index))?;

let input = &mut psbt.inputs[index];
//Fill in the satisfactions
input.final_script_sig = if script_sig.is_empty() {
None
Expand Down
45 changes: 40 additions & 5 deletions src/psbt/mod.rs
Expand Up @@ -21,12 +21,11 @@

use std::{error, fmt};

use bitcoin::util::psbt;
use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;

use bitcoin;
use bitcoin::Script;
use miniscript::satisfy::bitcoinsig_from_rawsig;
use miniscript::satisfy::{bitcoinsig_from_rawsig, After, Older};
use BitcoinSig;
use Satisfier;
use {MiniscriptKey, ToPublicKey};
Expand Down Expand Up @@ -183,9 +182,35 @@ impl fmt::Display for Error {
}
}

impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for psbt::Input {
/// Psbt satisfier for at inputs at a particular index
/// Takes in &psbt because multiple inputs will share
/// the same psbt structure
/// All operations on this structure will panic if index
/// is more than number of inputs in pbst
pub struct PsbtInputSatisfier<'psbt> {
/// pbst
pub psbt: &'psbt Psbt,
/// input index
pub index: usize,
}

impl<'psbt> PsbtInputSatisfier<'psbt> {
/// create a new PsbtInputsatisfier from
/// psbt and index
pub fn new(psbt: &'psbt Psbt, index: usize) -> Self {
Self {
psbt: psbt,
index: index,
}
}
}

impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfier<'psbt> {
fn lookup_sig(&self, pk: &Pk) -> Option<BitcoinSig> {
if let Some(rawsig) = self.partial_sigs.get(&pk.to_public_key()) {
if let Some(rawsig) = self.psbt.inputs[self.index]
.partial_sigs
.get(&pk.to_public_key())
{
// We have already previously checked that all signatures have the
// correct sighash flag.
bitcoinsig_from_rawsig(rawsig).ok()
Expand All @@ -195,7 +220,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for psbt::Input {
}

fn lookup_pkh_sig(&self, pkh: &Pk::Hash) -> Option<(bitcoin::PublicKey, BitcoinSig)> {
if let Some((pk, sig)) = self
if let Some((pk, sig)) = self.psbt.inputs[self.index]
.partial_sigs
.iter()
.filter(|&(pubkey, _sig)| pubkey.to_pubkeyhash() == Pk::hash_to_hash160(pkh))
Expand All @@ -209,6 +234,16 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for psbt::Input {
None
}
}

fn check_after(&self, n: u32) -> bool {
let cltv = self.psbt.global.unsigned_tx.lock_time;
<Satisfier<Pk>>::check_after(&After(cltv), n)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotta do time/height checks :)


fn check_older(&self, n: u32) -> bool {
let csv = self.psbt.global.unsigned_tx.input[self.index].sequence;
<Satisfier<Pk>>::check_older(&Older(csv), n)
}
}

fn sanity_check(psbt: &Psbt) -> Result<(), Error> {
Expand Down