88// licenses.
99
1010use crate :: io_extras:: sink;
11- use crate :: prelude:: * ;
11+ use crate :: { io , prelude:: * } ;
1212
1313use bitcoin:: absolute:: LockTime as AbsoluteLockTime ;
1414use bitcoin:: amount:: Amount ;
1515use bitcoin:: consensus:: Encodable ;
1616use bitcoin:: constants:: WITNESS_SCALE_FACTOR ;
17+ use bitcoin:: hashes:: Hash ;
1718use bitcoin:: policy:: MAX_STANDARD_TX_WEIGHT ;
1819use bitcoin:: secp256k1:: PublicKey ;
1920use bitcoin:: transaction:: Version ;
@@ -26,11 +27,13 @@ use crate::ln::msgs;
2627use crate :: ln:: msgs:: { MessageSendEvent , SerialId , TxSignatures } ;
2728use crate :: ln:: types:: ChannelId ;
2829use crate :: sign:: { EntropySource , P2TR_KEY_PATH_WITNESS_WEIGHT , P2WPKH_WITNESS_WEIGHT } ;
29- use crate :: util:: ser:: TransactionU16LenLimited ;
30+ use crate :: util:: ser:: { Readable , TransactionU16LenLimited , Writeable , Writer } ;
3031
3132use core:: fmt:: Display ;
3233use core:: ops:: Deref ;
3334
35+ use super :: msgs:: DecodeError ;
36+
3437/// The number of received `tx_add_input` messages during a negotiation at which point the
3538/// negotiation MUST be failed.
3639const MAX_RECEIVED_TX_ADD_INPUT_COUNT : u16 = 4096 ;
@@ -168,6 +171,61 @@ pub(crate) struct ConstructedTransaction {
168171 holder_sends_tx_signatures_first : bool ,
169172}
170173
174+ impl Writeable for ConstructedTransaction {
175+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
176+ let lock_time = self . lock_time . to_consensus_u32 ( ) ;
177+ write_tlv_fields ! ( writer, {
178+ ( 1 , self . holder_is_initiator, required) ,
179+ ( 3 , self . inputs, required) ,
180+ ( 5 , self . outputs, required) ,
181+ ( 7 , self . local_inputs_value_satoshis, required) ,
182+ ( 9 , self . local_outputs_value_satoshis, required) ,
183+ ( 11 , self . remote_inputs_value_satoshis, required) ,
184+ ( 13 , self . remote_outputs_value_satoshis, required) ,
185+ ( 15 , lock_time, required) ,
186+ ( 17 , self . holder_sends_tx_signatures_first, required) ,
187+ } ) ;
188+ Ok ( ( ) )
189+ }
190+ }
191+
192+ impl Readable for ConstructedTransaction {
193+ fn read < R : io:: Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
194+ let mut holder_is_initiator = false ;
195+ let mut inputs: Vec < InteractiveTxInput > = vec ! [ ] ;
196+ let mut outputs: Vec < InteractiveTxOutput > = vec ! [ ] ;
197+ let mut local_inputs_value_satoshis: u64 = 0 ;
198+ let mut local_outputs_value_satoshis: u64 = 0 ;
199+ let mut remote_inputs_value_satoshis: u64 = 0 ;
200+ let mut remote_outputs_value_satoshis: u64 = 0 ;
201+ let mut lock_time: u32 = 0 ;
202+ let mut holder_sends_tx_signatures_first = false ;
203+ read_tlv_fields ! ( reader, {
204+ ( 1 , holder_is_initiator, required) ,
205+ ( 3 , inputs, required) ,
206+ ( 5 , outputs, required) ,
207+ ( 7 , local_inputs_value_satoshis, required) ,
208+ ( 9 , local_outputs_value_satoshis, required) ,
209+ ( 11 , remote_inputs_value_satoshis, required) ,
210+ ( 13 , remote_outputs_value_satoshis, required) ,
211+ ( 15 , lock_time, required) ,
212+ ( 17 , holder_sends_tx_signatures_first, required) ,
213+ } ) ;
214+ let lock_time = AbsoluteLockTime :: from_consensus ( lock_time) ;
215+ Ok ( ConstructedTransaction {
216+ holder_is_initiator,
217+ inputs,
218+ outputs,
219+ local_inputs_value_satoshis,
220+ local_outputs_value_satoshis,
221+ remote_inputs_value_satoshis,
222+ remote_outputs_value_satoshis,
223+ lock_time,
224+ holder_sends_tx_signatures_first,
225+ } )
226+ }
227+ }
228+
171229impl ConstructedTransaction {
172230 fn new ( context : NegotiationContext ) -> Self {
173231 let local_inputs_value_satoshis = context
@@ -418,6 +476,13 @@ impl InteractiveTxSigningSession {
418476 }
419477}
420478
479+ impl_writeable_tlv_based ! ( InteractiveTxSigningSession , {
480+ ( 1 , unsigned_tx, required) ,
481+ ( 3 , holder_sends_tx_signatures_first, required) ,
482+ ( 5 , has_received_commitment_signed, required) ,
483+ ( 7 , holder_tx_signatures, required) ,
484+ } ) ;
485+
421486#[ derive( Debug ) ]
422487struct NegotiationContext {
423488 holder_node_id : PublicKey ,
@@ -1141,6 +1206,11 @@ enum AddingRole {
11411206 Remote ,
11421207}
11431208
1209+ impl_writeable_tlv_based_enum ! ( AddingRole ,
1210+ ( 1 , Local ) => { } ,
1211+ ( 3 , Remote ) => { } ,
1212+ ) ;
1213+
11441214/// Represents an input -- local or remote (both have the same fields)
11451215#[ derive( Clone , Debug , Eq , PartialEq ) ]
11461216pub struct LocalOrRemoteInput {
@@ -1149,19 +1219,68 @@ pub struct LocalOrRemoteInput {
11491219 prev_output : TxOut ,
11501220}
11511221
1222+ impl Writeable for LocalOrRemoteInput {
1223+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
1224+ write_tlv_fields ! ( writer, {
1225+ ( 1 , self . serial_id, required) ,
1226+ ( 3 , self . input. sequence. 0 , required) ,
1227+ ( 5 , self . input. previous_output, required) ,
1228+ ( 7 , self . input. script_sig, required) ,
1229+ ( 9 , self . input. witness, required) ,
1230+ ( 11 , self . prev_output, required) ,
1231+ } ) ;
1232+ Ok ( ( ) )
1233+ }
1234+ }
1235+
1236+ impl Readable for LocalOrRemoteInput {
1237+ fn read < R : io:: Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
1238+ let mut serial_id: u64 = 0 ;
1239+ let mut sequence: u32 = 0 ;
1240+ let mut previous_output = OutPoint :: new ( Txid :: from_byte_array ( [ 0 ; 32 ] ) , 0 ) ;
1241+ let mut script_sig = ScriptBuf :: default ( ) ;
1242+ let mut witness = Witness :: new ( ) ;
1243+ let mut prev_output =
1244+ TxOut { value : Amount :: default ( ) , script_pubkey : ScriptBuf :: default ( ) } ;
1245+ read_tlv_fields ! ( reader, {
1246+ ( 1 , serial_id, required) ,
1247+ ( 3 , sequence, required) ,
1248+ ( 5 , previous_output, required) ,
1249+ ( 7 , script_sig, required) ,
1250+ ( 9 , witness, required) ,
1251+ ( 11 , prev_output, required) ,
1252+ } ) ;
1253+ Ok ( LocalOrRemoteInput {
1254+ serial_id,
1255+ input : TxIn { previous_output, script_sig, sequence : Sequence ( sequence) , witness } ,
1256+ prev_output,
1257+ } )
1258+ }
1259+ }
1260+
11521261#[ derive( Clone , Debug , Eq , PartialEq ) ]
11531262pub ( crate ) enum InteractiveTxInput {
11541263 Local ( LocalOrRemoteInput ) ,
11551264 Remote ( LocalOrRemoteInput ) ,
11561265 // TODO(splicing) SharedInput should be added
11571266}
11581267
1268+ impl_writeable_tlv_based_enum ! ( InteractiveTxInput ,
1269+ { 1 , Local } => ( ) ,
1270+ { 3 , Remote } => ( ) ,
1271+ ) ;
1272+
11591273#[ derive( Clone , Debug , Eq , PartialEq ) ]
11601274pub struct SharedOwnedOutput {
11611275 tx_out : TxOut ,
11621276 local_owned : u64 ,
11631277}
11641278
1279+ impl_writeable_tlv_based ! ( SharedOwnedOutput , {
1280+ ( 1 , tx_out, required) ,
1281+ ( 3 , local_owned, required) ,
1282+ } ) ;
1283+
11651284impl SharedOwnedOutput {
11661285 fn new ( tx_out : TxOut , local_owned : u64 ) -> SharedOwnedOutput {
11671286 debug_assert ! (
@@ -1191,6 +1310,12 @@ pub enum OutputOwned {
11911310 Shared ( SharedOwnedOutput ) ,
11921311}
11931312
1313+ impl_writeable_tlv_based_enum ! ( OutputOwned ,
1314+ { 1 , Single } => ( ) ,
1315+ { 3 , SharedControlFullyOwned } => ( ) ,
1316+ { 5 , Shared } => ( ) ,
1317+ ) ;
1318+
11941319impl OutputOwned {
11951320 fn tx_out ( & self ) -> & TxOut {
11961321 match self {
@@ -1250,6 +1375,12 @@ pub(crate) struct InteractiveTxOutput {
12501375 output : OutputOwned ,
12511376}
12521377
1378+ impl_writeable_tlv_based ! ( InteractiveTxOutput , {
1379+ ( 1 , serial_id, required) ,
1380+ ( 3 , added_by, required) ,
1381+ ( 5 , output, required) ,
1382+ } ) ;
1383+
12531384impl InteractiveTxOutput {
12541385 pub fn tx_out ( & self ) -> & TxOut {
12551386 self . output . tx_out ( )
0 commit comments