8
8
// licenses.
9
9
10
10
use crate :: io_extras:: sink;
11
- use crate :: prelude:: * ;
11
+ use crate :: { io , prelude:: * } ;
12
12
13
13
use bitcoin:: absolute:: LockTime as AbsoluteLockTime ;
14
14
use bitcoin:: amount:: Amount ;
15
15
use bitcoin:: consensus:: Encodable ;
16
16
use bitcoin:: constants:: WITNESS_SCALE_FACTOR ;
17
+ use bitcoin:: hashes:: Hash ;
17
18
use bitcoin:: policy:: MAX_STANDARD_TX_WEIGHT ;
18
19
use bitcoin:: secp256k1:: PublicKey ;
19
20
use bitcoin:: transaction:: Version ;
@@ -26,11 +27,13 @@ use crate::ln::msgs;
26
27
use crate :: ln:: msgs:: { MessageSendEvent , SerialId , TxSignatures } ;
27
28
use crate :: ln:: types:: ChannelId ;
28
29
use 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 } ;
30
31
31
32
use core:: fmt:: Display ;
32
33
use core:: ops:: Deref ;
33
34
35
+ use super :: msgs:: DecodeError ;
36
+
34
37
/// The number of received `tx_add_input` messages during a negotiation at which point the
35
38
/// negotiation MUST be failed.
36
39
const MAX_RECEIVED_TX_ADD_INPUT_COUNT : u16 = 4096 ;
@@ -168,6 +171,61 @@ pub(crate) struct ConstructedTransaction {
168
171
holder_sends_tx_signatures_first : bool ,
169
172
}
170
173
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
+
171
229
impl ConstructedTransaction {
172
230
fn new ( context : NegotiationContext ) -> Self {
173
231
let local_inputs_value_satoshis = context
@@ -418,6 +476,13 @@ impl InteractiveTxSigningSession {
418
476
}
419
477
}
420
478
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
+
421
486
#[ derive( Debug ) ]
422
487
struct NegotiationContext {
423
488
holder_node_id : PublicKey ,
@@ -1141,6 +1206,11 @@ enum AddingRole {
1141
1206
Remote ,
1142
1207
}
1143
1208
1209
+ impl_writeable_tlv_based_enum ! ( AddingRole ,
1210
+ ( 1 , Local ) => { } ,
1211
+ ( 3 , Remote ) => { } ,
1212
+ ) ;
1213
+
1144
1214
/// Represents an input -- local or remote (both have the same fields)
1145
1215
#[ derive( Clone , Debug , Eq , PartialEq ) ]
1146
1216
pub struct LocalOrRemoteInput {
@@ -1149,19 +1219,68 @@ pub struct LocalOrRemoteInput {
1149
1219
prev_output : TxOut ,
1150
1220
}
1151
1221
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
+
1152
1261
#[ derive( Clone , Debug , Eq , PartialEq ) ]
1153
1262
pub ( crate ) enum InteractiveTxInput {
1154
1263
Local ( LocalOrRemoteInput ) ,
1155
1264
Remote ( LocalOrRemoteInput ) ,
1156
1265
// TODO(splicing) SharedInput should be added
1157
1266
}
1158
1267
1268
+ impl_writeable_tlv_based_enum ! ( InteractiveTxInput ,
1269
+ { 1 , Local } => ( ) ,
1270
+ { 3 , Remote } => ( ) ,
1271
+ ) ;
1272
+
1159
1273
#[ derive( Clone , Debug , Eq , PartialEq ) ]
1160
1274
pub struct SharedOwnedOutput {
1161
1275
tx_out : TxOut ,
1162
1276
local_owned : u64 ,
1163
1277
}
1164
1278
1279
+ impl_writeable_tlv_based ! ( SharedOwnedOutput , {
1280
+ ( 1 , tx_out, required) ,
1281
+ ( 3 , local_owned, required) ,
1282
+ } ) ;
1283
+
1165
1284
impl SharedOwnedOutput {
1166
1285
fn new ( tx_out : TxOut , local_owned : u64 ) -> SharedOwnedOutput {
1167
1286
debug_assert ! (
@@ -1191,6 +1310,12 @@ pub enum OutputOwned {
1191
1310
Shared ( SharedOwnedOutput ) ,
1192
1311
}
1193
1312
1313
+ impl_writeable_tlv_based_enum ! ( OutputOwned ,
1314
+ { 1 , Single } => ( ) ,
1315
+ { 3 , SharedControlFullyOwned } => ( ) ,
1316
+ { 5 , Shared } => ( ) ,
1317
+ ) ;
1318
+
1194
1319
impl OutputOwned {
1195
1320
fn tx_out ( & self ) -> & TxOut {
1196
1321
match self {
@@ -1250,6 +1375,12 @@ pub(crate) struct InteractiveTxOutput {
1250
1375
output : OutputOwned ,
1251
1376
}
1252
1377
1378
+ impl_writeable_tlv_based ! ( InteractiveTxOutput , {
1379
+ ( 1 , serial_id, required) ,
1380
+ ( 3 , added_by, required) ,
1381
+ ( 5 , output, required) ,
1382
+ } ) ;
1383
+
1253
1384
impl InteractiveTxOutput {
1254
1385
pub fn tx_out ( & self ) -> & TxOut {
1255
1386
self . output . tx_out ( )
0 commit comments