Skip to content

Commit f2a2dae

Browse files
committed
refactor(signer): Remove trait ComputeSighash
1 parent 6dab68d commit f2a2dae

1 file changed

Lines changed: 146 additions & 179 deletions

File tree

crates/wallet/src/wallet/signer.rs

Lines changed: 146 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ use miniscript::descriptor::{
9999
Descriptor, DescriptorMultiXKey, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey,
100100
InnerXKey, KeyMap, SinglePriv, SinglePubKey,
101101
};
102-
use miniscript::{Legacy, Segwitv0, SigType, Tap, ToPublicKey};
102+
use miniscript::{SigType, ToPublicKey};
103103

104104
use super::utils::SecpCtx;
105105
use crate::descriptor::{DescriptorMeta, XKeyUtils};
@@ -481,7 +481,7 @@ impl InputSigner for SignerWrapper<PrivateKey> {
481481
&& sign_options.sign_with_tap_internal_key
482482
&& x_only_pubkey == psbt_internal_key
483483
{
484-
let (hash, hash_ty) = Tap::sighash(psbt, input_index, None)?;
484+
let (hash, hash_ty) = compute_tap_sighash(psbt, input_index, None)?;
485485
sign_psbt_schnorr(
486486
&self.inner,
487487
x_only_pubkey,
@@ -516,7 +516,7 @@ impl InputSigner for SignerWrapper<PrivateKey> {
516516
.cloned()
517517
.collect::<Vec<_>>();
518518
for lh in leaf_hashes {
519-
let (hash, hash_ty) = Tap::sighash(psbt, input_index, Some(lh))?;
519+
let (hash, hash_ty) = compute_tap_sighash(psbt, input_index, Some(lh))?;
520520
sign_psbt_schnorr(
521521
&self.inner,
522522
x_only_pubkey,
@@ -538,12 +538,12 @@ impl InputSigner for SignerWrapper<PrivateKey> {
538538

539539
let (hash, hash_ty) = match self.ctx {
540540
SignerContext::Segwitv0 => {
541-
let (h, t) = Segwitv0::sighash(psbt, input_index, ())?;
541+
let (h, t) = compute_segwitv0_sighash(psbt, input_index)?;
542542
let h = h.to_raw_hash();
543543
(h, t)
544544
}
545545
SignerContext::Legacy => {
546-
let (h, t) = Legacy::sighash(psbt, input_index, ())?;
546+
let (h, t) = compute_legacy_sighash(psbt, input_index)?;
547547
let h = h.to_raw_hash();
548548
(h, t)
549549
}
@@ -853,198 +853,165 @@ impl Default for SignOptions {
853853
}
854854
}
855855

856-
pub(crate) trait ComputeSighash {
857-
type Extra;
858-
type Sighash;
859-
type SighashType;
860-
861-
fn sighash(
862-
psbt: &Psbt,
863-
input_index: usize,
864-
extra: Self::Extra,
865-
) -> Result<(Self::Sighash, Self::SighashType), SignerError>;
866-
}
856+
/// Computes the legacy sighash.
857+
fn compute_legacy_sighash(
858+
psbt: &Psbt,
859+
input_index: usize,
860+
) -> Result<(sighash::LegacySighash, EcdsaSighashType), SignerError> {
861+
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
862+
return Err(SignerError::InputIndexOutOfRange);
863+
}
867864

868-
impl ComputeSighash for Legacy {
869-
type Extra = ();
870-
type Sighash = sighash::LegacySighash;
871-
type SighashType = EcdsaSighashType;
865+
let psbt_input = &psbt.inputs[input_index];
866+
let tx_input = &psbt.unsigned_tx.input[input_index];
867+
868+
let sighash_type = psbt_input
869+
.sighash_type
870+
.unwrap_or_else(|| EcdsaSighashType::All.into())
871+
.ecdsa_hash_ty()
872+
.map_err(|_| SignerError::InvalidSighash)?;
873+
874+
let script = match psbt_input.redeem_script {
875+
Some(ref redeem_script) => redeem_script.clone(),
876+
None => {
877+
let non_witness_utxo = psbt_input
878+
.non_witness_utxo
879+
.as_ref()
880+
.ok_or(SignerError::MissingNonWitnessUtxo)?;
881+
let prev_out = non_witness_utxo
882+
.output
883+
.get(tx_input.previous_output.vout as usize)
884+
.ok_or(SignerError::InvalidNonWitnessUtxo)?;
872885

873-
fn sighash(
874-
psbt: &Psbt,
875-
input_index: usize,
876-
_extra: (),
877-
) -> Result<(Self::Sighash, Self::SighashType), SignerError> {
878-
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
879-
return Err(SignerError::InputIndexOutOfRange);
886+
prev_out.script_pubkey.clone()
880887
}
888+
};
881889

882-
let psbt_input = &psbt.inputs[input_index];
883-
let tx_input = &psbt.unsigned_tx.input[input_index];
884-
885-
let sighash = psbt_input
886-
.sighash_type
887-
.unwrap_or_else(|| EcdsaSighashType::All.into())
888-
.ecdsa_hash_ty()
889-
.map_err(|_| SignerError::InvalidSighash)?;
890-
let script = match psbt_input.redeem_script {
891-
Some(ref redeem_script) => redeem_script.clone(),
892-
None => {
893-
let non_witness_utxo = psbt_input
894-
.non_witness_utxo
895-
.as_ref()
896-
.ok_or(SignerError::MissingNonWitnessUtxo)?;
897-
let prev_out = non_witness_utxo
898-
.output
899-
.get(tx_input.previous_output.vout as usize)
900-
.ok_or(SignerError::InvalidNonWitnessUtxo)?;
901-
902-
prev_out.script_pubkey.clone()
903-
}
904-
};
905-
906-
Ok((
907-
sighash::SighashCache::new(&psbt.unsigned_tx).legacy_signature_hash(
908-
input_index,
909-
&script,
910-
sighash.to_u32(),
911-
)?,
912-
sighash,
913-
))
914-
}
890+
Ok((
891+
sighash::SighashCache::new(&psbt.unsigned_tx).legacy_signature_hash(
892+
input_index,
893+
&script,
894+
sighash_type.to_u32(),
895+
)?,
896+
sighash_type,
897+
))
915898
}
916899

917-
impl ComputeSighash for Segwitv0 {
918-
type Extra = ();
919-
type Sighash = sighash::SegwitV0Sighash;
920-
type SighashType = EcdsaSighashType;
921-
922-
fn sighash(
923-
psbt: &Psbt,
924-
input_index: usize,
925-
_extra: (),
926-
) -> Result<(Self::Sighash, Self::SighashType), SignerError> {
927-
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
928-
return Err(SignerError::InputIndexOutOfRange);
929-
}
900+
/// Computes the segwitv0 sighash.
901+
fn compute_segwitv0_sighash(
902+
psbt: &Psbt,
903+
input_index: usize,
904+
) -> Result<(sighash::SegwitV0Sighash, EcdsaSighashType), SignerError> {
905+
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
906+
return Err(SignerError::InputIndexOutOfRange);
907+
}
930908

931-
let psbt_input = &psbt.inputs[input_index];
932-
let tx_input = &psbt.unsigned_tx.input[input_index];
909+
let psbt_input = &psbt.inputs[input_index];
910+
let tx_input = &psbt.unsigned_tx.input[input_index];
933911

934-
let sighash_type = psbt_input
935-
.sighash_type
936-
.unwrap_or_else(|| EcdsaSighashType::All.into())
937-
.ecdsa_hash_ty()
938-
.map_err(|_| SignerError::InvalidSighash)?;
912+
let sighash_type = psbt_input
913+
.sighash_type
914+
.unwrap_or_else(|| EcdsaSighashType::All.into())
915+
.ecdsa_hash_ty()
916+
.map_err(|_| SignerError::InvalidSighash)?;
939917

940-
// Always try first with the non-witness utxo
941-
let utxo = if let Some(prev_tx) = &psbt_input.non_witness_utxo {
942-
// Check the provided prev-tx
943-
if prev_tx.compute_txid() != tx_input.previous_output.txid {
944-
return Err(SignerError::InvalidNonWitnessUtxo);
945-
}
918+
// Always try first with the non-witness utxo
919+
let utxo = if let Some(prev_tx) = &psbt_input.non_witness_utxo {
920+
// Check the provided prev-tx
921+
if prev_tx.compute_txid() != tx_input.previous_output.txid {
922+
return Err(SignerError::InvalidNonWitnessUtxo);
923+
}
946924

947-
// The output should be present, if it's missing the `non_witness_utxo` is invalid
948-
prev_tx
949-
.output
950-
.get(tx_input.previous_output.vout as usize)
951-
.ok_or(SignerError::InvalidNonWitnessUtxo)?
952-
} else if let Some(witness_utxo) = &psbt_input.witness_utxo {
953-
// Fallback to the witness_utxo. If we aren't allowed to use it, signing should fail
954-
// before we get to this point
955-
witness_utxo
956-
} else {
957-
// Nothing has been provided
958-
return Err(SignerError::MissingNonWitnessUtxo);
959-
};
960-
let value = utxo.value;
925+
// The output should be present, if it's missing the `non_witness_utxo` is invalid
926+
prev_tx
927+
.output
928+
.get(tx_input.previous_output.vout as usize)
929+
.ok_or(SignerError::InvalidNonWitnessUtxo)?
930+
} else if let Some(witness_utxo) = &psbt_input.witness_utxo {
931+
// Fallback to the witness_utxo. If we aren't allowed to use it, signing should fail
932+
// before we get to this point
933+
witness_utxo
934+
} else {
935+
// Nothing has been provided
936+
return Err(SignerError::MissingNonWitnessUtxo);
937+
};
938+
let value = utxo.value;
961939

962-
let mut sighasher = sighash::SighashCache::new(&psbt.unsigned_tx);
940+
let mut sighasher = sighash::SighashCache::new(&psbt.unsigned_tx);
963941

964-
let sighash = match psbt_input.witness_script {
965-
Some(ref witness_script) => {
966-
sighasher.p2wsh_signature_hash(input_index, witness_script, value, sighash_type)?
967-
}
968-
None => {
969-
if utxo.script_pubkey.is_p2wpkh() {
970-
sighasher.p2wpkh_signature_hash(
971-
input_index,
972-
&utxo.script_pubkey,
973-
value,
974-
sighash_type,
975-
)?
976-
} else if psbt_input
977-
.redeem_script
978-
.as_ref()
979-
.map(|s| s.is_p2wpkh())
980-
.unwrap_or(false)
981-
{
982-
let script_pubkey = psbt_input.redeem_script.as_ref().unwrap();
983-
sighasher.p2wpkh_signature_hash(
984-
input_index,
985-
script_pubkey,
986-
value,
987-
sighash_type,
988-
)?
989-
} else {
990-
return Err(SignerError::MissingWitnessScript);
991-
}
942+
let sighash = match psbt_input.witness_script {
943+
Some(ref witness_script) => {
944+
sighasher.p2wsh_signature_hash(input_index, witness_script, value, sighash_type)?
945+
}
946+
None => {
947+
if utxo.script_pubkey.is_p2wpkh() {
948+
sighasher.p2wpkh_signature_hash(
949+
input_index,
950+
&utxo.script_pubkey,
951+
value,
952+
sighash_type,
953+
)?
954+
} else if psbt_input
955+
.redeem_script
956+
.as_ref()
957+
.map(|s| s.is_p2wpkh())
958+
.unwrap_or(false)
959+
{
960+
let script_pubkey = psbt_input.redeem_script.as_ref().unwrap();
961+
sighasher.p2wpkh_signature_hash(input_index, script_pubkey, value, sighash_type)?
962+
} else {
963+
return Err(SignerError::MissingWitnessScript);
992964
}
993-
};
994-
Ok((sighash, sighash_type))
995-
}
965+
}
966+
};
967+
Ok((sighash, sighash_type))
996968
}
997969

998-
impl ComputeSighash for Tap {
999-
type Extra = Option<taproot::TapLeafHash>;
1000-
type Sighash = TapSighash;
1001-
type SighashType = TapSighashType;
1002-
1003-
fn sighash(
1004-
psbt: &Psbt,
1005-
input_index: usize,
1006-
extra: Self::Extra,
1007-
) -> Result<(Self::Sighash, TapSighashType), SignerError> {
1008-
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
1009-
return Err(SignerError::InputIndexOutOfRange);
1010-
}
970+
/// Computes the taproot sighash.
971+
fn compute_tap_sighash(
972+
psbt: &Psbt,
973+
input_index: usize,
974+
extra: Option<taproot::TapLeafHash>,
975+
) -> Result<(sighash::TapSighash, TapSighashType), SignerError> {
976+
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
977+
return Err(SignerError::InputIndexOutOfRange);
978+
}
1011979

1012-
let psbt_input = &psbt.inputs[input_index];
1013-
1014-
let sighash_type = psbt_input
1015-
.sighash_type
1016-
.unwrap_or_else(|| TapSighashType::Default.into())
1017-
.taproot_hash_ty()
1018-
.map_err(|_| SignerError::InvalidSighash)?;
1019-
let witness_utxos = (0..psbt.inputs.len())
1020-
.map(|i| psbt.get_utxo_for(i))
1021-
.collect::<Vec<_>>();
1022-
let mut all_witness_utxos = vec![];
1023-
1024-
let mut cache = sighash::SighashCache::new(&psbt.unsigned_tx);
1025-
let is_anyone_can_pay = psbt::PsbtSighashType::from(sighash_type).to_u32() & 0x80 != 0;
1026-
let prevouts = if is_anyone_can_pay {
1027-
sighash::Prevouts::One(
1028-
input_index,
1029-
witness_utxos[input_index]
1030-
.as_ref()
1031-
.ok_or(SignerError::MissingWitnessUtxo)?,
1032-
)
1033-
} else if witness_utxos.iter().all(Option::is_some) {
1034-
all_witness_utxos.extend(witness_utxos.iter().filter_map(|x| x.as_ref()));
1035-
sighash::Prevouts::All(&all_witness_utxos)
1036-
} else {
1037-
return Err(SignerError::MissingWitnessUtxo);
1038-
};
980+
let psbt_input = &psbt.inputs[input_index];
981+
982+
let sighash_type = psbt_input
983+
.sighash_type
984+
.unwrap_or_else(|| TapSighashType::Default.into())
985+
.taproot_hash_ty()
986+
.map_err(|_| SignerError::InvalidSighash)?;
987+
let witness_utxos = (0..psbt.inputs.len())
988+
.map(|i| psbt.get_utxo_for(i))
989+
.collect::<Vec<_>>();
990+
let mut all_witness_utxos = vec![];
991+
992+
let mut cache = sighash::SighashCache::new(&psbt.unsigned_tx);
993+
let is_anyone_can_pay = psbt::PsbtSighashType::from(sighash_type).to_u32() & 0x80 != 0;
994+
let prevouts = if is_anyone_can_pay {
995+
sighash::Prevouts::One(
996+
input_index,
997+
witness_utxos[input_index]
998+
.as_ref()
999+
.ok_or(SignerError::MissingWitnessUtxo)?,
1000+
)
1001+
} else if witness_utxos.iter().all(Option::is_some) {
1002+
all_witness_utxos.extend(witness_utxos.iter().filter_map(|x| x.as_ref()));
1003+
sighash::Prevouts::All(&all_witness_utxos)
1004+
} else {
1005+
return Err(SignerError::MissingWitnessUtxo);
1006+
};
10391007

1040-
// Assume no OP_CODESEPARATOR
1041-
let extra = extra.map(|leaf_hash| (leaf_hash, 0xFFFFFFFF));
1008+
// Assume no OP_CODESEPARATOR
1009+
let extra = extra.map(|leaf_hash| (leaf_hash, 0xFFFFFFFF));
10421010

1043-
Ok((
1044-
cache.taproot_signature_hash(input_index, &prevouts, None, extra, sighash_type)?,
1045-
sighash_type,
1046-
))
1047-
}
1011+
Ok((
1012+
cache.taproot_signature_hash(input_index, &prevouts, None, extra, sighash_type)?,
1013+
sighash_type,
1014+
))
10481015
}
10491016

10501017
impl PartialOrd for SignersContainerKey {

0 commit comments

Comments
 (0)