@@ -286,73 +286,81 @@ struct CMutableTransaction;
286
286
* - CTxWitness wit;
287
287
* - uint32_t nLockTime
288
288
*/
289
- template <typename Stream, typename Operation, typename TxType>
290
- inline void SerializeTransaction (TxType& tx, Stream& s, Operation ser_action ) {
289
+ template <typename Stream, typename TxType>
290
+ inline void UnserializeTransaction (TxType& tx, Stream& s) {
291
291
const bool fAllowWitness = !(s.GetVersion () & SERIALIZE_TRANSACTION_NO_WITNESS);
292
292
293
- READWRITE (* const_cast < int32_t *>(& tx.nVersion )) ;
293
+ s >> tx.nVersion ;
294
294
unsigned char flags = 0 ;
295
- if (ser_action.ForRead ()) {
296
- const_cast <std::vector<CTxIn>*>(&tx.vin )->clear ();
297
- const_cast <std::vector<CTxOut>*>(&tx.vout )->clear ();
298
- const_cast <CTxWitness*>(&tx.wit )->SetNull ();
299
- /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
300
- READWRITE (*const_cast <std::vector<CTxIn>*>(&tx.vin ));
301
- if (tx.vin .size () == 0 && fAllowWitness ) {
302
- /* We read a dummy or an empty vin. */
303
- READWRITE (flags);
304
- if (flags != 0 ) {
305
- READWRITE (*const_cast <std::vector<CTxIn>*>(&tx.vin ));
306
- READWRITE (*const_cast <std::vector<CTxOut>*>(&tx.vout ));
307
- }
308
- } else {
309
- /* We read a non-empty vin. Assume a normal vout follows. */
310
- READWRITE (*const_cast <std::vector<CTxOut>*>(&tx.vout ));
311
- }
312
- if ((flags & 1 ) && fAllowWitness ) {
313
- /* The witness flag is present, and we support witnesses. */
314
- flags ^= 1 ;
315
- const_cast <CTxWitness*>(&tx.wit )->vtxinwit .resize (tx.vin .size ());
316
- READWRITE (tx.wit );
317
- }
318
- if (flags) {
319
- /* Unknown flag in the serialization */
320
- throw std::ios_base::failure (" Unknown transaction optional data" );
295
+ tx.vin .clear ();
296
+ tx.vout .clear ();
297
+ tx.wit .SetNull ();
298
+ /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
299
+ s >> tx.vin ;
300
+ if (tx.vin .size () == 0 && fAllowWitness ) {
301
+ /* We read a dummy or an empty vin. */
302
+ s >> flags;
303
+ if (flags != 0 ) {
304
+ s >> tx.vin ;
305
+ s >> tx.vout ;
321
306
}
322
307
} else {
323
- // Consistency check
324
- assert (tx.wit .vtxinwit .size () <= tx.vin .size ());
325
- if (fAllowWitness ) {
326
- /* Check whether witnesses need to be serialized. */
327
- if (!tx.wit .IsNull ()) {
328
- flags |= 1 ;
329
- }
330
- }
331
- if (flags) {
332
- /* Use extended format in case witnesses are to be serialized. */
333
- std::vector<CTxIn> vinDummy;
334
- READWRITE (vinDummy);
335
- READWRITE (flags);
308
+ /* We read a non-empty vin. Assume a normal vout follows. */
309
+ s >> tx.vout ;
310
+ }
311
+ if ((flags & 1 ) && fAllowWitness ) {
312
+ /* The witness flag is present, and we support witnesses. */
313
+ flags ^= 1 ;
314
+ tx.wit .vtxinwit .resize (tx.vin .size ());
315
+ s >> tx.wit ;
316
+ }
317
+ if (flags) {
318
+ /* Unknown flag in the serialization */
319
+ throw std::ios_base::failure (" Unknown transaction optional data" );
320
+ }
321
+ s >> tx.nLockTime ;
322
+ }
323
+
324
+ template <typename Stream, typename TxType>
325
+ inline void SerializeTransaction (const TxType& tx, Stream& s) {
326
+ const bool fAllowWitness = !(s.GetVersion () & SERIALIZE_TRANSACTION_NO_WITNESS);
327
+
328
+ s << tx.nVersion ;
329
+ unsigned char flags = 0 ;
330
+ // Consistency check
331
+ assert (tx.wit .vtxinwit .size () <= tx.vin .size ());
332
+ if (fAllowWitness ) {
333
+ /* Check whether witnesses need to be serialized. */
334
+ if (!tx.wit .IsNull ()) {
335
+ flags |= 1 ;
336
336
}
337
- READWRITE (*const_cast <std::vector<CTxIn>*>(&tx.vin ));
338
- READWRITE (*const_cast <std::vector<CTxOut>*>(&tx.vout ));
339
- if (flags & 1 ) {
340
- const_cast <CTxWitness*>(&tx.wit )->vtxinwit .resize (tx.vin .size ());
341
- READWRITE (tx.wit );
337
+ }
338
+ if (flags) {
339
+ /* Use extended format in case witnesses are to be serialized. */
340
+ std::vector<CTxIn> vinDummy;
341
+ s << vinDummy;
342
+ s << flags;
343
+ }
344
+ s << tx.vin ;
345
+ s << tx.vout ;
346
+ if (flags & 1 ) {
347
+ for (size_t i = 0 ; i < tx.vin .size (); i++) {
348
+ if (i < tx.wit .vtxinwit .size ()) {
349
+ s << tx.wit .vtxinwit [i];
350
+ } else {
351
+ s << CTxInWitness ();
352
+ }
342
353
}
343
354
}
344
- READWRITE (* const_cast < uint32_t *>(& tx.nLockTime )) ;
355
+ s << tx.nLockTime ;
345
356
}
346
357
358
+
347
359
/* * The basic transaction that is broadcasted on the network and contained in
348
360
* blocks. A transaction can contain multiple inputs and outputs.
349
361
*/
350
362
class CTransaction
351
363
{
352
- private:
353
- /* * Memory only. */
354
- const uint256 hash;
355
-
356
364
public:
357
365
// Default transaction version.
358
366
static const int32_t CURRENT_VERSION=1 ;
@@ -374,25 +382,27 @@ class CTransaction
374
382
CTxWitness wit; // Not const: can change without invalidating the txid cache
375
383
const uint32_t nLockTime;
376
384
385
+ private:
386
+ /* * Memory only. */
387
+ const uint256 hash;
388
+
389
+ uint256 ComputeHash () const ;
390
+
391
+ public:
377
392
/* * Construct a CTransaction that qualifies as IsNull() */
378
393
CTransaction ();
379
394
380
395
/* * Convert a CMutableTransaction into a CTransaction. */
381
396
CTransaction (const CMutableTransaction &tx);
382
397
CTransaction (CMutableTransaction &&tx);
383
398
384
- CTransaction& operator =(const CTransaction& tx);
385
-
386
- ADD_SERIALIZE_METHODS;
387
-
388
- template <typename Stream, typename Operation>
389
- inline void SerializationOp (Stream& s, Operation ser_action) {
390
- SerializeTransaction (*this , s, ser_action);
391
- if (ser_action.ForRead ()) {
392
- UpdateHash ();
393
- }
399
+ template <typename Stream>
400
+ inline void Serialize (Stream& s) const {
401
+ SerializeTransaction (*this , s);
394
402
}
395
403
404
+ /* * This deserializing constructor is provided instead of an Unserialize method.
405
+ * Unserialize is not possible, since it would require overwriting const fields. */
396
406
template <typename Stream>
397
407
CTransaction (deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}
398
408
@@ -417,7 +427,7 @@ class CTransaction
417
427
418
428
// Compute modified tx size for priority calculation (optionally given tx size)
419
429
unsigned int CalculateModifiedSize (unsigned int nTxSize=0 ) const ;
420
-
430
+
421
431
/* *
422
432
* Get the total transaction size in bytes, including witness data.
423
433
* "Total Size" defined in BIP141 and BIP144.
@@ -441,8 +451,6 @@ class CTransaction
441
451
}
442
452
443
453
std::string ToString () const ;
444
-
445
- void UpdateHash () const ;
446
454
};
447
455
448
456
/* * A mutable version of CTransaction. */
@@ -457,11 +465,15 @@ struct CMutableTransaction
457
465
CMutableTransaction ();
458
466
CMutableTransaction (const CTransaction& tx);
459
467
460
- ADD_SERIALIZE_METHODS;
468
+ template <typename Stream>
469
+ inline void Serialize (Stream& s) const {
470
+ SerializeTransaction (*this , s);
471
+ }
461
472
462
- template <typename Stream, typename Operation>
463
- inline void SerializationOp (Stream& s, Operation ser_action) {
464
- SerializeTransaction (*this , s, ser_action);
473
+
474
+ template <typename Stream>
475
+ inline void Unserialize (Stream& s) {
476
+ UnserializeTransaction (*this , s);
465
477
}
466
478
467
479
template <typename Stream>
0 commit comments