@@ -429,6 +429,53 @@ pub struct ChannelReady {
429
429
pub short_channel_id_alias : Option < u64 > ,
430
430
}
431
431
432
+ /// A splice message to be sent by or received from the splice initiator.
433
+ /// TODO(splicing): Is using 'splice initiator' role OK?
434
+ /// TODO(splicing): Can the channel acceptor later be the splice initiator?
435
+ ///
436
+ // TODO(splicing): Add spec link for `splice`; still in draft, using from https://github.com/lightning/bolts/pull/863
437
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
438
+ pub struct Splice {
439
+ /// The channel ID where splicing is intended
440
+ pub channel_id : ChannelId ,
441
+ /// The genesis hash of the blockchain where the channel is intended to be spliced
442
+ pub chain_hash : BlockHash ,
443
+ /// The intended change in channel capacity: the amount to be added (positive value)
444
+ /// or removed (negative value) by the sender (splice initiator) by splicing into/from the channel.
445
+ pub relative_satoshis : i64 ,
446
+ /// The feerate for the new funding transaction, set by the splice initiator
447
+ pub funding_feerate_perkw : u32 ,
448
+ /// The locktime for the new funding transaction
449
+ pub locktime : u32 ,
450
+ /// The key of the sender (splice initiator) controlling the new funding transaction
451
+ pub funding_pubkey : PublicKey ,
452
+ }
453
+
454
+ /// A splice_ack message to be received by or sent to the splice initiator.
455
+ ///
456
+ // TODO(splicing): Add spec link for `splice_ack`; still in draft, using from https://github.com/lightning/bolts/pull/863
457
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
458
+ pub struct SpliceAck {
459
+ /// The channel ID where splicing is intended
460
+ pub channel_id : ChannelId ,
461
+ /// The genesis hash of the blockchain where the channel is intended to be spliced
462
+ pub chain_hash : BlockHash ,
463
+ /// The intended change in channel capacity: the amount to be added (positive value)
464
+ /// or removed (negative value) by the sender (splice acceptor) by splicing into/from the channel.
465
+ pub relative_satoshis : i64 ,
466
+ /// The key of the sender (splice acceptor) controlling the new funding transaction
467
+ pub funding_pubkey : PublicKey ,
468
+ }
469
+
470
+ /// A splice_locked message to be sent to or received from a peer.
471
+ ///
472
+ // TODO(splicing): Add spec link for `splice_locked`; still in draft, using from https://github.com/lightning/bolts/pull/863
473
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
474
+ pub struct SpliceLocked {
475
+ /// The channel ID
476
+ pub channel_id : ChannelId ,
477
+ }
478
+
432
479
/// A tx_add_input message for adding an input during interactive transaction construction
433
480
///
434
481
// TODO(dual_funding): Add spec link for `tx_add_input`.
@@ -1229,12 +1276,20 @@ pub trait ChannelMessageHandler : MessageSendEventsProvider {
1229
1276
/// Handle an incoming `channel_ready` message from the given peer.
1230
1277
fn handle_channel_ready ( & self , their_node_id : & PublicKey , msg : & ChannelReady ) ;
1231
1278
1232
- // Channl close:
1279
+ // Channel close:
1233
1280
/// Handle an incoming `shutdown` message from the given peer.
1234
1281
fn handle_shutdown ( & self , their_node_id : & PublicKey , msg : & Shutdown ) ;
1235
1282
/// Handle an incoming `closing_signed` message from the given peer.
1236
1283
fn handle_closing_signed ( & self , their_node_id : & PublicKey , msg : & ClosingSigned ) ;
1237
1284
1285
+ // Splicing
1286
+ /// Handle an incoming `splice` message from the given peer.
1287
+ fn handle_splice ( & self , their_node_id : & PublicKey , msg : & Splice ) ;
1288
+ /// Handle an incoming `splice_ack` message from the given peer.
1289
+ fn handle_splice_ack ( & self , their_node_id : & PublicKey , msg : & SpliceAck ) ;
1290
+ /// Handle an incoming `splice_locked` message from the given peer.
1291
+ fn handle_splice_locked ( & self , their_node_id : & PublicKey , msg : & SpliceLocked ) ;
1292
+
1238
1293
// Interactive channel construction
1239
1294
/// Handle an incoming `tx_add_input message` from the given peer.
1240
1295
fn handle_tx_add_input ( & self , their_node_id : & PublicKey , msg : & TxAddInput ) ;
@@ -1613,6 +1668,26 @@ impl_writeable_msg!(AcceptChannelV2, {
1613
1668
( 2 , require_confirmed_inputs, option) ,
1614
1669
} ) ;
1615
1670
1671
+ impl_writeable_msg ! ( Splice , {
1672
+ channel_id,
1673
+ chain_hash,
1674
+ relative_satoshis,
1675
+ funding_feerate_perkw,
1676
+ locktime,
1677
+ funding_pubkey,
1678
+ } , { } ) ;
1679
+
1680
+ impl_writeable_msg ! ( SpliceAck , {
1681
+ channel_id,
1682
+ chain_hash,
1683
+ relative_satoshis,
1684
+ funding_pubkey,
1685
+ } , { } ) ;
1686
+
1687
+ impl_writeable_msg ! ( SpliceLocked , {
1688
+ channel_id,
1689
+ } , { } ) ;
1690
+
1616
1691
impl_writeable_msg ! ( TxAddInput , {
1617
1692
channel_id,
1618
1693
serial_id,
@@ -3115,6 +3190,45 @@ mod tests {
3115
3190
assert_eq ! ( encoded_value, target_value) ;
3116
3191
}
3117
3192
3193
+ #[ test]
3194
+ fn encoding_splice ( ) {
3195
+ let secp_ctx = Secp256k1 :: new ( ) ;
3196
+ let ( _, pubkey_1, ) = get_keys_from ! ( "0101010101010101010101010101010101010101010101010101010101010101" , secp_ctx) ;
3197
+ let splice = msgs:: Splice {
3198
+ chain_hash : BlockHash :: from_hex ( "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000" ) . unwrap ( ) ,
3199
+ channel_id : ChannelId :: from_bytes ( [ 2 ; 32 ] ) ,
3200
+ relative_satoshis : 123456 ,
3201
+ funding_feerate_perkw : 2000 ,
3202
+ locktime : 0 ,
3203
+ funding_pubkey : pubkey_1,
3204
+ } ;
3205
+ let encoded_value = splice. encode ( ) ;
3206
+ assert_eq ! ( hex:: encode( encoded_value) , "0202020202020202020202020202020202020202020202020202020202020202000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f000000000001e240000007d000000000031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" ) ;
3207
+ }
3208
+
3209
+ #[ test]
3210
+ fn encoding_splice_ack ( ) {
3211
+ let secp_ctx = Secp256k1 :: new ( ) ;
3212
+ let ( _, pubkey_1, ) = get_keys_from ! ( "0101010101010101010101010101010101010101010101010101010101010101" , secp_ctx) ;
3213
+ let splice = msgs:: SpliceAck {
3214
+ chain_hash : BlockHash :: from_hex ( "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000" ) . unwrap ( ) ,
3215
+ channel_id : ChannelId :: from_bytes ( [ 2 ; 32 ] ) ,
3216
+ relative_satoshis : 123456 ,
3217
+ funding_pubkey : pubkey_1,
3218
+ } ;
3219
+ let encoded_value = splice. encode ( ) ;
3220
+ assert_eq ! ( hex:: encode( encoded_value) , "0202020202020202020202020202020202020202020202020202020202020202000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f000000000001e240031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" ) ;
3221
+ }
3222
+
3223
+ #[ test]
3224
+ fn encoding_splice_locked ( ) {
3225
+ let splice = msgs:: SpliceLocked {
3226
+ channel_id : ChannelId :: from_bytes ( [ 2 ; 32 ] ) ,
3227
+ } ;
3228
+ let encoded_value = splice. encode ( ) ;
3229
+ assert_eq ! ( hex:: encode( encoded_value) , "0202020202020202020202020202020202020202020202020202020202020202" ) ;
3230
+ }
3231
+
3118
3232
#[ test]
3119
3233
fn encoding_tx_add_input ( ) {
3120
3234
let tx_add_input = msgs:: TxAddInput {
0 commit comments