Skip to content

Commit 66bc7b1

Browse files
committed
refactor(signer): Remove trait ComputeSighash
1 parent 4a8452f commit 66bc7b1

File tree

1 file changed

+145
-179
lines changed

1 file changed

+145
-179
lines changed

crates/wallet/src/wallet/signer.rs

Lines changed: 145 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ use miniscript::descriptor::{
9898
Descriptor, DescriptorMultiXKey, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey,
9999
InnerXKey, KeyMap, SinglePriv, SinglePubKey,
100100
};
101-
use miniscript::{Legacy, Segwitv0, SigType, Tap, ToPublicKey};
101+
use miniscript::{SigType, ToPublicKey};
102102

103103
use super::utils::SecpCtx;
104104
use crate::descriptor::{DescriptorMeta, XKeyUtils};
@@ -462,7 +462,7 @@ impl InputSigner for SignerWrapper<PrivateKey> {
462462
&& sign_options.sign_with_tap_internal_key
463463
&& x_only_pubkey == psbt_internal_key
464464
{
465-
let (hash, hash_ty) = Tap::sighash(psbt, input_index, None)?;
465+
let (hash, hash_ty) = compute_tap_sighash(psbt, input_index, None)?;
466466
sign_psbt_schnorr(
467467
&self.inner,
468468
x_only_pubkey,
@@ -497,7 +497,7 @@ impl InputSigner for SignerWrapper<PrivateKey> {
497497
.cloned()
498498
.collect::<Vec<_>>();
499499
for lh in leaf_hashes {
500-
let (hash, hash_ty) = Tap::sighash(psbt, input_index, Some(lh))?;
500+
let (hash, hash_ty) = compute_tap_sighash(psbt, input_index, Some(lh))?;
501501
sign_psbt_schnorr(
502502
&self.inner,
503503
x_only_pubkey,
@@ -519,12 +519,12 @@ impl InputSigner for SignerWrapper<PrivateKey> {
519519

520520
let (hash, hash_ty) = match self.ctx {
521521
SignerContext::Segwitv0 => {
522-
let (h, t) = Segwitv0::sighash(psbt, input_index, ())?;
522+
let (h, t) = compute_segwitv0_sighash(psbt, input_index)?;
523523
let h = h.to_raw_hash();
524524
(h, t)
525525
}
526526
SignerContext::Legacy => {
527-
let (h, t) = Legacy::sighash(psbt, input_index, ())?;
527+
let (h, t) = compute_legacy_sighash(psbt, input_index)?;
528528
let h = h.to_raw_hash();
529529
(h, t)
530530
}
@@ -845,198 +845,164 @@ impl Default for SignOptions {
845845
}
846846
}
847847

848-
pub(crate) trait ComputeSighash {
849-
type Extra;
850-
type Sighash;
851-
type SighashType;
852-
853-
fn sighash(
854-
psbt: &Psbt,
855-
input_index: usize,
856-
extra: Self::Extra,
857-
) -> Result<(Self::Sighash, Self::SighashType), SignerError>;
858-
}
848+
/// Computes the legacy sighash.
849+
fn compute_legacy_sighash(
850+
psbt: &Psbt,
851+
input_index: usize,
852+
) -> Result<(sighash::LegacySighash, EcdsaSighashType), SignerError> {
853+
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
854+
return Err(SignerError::InputIndexOutOfRange);
855+
}
859856

860-
impl ComputeSighash for Legacy {
861-
type Extra = ();
862-
type Sighash = sighash::LegacySighash;
863-
type SighashType = EcdsaSighashType;
857+
let psbt_input = &psbt.inputs[input_index];
858+
let tx_input = &psbt.unsigned_tx.input[input_index];
859+
860+
let sighash = psbt_input
861+
.sighash_type
862+
.unwrap_or_else(|| EcdsaSighashType::All.into())
863+
.ecdsa_hash_ty()
864+
.map_err(|_| SignerError::InvalidSighash)?;
865+
let script = match psbt_input.redeem_script {
866+
Some(ref redeem_script) => redeem_script.clone(),
867+
None => {
868+
let non_witness_utxo = psbt_input
869+
.non_witness_utxo
870+
.as_ref()
871+
.ok_or(SignerError::MissingNonWitnessUtxo)?;
872+
let prev_out = non_witness_utxo
873+
.output
874+
.get(tx_input.previous_output.vout as usize)
875+
.ok_or(SignerError::InvalidNonWitnessUtxo)?;
864876

865-
fn sighash(
866-
psbt: &Psbt,
867-
input_index: usize,
868-
_extra: (),
869-
) -> Result<(Self::Sighash, Self::SighashType), SignerError> {
870-
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
871-
return Err(SignerError::InputIndexOutOfRange);
877+
prev_out.script_pubkey.clone()
872878
}
879+
};
873880

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

909-
impl ComputeSighash for Segwitv0 {
910-
type Extra = ();
911-
type Sighash = sighash::SegwitV0Sighash;
912-
type SighashType = EcdsaSighashType;
913-
914-
fn sighash(
915-
psbt: &Psbt,
916-
input_index: usize,
917-
_extra: (),
918-
) -> Result<(Self::Sighash, Self::SighashType), SignerError> {
919-
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
920-
return Err(SignerError::InputIndexOutOfRange);
921-
}
891+
/// Computes the segwitv0 sighash.
892+
fn compute_segwitv0_sighash(
893+
psbt: &Psbt,
894+
input_index: usize,
895+
) -> Result<(sighash::SegwitV0Sighash, EcdsaSighashType), SignerError> {
896+
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
897+
return Err(SignerError::InputIndexOutOfRange);
898+
}
922899

923-
let psbt_input = &psbt.inputs[input_index];
924-
let tx_input = &psbt.unsigned_tx.input[input_index];
900+
let psbt_input = &psbt.inputs[input_index];
901+
let tx_input = &psbt.unsigned_tx.input[input_index];
925902

926-
let sighash_type = psbt_input
927-
.sighash_type
928-
.unwrap_or_else(|| EcdsaSighashType::All.into())
929-
.ecdsa_hash_ty()
930-
.map_err(|_| SignerError::InvalidSighash)?;
903+
let sighash_type = psbt_input
904+
.sighash_type
905+
.unwrap_or_else(|| EcdsaSighashType::All.into())
906+
.ecdsa_hash_ty()
907+
.map_err(|_| SignerError::InvalidSighash)?;
931908

932-
// Always try first with the non-witness utxo
933-
let utxo = if let Some(prev_tx) = &psbt_input.non_witness_utxo {
934-
// Check the provided prev-tx
935-
if prev_tx.txid() != tx_input.previous_output.txid {
936-
return Err(SignerError::InvalidNonWitnessUtxo);
937-
}
909+
// Always try first with the non-witness utxo
910+
let utxo = if let Some(prev_tx) = &psbt_input.non_witness_utxo {
911+
// Check the provided prev-tx
912+
if prev_tx.txid() != tx_input.previous_output.txid {
913+
return Err(SignerError::InvalidNonWitnessUtxo);
914+
}
938915

939-
// The output should be present, if it's missing the `non_witness_utxo` is invalid
940-
prev_tx
941-
.output
942-
.get(tx_input.previous_output.vout as usize)
943-
.ok_or(SignerError::InvalidNonWitnessUtxo)?
944-
} else if let Some(witness_utxo) = &psbt_input.witness_utxo {
945-
// Fallback to the witness_utxo. If we aren't allowed to use it, signing should fail
946-
// before we get to this point
947-
witness_utxo
948-
} else {
949-
// Nothing has been provided
950-
return Err(SignerError::MissingNonWitnessUtxo);
951-
};
952-
let value = utxo.value;
916+
// The output should be present, if it's missing the `non_witness_utxo` is invalid
917+
prev_tx
918+
.output
919+
.get(tx_input.previous_output.vout as usize)
920+
.ok_or(SignerError::InvalidNonWitnessUtxo)?
921+
} else if let Some(witness_utxo) = &psbt_input.witness_utxo {
922+
// Fallback to the witness_utxo. If we aren't allowed to use it, signing should fail
923+
// before we get to this point
924+
witness_utxo
925+
} else {
926+
// Nothing has been provided
927+
return Err(SignerError::MissingNonWitnessUtxo);
928+
};
929+
let value = utxo.value;
953930

954-
let mut sighasher = sighash::SighashCache::new(&psbt.unsigned_tx);
931+
let mut sighasher = sighash::SighashCache::new(&psbt.unsigned_tx);
955932

956-
let sighash = match psbt_input.witness_script {
957-
Some(ref witness_script) => {
958-
sighasher.p2wsh_signature_hash(input_index, witness_script, value, sighash_type)?
959-
}
960-
None => {
961-
if utxo.script_pubkey.is_p2wpkh() {
962-
sighasher.p2wpkh_signature_hash(
963-
input_index,
964-
&utxo.script_pubkey,
965-
value,
966-
sighash_type,
967-
)?
968-
} else if psbt_input
969-
.redeem_script
970-
.as_ref()
971-
.map(|s| s.is_p2wpkh())
972-
.unwrap_or(false)
973-
{
974-
let script_pubkey = psbt_input.redeem_script.as_ref().unwrap();
975-
sighasher.p2wpkh_signature_hash(
976-
input_index,
977-
script_pubkey,
978-
value,
979-
sighash_type,
980-
)?
981-
} else {
982-
return Err(SignerError::MissingWitnessScript);
983-
}
933+
let sighash = match psbt_input.witness_script {
934+
Some(ref witness_script) => {
935+
sighasher.p2wsh_signature_hash(input_index, witness_script, value, sighash_type)?
936+
}
937+
None => {
938+
if utxo.script_pubkey.is_p2wpkh() {
939+
sighasher.p2wpkh_signature_hash(
940+
input_index,
941+
&utxo.script_pubkey,
942+
value,
943+
sighash_type,
944+
)?
945+
} else if psbt_input
946+
.redeem_script
947+
.as_ref()
948+
.map(|s| s.is_p2wpkh())
949+
.unwrap_or(false)
950+
{
951+
let script_pubkey = psbt_input.redeem_script.as_ref().unwrap();
952+
sighasher.p2wpkh_signature_hash(input_index, script_pubkey, value, sighash_type)?
953+
} else {
954+
return Err(SignerError::MissingWitnessScript);
984955
}
985-
};
986-
Ok((sighash, sighash_type))
987-
}
956+
}
957+
};
958+
Ok((sighash, sighash_type))
988959
}
989960

990-
impl ComputeSighash for Tap {
991-
type Extra = Option<taproot::TapLeafHash>;
992-
type Sighash = TapSighash;
993-
type SighashType = TapSighashType;
994-
995-
fn sighash(
996-
psbt: &Psbt,
997-
input_index: usize,
998-
extra: Self::Extra,
999-
) -> Result<(Self::Sighash, TapSighashType), SignerError> {
1000-
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
1001-
return Err(SignerError::InputIndexOutOfRange);
1002-
}
961+
/// Computes the taproot sighash.
962+
fn compute_tap_sighash(
963+
psbt: &Psbt,
964+
input_index: usize,
965+
extra: Option<taproot::TapLeafHash>,
966+
) -> Result<(sighash::TapSighash, TapSighashType), SignerError> {
967+
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
968+
return Err(SignerError::InputIndexOutOfRange);
969+
}
1003970

1004-
let psbt_input = &psbt.inputs[input_index];
1005-
1006-
let sighash_type = psbt_input
1007-
.sighash_type
1008-
.unwrap_or_else(|| TapSighashType::Default.into())
1009-
.taproot_hash_ty()
1010-
.map_err(|_| SignerError::InvalidSighash)?;
1011-
let witness_utxos = (0..psbt.inputs.len())
1012-
.map(|i| psbt.get_utxo_for(i))
1013-
.collect::<Vec<_>>();
1014-
let mut all_witness_utxos = vec![];
1015-
1016-
let mut cache = sighash::SighashCache::new(&psbt.unsigned_tx);
1017-
let is_anyone_can_pay = psbt::PsbtSighashType::from(sighash_type).to_u32() & 0x80 != 0;
1018-
let prevouts = if is_anyone_can_pay {
1019-
sighash::Prevouts::One(
1020-
input_index,
1021-
witness_utxos[input_index]
1022-
.as_ref()
1023-
.ok_or(SignerError::MissingWitnessUtxo)?,
1024-
)
1025-
} else if witness_utxos.iter().all(Option::is_some) {
1026-
all_witness_utxos.extend(witness_utxos.iter().filter_map(|x| x.as_ref()));
1027-
sighash::Prevouts::All(&all_witness_utxos)
1028-
} else {
1029-
return Err(SignerError::MissingWitnessUtxo);
1030-
};
971+
let psbt_input = &psbt.inputs[input_index];
972+
973+
let sighash_type = psbt_input
974+
.sighash_type
975+
.unwrap_or_else(|| TapSighashType::Default.into())
976+
.taproot_hash_ty()
977+
.map_err(|_| SignerError::InvalidSighash)?;
978+
let witness_utxos = (0..psbt.inputs.len())
979+
.map(|i| psbt.get_utxo_for(i))
980+
.collect::<Vec<_>>();
981+
let mut all_witness_utxos = vec![];
982+
983+
let mut cache = sighash::SighashCache::new(&psbt.unsigned_tx);
984+
let is_anyone_can_pay = psbt::PsbtSighashType::from(sighash_type).to_u32() & 0x80 != 0;
985+
let prevouts = if is_anyone_can_pay {
986+
sighash::Prevouts::One(
987+
input_index,
988+
witness_utxos[input_index]
989+
.as_ref()
990+
.ok_or(SignerError::MissingWitnessUtxo)?,
991+
)
992+
} else if witness_utxos.iter().all(Option::is_some) {
993+
all_witness_utxos.extend(witness_utxos.iter().filter_map(|x| x.as_ref()));
994+
sighash::Prevouts::All(&all_witness_utxos)
995+
} else {
996+
return Err(SignerError::MissingWitnessUtxo);
997+
};
1031998

1032-
// Assume no OP_CODESEPARATOR
1033-
let extra = extra.map(|leaf_hash| (leaf_hash, 0xFFFFFFFF));
999+
// Assume no OP_CODESEPARATOR
1000+
let extra = extra.map(|leaf_hash| (leaf_hash, 0xFFFFFFFF));
10341001

1035-
Ok((
1036-
cache.taproot_signature_hash(input_index, &prevouts, None, extra, sighash_type)?,
1037-
sighash_type,
1038-
))
1039-
}
1002+
Ok((
1003+
cache.taproot_signature_hash(input_index, &prevouts, None, extra, sighash_type)?,
1004+
sighash_type,
1005+
))
10401006
}
10411007

10421008
impl PartialOrd for SignersContainerKey {

0 commit comments

Comments
 (0)