Merge rust-bitcoin/rust-bitcoin#1621: Rename `from_slice` methods to `decode`

32d2d62e0f Rename from_slice methods to decode (Tobin C. Harding)

Pull request description:

  The `TaprootMerkleBranch` and `ControlBlock` both have methods on them called `from_slice` but these methods do more that just basic copy from a slice. `decode` is a more descriptive name.

  Deprecate the `from_slice` methods and implement `decode`, on other changes to the logic.

  cc sanket1729

ACKs for top commit:
  apoelstra:
    ACK 32d2d62e0f
  Kixunil:
    ACK 32d2d62e0f

Tree-SHA512: e8c089545411a214ef9393f65d3990be46983000bd045182cc27dd70b62273bf48ac97adaf89d1e7fc807c72964a01eef176c7685684e8f87a01c219746d6d3d
This commit is contained in:
Andrew Poelstra 2023-02-07 16:38:52 +00:00
commit cc3b5a080b
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
3 changed files with 32 additions and 10 deletions

View File

@ -335,7 +335,7 @@ impl Serialize for ControlBlock {
impl Deserialize for ControlBlock {
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
Self::from_slice(bytes)
Self::decode(bytes)
.map_err(|_| Error::InvalidControlBlock)
}
}

View File

@ -644,8 +644,22 @@ impl TaprootMerkleBranch {
/// Returns a reference to the inner vector of hashes.
pub fn as_inner(&self) -> &[TapNodeHash] { &self.0 }
/// Creates a merkle proof from raw data representing a list of hashes.
/// Decodes bytes from control block.
#[deprecated(since = "0.30.0", note = "Use decode instead")]
pub fn from_slice(sl: &[u8]) -> Result<Self, TaprootError> {
Self::decode(sl)
}
/// Decodes bytes from control block.
///
/// This reads the branch as encoded in the control block: the concatenated 32B byte chunks -
/// one for each hash.
///
/// # Errors
///
/// The function returns an error if the the number of bytes is not an integer multiple of 32 or
/// if the number of hashes exceeds 128.
pub fn decode(sl: &[u8]) -> Result<Self, TaprootError> {
if sl.len() % TAPROOT_CONTROL_NODE_SIZE != 0 {
Err(TaprootError::InvalidMerkleBranchSize(sl.len()))
} else if sl.len() > TAPROOT_CONTROL_NODE_SIZE * TAPROOT_CONTROL_MAX_NODE_COUNT {
@ -760,9 +774,17 @@ pub struct ControlBlock {
}
impl ControlBlock {
/// Constructs a `ControlBlock` from slice. This is an extra witness element that provides the
/// proof that taproot script pubkey is correctly computed with some specified leaf hash. This
/// is the last element in taproot witness when spending a output via script path.
/// Constructs a `ControlBlock` from slice.
#[deprecated(since = "0.30.0", note = "Use decode instead")]
pub fn from_slice(sl: &[u8]) -> Result<ControlBlock, TaprootError> {
Self::decode(sl)
}
/// Decodes bytes representing a `ControlBlock`.
///
/// This is an extra witness element that provides the proof that taproot script pubkey is
/// correctly computed with some specified leaf hash. This is the last element in taproot
/// witness when spending a output via script path.
///
/// # Errors
///
@ -771,7 +793,7 @@ impl ControlBlock {
/// - [`TaprootError::InvalidTaprootLeafVersion`] if first byte of `sl` is not a valid leaf version.
/// - [`TaprootError::InvalidInternalKey`] if internal key is invalid (first 32 bytes after the parity byte).
/// - [`TaprootError::InvalidMerkleTreeDepth`] if merkle tree is too deep (more than 128 levels).
pub fn from_slice(sl: &[u8]) -> Result<ControlBlock, TaprootError> {
pub fn decode(sl: &[u8]) -> Result<ControlBlock, TaprootError> {
if sl.len() < TAPROOT_CONTROL_BASE_SIZE
|| (sl.len() - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE != 0
{
@ -782,7 +804,7 @@ impl ControlBlock {
let leaf_version = LeafVersion::from_consensus(sl[0] & TAPROOT_LEAF_MASK)?;
let internal_key = UntweakedPublicKey::from_slice(&sl[1..TAPROOT_CONTROL_BASE_SIZE])
.map_err(TaprootError::InvalidInternalKey)?;
let merkle_branch = TaprootMerkleBranch::from_slice(&sl[TAPROOT_CONTROL_BASE_SIZE..])?;
let merkle_branch = TaprootMerkleBranch::decode(&sl[TAPROOT_CONTROL_BASE_SIZE..])?;
Ok(ControlBlock { leaf_version, output_key_parity, internal_key, merkle_branch })
}
@ -1224,7 +1246,7 @@ mod test {
let out_pk = TweakedPublicKey::dangerous_assume_tweaked(out_pk);
let script = ScriptBuf::from_hex(script_hex).unwrap();
let control_block =
ControlBlock::from_slice(&Vec::<u8>::from_hex(control_block_hex).unwrap()).unwrap();
ControlBlock::decode(&Vec::<u8>::from_hex(control_block_hex).unwrap()).unwrap();
assert_eq!(control_block_hex, control_block.serialize().to_lower_hex_string());
assert!(control_block.verify_taproot_commitment(secp, out_pk.to_inner(), &script));
}
@ -1448,7 +1470,7 @@ mod test {
let spend_info = builder.finalize(secp, internal_key).unwrap();
for (i, script_ver) in leaves.iter().enumerate() {
let expected_leaf_hash = leaf_hashes[i].as_str().unwrap();
let expected_ctrl_blk = ControlBlock::from_slice(
let expected_ctrl_blk = ControlBlock::decode(
&Vec::<u8>::from_hex(ctrl_blks[i].as_str().unwrap()).unwrap(),
)
.unwrap();

View File

@ -187,7 +187,7 @@ fn serde_regression_ecdsa_sig() {
#[test]
fn serde_regression_control_block() {
let s = include_str!("data/serde/control_block_hex");
let block = ControlBlock::from_slice(&Vec::<u8>::from_hex(s.trim()).unwrap()).unwrap();
let block = ControlBlock::decode(&Vec::<u8>::from_hex(s.trim()).unwrap()).unwrap();
let got = serialize(&block).unwrap();
let want = include_bytes!("data/serde/control_block_bincode") as &[_];