@@ -441,6 +441,53 @@ pub struct ChannelReady {
441441 pub short_channel_id_alias : Option < u64 > ,
442442}
443443
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+
444491/// A tx_add_input message for adding an input during interactive transaction construction
445492///
446493// TODO(dual_funding): Add spec link for `tx_add_input`.
@@ -1409,6 +1456,14 @@ pub trait ChannelMessageHandler : MessageSendEventsProvider {
14091456 /// Handle an incoming `closing_signed` message from the given peer.
14101457 fn handle_closing_signed ( & self , their_node_id : & PublicKey , msg : & ClosingSigned ) ;
14111458
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+
14121467 // Interactive channel construction
14131468 /// Handle an incoming `tx_add_input message` from the given peer.
14141469 fn handle_tx_add_input ( & self , their_node_id : & PublicKey , msg : & TxAddInput ) ;
@@ -1813,6 +1868,26 @@ impl_writeable_msg!(AcceptChannelV2, {
18131868 ( 2 , require_confirmed_inputs, option) ,
18141869} ) ;
18151870
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+
18161891impl_writeable_msg ! ( TxAddInput , {
18171892 channel_id,
18181893 serial_id,
@@ -3365,6 +3440,45 @@ mod tests {
33653440 assert_eq ! ( encoded_value, target_value) ;
33663441 }
33673442
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+
33683482 #[ test]
33693483 fn encoding_tx_add_input ( ) {
33703484 let tx_add_input = msgs:: TxAddInput {
0 commit comments