@@ -166,6 +166,193 @@ macro_rules! try_consume_checkpoint {
166
166
} } ;
167
167
}
168
168
169
+ #[ macro_export]
170
+ macro_rules! try_consume_sign_options {
171
+ ( $data_iter: expr) => { {
172
+ let mut sign_options = SignOptions :: default ( ) ;
173
+
174
+ if try_consume_bool!( $data_iter) {
175
+ sign_options. trust_witness_utxo = true ;
176
+ }
177
+
178
+ if try_consume_bool!( $data_iter) {
179
+ let height = try_consume_u32!( $data_iter) ;
180
+ sign_options. assume_height = Some ( height) ;
181
+ }
182
+
183
+ if try_consume_bool!( $data_iter) {
184
+ sign_options. allow_all_sighashes = true ;
185
+ }
186
+
187
+ if try_consume_bool!( $data_iter) {
188
+ sign_options. try_finalize = false ;
189
+ }
190
+
191
+ if try_consume_bool!( $data_iter) {
192
+ // FIXME: how can we use the other include/exclude variants here ?
193
+ if try_consume_bool!( $data_iter) {
194
+ sign_options. tap_leaves_options = TapLeavesOptions :: All ;
195
+ } else {
196
+ sign_options. tap_leaves_options = TapLeavesOptions :: None ;
197
+ }
198
+ }
199
+
200
+ if try_consume_bool!( $data_iter) {
201
+ sign_options. sign_with_tap_internal_key = false ;
202
+ }
203
+
204
+ if try_consume_bool!( $data_iter) {
205
+ sign_options. allow_grinding = false ;
206
+ }
207
+
208
+ sign_options
209
+ } } ;
210
+ }
211
+
212
+ #[ macro_export]
213
+ macro_rules! try_consume_tx_builder {
214
+ ( $data: expr, $wallet: expr) => { {
215
+ let mut data_iter = $data. into_iter( ) ;
216
+
217
+ let utxo = $wallet. list_unspent( ) . next( ) ;
218
+
219
+ let recipients_count = * try_consume_byte!( data_iter) as usize ;
220
+ let mut recipients = Vec :: with_capacity( recipients_count) ;
221
+ for _ in 0 ..recipients_count {
222
+ let spk = consume_spk( $data, $wallet) ;
223
+ let amount = * try_consume_byte!( data_iter) as u64 * 1_000 ;
224
+ let amount = bitcoin:: Amount :: from_sat( amount) ;
225
+ recipients. push( ( spk, amount) ) ;
226
+ }
227
+
228
+ let drain_to = consume_spk( $data, $wallet) ;
229
+
230
+ let mut tx_builder = match try_consume_bool!( data_iter) {
231
+ true => $wallet. build_tx( ) ,
232
+ false => {
233
+ // FIXME: (@leonardo) get a randomized txid.
234
+ let txid = $wallet
235
+ . tx_graph( )
236
+ . full_txs( )
237
+ . next( )
238
+ . map( |tx_node| tx_node. txid) ;
239
+ match txid {
240
+ Some ( txid) => match $wallet. build_fee_bump( txid) {
241
+ Ok ( builder) => builder,
242
+ Err ( _) => continue ,
243
+ } ,
244
+ None => continue ,
245
+ }
246
+ }
247
+ } ;
248
+
249
+ if try_consume_bool!( data_iter) {
250
+ let mut rate = * try_consume_byte!( data_iter) as u64 ;
251
+ if try_consume_bool!( data_iter) {
252
+ rate *= 1_000 ;
253
+ }
254
+ let rate =
255
+ bitcoin:: FeeRate :: from_sat_per_vb( rate) . expect( "It should be a valid fee rate." ) ;
256
+ tx_builder. fee_rate( rate) ;
257
+ }
258
+
259
+ if try_consume_bool!( data_iter) {
260
+ let mut fee = * try_consume_byte!( data_iter) as u64 ;
261
+ if try_consume_bool!( data_iter) {
262
+ fee *= 1_000 ;
263
+ }
264
+ let fee = bitcoin:: Amount :: from_sat( fee) ;
265
+ tx_builder. fee_absolute( fee) ;
266
+ }
267
+
268
+ if try_consume_bool!( data_iter) {
269
+ if let Some ( ref utxo) = utxo {
270
+ tx_builder
271
+ . add_utxo( utxo. outpoint)
272
+ . expect( "It should be a known UTXO." ) ;
273
+ }
274
+ }
275
+
276
+ // FIXME: add the fuzzed option for `TxBuilder.add_foreign_utxo`.
277
+
278
+ if try_consume_bool!( data_iter) {
279
+ tx_builder. manually_selected_only( ) ;
280
+ }
281
+
282
+ if try_consume_bool!( data_iter) {
283
+ if let Some ( ref utxo) = utxo {
284
+ tx_builder. add_unspendable( utxo. outpoint) ;
285
+ }
286
+ }
287
+
288
+ if try_consume_bool!( data_iter) {
289
+ let sighash =
290
+ bitcoin:: psbt:: PsbtSighashType :: from_u32( * try_consume_byte!( data_iter) as u32 ) ;
291
+ tx_builder. sighash( sighash) ;
292
+ }
293
+
294
+ if try_consume_bool!( data_iter) {
295
+ let ordering = if try_consume_bool!( data_iter) {
296
+ TxOrdering :: Shuffle
297
+ } else {
298
+ TxOrdering :: Untouched
299
+ } ;
300
+ tx_builder. ordering( ordering) ;
301
+ }
302
+
303
+ if try_consume_bool!( data_iter) {
304
+ let lock_time = try_consume_u32!( data_iter) ;
305
+ let lock_time = bitcoin:: absolute:: LockTime :: from_consensus( lock_time) ;
306
+ tx_builder. nlocktime( lock_time) ;
307
+ }
308
+
309
+ if try_consume_bool!( data_iter) {
310
+ let version = try_consume_u32!( data_iter) ;
311
+ tx_builder. version( version as i32 ) ;
312
+ }
313
+
314
+ if try_consume_bool!( data_iter) {
315
+ tx_builder. do_not_spend_change( ) ;
316
+ }
317
+
318
+ if try_consume_bool!( data_iter) {
319
+ tx_builder. only_spend_change( ) ;
320
+ }
321
+
322
+ if try_consume_bool!( data_iter) {
323
+ tx_builder. only_witness_utxo( ) ;
324
+ }
325
+
326
+ if try_consume_bool!( data_iter) {
327
+ tx_builder. include_output_redeem_witness_script( ) ;
328
+ }
329
+
330
+ if try_consume_bool!( data_iter) {
331
+ tx_builder. add_global_xpubs( ) ;
332
+ }
333
+
334
+ if try_consume_bool!( data_iter) {
335
+ tx_builder. drain_wallet( ) ;
336
+ }
337
+
338
+ if try_consume_bool!( data_iter) {
339
+ tx_builder. allow_dust( true ) ;
340
+ }
341
+
342
+ if try_consume_bool!( data_iter) {
343
+ tx_builder. set_recipients( recipients) ;
344
+ }
345
+
346
+ // FIXME: add the fuzzed option for `TxBuilder.add_data()` method.
347
+
348
+ if try_consume_bool!( data_iter) {
349
+ tx_builder. drain_to( drain_to) ;
350
+ }
351
+
352
+ tx_builder
353
+ } } ;
354
+ }
355
+
169
356
pub fn consume_txid ( data : & mut & [ u8 ] ) -> Txid {
170
357
let bytes: [ u8 ; 32 ] = consume_bytes ( data, 32 ) . try_into ( ) . unwrap_or ( [ 0 ; 32 ] ) ;
171
358
0 commit comments