Skip to content

Commit eb88dc0

Browse files
committed
Expose splice negotiation events over gRPC
1 parent db32dda commit eb88dc0

4 files changed

Lines changed: 116 additions & 2 deletions

File tree

e2e-tests/tests/e2e.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,11 +1178,24 @@ async fn splice_in_via_cli(splice_amount: &str) {
11781178
let server_b = LdkServerHandle::start(&bitcoind).await;
11791179
let user_channel_id = setup_funded_channel(&bitcoind, &server_a, &server_b, 100_000).await;
11801180

1181+
let mut events_a = server_a.client().subscribe_events().await.unwrap();
1182+
11811183
let output = run_cli(
11821184
&server_a,
11831185
&["splice-in", &user_channel_id, server_b.node_id(), splice_amount],
11841186
);
11851187
assert!(output.is_object());
1188+
1189+
let event_a =
1190+
wait_for_event(&mut events_a, |e| matches!(e, Event::SpliceNegotiated(_))).await;
1191+
match &event_a.event {
1192+
Some(Event::SpliceNegotiated(splice_negotiated)) => {
1193+
assert_eq!(splice_negotiated.user_channel_id, user_channel_id);
1194+
assert_eq!(splice_negotiated.counterparty_node_id, server_b.node_id());
1195+
assert!(!splice_negotiated.new_funding_txo.is_empty());
1196+
},
1197+
other => panic!("expected SpliceNegotiated event, got {other:?}"),
1198+
}
11861199
}
11871200

11881201
#[tokio::test]

ldk-server-grpc/src/events.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#[allow(clippy::derive_partial_eq_without_eq)]
1515
#[derive(Clone, PartialEq, ::prost::Message)]
1616
pub struct EventEnvelope {
17-
#[prost(oneof = "event_envelope::Event", tags = "2, 3, 4, 6, 7, 8")]
17+
#[prost(oneof = "event_envelope::Event", tags = "2, 3, 4, 6, 7, 8, 9, 10")]
1818
pub event: ::core::option::Option<event_envelope::Event>,
1919
}
2020
/// Nested message and enum types in `EventEnvelope`.
@@ -36,6 +36,10 @@ pub mod event_envelope {
3636
PaymentClaimable(super::PaymentClaimable),
3737
#[prost(message, tag = "8")]
3838
ChannelStateChanged(super::ChannelStateChanged),
39+
#[prost(message, tag = "9")]
40+
SpliceNegotiated(super::SpliceNegotiated),
41+
#[prost(message, tag = "10")]
42+
SpliceNegotiationFailed(super::SpliceNegotiationFailed),
3943
}
4044
}
4145
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -140,6 +144,38 @@ pub struct ChannelStateChanged {
140144
#[prost(enumeration = "ChannelClosureInitiator", tag = "7")]
141145
pub closure_initiator: i32,
142146
}
147+
/// SpliceNegotiated indicates a channel splice has been negotiated and the funding
148+
/// transaction is pending confirmation on-chain.
149+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
150+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
151+
#[cfg_attr(feature = "serde", serde(default))]
152+
#[allow(clippy::derive_partial_eq_without_eq)]
153+
#[derive(Clone, PartialEq, ::prost::Message)]
154+
pub struct SpliceNegotiated {
155+
#[prost(string, tag = "1")]
156+
pub channel_id: ::prost::alloc::string::String,
157+
#[prost(string, tag = "2")]
158+
pub user_channel_id: ::prost::alloc::string::String,
159+
#[prost(string, tag = "3")]
160+
pub counterparty_node_id: ::prost::alloc::string::String,
161+
/// The outpoint of the channel's splice funding transaction.
162+
#[prost(string, tag = "4")]
163+
pub new_funding_txo: ::prost::alloc::string::String,
164+
}
165+
/// SpliceNegotiationFailed indicates a channel splice negotiation round has failed.
166+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
167+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
168+
#[cfg_attr(feature = "serde", serde(default))]
169+
#[allow(clippy::derive_partial_eq_without_eq)]
170+
#[derive(Clone, PartialEq, ::prost::Message)]
171+
pub struct SpliceNegotiationFailed {
172+
#[prost(string, tag = "1")]
173+
pub channel_id: ::prost::alloc::string::String,
174+
#[prost(string, tag = "2")]
175+
pub user_channel_id: ::prost::alloc::string::String,
176+
#[prost(string, tag = "3")]
177+
pub counterparty_node_id: ::prost::alloc::string::String,
178+
}
143179
/// PaymentReceived indicates a payment has been received.
144180
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
145181
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]

