Skip to content

Commit b7d57ea

Browse files
committed
Use &mut self in invoice updaters, not take-self-return-Self
The take-self-return-Self idiom in Rust is substantially less usable than it is in Java, where its more common. Because we have to take self by move, it prevents using the update methods to actually update features, something we occasionally want to do. See, eg, the change in lightning-invoice where we previously had to copy and re-create an entire vec of fields just to update the features field, which is nuts. There are a few places where this makes things a little less clean, but the tradeoff to enable more effecient and broader uses of the update methods seems worth it.
1 parent e43cfe1 commit b7d57ea

File tree

3 files changed

+26
-23
lines changed

3 files changed

+26
-23
lines changed

lightning-invoice/src/lib.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,9 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, S: tb::Bool> InvoiceBuilder<D, H, T,
610610
impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T, C, tb::False> {
611611
/// Sets the payment secret and relevant features.
612612
pub fn payment_secret(mut self, payment_secret: PaymentSecret) -> InvoiceBuilder<D, H, T, C, tb::True> {
613-
let features = InvoiceFeatures::empty()
614-
.set_variable_length_onion_required()
615-
.set_payment_secret_required();
613+
let mut features = InvoiceFeatures::empty();
614+
features.set_variable_length_onion_required();
615+
features.set_payment_secret_required();
616616
self.tagged_fields.push(TaggedField::PaymentSecret(payment_secret));
617617
self.tagged_fields.push(TaggedField::Features(features));
618618
self.set_flags()
@@ -622,13 +622,11 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T,
622622
impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool> InvoiceBuilder<D, H, T, C, tb::True> {
623623
/// Sets the `basic_mpp` feature as optional.
624624
pub fn basic_mpp(mut self) -> Self {
625-
self.tagged_fields = self.tagged_fields
626-
.drain(..)
627-
.map(|field| match field {
628-
TaggedField::Features(f) => TaggedField::Features(f.set_basic_mpp_optional()),
629-
_ => field,
630-
})
631-
.collect();
625+
for field in self.tagged_fields.iter_mut() {
626+
if let TaggedField::Features(f) = field {
627+
f.set_basic_mpp_optional();
628+
}
629+
}
632630
self
633631
}
634632
}

lightning/src/ln/features.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -318,15 +318,13 @@ mod sealed {
318318

319319
impl <T: $feature> Features<T> {
320320
/// Set this feature as optional.
321-
pub fn $optional_setter(mut self) -> Self {
321+
pub fn $optional_setter(&mut self) {
322322
<T as $feature>::set_optional_bit(&mut self.flags);
323-
self
324323
}
325324

326325
/// Set this feature as required.
327-
pub fn $required_setter(mut self) -> Self {
326+
pub fn $required_setter(&mut self) {
328327
<T as $feature>::set_required_bit(&mut self.flags);
329-
self
330328
}
331329

332330
/// Checks if this feature is supported.
@@ -506,7 +504,9 @@ impl InvoiceFeatures {
506504
/// [`PaymentParameters::for_keysend`]: crate::routing::router::PaymentParameters::for_keysend
507505
/// [`find_route`]: crate::routing::router::find_route
508506
pub(crate) fn for_keysend() -> InvoiceFeatures {
509-
InvoiceFeatures::empty().set_variable_length_onion_optional()
507+
let mut res = InvoiceFeatures::empty();
508+
res.set_variable_length_onion_optional();
509+
res
510510
}
511511
}
512512

@@ -838,11 +838,13 @@ mod tests {
838838
assert!(!features.requires_unknown_bits());
839839
assert!(!features.supports_unknown_bits());
840840

841-
let features = ChannelFeatures::empty().set_unknown_feature_required();
841+
let mut features = ChannelFeatures::empty();
842+
features.set_unknown_feature_required();
842843
assert!(features.requires_unknown_bits());
843844
assert!(features.supports_unknown_bits());
844845

845-
let features = ChannelFeatures::empty().set_unknown_feature_optional();
846+
let mut features = ChannelFeatures::empty();
847+
features.set_unknown_feature_optional();
846848
assert!(!features.requires_unknown_bits());
847849
assert!(features.supports_unknown_bits());
848850
}
@@ -886,17 +888,18 @@ mod tests {
886888
fn convert_to_context_with_unknown_flags() {
887889
// Ensure the `from` context has fewer known feature bytes than the `to` context.
888890
assert!(InvoiceFeatures::known().flags.len() < NodeFeatures::known().flags.len());
889-
let invoice_features = InvoiceFeatures::known().set_unknown_feature_optional();
891+
let mut invoice_features = InvoiceFeatures::known();
892+
invoice_features.set_unknown_feature_optional();
890893
assert!(invoice_features.supports_unknown_bits());
891894
let node_features: NodeFeatures = invoice_features.to_context();
892895
assert!(!node_features.supports_unknown_bits());
893896
}
894897

895898
#[test]
896899
fn set_feature_bits() {
897-
let features = InvoiceFeatures::empty()
898-
.set_basic_mpp_optional()
899-
.set_payment_secret_required();
900+
let mut features = InvoiceFeatures::empty();
901+
features.set_basic_mpp_optional();
902+
features.set_payment_secret_required();
900903
assert!(features.supports_basic_mpp());
901904
assert!(!features.requires_basic_mpp());
902905
assert!(features.requires_payment_secret());
@@ -938,7 +941,8 @@ mod tests {
938941
fn test_channel_type_mapping() {
939942
// If we map an InvoiceFeatures with StaticRemoteKey optional, it should map into a
940943
// required-StaticRemoteKey ChannelTypeFeatures.
941-
let init_features = InitFeatures::empty().set_static_remote_key_optional();
944+
let mut init_features = InitFeatures::empty();
945+
init_features.set_static_remote_key_optional();
942946
let converted_features = ChannelTypeFeatures::from_counterparty_init(&init_features);
943947
assert_eq!(converted_features, ChannelTypeFeatures::only_static_remote_key());
944948
assert!(!converted_features.supports_any_optional_bits());

lightning/src/routing/router.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2369,7 +2369,8 @@ mod tests {
23692369
let scorer = test_utils::TestScorer::with_penalty(0);
23702370

23712371
// Disable nodes 1, 2, and 8 by requiring unknown feature bits
2372-
let unknown_features = NodeFeatures::known().set_unknown_feature_required();
2372+
let mut unknown_features = NodeFeatures::known();
2373+
unknown_features.set_unknown_feature_required();
23732374
add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[0], unknown_features.clone(), 1);
23742375
add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[1], unknown_features.clone(), 1);
23752376
add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[7], unknown_features.clone(), 1);

0 commit comments

Comments
 (0)