Skip to content

Commit eed0493

Browse files
committed
lsp_plugin: add reversed feature-bit check
Core-Lightning returns the feature-bits in reversed order but we don't want to rely on the caller to reverse the u8 slice themselfs. This commit adds a convenience function that reverses the bitmap to avoid hard to debug mistakes. Signed-off-by: Peter Neuroth <pet.v.ne@gmail.com>
1 parent bfbc818 commit eed0493

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

plugins/lsps-plugin/src/client.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,9 +591,7 @@ async fn ensure_lsp_connected(cln_client: &mut ClnRpc, lsp_id: &str) -> Result<(
591591
// Check that feature bit is set
592592
peer.features.as_deref().map_or(false, |f_str| {
593593
if let Some(feature_bits) = hex::decode(f_str).ok() {
594-
let mut fb = feature_bits.clone();
595-
fb.reverse();
596-
util::is_feature_bit_set(&fb, LSP_FEATURE_BIT)
594+
util::is_feature_bit_set_reversed(&feature_bits, LSP_FEATURE_BIT)
597595
} else {
598596
false
599597
}

plugins/lsps-plugin/src/util.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,32 @@ use core::fmt;
55
use serde_json::Value;
66
use std::str::FromStr;
77

8+
/// Checks whether a feature bit is set in a bitmap interpreted as
9+
/// **big-endian across bytes**, while keeping **LSB-first within each byte**.
10+
///
11+
/// This function creates a reversed copy of `bitmap` (so the least-significant
12+
/// byte becomes last), then calls the simple LSB-first `is_feature_bit_set` on it.
13+
/// No mutation of the caller’s slice occurs.
14+
///
15+
/// In other words:
16+
/// - byte order: **reversed** (big-endian across the slice)
17+
/// - bit order within a byte: **LSB-first** (unchanged)
18+
///
19+
/// If you need *full* MSB-first (also within a byte), don’t use this helper—
20+
/// rewrite the mask as `1u8 << (7 - bit_index)` instead.
21+
///
22+
/// # Arguments
23+
/// * `bitmap` – byte slice containing the bitfield (original order, not modified)
24+
/// * `feature_bit` – zero-based bit index across the entire bitmap
25+
///
26+
/// # Returns
27+
/// `true` if the bit is set; `false` if the bit is unset or out of bounds
28+
pub fn is_feature_bit_set_reversed(bitmap: &[u8], feature_bit: usize) -> bool {
29+
let mut reversed = bitmap.to_vec();
30+
reversed.reverse();
31+
is_feature_bit_set(&reversed, feature_bit)
32+
}
33+
834
/// Checks if the feature bit is set in the provided bitmap.
935
/// Returns true if the `feature_bit` is set in the `bitmap`. Returns false if
1036
/// the `feature_bit` is unset or our ouf bounds.

0 commit comments

Comments
 (0)