Skip to content

Commit 442b9d8

Browse files
committed
fixup! Expose per-channel features in ChannelDetails
refactor ffi::InitFeatures to wrap LdkInitFeatures
1 parent e60e42d commit 442b9d8

File tree

2 files changed

+102
-14
lines changed

2 files changed

+102
-14
lines changed

src/ffi/types.rs

Lines changed: 95 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ pub use lightning_liquidity::lsps0::ser::LSPSDateTime;
4343
pub use lightning_liquidity::lsps1::msgs::{
4444
LSPS1ChannelInfo, LSPS1OrderId, LSPS1OrderParams, LSPS1PaymentState,
4545
};
46-
#[cfg(feature = "uniffi")]
47-
use lightning_types::features::InitFeatures;
46+
use lightning_types::features::InitFeatures as LdkInitFeatures;
4847
pub use lightning_types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
4948
pub use lightning_types::string::UntrustedString;
5049
use vss_client::headers::{
@@ -1498,17 +1497,101 @@ pub enum ClosureReason {
14981497
},
14991498
}
15001499

1501-
#[cfg(feature = "uniffi")]
1502-
uniffi::custom_type!(InitFeatures, Vec<u8>, {
1503-
remote,
1504-
try_lift: |val| Ok(InitFeatures::from_be_bytes(val)),
1505-
lower: |obj| {
1506-
let mut flags = obj.le_flags().to_vec();
1507-
flags.reverse();
1508-
flags
1509-
},
1510-
});
1500+
#[derive(Debug, Clone, PartialEq, Eq, uniffi::Object)]
1501+
#[uniffi::export(Debug, Eq)]
1502+
pub struct InitFeatures {
1503+
pub(crate) inner: LdkInitFeatures,
1504+
}
1505+
1506+
impl InitFeatures {
1507+
/// Constructs init features from big-endian BOLT 9 encoded bytes.
1508+
#[uniffi::constructor]
1509+
pub fn from_bytes(bytes: &[u8]) -> Self {
1510+
Self { inner: LdkInitFeatures::from_be_bytes(bytes.to_vec()).into() }
1511+
}
1512+
1513+
/// Returns the BOLT 9 big-endian encoded representation of these features.
1514+
pub fn to_bytes(&self) -> Vec<u8> {
1515+
self.inner.encode()
1516+
}
1517+
1518+
/// Whether the peer supports `option_static_remotekey` (bit 13).
1519+
///
1520+
/// This ensures the non-broadcaster's output pays directly to their specified key,
1521+
/// simplifying recovery if a channel is force-closed.
1522+
pub fn supports_static_remote_key(&self) -> bool {
1523+
self.inner.supports_static_remote_key()
1524+
}
1525+
1526+
/// Whether the peer supports `option_anchors_zero_fee_htlc_tx` (bit 23).
1527+
///
1528+
/// Anchor channels allow fee-bumping commitment transactions after broadcast,
1529+
/// improving on-chain fee management.
1530+
pub fn supports_anchors_zero_fee_htlc_tx(&self) -> bool {
1531+
self.inner.supports_anchors_zero_fee_htlc_tx()
1532+
}
1533+
1534+
/// Whether the peer supports `option_support_large_channel` (bit 19).
1535+
///
1536+
/// When supported, channels larger than 2^24 satoshis (≈0.168 BTC) may be opened.
1537+
pub fn supports_wumbo(&self) -> bool {
1538+
self.inner.supports_wumbo()
1539+
}
1540+
1541+
/// Whether the peer supports `option_route_blinding` (bit 25).
1542+
///
1543+
/// Route blinding allows the recipient to hide their node identity and
1544+
/// last-hop channel from the sender.
1545+
pub fn supports_route_blinding(&self) -> bool {
1546+
self.inner.supports_route_blinding()
1547+
}
1548+
1549+
/// Whether the peer supports `option_onion_messages` (bit 39).
1550+
///
1551+
/// Onion messages enable communication over the Lightning Network without
1552+
/// requiring a payment, used by BOLT 12 offers and async payments.
1553+
pub fn supports_onion_messages(&self) -> bool {
1554+
self.inner.supports_onion_messages()
1555+
}
1556+
1557+
/// Whether the peer supports `option_scid_alias` (bit 47).
1558+
///
1559+
/// When supported, the peer will only forward using short channel ID aliases,
1560+
/// preventing the real channel UTXO from being revealed during routing.
1561+
pub fn supports_scid_privacy(&self) -> bool {
1562+
self.inner.supports_scid_privacy()
1563+
}
1564+
1565+
/// Whether the peer supports `option_zeroconf` (bit 51).
1566+
///
1567+
/// Zero-conf channels can be used immediately without waiting for
1568+
/// on-chain funding confirmations.
1569+
pub fn supports_zero_conf(&self) -> bool {
1570+
self.inner.requires_zero_conf()
1571+
}
1572+
1573+
/// Whether the peer supports `option_dual_fund` (bit 29).
1574+
///
1575+
/// Dual-funded channels allow both parties to contribute funds
1576+
/// to the channel opening transaction.
1577+
pub fn supports_dual_fund(&self) -> bool {
1578+
self.inner.supports_dual_fund()
1579+
}
15111580

1581+
/// Whether the peer supports `option_quiesce` (bit 35).
1582+
///
1583+
/// Quiescence is a prerequisite for splicing, allowing both sides to
1584+
/// pause HTLC activity before modifying the funding transaction.
1585+
pub fn supports_quiescence(&self) -> bool {
1586+
self.inner.supports_quiescence()
1587+
}
1588+
}
1589+
1590+
impl From<LdkInitFeatures> for InitFeatures {
1591+
fn from(ldk_init: LdkInitFeatures) -> Self {
1592+
Self { inner: ldk_init }
1593+
}
1594+
}
15121595
#[cfg(test)]
15131596
mod tests {
15141597
use std::num::NonZeroU64;

src/types.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use lightning::routing::gossip;
2424
use lightning::routing::router::DefaultRouter;
2525
use lightning::routing::scoring::{CombinedScorer, ProbabilisticScoringFeeParameters};
2626
use lightning::sign::InMemorySigner;
27-
use lightning::types::features::InitFeatures;
2827
use lightning::util::persist::{KVStore, KVStoreSync, MonitorUpdatingPersisterAsync};
2928
use lightning::util::ser::{Readable, Writeable, Writer};
3029
use lightning::util::sweep::OutputSweeper;
@@ -37,11 +36,17 @@ use crate::chain::ChainSource;
3736
use crate::config::{AnchorChannelsConfig, ChannelConfig};
3837
use crate::data_store::DataStore;
3938
use crate::fee_estimator::OnchainFeeEstimator;
39+
use crate::ffi::maybe_wrap;
4040
use crate::logger::Logger;
4141
use crate::message_handler::NodeCustomMessageHandler;
4242
use crate::payment::{PaymentDetails, PendingPaymentDetails};
4343
use crate::runtime::RuntimeSpawner;
4444

45+
#[cfg(not(feature = "uniffi"))]
46+
type InitFeatures = lightning::types::features::InitFeatures;
47+
#[cfg(feature = "uniffi")]
48+
type InitFeatures = Arc<crate::ffi::InitFeatures>;
49+
4550
/// A supertrait that requires that a type implements both [`KVStore`] and [`KVStoreSync`] at the
4651
/// same time.
4752
pub trait SyncAndAsyncKVStore: KVStore + KVStoreSync {}
@@ -652,7 +657,7 @@ impl ChannelDetails {
652657
channel_id: value.channel_id,
653658
counterparty: ChannelCounterparty {
654659
node_id: value.counterparty.node_id,
655-
features: value.counterparty.features,
660+
features: maybe_wrap(value.counterparty.features),
656661
unspendable_punishment_reserve: value.counterparty.unspendable_punishment_reserve,
657662
forwarding_info: value.counterparty.forwarding_info,
658663
outbound_htlc_minimum_msat: value.counterparty.outbound_htlc_minimum_msat,

0 commit comments

Comments
 (0)