@@ -429,6 +429,53 @@ pub struct ChannelReady {
429429 pub short_channel_id_alias : Option < u64 > ,
430430}
431431
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+
432479/// A tx_add_input message for adding an input during interactive transaction construction
433480///
434481// TODO(dual_funding): Add spec link for `tx_add_input`.
@@ -1229,12 +1276,20 @@ pub trait ChannelMessageHandler : MessageSendEventsProvider {
12291276 /// Handle an incoming `channel_ready` message from the given peer.
12301277 fn handle_channel_ready ( & self , their_node_id : & PublicKey , msg : & ChannelReady ) ;
12311278
1232- // Channl close:
1279+ // Channel close:
12331280 /// Handle an incoming `shutdown` message from the given peer.
12341281 fn handle_shutdown ( & self , their_node_id : & PublicKey , msg : & Shutdown ) ;
12351282 /// Handle an incoming `closing_signed` message from the given peer.
12361283 fn handle_closing_signed ( & self , their_node_id : & PublicKey , msg : & ClosingSigned ) ;
12371284
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+
12381293 // Interactive channel construction
12391294 /// Handle an incoming `tx_add_input message` from the given peer.
12401295 fn handle_tx_add_input ( & self , their_node_id : & PublicKey , msg : & TxAddInput ) ;
@@ -1613,6 +1668,26 @@ impl_writeable_msg!(AcceptChannelV2, {
16131668 ( 2 , require_confirmed_inputs, option) ,
16141669} ) ;
16151670
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+
16161691impl_writeable_msg ! ( TxAddInput , {
16171692 channel_id,
16181693 serial_id,
@@ -3115,6 +3190,45 @@ mod tests {
31153190 assert_eq ! ( encoded_value, target_value) ;
31163191 }
31173192
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+
31183232 #[ test]
31193233 fn encoding_tx_add_input ( ) {
31203234 let tx_add_input = msgs:: TxAddInput {
0 commit comments