Skip to content

Commit

Permalink
fix: better handle invalid XOnlyPks
Browse files Browse the repository at this point in the history
  • Loading branch information
storopoli committed Jan 24, 2025
1 parent 2989163 commit a553dc2
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 10 deletions.
1 change: 1 addition & 0 deletions bin/strata-client/src/extractor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ mod tests {
let random_buf = generate_valid_xonly_pk_buf32();
let dest_addr = XOnlyPk::new(random_buf);
let dest_descriptor = dest_addr
.expect("infallible due to generate_valid_xonly_pk_buf32")
.to_descriptor()
.expect("infallible due to generate_valid_xonly_pk_buf32");

Expand Down
19 changes: 12 additions & 7 deletions crates/bridge-tx-builder/src/withdrawal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,10 @@ mod tests {

let user_pk = XOnlyPk::new(Buf32(pubkeys[user_index].x_only_public_key().0.serialize()));

let user_descriptor = user_pk.to_descriptor().expect("infallible");
let user_descriptor = user_pk
.expect("infallible")
.to_descriptor()
.expect("infallible");

let assigned_operator_idx = assigned_operator_idx as OperatorIdx;

Expand Down Expand Up @@ -281,13 +284,14 @@ mod tests {
"use separate indexes for user and assigned operator"
);

let user_pk = XOnlyPk::new(Buf32(pubkeys[user_index].x_only_public_key().0.serialize()));
let user_descriptor = user_pk.to_descriptor();
let user_pk =
XOnlyPk::new(Buf32(pubkeys[user_index].x_only_public_key().0.serialize())).unwrap();
let user_descriptor = user_pk.to_descriptor().unwrap();
let assigned_operator_idx = assigned_operator_idx as OperatorIdx;

let withdrawal_info = CooperativeWithdrawalInfo::new(
deposit_outpoint,
user_descriptor.unwrap(),
user_descriptor,
assigned_operator_idx,
0,
);
Expand Down Expand Up @@ -325,13 +329,14 @@ mod tests {
"use separate indexes for user and assigned operator"
);

let user_pk = XOnlyPk::new(Buf32(pubkeys[user_index].x_only_public_key().0.serialize()));
let user_descriptor = user_pk.to_descriptor();
let user_pk =
XOnlyPk::new(Buf32(pubkeys[user_index].x_only_public_key().0.serialize())).unwrap();
let user_descriptor = user_pk.to_descriptor().unwrap();
let assigned_operator_idx = assigned_operator_idx as OperatorIdx;

let withdrawal_info = CooperativeWithdrawalInfo::new(
deposit_outpoint,
user_descriptor.unwrap(),
user_descriptor,
assigned_operator_idx,
0,
);
Expand Down
15 changes: 12 additions & 3 deletions crates/primitives/src/l1/btc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,8 +712,12 @@ pub struct XOnlyPk(Buf32);

impl XOnlyPk {
/// Construct a new [`XOnlyPk`] directly from a [`Buf32`].
pub fn new(val: Buf32) -> Self {
Self(val)
pub fn new(val: Buf32) -> Result<Self, ParseError> {
if Self::is_valid_xonly_public_key(&val) {
Ok(Self(val))
} else {
Err(ParseError::InvalidPoint(val))

Check warning on line 719 in crates/primitives/src/l1/btc.rs

View check run for this annotation

Codecov / codecov/patch

crates/primitives/src/l1/btc.rs#L719

Added line #L719 was not covered by tests
}
}

/// Get the underlying [`Buf32`].
Expand Down Expand Up @@ -761,6 +765,11 @@ impl XOnlyPk {
Descriptor::new_p2tr(&self.to_xonly_public_key().serialize())
.map_err(|_| ParseError::InvalidPoint(self.0))
}

/// Checks if the [`Buf32`] is a valid [`XOnlyPublicKey`].
fn is_valid_xonly_public_key(buf: &Buf32) -> bool {
XOnlyPublicKey::from_slice(buf.as_bytes()).is_ok()
}
}

impl TryFrom<XOnlyPk> for Descriptor {
Expand Down Expand Up @@ -1332,7 +1341,7 @@ mod tests {

#[test]
fn test_xonly_pk_to_descriptor() {
let xonly_pk = XOnlyPk::new(Buf32::from([2u8; 32]));
let xonly_pk = XOnlyPk::new(Buf32::from([2u8; 32])).unwrap();
let descriptor = xonly_pk.to_descriptor().unwrap();
assert_eq!(descriptor.type_tag(), DescriptorType::P2tr);

Expand Down

0 comments on commit a553dc2

Please sign in to comment.