ldk-server-grpc/src/proto/events.proto

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ message EventEnvelope {
1111
PaymentForwarded payment_forwarded = 6;
1212
PaymentClaimable payment_claimable = 7;
1313
ChannelStateChanged channel_state_changed = 8;
14+
SpliceNegotiated splice_negotiated = 9;
15+
SpliceNegotiationFailed splice_negotiation_failed = 10;
1416
}
1517
}
1618

@@ -92,6 +94,23 @@ message ChannelStateChanged {
9294
ChannelClosureInitiator closure_initiator = 7;
9395
}
9496

97+
// SpliceNegotiated indicates a channel splice has been negotiated and the funding
98+
// transaction is pending confirmation on-chain.
99+
message SpliceNegotiated {
100+
string channel_id = 1;
101+
string user_channel_id = 2;
102+
string counterparty_node_id = 3;
103+
// The outpoint of the channel's splice funding transaction.
104+
string new_funding_txo = 4;
105+
}
106+
107+
// SpliceNegotiationFailed indicates a channel splice negotiation round has failed.
108+
message SpliceNegotiationFailed {
109+
string channel_id = 1;
110+
string user_channel_id = 2;
111+
string counterparty_node_id = 3;
112+
}
113+
95114
// PaymentReceived indicates a payment has been received.
96115
message PaymentReceived {
97116
// The payment details for the payment in event.

ldk-server/src/main.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,11 +632,57 @@ fn main() {
632632
}
633633
}
634634
},
635-
_ => {
635+
Event::SpliceNegotiated {
636+
channel_id,
637+
user_channel_id,
638+
counterparty_node_id,
639+
new_funding_txo,
640+
} => {
641+
info!(
642+
"SPLICE_NEGOTIATED: {} from counterparty {}",
643+
channel_id, counterparty_node_id
644+
);
645+
646+
send_channel_state_event(
647+
event_envelope::Event::SpliceNegotiated(events::SpliceNegotiated {
648+
channel_id: channel_id.0.to_lower_hex_string(),
649+
user_channel_id: user_channel_id.0.to_string(),
650+
counterparty_node_id: counterparty_node_id.to_string(),
651+
new_funding_txo: new_funding_txo.to_string(),
652+
}),
653+
&event_sender,
654+
);
655+
636656
if let Err(e) = event_node.event_handled() {
637657
error!("Failed to mark event as handled: {e}");
638658
}
639659
},
660+
Event::SpliceNegotiationFailed {
661+
channel_id,
662+
user_channel_id,
663+
counterparty_node_id,
664+
} => {
665+
info!(
666+
"SPLICE_NEGOTIATION_FAILED: {} from counterparty {}",
667+
channel_id, counterparty_node_id
668+
);
669+
670+
send_channel_state_event(
671+
event_envelope::Event::SpliceNegotiationFailed(
672+
events::SpliceNegotiationFailed {
673+
channel_id: channel_id.0.to_lower_hex_string(),
674+
user_channel_id: user_channel_id.0.to_string(),
675+
counterparty_node_id: counterparty_node_id.to_string(),
676+
},
677+
),
678+
&event_sender,
679+
);
680+
681+
if let Err(e) = event_node.event_handled() {
682+
error!("Failed to mark event as handled: {e}");
683+
}
684+
},
685+
640686
}
641687
},
642688
res = grpc_listener.accept() => {

0 commit comments

Comments
 (0)