Repository: rust-bitcoin/rust-bitcoin
Pull request #2010 (2023-08-19 13:12:31)

Use weight type for stripped_size
Return Weight type for the strippedize function.

apoelstra: What does it mean to multiply two weights together? What uses wu^2 units?

Patch:
diff --git a/Cargo-minimal.lock b/Cargo-minimal.lock
index 2994ad2f..ea1e7cee 100644
--- a/Cargo-minimal.lock
+++ b/Cargo-minimal.lock
@@ -38,7 +38,7 @@ dependencies = [
  "bech32",
  "bincode",
  "bitcoin-internals",
- "bitcoin_hashes 0.13.0",
+ "bitcoin_hashes",
  "bitcoinconsensus",
  "core2",
  "hex-conservative",
@@ -69,24 +69,9 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "bitcoin-private"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57"
-
 [[package]]
 name = "bitcoin_hashes"
 version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501"
-dependencies = [
- "bitcoin-private",
-]
-
-[[package]]
-name = "bitcoin_hashes"
-version = "0.13.0"
 dependencies = [
  "bitcoin-internals",
  "core2",
@@ -411,7 +396,7 @@ version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f"
 dependencies = [
- "bitcoin_hashes 0.12.0",
+ "bitcoin_hashes",
  "rand",
  "secp256k1-sys",
  "serde",
diff --git a/Cargo-recent.lock b/Cargo-recent.lock
index 8cced221..31b69aaa 100644
--- a/Cargo-recent.lock
+++ b/Cargo-recent.lock
@@ -37,7 +37,7 @@ dependencies = [
  "bech32",
  "bincode",
  "bitcoin-internals",
- "bitcoin_hashes 0.13.0",
+ "bitcoin_hashes",
  "bitcoinconsensus",
  "core2",
  "hex-conservative",
@@ -68,24 +68,9 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "bitcoin-private"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57"
-
 [[package]]
 name = "bitcoin_hashes"
 version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501"
-dependencies = [
- "bitcoin-private",
-]
-
-[[package]]
-name = "bitcoin_hashes"
-version = "0.13.0"
 dependencies = [
  "bitcoin-internals",
  "core2",
@@ -400,7 +385,7 @@ version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f"
 dependencies = [
- "bitcoin_hashes 0.12.0",
+ "bitcoin_hashes",
  "rand",
  "secp256k1-sys",
  "serde",
diff --git a/bitcoin/Cargo.toml b/bitcoin/Cargo.toml
index c928b6b0..f7a12a22 100644
--- a/bitcoin/Cargo.toml
+++ b/bitcoin/Cargo.toml
@@ -37,7 +37,7 @@ rustdoc-args = ["--cfg", "docsrs"]
 internals = { package = "bitcoin-internals", version = "0.2.0" }
 hex = { package = "hex-conservative", version = "0.1.1", default-features = false }
 bech32 = { version = "0.9.0", default-features = false }
-hashes = { package = "bitcoin_hashes", version = "0.13.0", default-features = false }
+hashes = { package = "bitcoin_hashes", version = "0.12.0", default-features = false }
 secp256k1 = { version = "0.27.0", default-features = false, features = ["bitcoin_hashes"] }
 hex_lit = "0.1.1"
 
diff --git a/bitcoin/examples/sighash.rs b/bitcoin/examples/sighash.rs
index 746c0df9..9bb3a497 100644
--- a/bitcoin/examples/sighash.rs
+++ b/bitcoin/examples/sighash.rs
@@ -1,4 +1,3 @@
-use bitcoin::hashes::Hash;
 use bitcoin::{consensus, ecdsa, sighash, Amount, PublicKey, Script, ScriptBuf, Transaction};
 use hex_lit::hex;
 
@@ -39,15 +38,14 @@ fn compute_sighash_p2wpkh(raw_tx: &[u8], inp_idx: usize, value: u64) {
     let wpkh = pk.wpubkey_hash().expect("compressed key");
     println!("Script pubkey hash: {:x}", wpkh);
     let spk = ScriptBuf::new_v0_p2wpkh(&wpkh);
+    let script_code = spk.p2wpkh_script_code().expect("spk is known to be p2wpkh");
 
     let mut cache = sighash::SighashCache::new(&tx);
     let sighash = cache
-        .p2wpkh_signature_hash(inp_idx, &spk, Amount::from_sat(value), sig.hash_ty)
+        .segwit_signature_hash(inp_idx, &script_code, Amount::from_sat(value), sig.hash_ty)
         .expect("failed to compute sighash");
     println!("Segwit p2wpkh sighash: {:x}", sighash);
-    // TODO: After upgrade of secp change this to Message::from_digest(sighash.to_byte_array()).
-    let msg =
-        secp256k1::Message::from_slice(sighash.as_byte_array()).expect("sighash is 32 bytes long");
+    let msg = secp256k1::Message::from(sighash);
     println!("Message is {:x}", msg);
     let secp = secp256k1::Secp256k1::verification_only();
     secp.verify_ecdsa(&msg, &sig.sig, &pk.inner).unwrap();
@@ -126,7 +124,7 @@ fn compute_sighash_p2wsh(raw_tx: &[u8], inp_idx: usize, value: u64) {
         assert!((70..=72).contains(&sig_len), "signature length {} out of bounds", sig_len);
         //here we assume that all sighash_flags are the same. Can they be different?
         let sighash = cache
-            .p2wsh_signature_hash(inp_idx, witness_script, Amount::from_sat(value), sig.hash_ty)
+            .segwit_signature_hash(inp_idx, witness_script, Amount::from_sat(value), sig.hash_ty)
             .expect("failed to compute sighash");
         println!("Segwit p2wsh sighash: {:x} ({})", sighash, sig.hash_ty);
     }
diff --git a/bitcoin/examples/taproot-psbt.rs b/bitcoin/examples/taproot-psbt.rs
index 367d69aa..3794688d 100644
--- a/bitcoin/examples/taproot-psbt.rs
+++ b/bitcoin/examples/taproot-psbt.rs
@@ -80,7 +80,6 @@
 
 use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey, Fingerprint};
 use bitcoin::consensus::encode;
-use bitcoin::hashes::Hash;
 use bitcoin::key::{TapTweak, XOnlyPublicKey};
 use bitcoin::opcodes::all::{OP_CHECKSIG, OP_CLTV, OP_DROP};
 use bitcoin::psbt::{self, Input, Output, Psbt, PsbtSighashType};
@@ -738,10 +737,7 @@ fn sign_psbt_taproot(
         Some(_) => keypair, // no tweak for script spend
     };
 
-    // TODO: After upgrade of secp change this to Message::from_digest(sighash.to_byte_array()).
-    let msg =
-        secp256k1::Message::from_slice(hash.as_byte_array()).expect("tap sighash is 32 bytes long");
-    let sig = secp.sign_schnorr(&msg, &keypair);
+    let sig = secp.sign_schnorr(&hash.into(), &keypair);
 
     let final_signature = taproot::Signature { sig, hash_ty };
 
diff --git a/bitcoin/src/bip152.rs b/bitcoin/src/bip152.rs
index 39679a6c..17c296c0 100644
--- a/bitcoin/src/bip152.rs
+++ b/bitcoin/src/bip152.rs
@@ -74,7 +74,7 @@ fn as_ref(&self) -> &Transaction { &self.tx }
 impl Encodable for PrefilledTransaction {
     #[inline]
     fn consensus_encode<S: io::Write + ?Sized>(&self, mut s: &mut S) -> Result<usize, io::Error> {
-        Ok(VarInt::from(self.idx).consensus_encode(&mut s)? + self.tx.consensus_encode(&mut s)?)
+        Ok(VarInt(self.idx as u64).consensus_encode(&mut s)? + self.tx.consensus_encode(&mut s)?)
     }
 }
 
diff --git a/bitcoin/src/bip158.rs b/bitcoin/src/bip158.rs
index 603fae65..2f794ca8 100644
--- a/bitcoin/src/bip158.rs
+++ b/bitcoin/src/bip158.rs
@@ -391,7 +391,7 @@ pub fn finish(&mut self) -> Result<usize, io::Error> {
         mapped.sort_unstable();
 
         // write number of elements as varint
-        let mut wrote = VarInt::from(mapped.len()).consensus_encode(&mut self.writer)?;
+        let mut wrote = VarInt(mapped.len() as u64).consensus_encode(&mut self.writer)?;
 
         // write out deltas of sorted values into a Golonb-Rice coded bit stream
         let mut writer = BitStreamWriter::new(self.writer);
diff --git a/bitcoin/src/blockdata/block.rs b/bitcoin/src/blockdata/block.rs
index e3fa9334..222475ef 100644
--- a/bitcoin/src/blockdata/block.rs
+++ b/bitcoin/src/blockdata/block.rs
@@ -276,7 +276,7 @@ pub fn witness_root(&self) -> Option<WitnessMerkleNode> {
     }
 
     /// base_size == size of header + size of encoded transaction count.
-    fn base_size(&self) -> usize { 80 + VarInt::from(self.txdata.len()).len() }
+    fn base_size(&self) -> usize { 80 + VarInt(self.txdata.len() as u64).len() }
 
     /// Returns the size of the block.
     ///
@@ -286,10 +286,17 @@ pub fn size(&self) -> usize {
         self.base_size() + txs_size
     }
 
-    /// Returns the strippedsize of the block.
-    pub fn strippedsize(&self) -> usize {
-        let txs_size: usize = self.txdata.iter().map(Transaction::strippedsize).sum();
-        self.base_size() + txs_size
+    /// Returns the stripped size of the block.
+    #[deprecated(
+        since = "0.31.0",
+        note = "Truncates on 32-bit machines, Use Block::stripped_size() instead"
+    )]
+    pub fn strippedsize(&self) -> usize { Self::stripped_size(self).to_wu() as usize }
+
+    /// Returns the stripped size of the block.
+    pub fn stripped_size(&self) -> Weight {
+        let txs_size: Weight = self.txdata.iter().map(Transaction::stripped_size).sum();
+        Weight::from_wu_usize(self.base_size()) + txs_size
     }
 
     /// Returns the weight of the block.
@@ -481,7 +488,7 @@ fn block_test() {
         // [test] TODO: check the transaction data
 
         assert_eq!(real_decode.size(), some_block.len());
-        assert_eq!(real_decode.strippedsize(), some_block.len());
+        assert_eq!(real_decode.stripped_size(), Weight::from_wu_usize(some_block.len()));
         assert_eq!(
             real_decode.weight(),
             Weight::from_non_witness_data_size(some_block.len() as u64)
@@ -523,7 +530,7 @@ fn segwit_block_test() {
         // [test] TODO: check the transaction data
 
         assert_eq!(real_decode.size(), segwit_block.len());
-        assert_eq!(real_decode.strippedsize(), 4283);
+        assert_eq!(real_decode.stripped_size(), Weight::from_wu(4283));
         assert_eq!(real_decode.weight(), Weight::from_wu(17168));
 
         assert!(real_decode.check_witness_commitment());
diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs
index c4a5e67f..181d566c 100644
--- a/bitcoin/src/blockdata/transaction.rs
+++ b/bitcoin/src/blockdata/transaction.rs
@@ -227,7 +227,7 @@ pub fn legacy_weight(&self) -> Weight {
         // Size in vbytes:
         // previous_output (36) + script_sig varint len + script_sig push + sequence (4)
         Weight::from_non_witness_data_size(
-            (36 + VarInt::from(script_sig_size).len() + script_sig_size + 4) as u64,
+            (36 + VarInt(script_sig_size as u64).len() + script_sig_size + 4) as u64,
         )
     }
 
@@ -501,7 +501,9 @@ pub fn weight(&self) -> Weight {
         let script_len = self.script_pubkey.len();
         // In vbytes:
         // value (8) + script varint len + script push
-        Weight::from_non_witness_data_size((8 + VarInt::from(script_len).len() + script_len) as u64)
+        Weight::from_non_witness_data_size(
+            (8 + VarInt(script_len as u64).len() + script_len) as u64,
+        )
     }
 
     /// Creates a `TxOut` with given script and the smallest possible `value` that is **not** dust
@@ -711,28 +713,32 @@ pub fn vsize(&self) -> usize {
     }
 
     /// Returns the size of this transaction excluding the witness data.
-    pub fn strippedsize(&self) -> usize {
-        let mut input_size = 0;
+    #[deprecated(since = "0.31.0", note = "Use Transaction::stripped_size() instead")]
+    pub fn strippedsize(&self) -> usize { Self::stripped_size(self).to_wu() as usize }
+
+    /// Returns the size of this transaction excluding the witness data.
+    pub fn stripped_size(&self) -> Weight {
+        let mut input_size: Weight = Weight::ZERO;
         for input in &self.input {
-            input_size += TxIn::BASE_WEIGHT.to_wu() as usize
-                + VarInt(input.script_sig.len() as u64).len()
-                + input.script_sig.len();
+            input_size += TxIn::BASE_WEIGHT
+                + Weight::from_wu_usize(VarInt(input.script_sig.len() as u64).len())
+                + Weight::from_wu_usize(input.script_sig.len());
         }
-        let mut output_size = 0;
+        let mut output_size = Weight::ZERO;
         for output in &self.output {
-            output_size += 8 + // value
-                VarInt(output.script_pubkey.len() as u64).len() +
-                output.script_pubkey.len();
+            output_size += Weight::from_wu(8)+ // value
+                Weight::from_wu_usize(VarInt(output.script_pubkey.len() as u64).len()) +
+                Weight::from_wu_usize(output.script_pubkey.len());
         }
-        let non_input_size =
+        let non_input_size: Weight =
         // version:
-        4 +
+        Weight::from_wu(4)+
         // count varints:
-        VarInt(self.input.len() as u64).len() +
-        VarInt(self.output.len() as u64).len() +
+        Weight::from_wu_usize(VarInt(self.input.len() as u64).len()) +
+        Weight::from_wu_usize(VarInt(self.output.len() as u64).len()) +
         output_size +
         // lock_time
-        4;
+        Weight::from_wu(4);
         non_input_size + input_size
     }
 
@@ -1392,7 +1398,7 @@ fn test_nonsegwit_transaction() {
         assert_eq!(realtx.weight().to_wu() as usize, tx_bytes.len() * WITNESS_SCALE_FACTOR);
         assert_eq!(realtx.size(), tx_bytes.len());
         assert_eq!(realtx.vsize(), tx_bytes.len());
-        assert_eq!(realtx.strippedsize(), tx_bytes.len());
+        assert_eq!(realtx.stripped_size(), Weight::from_wu_usize(tx_bytes.len()));
     }
 
     #[test]
@@ -1438,19 +1444,21 @@ fn test_segwit_transaction() {
         //     weight = WITNESS_SCALE_FACTOR * stripped_size + witness_size
         // then,
         //     stripped_size = (weight - size) / (WITNESS_SCALE_FACTOR - 1)
-        let expected_strippedsize =
-            (EXPECTED_WEIGHT.to_wu() as usize - tx_bytes.len()) / (WITNESS_SCALE_FACTOR - 1);
-        assert_eq!(realtx.strippedsize(), expected_strippedsize);
+        let expected_strippedsize: Weight = Weight::from_wu(
+            (EXPECTED_WEIGHT - Weight::from_wu_usize(tx_bytes.len()))
+                / (Weight::from_wu_usize(WITNESS_SCALE_FACTOR - 1)),
+        );
+        assert_eq!(realtx.stripped_size(), expected_strippedsize);
         // Construct a transaction without the witness data.
         let mut tx_without_witness = realtx;
         tx_without_witness.input.iter_mut().for_each(|input| input.witness.clear());
         assert_eq!(
-            tx_without_witness.weight().to_wu() as usize,
-            expected_strippedsize * WITNESS_SCALE_FACTOR
+            tx_without_witness.weight(),
+            expected_strippedsize.scale_by_witness_factor().unwrap()
         );
-        assert_eq!(tx_without_witness.size(), expected_strippedsize);
-        assert_eq!(tx_without_witness.vsize(), expected_strippedsize);
-        assert_eq!(tx_without_witness.strippedsize(), expected_strippedsize);
+        assert_eq!(Weight::from_wu_usize(tx_without_witness.size()), expected_strippedsize);
+        assert_eq!(Weight::from_wu_usize(tx_without_witness.vsize()), expected_strippedsize);
+        assert_eq!(tx_without_witness.stripped_size(), expected_strippedsize);
     }
 
     // We temporarily abuse `Transaction` for testing consensus serde adapter.
diff --git a/bitcoin/src/blockdata/weight.rs b/bitcoin/src/blockdata/weight.rs
index d066bc54..6f6fa872 100644
--- a/bitcoin/src/blockdata/weight.rs
+++ b/bitcoin/src/blockdata/weight.rs
@@ -31,22 +31,30 @@ impl Weight {
     /// Maximum possible value.
     pub const MAX: Weight = Weight(u64::MAX);
 
+    /// The factor that non-witness serialization data is multiplied by during weight calculation.
+    pub const WITNESS_SCALE_FACTOR: u64 = crate::blockdata::constants::WITNESS_SCALE_FACTOR as u64;
+
     /// The maximum allowed weight for a block, see BIP 141 (network rule).
     pub const MAX_BLOCK: Weight = Weight(4_000_000);
 
     /// The minimum transaction weight for a valid serialized transaction.
-    pub const MIN_TRANSACTION: Weight = Weight(4 * 60);
+    pub const MIN_TRANSACTION: Weight = Weight(Self::WITNESS_SCALE_FACTOR * 60);
 
     /// Directly constructs `Weight` from weight units.
     pub const fn from_wu(wu: u64) -> Self { Weight(wu) }
 
-    /// Constructs `Weight` from kilo weight units returning `None` if overflow occurred.
+    /// Directly constructs `Weight` from usize weight units.
+    pub const fn from_wu_usize(wu: usize) -> Self { Weight(wu as u64) }
+
+    /// Constructs `Weight` from kilo weight units returning `None` if an overflow occurred.
     pub fn from_kwu(wu: u64) -> Option<Self> { wu.checked_mul(1000).map(Weight) }
 
     /// Constructs `Weight` from virtual bytes, returning `None` on overflow.
-    pub fn from_vb(vb: u64) -> Option<Self> { vb.checked_mul(4).map(Weight::from_wu) }
+    pub fn from_vb(vb: u64) -> Option<Self> {
+        vb.checked_mul(Self::WITNESS_SCALE_FACTOR).map(Weight::from_wu)
+    }
 
-    /// Constructs `Weight` from virtual bytes without overflow check.
+    /// Constructs `Weight` from virtual bytes without an overflow check.
     pub const fn from_vb_unchecked(vb: u64) -> Self { Weight::from_wu(vb * 4) }
 
     /// Constructs `Weight` from witness size.
@@ -54,7 +62,7 @@ pub const fn from_witness_data_size(witness_size: u64) -> Self { Weight(witness_
 
     /// Constructs `Weight` from non-witness size.
     pub const fn from_non_witness_data_size(non_witness_size: u64) -> Self {
-        Weight(non_witness_size * 4)
+        Weight(non_witness_size * Self::WITNESS_SCALE_FACTOR)
     }
 
     /// Returns raw weight units.
@@ -66,30 +74,39 @@ pub const fn to_wu(self) -> u64 { self.0 }
     pub const fn to_kwu_floor(self) -> u64 { self.0 / 1000 }
 
     /// Converts to vB rounding down.
-    pub const fn to_vbytes_floor(self) -> u64 { self.0 / 4 }
+    pub const fn to_vbytes_floor(self) -> u64 { self.0 / Self::WITNESS_SCALE_FACTOR }
 
     /// Converts to vB rounding up.
-    pub const fn to_vbytes_ceil(self) -> u64 { (self.0 + 3) / 4 }
+    pub const fn to_vbytes_ceil(self) -> u64 {
+        (self.0 + Self::WITNESS_SCALE_FACTOR - 1) / Self::WITNESS_SCALE_FACTOR
+    }
 
     /// Checked addition.
     ///
-    /// Computes `self + rhs` returning `None` if overflow occurred.
+    /// Computes `self + rhs` returning `None` if an overflow occurred.
     pub fn checked_add(self, rhs: Self) -> Option<Self> { self.0.checked_add(rhs.0).map(Self) }
 
     /// Checked subtraction.
     ///
-    /// Computes `self - rhs` returning `None` if overflow occurred.
+    /// Computes `self - rhs` returning `None` if an overflow occurred.
     pub fn checked_sub(self, rhs: Self) -> Option<Self> { self.0.checked_sub(rhs.0).map(Self) }
 
     /// Checked multiplication.
     ///
-    /// Computes `self * rhs` returning `None` if overflow occurred.
+    /// Computes `self * rhs` returning `None` if an overflow occurred.
     pub fn checked_mul(self, rhs: u64) -> Option<Self> { self.0.checked_mul(rhs).map(Self) }
 
     /// Checked division.
     ///
     /// Computes `self / rhs` returning `None` if `rhs == 0`.
     pub fn checked_div(self, rhs: u64) -> Option<Self> { self.0.checked_div(rhs).map(Self) }
+
+    /// Scale by witness factor.
+    ///
+    /// Computes `self * WITNESS_SCALE_FACTOR` returning `None` if an overflow occurred.
+    pub fn scale_by_witness_factor(self) -> Option<Self> {
+        Self::checked_mul(self, Self::WITNESS_SCALE_FACTOR)
+    }
 }
 
 /// Alternative will display the unit.
@@ -108,23 +125,24 @@ mod tests {
     use super::*;
 
     #[test]
-    fn weight_constructor_test() {
+    fn weight_constructor() {
         assert_eq!(Weight::ZERO, Weight::from_wu(0));
+        assert_eq!(Weight::ZERO, Weight::from_wu_usize(0_usize));
     }
 
     #[test]
-    fn kilo_weight_constructor_test() {
+    fn kilo_weight_constructor() {
         assert_eq!(Weight(1_000), Weight::from_kwu(1).expect("expected weight unit"));
     }
 
     #[test]
     #[should_panic]
-    fn kilo_weight_constructor_panic_test() {
+    fn kilo_weight_constructor_panic() {
         Weight::from_kwu(u64::MAX).expect("expected weight unit");
     }
 
     #[test]
-    fn from_vb_test() {
+    fn from_vb() {
         let vb = Weight::from_vb(1).expect("expected weight unit");
         assert_eq!(Weight(4), vb);
 
@@ -133,45 +151,45 @@ fn from_vb_test() {
     }
 
     #[test]
-    fn from_vb_unchecked_test() {
+    fn from_vb_unchecked() {
         let vb = Weight::from_vb_unchecked(1);
         assert_eq!(Weight(4), vb);
     }
 
     #[test]
     #[should_panic]
-    fn from_vb_unchecked_panic_test() { Weight::from_vb_unchecked(u64::MAX); }
+    fn from_vb_unchecked_panic() { Weight::from_vb_unchecked(u64::MAX); }
 
     #[test]
-    fn from_witness_data_size_test() {
+    fn from_witness_data_size() {
         let witness_data_size = 1;
         assert_eq!(Weight(witness_data_size), Weight::from_witness_data_size(witness_data_size));
     }
 
     #[test]
-    fn from_non_witness_data_size_test() {
+    fn from_non_witness_data_size() {
         assert_eq!(Weight(4), Weight::from_non_witness_data_size(1));
     }
 
     #[test]
-    fn to_kwu_floor_test() {
+    fn to_kwu_floor() {
         assert_eq!(1, Weight(1_000).to_kwu_floor());
     }
 
     #[test]
-    fn to_vb_floor_test() {
+    fn to_vb_floor() {
         assert_eq!(1, Weight(4).to_vbytes_floor());
         assert_eq!(1, Weight(5).to_vbytes_floor());
     }
 
     #[test]
-    fn to_vb_ceil_test() {
+    fn to_vb_ceil() {
         assert_eq!(1, Weight(4).to_vbytes_ceil());
         assert_eq!(2, Weight(5).to_vbytes_ceil());
     }
 
     #[test]
-    fn checked_add_test() {
+    fn checked_add() {
         let result = Weight(1).checked_add(Weight(1)).expect("expected weight unit");
         assert_eq!(Weight(2), result);
 
@@ -180,7 +198,7 @@ fn checked_add_test() {
     }
 
     #[test]
-    fn checked_sub_test() {
+    fn checked_sub() {
         let result = Weight(1).checked_sub(Weight(1)).expect("expected weight unit");
         assert_eq!(Weight::ZERO, result);
 
@@ -189,7 +207,7 @@ fn checked_sub_test() {
     }
 
     #[test]
-    fn checked_mul_test() {
+    fn checked_mul() {
         let result = Weight(2).checked_mul(2).expect("expected weight unit");
         assert_eq!(Weight(4), result);
 
@@ -198,13 +216,22 @@ fn checked_mul_test() {
     }
 
     #[test]
-    fn checked_div_test() {
+    fn checked_div() {
         let result = Weight(2).checked_div(2).expect("expected weight unit");
         assert_eq!(Weight(1), result);
 
         let result = Weight(2).checked_div(0);
         assert_eq!(None, result);
     }
+
+    #[test]
+    fn scale_by_witness_factor() {
+        let result = Weight(1).scale_by_witness_factor().expect("expected weight unit");
+        assert_eq!(Weight(4), result);
+
+        let result = Weight::MAX.scale_by_witness_factor();
+        assert_eq!(None, result);
+    }
 }
 
 impl From<Weight> for u64 {
diff --git a/bitcoin/src/blockdata/witness.rs b/bitcoin/src/blockdata/witness.rs
index 53a846ee..390ff0b0 100644
--- a/bitcoin/src/blockdata/witness.rs
+++ b/bitcoin/src/blockdata/witness.rs
@@ -213,7 +213,7 @@ fn resize_if_needed(vec: &mut Vec<u8>, required_len: usize) {
 
 impl Encodable for Witness {
     fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
-        let len = VarInt::from(self.witness_elements);
+        let len = VarInt(self.witness_elements as u64);
         len.consensus_encode(w)?;
         let content_with_indices_len = self.content.len();
         let indices_size = self.witness_elements * 4;
@@ -233,14 +233,14 @@ pub fn from_slice<T: AsRef<[u8]>>(slice: &[T]) -> Self {
         let index_size = witness_elements * 4;
         let content_size = slice
             .iter()
-            .map(|elem| elem.as_ref().len() + VarInt::from(elem.as_ref().len()).len())
+            .map(|elem| elem.as_ref().len() + VarInt(elem.as_ref().len() as u64).len())
             .sum();
 
         let mut content = vec![0u8; content_size + index_size];
         let mut cursor = 0usize;
         for (i, elem) in slice.iter().enumerate() {
             encode_cursor(&mut content, content_size, i, cursor);
-            let elem_len_varint = VarInt::from(elem.as_ref().len());
+            let elem_len_varint = VarInt(elem.as_ref().len() as u64);
             elem_len_varint
                 .consensus_encode(&mut &mut content[cursor..cursor + elem_len_varint.len()])
                 .expect("writers on vec don't errors, space granted by content_size");
@@ -268,8 +268,8 @@ pub fn len(&self) -> usize { self.witness_elements }
 
     /// Returns the bytes required when this Witness is consensus encoded.
     pub fn serialized_len(&self) -> usize {
-        self.iter().map(|el| VarInt::from(el.len()).len() + el.len()).sum::<usize>()
-            + VarInt::from(self.witness_elements).len()
+        self.iter().map(|el| VarInt(el.len() as u64).len() + el.len()).sum::<usize>()
+            + VarInt(self.witness_elements as u64).len()
     }
 
     /// Clear the witness.
@@ -288,7 +288,7 @@ pub fn push<T: AsRef<[u8]>>(&mut self, new_element: T) {
     fn push_slice(&mut self, new_element: &[u8]) {
         self.witness_elements += 1;
         let previous_content_end = self.indices_start;
-        let element_len_varint = VarInt::from(new_element.len());
+        let element_len_varint = VarInt(new_element.len() as u64);
         let current_content_len = self.content.len();
         let new_item_total_len = element_len_varint.len() + new_element.len();
         self.content.resize(current_content_len + new_item_total_len + 4, 0);
diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs
index 1aa927f0..297d1c08 100644
--- a/bitcoin/src/consensus/encode.rs
+++ b/bitcoin/src/consensus/encode.rs
@@ -399,21 +399,6 @@ pub const fn len(&self) -> usize {
     }
 }
 
-/// Implements `From<T> for VarInt`.
-///
-/// `VarInt`s are consensus encoded as `u64`s so we store them as such. Casting from any integer size smaller than or equal to `u64` is always safe and the cast value is correctly handled by `consensus_encode`.
-macro_rules! impl_var_int_from {
-    ($($ty:tt),*) => {
-        $(
-            /// Creates a `VarInt` from a `usize` by casting the to a `u64`.
-            impl From<$ty> for VarInt {
-                fn from(x: $ty) -> Self { VarInt(x as u64) }
-            }
-        )*
-    }
-}
-impl_var_int_from!(u8, u16, u32, u64, usize);
-
 impl Encodable for VarInt {
     #[inline]
     fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
@@ -451,7 +436,7 @@ fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
                 if x < 0x100000000 {
                     Err(self::Error::NonMinimalVarInt)
                 } else {
-                    Ok(VarInt::from(x))
+                    Ok(VarInt(x))
                 }
             }
             0xFE => {
@@ -459,7 +444,7 @@ fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
                 if x < 0x10000 {
                     Err(self::Error::NonMinimalVarInt)
                 } else {
-                    Ok(VarInt::from(x))
+                    Ok(VarInt(x as u64))
                 }
             }
             0xFD => {
@@ -467,10 +452,10 @@ fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
                 if x < 0xFD {
                     Err(self::Error::NonMinimalVarInt)
                 } else {
-                    Ok(VarInt::from(x))
+                    Ok(VarInt(x as u64))
                 }
             }
-            n => Ok(VarInt::from(n)),
+            n => Ok(VarInt(n as u64)),
         }
     }
 }
diff --git a/bitcoin/src/crypto/sighash.rs b/bitcoin/src/crypto/sighash.rs
index a24d9319..751410a9 100644
--- a/bitcoin/src/crypto/sighash.rs
+++ b/bitcoin/src/crypto/sighash.rs
@@ -239,9 +239,6 @@ pub enum Error {
 
     /// Invalid Sighash type.
     InvalidSighashType(u32),
-
-    /// Script is not a witness program for a p2wpkh output.
-    NotP2wpkhScript,
 }
 
 impl fmt::Display for Error {
@@ -257,7 +254,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             PrevoutKind => write!(f, "a single prevout has been provided but all prevouts are needed without `ANYONECANPAY`"),
             WrongAnnex => write!(f, "annex must be at least one byte long and the first bytes must be `0x50`"),
             InvalidSighashType(hash_ty) => write!(f, "Invalid taproot signature hash type : {} ", hash_ty),
-            NotP2wpkhScript => write!(f, "script is not a script pubkey for a p2wpkh output"),
         }
     }
 }
@@ -275,8 +271,7 @@ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
             | PrevoutIndex
             | PrevoutKind
             | WrongAnnex
-            | InvalidSighashType(_)
-            | NotP2wpkhScript => None,
+            | InvalidSighashType(_) => None,
         }
     }
 }
@@ -766,25 +761,7 @@ pub fn taproot_script_spend_signature_hash<S: Into<TapLeafHash>, T: Borrow<TxOut
 
     /// Encodes the BIP143 signing data for any flag type into a given object implementing a
     /// [`std::io::Write`] trait.
-    #[deprecated(since = "0.31.0", note = "use segwit_v0_encode_signing_data_to instead")]
     pub fn segwit_encode_signing_data_to<Write: io::Write>(
-        &mut self,
-        writer: Write,
-        input_index: usize,
-        script_code: &Script,
-        value: Amount,
-        sighash_type: EcdsaSighashType,
-    ) -> Result<(), Error> {
-        self.segwit_v0_encode_signing_data_to(writer, input_index, script_code, value, sighash_type)
-    }
-
-    /// Encodes the BIP143 signing data for any flag type into a given object implementing a
-    /// [`std::io::Write`] trait.
-    ///
-    /// `script_code` is dependent on the type of the spend transaction. For p2wpkh use
-    /// [`Script::p2wpkh_script_code`], for p2wsh just pass in the witness script. (Also see
-    /// [`Self::p2wpkh_signature_hash`] and [`SighashCache::p2wsh_signature_hash`].)
-    pub fn segwit_v0_encode_signing_data_to<Write: io::Write>(
         &mut self,
         mut writer: Write,
         input_index: usize,
@@ -844,7 +821,6 @@ pub fn segwit_v0_encode_signing_data_to<Write: io::Write>(
     }
 
     /// Computes the BIP143 sighash for any flag type.
-    #[deprecated(since = "0.31.0", note = "use segwit_v0_signature_hash instead")]
     pub fn segwit_signature_hash(
         &mut self,
         input_index: usize,
@@ -853,7 +829,7 @@ pub fn segwit_signature_hash(
         sighash_type: EcdsaSighashType,
     ) -> Result<SegwitV0Sighash, Error> {
         let mut enc = SegwitV0Sighash::engine();
-        self.segwit_v0_encode_signing_data_to(
+        self.segwit_encode_signing_data_to(
             &mut enc,
             input_index,
             script_code,
@@ -863,49 +839,6 @@ pub fn segwit_signature_hash(
         Ok(SegwitV0Sighash::from_engine(enc))
     }
 
-    /// Computes the BIP143 sighash to spend a p2wpkh transaction for any flag type.
-    ///
-    /// `script_pubkey` is the `scriptPubkey` (native segwit) of the spend transaction
-    /// ([`TxOut::script_pubkey`]) or the `redeemScript` (wrapped segwit).
-    pub fn p2wpkh_signature_hash(
-        &mut self,
-        input_index: usize,
-        script_pubkey: &Script,
-        value: Amount,
-        sighash_type: EcdsaSighashType,
-    ) -> Result<SegwitV0Sighash, Error> {
-        let script_code = script_pubkey.p2wpkh_script_code().ok_or(Error::NotP2wpkhScript)?;
-
-        let mut enc = SegwitV0Sighash::engine();
-        self.segwit_v0_encode_signing_data_to(
-            &mut enc,
-            input_index,
-            &script_code,
-            value,
-            sighash_type,
-        )?;
-        Ok(SegwitV0Sighash::from_engine(enc))
-    }
-
-    /// Computes the BIP143 sighash to spend a p2wsh transaction for any flag type.
-    pub fn p2wsh_signature_hash(
-        &mut self,
-        input_index: usize,
-        witness_script: &Script,
-        value: Amount,
-        sighash_type: EcdsaSighashType,
-    ) -> Result<SegwitV0Sighash, Error> {
-        let mut enc = SegwitV0Sighash::engine();
-        self.segwit_v0_encode_signing_data_to(
-            &mut enc,
-            input_index,
-            witness_script,
-            value,
-            sighash_type,
-        )?;
-        Ok(SegwitV0Sighash::from_engine(enc))
-    }
-
     /// Encodes the legacy signing data from which a signature hash for a given input index with a
     /// given sighash flag can be computed.
     ///
@@ -1261,10 +1194,13 @@ mod tests {
     use hex::FromHex;
 
     use super::*;
+    use crate::address::Address;
     use crate::blockdata::locktime::absolute;
     use crate::consensus::deserialize;
+    use crate::crypto::key::PublicKey;
     use crate::crypto::sighash::{LegacySighash, TapSighash};
     use crate::internal_macros::hex;
+    use crate::network::Network;
     use crate::taproot::TapLeafHash;
 
     extern crate serde_json;
@@ -1751,9 +1687,7 @@ struct TestData {
                 .taproot_signature_hash(tx_ind, &Prevouts::All(&utxos), None, None, hash_ty)
                 .unwrap();
 
-            // TODO: After upgrade of secp change this to Message::from_digest(sighash.to_byte_array()).
-            let msg = secp256k1::Message::from_slice(sighash.as_byte_array())
-                .expect("sighash is 32 bytes long");
+            let msg = secp256k1::Message::from(sighash);
             let key_spend_sig = secp.sign_schnorr_with_aux_rand(&msg, &tweaked_keypair, &[0u8; 32]);
 
             assert_eq!(expected.internal_pubkey, internal_key);
@@ -1805,6 +1739,11 @@ fn sighashtype_fromstr_display() {
         }
     }
 
+    fn p2pkh_hex(pk: &str) -> ScriptBuf {
+        let pk: PublicKey = PublicKey::from_str(pk).unwrap();
+        Address::p2pkh(&pk, Network::Bitcoin).script_pubkey()
+    }
+
     #[test]
     fn bip143_p2wpkh() {
         let tx = deserialize::<Transaction>(
@@ -1816,12 +1755,13 @@ fn bip143_p2wpkh() {
             ),
         ).unwrap();
 
-        let spk = ScriptBuf::from_hex("00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1").unwrap();
+        let witness_script =
+            p2pkh_hex("025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357");
         let value = Amount::from_sat(600_000_000);
 
         let mut cache = SighashCache::new(&tx);
         assert_eq!(
-            cache.p2wpkh_signature_hash(1, &spk, value, EcdsaSighashType::All).unwrap(),
+            cache.segwit_signature_hash(1, &witness_script, value, EcdsaSighashType::All).unwrap(),
             "c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670"
                 .parse::<SegwitV0Sighash>()
                 .unwrap(),
@@ -1856,13 +1796,13 @@ fn bip143_p2wpkh_nested_in_p2sh() {
             ),
         ).unwrap();
 
-        let redeem_script =
-            ScriptBuf::from_hex("001479091972186c449eb1ded22b78e40d009bdf0089").unwrap();
+        let witness_script =
+            p2pkh_hex("03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873");
         let value = Amount::from_sat(1_000_000_000);
 
         let mut cache = SighashCache::new(&tx);
         assert_eq!(
-            cache.p2wpkh_signature_hash(0, &redeem_script, value, EcdsaSighashType::All).unwrap(),
+            cache.segwit_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(),
             "64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6"
                 .parse::<SegwitV0Sighash>()
                 .unwrap(),
@@ -1887,10 +1827,8 @@ fn bip143_p2wpkh_nested_in_p2sh() {
         );
     }
 
-    // Note, if you are looking at the test vectors in BIP-143 and wondering why there is a `cf`
-    // prepended to all the script_code hex it is the length byte, it gets added when we consensus
-    // encode a script.
-    fn bip143_p2wsh_nested_in_p2sh_data() -> (Transaction, ScriptBuf, Amount) {
+    #[test]
+    fn bip143_p2wsh_nested_in_p2sh() {
         let tx = deserialize::<Transaction>(&hex!(
             "010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000\
              ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f\
@@ -1907,27 +1845,16 @@ fn bip143_p2wsh_nested_in_p2sh_data() -> (Transaction, ScriptBuf, Amount) {
              56ae",
         )
         .unwrap();
-
         let value = Amount::from_sat(987_654_321);
-        (tx, witness_script, value)
-    }
 
-    #[test]
-    fn bip143_p2wsh_nested_in_p2sh_sighash_type_all() {
-        let (tx, witness_script, value) = bip143_p2wsh_nested_in_p2sh_data();
         let mut cache = SighashCache::new(&tx);
         assert_eq!(
-            cache.p2wsh_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(),
+            cache.segwit_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(),
             "185c0be5263dce5b4bb50a047973c1b6272bfbd0103a89444597dc40b248ee7c"
                 .parse::<SegwitV0Sighash>()
                 .unwrap(),
         );
 
-        // We only test the cache intermediate values for `EcdsaSighashType::All` because they are
-        // not the same as the BIP test vectors for all the rest of the sighash types. These fields
-        // are private so it does not effect sighash cache usage, we do test against the produced
-        // sighash for all sighash types.
-
         let cache = cache.segwit_cache();
         // Parse hex into Vec because BIP143 test vector displays forwards but our sha256d::Hash displays backwards.
         assert_eq!(
@@ -1946,34 +1873,4 @@ fn bip143_p2wsh_nested_in_p2sh_sighash_type_all() {
                 .unwrap()[..],
         );
     }
-
-    macro_rules! check_bip143_p2wsh_nested_in_p2sh {
-        ($($test_name:ident, $sighash_type:ident, $sighash:literal);* $(;)?) => {
-            $(
-                #[test]
-                fn $test_name() {
-                    use EcdsaSighashType::*;
-
-                    let (tx, witness_script, value) = bip143_p2wsh_nested_in_p2sh_data();
-                    let mut cache = SighashCache::new(&tx);
-                    assert_eq!(
-                        cache
-                            .p2wsh_signature_hash(0, &witness_script, value, $sighash_type)
-                            .unwrap(),
-                        $sighash
-                            .parse::<SegwitV0Sighash>()
-                            .unwrap(),
-                    );
-                }
-            )*
-        }
-    }
-    check_bip143_p2wsh_nested_in_p2sh! {
-        // EcdsaSighashType::All tested above.
-        bip143_p2wsh_nested_in_p2sh_sighash_none, None, "e9733bc60ea13c95c6527066bb975a2ff29a925e80aa14c213f686cbae5d2f36";
-        bip143_p2wsh_nested_in_p2sh_sighash_single, Single, "1e1f1c303dc025bd664acb72e583e933fae4cff9148bf78c157d1e8f78530aea";
-        bip143_p2wsh_nested_in_p2sh_sighash_all_plus_anyonecanpay, AllPlusAnyoneCanPay, "2a67f03e63a6a422125878b40b82da593be8d4efaafe88ee528af6e5a9955c6e";
-        bip143_p2wsh_nested_in_p2sh_sighash_none_plus_anyonecanpay, NonePlusAnyoneCanPay, "781ba15f3779d5542ce8ecb5c18716733a5ee42a6f51488ec96154934e2c890a";
-        bip143_p2wsh_nested_in_p2sh_sighash_single_plus_anyonecanpay, SinglePlusAnyoneCanPay, "511e8e52ed574121fc1b654970395502128263f62662e076dc6baf05c2e6a99b";
-    }
 }
diff --git a/bitcoin/src/merkle_tree/block.rs b/bitcoin/src/merkle_tree/block.rs
index 076e55dc..6fff7650 100644
--- a/bitcoin/src/merkle_tree/block.rs
+++ b/bitcoin/src/merkle_tree/block.rs
@@ -436,7 +436,7 @@ fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io
         ret += self.hashes.consensus_encode(w)?;
 
         let nb_bytes_for_bits = (self.bits.len() + 7) / 8;
-        ret += encode::VarInt::from(nb_bytes_for_bits).consensus_encode(w)?;
+        ret += encode::VarInt(nb_bytes_for_bits as u64).consensus_encode(w)?;
         for chunk in self.bits.chunks(8) {
             let mut byte = 0u8;
             for (i, bit) in chunk.iter().enumerate() {
diff --git a/bitcoin/src/p2p/address.rs b/bitcoin/src/p2p/address.rs
index 11cbd882..58678bc9 100644
--- a/bitcoin/src/p2p/address.rs
+++ b/bitcoin/src/p2p/address.rs
@@ -148,7 +148,7 @@ fn encode_addr<W: io::Write + ?Sized>(
             bytes: &[u8],
         ) -> Result<usize, io::Error> {
             let len = network.consensus_encode(w)?
-                + VarInt::from(bytes.len()).consensus_encode(w)?
+                + VarInt(bytes.len() as u64).consensus_encode(w)?
                 + bytes.len();
             w.emit_slice(bytes)?;
             Ok(len)
diff --git a/bitcoin/src/p2p/message.rs b/bitcoin/src/p2p/message.rs
index 8b76e80e..8b048af2 100644
--- a/bitcoin/src/p2p/message.rs
+++ b/bitcoin/src/p2p/message.rs
@@ -335,7 +335,7 @@ impl<'a> Encodable for HeaderSerializationWrapper<'a> {
     #[inline]
     fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
         let mut len = 0;
-        len += VarInt::from(self.0.len()).consensus_encode(w)?;
+        len += VarInt(self.0.len() as u64).consensus_encode(w)?;
         for header in self.0.iter() {
             len += header.consensus_encode(w)?;
             len += 0u8.consensus_encode(w)?;
diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs
index a8a98e23..df9f6c90 100644
--- a/bitcoin/src/psbt/mod.rs
+++ b/bitcoin/src/psbt/mod.rs
@@ -11,7 +11,6 @@
 #[cfg(feature = "std")]
 use std::collections::{HashMap, HashSet};
 
-use hashes::Hash;
 use internals::write_err;
 use secp256k1::{Message, Secp256k1, Signing};
 
@@ -326,51 +325,38 @@ pub fn sighash_ecdsa<T: Borrow<Transaction>>(
         match self.output_type(input_index)? {
             Bare => {
                 let sighash = cache.legacy_signature_hash(input_index, spk, hash_ty.to_u32())?;
-                // TODO: After upgrade of secp change this to Message::from_digest(sighash.to_byte_array()).
-                Ok((
-                    Message::from_slice(sighash.as_byte_array()).expect("sighash is 32 bytes long"),
-                    hash_ty,
-                ))
+                Ok((Message::from(sighash), hash_ty))
             }
             Sh => {
                 let script_code =
                     input.redeem_script.as_ref().ok_or(SignError::MissingRedeemScript)?;
                 let sighash =
                     cache.legacy_signature_hash(input_index, script_code, hash_ty.to_u32())?;
-                // TODO: After upgrade of secp change this to Message::from_digest(sighash.to_byte_array()).
-                Ok((
-                    Message::from_slice(sighash.as_byte_array()).expect("sighash is 32 bytes long"),
-                    hash_ty,
-                ))
+                Ok((Message::from(sighash), hash_ty))
             }
             Wpkh => {
-                let sighash = cache.p2wpkh_signature_hash(input_index, spk, utxo.value, hash_ty)?;
-                // TODO: After upgrade of secp change this to Message::from_digest(sighash.to_byte_array()).
-                Ok((
-                    Message::from_slice(sighash.as_byte_array()).expect("sighash is 32 bytes long"),
-                    hash_ty,
-                ))
+                let script_code = spk.p2wpkh_script_code().ok_or(SignError::NotWpkh)?;
+                let sighash =
+                    cache.segwit_signature_hash(input_index, &script_code, utxo.value, hash_ty)?;
+                Ok((Message::from(sighash), hash_ty))
             }
             ShWpkh => {
-                let redeem_script = input.redeem_script.as_ref().expect("checked above");
+                let script_code = input
+                    .redeem_script
+                    .as_ref()
+                    .expect("checked above")
+                    .p2wpkh_script_code()
+                    .ok_or(SignError::NotWpkh)?;
                 let sighash =
-                    cache.p2wpkh_signature_hash(input_index, redeem_script, utxo.value, hash_ty)?;
-                // TODO: After upgrade of secp change this to Message::from_digest(sighash.to_byte_array()).
-                Ok((
-                    Message::from_slice(sighash.as_byte_array()).expect("sighash is 32 bytes long"),
-                    hash_ty,
-                ))
+                    cache.segwit_signature_hash(input_index, &script_code, utxo.value, hash_ty)?;
+                Ok((Message::from(sighash), hash_ty))
             }
             Wsh | ShWsh => {
-                let witness_script =
+                let script_code =
                     input.witness_script.as_ref().ok_or(SignError::MissingWitnessScript)?;
                 let sighash =
-                    cache.p2wsh_signature_hash(input_index, witness_script, utxo.value, hash_ty)?;
-                // TODO: After upgrade of secp change this to Message::from_digest(sighash.to_byte_array()).
-                Ok((
-                    Message::from_slice(sighash.as_byte_array()).expect("sighash is 32 bytes long"),
-                    hash_ty,
-                ))
+                    cache.segwit_signature_hash(input_index, script_code, utxo.value, hash_ty)?;
+                Ok((Message::from(sighash), hash_ty))
             }
             Tr => {
                 // This PSBT signing API is WIP, taproot to come shortly.
diff --git a/bitcoin/src/psbt/raw.rs b/bitcoin/src/psbt/raw.rs
index 3e80366b..aa312413 100644
--- a/bitcoin/src/psbt/raw.rs
+++ b/bitcoin/src/psbt/raw.rs
@@ -104,7 +104,7 @@ pub(crate) fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
 impl Serialize for Key {
     fn serialize(&self) -> Vec<u8> {
         let mut buf = Vec::new();
-        VarInt::from(self.key.len() + 1)
+        VarInt((self.key.len() + 1) as u64)
             .consensus_encode(&mut buf)
             .expect("in-memory writers don't error");
 
diff --git a/bitcoin/src/psbt/serialize.rs b/bitcoin/src/psbt/serialize.rs
index 43245b90..3f9c57ad 100644
--- a/bitcoin/src/psbt/serialize.rs
+++ b/bitcoin/src/psbt/serialize.rs
@@ -342,7 +342,7 @@ fn serialize(&self) -> Vec<u8> {
         let capacity = self
             .script_leaves()
             .map(|l| {
-                l.script().len() + VarInt::from(l.script().len()).len() // script version
+                l.script().len() + VarInt(l.script().len() as u64).len() // script version
             + 1 // merkle branch
             + 1 // leaf version
             })
diff --git a/bitcoin/src/sign_message.rs b/bitcoin/src/sign_message.rs
index bb9d47b7..d4a4a6da 100644
--- a/bitcoin/src/sign_message.rs
+++ b/bitcoin/src/sign_message.rs
@@ -19,7 +19,7 @@
 mod message_signing {
     use core::fmt;
 
-    use hashes::{sha256d, Hash};
+    use hashes::sha256d;
     use internals::write_err;
     use secp256k1;
     use secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
@@ -132,10 +132,7 @@ pub fn recover_pubkey<C: secp256k1::Verification>(
             secp_ctx: &secp256k1::Secp256k1<C>,
             msg_hash: sha256d::Hash,
         ) -> Result<PublicKey, MessageSignatureError> {
-            // TODO: After upgrade of secp change this to Message::from_digest(sighash.to_byte_array()).
-            let msg = secp256k1::Message::from_slice(msg_hash.as_byte_array())
-                .expect("sh256d hash is 32 bytes long");
-
+            let msg = secp256k1::Message::from(msg_hash);
             let pubkey = secp_ctx.recover_ecdsa(&msg, &self.signature)?;
             Ok(PublicKey { inner: pubkey, compressed: self.compressed })
         }
@@ -198,7 +195,7 @@ fn from_str(s: &str) -> Result<MessageSignature, MessageSignatureError> {
 pub fn signed_msg_hash(msg: &str) -> sha256d::Hash {
     let mut engine = sha256d::Hash::engine();
     engine.input(BITCOIN_SIGNED_MSG_PREFIX);
-    let msg_len = encode::VarInt::from(msg.len());
+    let msg_len = encode::VarInt(msg.len() as u64);
     msg_len.consensus_encode(&mut engine).expect("engines don't error");
     engine.input(msg.as_bytes());
     sha256d::Hash::from_engine(engine)
@@ -229,9 +226,7 @@ fn test_message_signature() {
         let secp = secp256k1::Secp256k1::new();
         let message = "rust-bitcoin MessageSignature test";
         let msg_hash = super::signed_msg_hash(message);
-        // TODO: After upgrade of secp change this to Message::from_digest(sighash.to_byte_array()).
-        let msg = secp256k1::Message::from_slice(msg_hash.as_byte_array())
-            .expect("sh256d hash is 32 bytes long");
+        let msg = secp256k1::Message::from(msg_hash);
 
         let privkey = secp256k1::SecretKey::new(&mut secp256k1::rand::thread_rng());
         let secp_sig = secp.sign_ecdsa_recoverable(&msg, &privkey);
diff --git a/contrib/update-lock-files.sh b/contrib/update-lock-files.sh
deleted file mode 100755
index 02ba1f7c..00000000
--- a/contrib/update-lock-files.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env bash
-#
-# Update the minimal/recent lock file
-
-set -euo pipefail
-
-for file in Cargo-minimal.lock Cargo-recent.lock; do
-    cp --force "$file" Cargo.lock
-    cargo check
-    cp --force Cargo.lock "$file"
-done
diff --git a/hashes/CHANGELOG.md b/hashes/CHANGELOG.md
index 5e6d739f..2eae01c3 100644
--- a/hashes/CHANGELOG.md
+++ b/hashes/CHANGELOG.md
@@ -1,18 +1,6 @@
-# 0.13.0 - 2023-06-29
+# Unreleased
 
-The main improvement in this version is removal of the `hex` module in favour of the new
-[`hex-conservative`](https://crates.io/crates/hex-conservative) crate (which we wrote). We also
-bumped the Minimum Supported Rust Version across the `rust-bitcoin` ecosystem to v1.48
-
-* Bump MSRV to 1.48.0 [#1729](https://github.com/rust-bitcoin/rust-bitcoin/pull/1729).
-* Depend on new `hex-conservative` crate and remove `hex` module [#1883](https://github.com/rust-bitcoin/rust-bitcoin/pull/1833).
 * Convert enum `crate::Error` to struct `crate::FromSliceError`.
-* Make `sha256t_hash_newtype!` evocative of the output [#1773](https://github.com/rust-bitcoin/rust-bitcoin/pull/1773).
-* Implement computing SHA256 in const context [#1769](https://github.com/rust-bitcoin/rust-bitcoin/pull/1769).
-* Add `from_bytes_ref` and `from_bytes_mut` to all hash types [#1761](https://github.com/rust-bitcoin/rust-bitcoin/pull/1761).
-* Rename `crate::Error` to `crate::FromSliceError` [#1873](https://github.com/rust-bitcoin/rust-bitcoin/pull/1873).
-* Add simd sha256 intrinsics for x86 machines [#1962](https://github.com/rust-bitcoin/rust-bitcoin/pull/1962).
-* Introduce the "small-hash" feature for `bitcoin_hashes` [#1990](https://github.com/rust-bitcoin/rust-bitcoin/pull/1990).
 
 # 0.12.0 - 2023-03-05
 
diff --git a/hashes/Cargo.toml b/hashes/Cargo.toml
index 00e908e1..44a2351f 100644
--- a/hashes/Cargo.toml
+++ b/hashes/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "bitcoin_hashes"
-version = "0.13.0"
+version = "0.12.0"
 authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"]
 license = "CC0-1.0"
 repository = "https://github.com/rust-bitcoin/rust-bitcoin"


Test patch:
diff --git a/bitcoin/contrib/test.sh b/bitcoin/contrib/test.sh
index fa87a21d..f8643822 100755
--- a/bitcoin/contrib/test.sh
+++ b/bitcoin/contrib/test.sh
@@ -36,12 +36,9 @@ then
     duplicate_dependencies=$(
         # Only show the actual duplicated deps, not their reverse tree, then
         # whitelist the 'syn' crate which is duplicated but it's not our fault.
-        #
-        # Whitelist `bitcoin_hashes` while we release it and until secp v0.28.0 comes out.
         cargo tree  --target=all --all-features --duplicates \
             | grep '^[0-9A-Za-z]' \
             | grep -v 'syn' \
-            | grep -v 'bitcoin_hashes' \
             | wc -l
                           )
     if [ "$duplicate_dependencies" -ne 0 ]; then