@@ -441,6 +441,53 @@ pub struct ChannelReady {
441
441
pub short_channel_id_alias : Option < u64 > ,
442
442
}
443
443
444
+ /// A splice message to be sent by or received from the splice initiator.
445
+ /// TODO(splicing): Is using 'splice initiator' role OK?
446
+ /// TODO(splicing): Can the channel acceptor later be the splice initiator?
447
+ ///
448
+ // TODO(splicing): Add spec link for `splice`; still in draft, using from https://github.com/lightning/bolts/pull/863
449
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
450
+ pub struct Splice {
451
+ /// The channel ID where splicing is intended
452
+ pub channel_id : ChannelId ,
453
+ /// The genesis hash of the blockchain where the channel is intended to be spliced
454
+ pub chain_hash : ChainHash ,
455
+ /// The intended change in channel capacity: the amount to be added (positive value)
456
+ /// or removed (negative value) by the sender (splice initiator) by splicing into/from the channel.
457
+ pub relative_satoshis : i64 ,
458
+ /// The feerate for the new funding transaction, set by the splice initiator
459
+ pub funding_feerate_perkw : u32 ,
460
+ /// The locktime for the new funding transaction
461
+ pub locktime : u32 ,
462
+ /// The key of the sender (splice initiator) controlling the new funding transaction
463
+ pub funding_pubkey : PublicKey ,
464
+ }
465
+
466
+ /// A splice_ack message to be received by or sent to the splice initiator.
467
+ ///
468
+ // TODO(splicing): Add spec link for `splice_ack`; still in draft, using from https://github.com/lightning/bolts/pull/863
469
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
470
+ pub struct SpliceAck {
471
+ /// The channel ID where splicing is intended
472
+ pub channel_id : ChannelId ,
473
+ /// The genesis hash of the blockchain where the channel is intended to be spliced
474
+ pub chain_hash : ChainHash ,
475
+ /// The intended change in channel capacity: the amount to be added (positive value)
476
+ /// or removed (negative value) by the sender (splice acceptor) by splicing into/from the channel.
477
+ pub relative_satoshis : i64 ,
478
+ /// The key of the sender (splice acceptor) controlling the new funding transaction
479
+ pub funding_pubkey : PublicKey ,
480
+ }
481
+
482
+ /// A splice_locked message to be sent to or received from a peer.
483
+ ///
484
+ // TODO(splicing): Add spec link for `splice_locked`; still in draft, using from https://github.com/lightning/bolts/pull/863
485
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
486
+ pub struct SpliceLocked {
487
+ /// The channel ID
488
+ pub channel_id : ChannelId ,
489
+ }
490
+
444
491
/// A tx_add_input message for adding an input during interactive transaction construction
445
492
///
446
493
// TODO(dual_funding): Add spec link for `tx_add_input`.
@@ -1409,6 +1456,14 @@ pub trait ChannelMessageHandler : MessageSendEventsProvider {
1409
1456
/// Handle an incoming `closing_signed` message from the given peer.
1410
1457
fn handle_closing_signed ( & self , their_node_id : & PublicKey , msg : & ClosingSigned ) ;
1411
1458
1459
+ // Splicing
1460
+ /// Handle an incoming `splice` message from the given peer.
1461
+ fn handle_splice ( & self , their_node_id : & PublicKey , msg : & Splice ) ;
1462
+ /// Handle an incoming `splice_ack` message from the given peer.
1463
+ fn handle_splice_ack ( & self , their_node_id : & PublicKey , msg : & SpliceAck ) ;
1464
+ /// Handle an incoming `splice_locked` message from the given peer.
1465
+ fn handle_splice_locked ( & self , their_node_id : & PublicKey , msg : & SpliceLocked ) ;
1466
+
1412
1467
// Interactive channel construction
1413
1468
/// Handle an incoming `tx_add_input message` from the given peer.
1414
1469
fn handle_tx_add_input ( & self , their_node_id : & PublicKey , msg : & TxAddInput ) ;
@@ -1813,6 +1868,26 @@ impl_writeable_msg!(AcceptChannelV2, {
1813
1868
( 2 , require_confirmed_inputs, option) ,
1814
1869
} ) ;
1815
1870
1871
+ impl_writeable_msg ! ( Splice , {
1872
+ channel_id,
1873
+ chain_hash,
1874
+ relative_satoshis,
1875
+ funding_feerate_perkw,
1876
+ locktime,
1877
+ funding_pubkey,
1878
+ } , { } ) ;
1879
+
1880
+ impl_writeable_msg ! ( SpliceAck , {
1881
+ channel_id,
1882
+ chain_hash,
1883
+ relative_satoshis,
1884
+ funding_pubkey,
1885
+ } , { } ) ;
1886
+
1887
+ impl_writeable_msg ! ( SpliceLocked , {
1888
+ channel_id,
1889
+ } , { } ) ;
1890
+
1816
1891
impl_writeable_msg ! ( TxAddInput , {
1817
1892
channel_id,
1818
1893
serial_id,
@@ -3365,6 +3440,45 @@ mod tests {
3365
3440
assert_eq ! ( encoded_value, target_value) ;
3366
3441
}
3367
3442
3443
+ #[ test]
3444
+ fn encoding_splice ( ) {
3445
+ let secp_ctx = Secp256k1 :: new ( ) ;
3446
+ let ( _, pubkey_1, ) = get_keys_from ! ( "0101010101010101010101010101010101010101010101010101010101010101" , secp_ctx) ;
3447
+ let splice = msgs:: Splice {
3448
+ chain_hash : ChainHash :: from_hex ( "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000" ) . unwrap ( ) ,
3449
+ channel_id : ChannelId :: from_bytes ( [ 2 ; 32 ] ) ,
3450
+ relative_satoshis : 123456 ,
3451
+ funding_feerate_perkw : 2000 ,
3452
+ locktime : 0 ,
3453
+ funding_pubkey : pubkey_1,
3454
+ } ;
3455
+ let encoded_value = splice. encode ( ) ;
3456
+ assert_eq ! ( hex:: encode( encoded_value) , "02020202020202020202020202020202020202020202020202020202020202026fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000000000000001e240000007d000000000031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" ) ;
3457
+ }
3458
+
3459
+ #[ test]
3460
+ fn encoding_splice_ack ( ) {
3461
+ let secp_ctx = Secp256k1 :: new ( ) ;
3462
+ let ( _, pubkey_1, ) = get_keys_from ! ( "0101010101010101010101010101010101010101010101010101010101010101" , secp_ctx) ;
3463
+ let splice = msgs:: SpliceAck {
3464
+ chain_hash : ChainHash :: from_hex ( "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000" ) . unwrap ( ) ,
3465
+ channel_id : ChannelId :: from_bytes ( [ 2 ; 32 ] ) ,
3466
+ relative_satoshis : 123456 ,
3467
+ funding_pubkey : pubkey_1,
3468
+ } ;
3469
+ let encoded_value = splice. encode ( ) ;
3470
+ assert_eq ! ( hex:: encode( encoded_value) , "02020202020202020202020202020202020202020202020202020202020202026fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000000000000001e240031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" ) ;
3471
+ }
3472
+
3473
+ #[ test]
3474
+ fn encoding_splice_locked ( ) {
3475
+ let splice = msgs:: SpliceLocked {
3476
+ channel_id : ChannelId :: from_bytes ( [ 2 ; 32 ] ) ,
3477
+ } ;
3478
+ let encoded_value = splice. encode ( ) ;
3479
+ assert_eq ! ( hex:: encode( encoded_value) , "0202020202020202020202020202020202020202020202020202020202020202" ) ;
3480
+ }
3481
+
3368
3482
#[ test]
3369
3483
fn encoding_tx_add_input ( ) {
3370
3484
let tx_add_input = msgs:: TxAddInput {
0 commit comments