<NME> transaction.h
<BEF> // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_PRIMITIVES_TRANSACTION_H
#define BITCOIN_PRIMITIVES_TRANSACTION_H

#include "amount.h"
#include "script/script.h"
#include "serialize.h"
#include "uint256.h"

#include <exception>

static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000;

static const int WITNESS_SCALE_FACTOR = 4;

class CBadTxIn : public std::exception
{
};

class CBadSequence : public CBadTxIn
{
};

/** Transaction types */
enum {
    TRANSACTION_NORMAL = 0,
    TRANSACTION_PROVIDER_REGISTER = 1,
    TRANSACTION_PROVIDER_UPDATE_SERVICE = 2,
    TRANSACTION_PROVIDER_UPDATE_REGISTRAR = 3,
    TRANSACTION_PROVIDER_UPDATE_REVOKE = 4,
    TRANSACTION_COINBASE = 5,
    TRANSACTION_QUORUM_COMMITMENT = 6,
    TRANSACTION_SPORK = 7,
    TRANSACTION_LELANTUS = 8
};

/** An outpoint - a combination of a transaction hash and an index n into its vout */
class COutPoint
{
public:
    uint256 hash;
    uint32_t n;

    COutPoint() { SetNull(); }
    COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; }

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        READWRITE(hash);
        READWRITE(n);
    }

    void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
    bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -1); }

    bool IsSigmaMintGroup() const { return hash.IsNull() && n >= 1; }

    friend bool operator<(const COutPoint& a, const COutPoint& b)
    {
        int cmp = a.hash.Compare(b.hash);
        return cmp < 0 || (cmp == 0 && a.n < b.n);
    }

    friend bool operator==(const COutPoint& a, const COutPoint& b)
    {
        return (a.hash == b.hash && a.n == b.n);
    }

    friend bool operator!=(const COutPoint& a, const COutPoint& b)
    {
        return !(a == b);
    }

    std::string ToString() const;
    std::string ToStringShort() const;
};

/** An input of a transaction.  It contains the location of the previous
 * transaction's output that it claims and a signature that matches the
 * output's public key.
 */
class CTxIn
{
public:
    COutPoint prevout;
    CScript scriptSig;
    uint32_t nSequence;
    CScript prevPubKey;
    CScriptWitness scriptWitness; //! Only serialized through CTransaction

    /* Setting nSequence to this value for every input in a transaction
     * disables nLockTime. */
    static const uint32_t SEQUENCE_FINAL = 0xffffffff;

    /* Below flags apply in the context of BIP 68*/
    /* If this flag set, CTxIn::nSequence is NOT interpreted as a
     * relative lock-time. */
    static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31);

    /* If CTxIn::nSequence encodes a relative lock-time and this flag
     * is set, the relative lock-time has units of 512 seconds,
     * otherwise it specifies blocks with a granularity of 1. */
    static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);

    /* If CTxIn::nSequence encodes a relative lock-time, this mask is
     * applied to extract that lock-time from the sequence field. */
    static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;

    /* In order to use the same number of bits to encode roughly the
     * same wall-clock duration, and because blocks are naturally
     * limited to occur every 600s on average, the minimum granularity
     * for time-based relative lock-time is fixed at 512 seconds.
     * Converting from CTxIn::nSequence to seconds is performed by
     * multiplying by 512 = 2^9, or equivalently shifting up by
     * 9 bits. */
    static const int SEQUENCE_LOCKTIME_GRANULARITY = 9;

    CTxIn()
    {
        nSequence = SEQUENCE_FINAL;
    }

    explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
    CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        READWRITE(prevout);
        READWRITE(*(CScriptBase*)(&scriptSig));
        READWRITE(nSequence);
    }

    friend bool operator==(const CTxIn& a, const CTxIn& b)
    {
        return (a.prevout   == b.prevout &&
                a.scriptSig == b.scriptSig &&
                a.nSequence == b.nSequence);
    }

    friend bool operator!=(const CTxIn& a, const CTxIn& b)
    {
        return !(a == b);
    }

    friend bool operator<(const CTxIn& a, const CTxIn& b)
    {
        return a.prevout<b.prevout;
    }

    std::string ToString() const;
    bool IsZerocoinSpend() const;
    bool IsSigmaSpend() const;
    bool IsLelantusJoinSplit() const;
    bool IsZerocoinRemint() const;
};

/** An output of a transaction.  It contains the public key that the next input
 * must be able to sign with to claim it.
 */
class CTxOut
{
public:
    CAmount nValue;
    CScript scriptPubKey;
    int nRounds;

    CTxOut()
    {
        SetNull();
    }

    CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        READWRITE(nValue);
        READWRITE(*(CScriptBase*)(&scriptPubKey));
        if (ser_action.ForRead())
            nRounds = -10;
    }

    void SetNull()
    {
        nValue = -1;
        scriptPubKey.clear();
        nRounds = -10; // an initial value, should be no way to get this by calculations
    }

    bool IsNull() const
    {
        return (nValue == -1);
    }

    CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const
    {
        // "Dust" is defined in terms of CTransaction::minRelayTxFee,
        // which has units satoshis-per-kilobyte.
        // If you'd pay more than 1/3 in fees
        // to spend something, then we consider it dust.
        // A typical spendable non-segwit txout is 34 bytes big, and will
        // need a CTxIn of at least 148 bytes to spend:
        // so dust is a spendable txout less than
        // 546*minRelayTxFee/1000 (in satoshis).
        // A typical spendable segwit txout is 31 bytes big, and will
        // need a CTxIn of at least 67 bytes to spend:
        // so dust is a spendable txout less than
        // 294*minRelayTxFee/1000 (in satoshis).
        if (scriptPubKey.IsUnspendable())
            return 0;

        size_t nSize = GetSerializeSize(*this, SER_DISK, 0);
        int witnessversion = 0;
        std::vector<unsigned char> witnessprogram;

        if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
            // sum the sizes of the parts of a transaction input
            // with 75% segwit discount applied to the script size.
            nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
        } else {
            nSize += (32 + 4 + 1 + 107 + 4); // the 148 mentioned above
        }

        return 3 * minRelayTxFee.GetFee(nSize);
    }

    bool IsDust() const
    {
        return false;
    }

    bool IsDust(const CFeeRate &minRelayTxFee) const
    {
//        return (nValue < GetDustThreshold(minRelayTxFee));
        //firo: disable dust
        return false;
    }

    friend bool operator==(const CTxOut& a, const CTxOut& b)
    {
        return (a.nValue       == b.nValue &&
                a.scriptPubKey == b.scriptPubKey);
    }

    friend bool operator!=(const CTxOut& a, const CTxOut& b)
    {
        return !(a == b);
    }

    friend bool operator<(const CTxOut& a, const CTxOut& b)
    {
        return a.nValue < b.nValue || (a.nValue == b.nValue && a.scriptPubKey < b.scriptPubKey);
    }

    uint256 GetHash() const { return SerializeHash(*this); }

    std::string ToString() const;
};

struct CMutableTransaction;

/**
 * Basic transaction serialization format:
 * - int32_t nVersion
 * - std::vector<CTxIn> vin
 * - std::vector<CTxOut> vout
 * - uint32_t nLockTime
 *
 * Extended transaction serialization format:
 * - int32_t nVersion
 * - unsigned char dummy = 0x00
 * - unsigned char flags (!= 0)
 * - std::vector<CTxIn> vin
 * - std::vector<CTxOut> vout
 * - if (flags & 1):
 *   - CTxWitness wit;
 * - uint32_t nLockTime
 */
template<typename Stream, typename TxType>
inline void UnserializeTransaction(TxType& tx, Stream& s) {
    const bool fAllowWitness = !(s.GetVersion() & SERIALIZE_TRANSACTION_NO_WITNESS);

    int32_t n32bitVersion;
    s >> n32bitVersion;
    tx.nVersion = (int16_t) (n32bitVersion & 0xffff);
    tx.nType = (int16_t) ((n32bitVersion >> 16) & 0xffff);

    unsigned char flags = 0;
    tx.vin.clear();
    tx.vout.clear();
    /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
    s >> tx.vin;
    if (tx.vin.size() == 0 && fAllowWitness) {
        /* We read a dummy or an empty vin. */
        s >> flags;
        if (flags != 0) {
            s >> tx.vin;
            s >> tx.vout;
        }
    } else {
        /* We read a non-empty vin. Assume a normal vout follows. */
        s >> tx.vout;
    }
    if ((flags & 1) && fAllowWitness) {
        /* The witness flag is present, and we support witnesses. */
        flags ^= 1;
        for (size_t i = 0; i < tx.vin.size(); i++) {
            s >> tx.vin[i].scriptWitness.stack;
        }
    }
    if (flags) {
        /* Unknown flag in the serialization */
        throw std::ios_base::failure("Unknown transaction optional data");
    }
    s >> tx.nLockTime;

    if (tx.nVersion == 3 && tx.nType != TRANSACTION_NORMAL) {
        s >> tx.vExtraPayload;
    }
}

template<typename Stream, typename TxType>
inline void SerializeTransaction(const TxType& tx, Stream& s) {
    const bool fAllowWitness = !(s.GetVersion() & SERIALIZE_TRANSACTION_NO_WITNESS);

    int32_t n32bitVersion = tx.nVersion | (tx.nType << 16);
    s << n32bitVersion;
    unsigned char flags = 0;
    // Consistency check
    if (fAllowWitness) {
        /* Check whether witnesses need to be serialized. */
        if (tx.HasWitness()) {
            flags |= 1;
        }
    }
    if (flags) {
        /* Use extended format in case witnesses are to be serialized. */
        std::vector<CTxIn> vinDummy;
        s << vinDummy;
        s << flags;
    }
    s << tx.vin;
    s << tx.vout;
    if (flags & 1) {
        for (size_t i = 0; i < tx.vin.size(); i++) {
            s << tx.vin[i].scriptWitness.stack;
        }
    }
    s << tx.nLockTime;
    if (tx.nVersion == 3 && tx.nType != TRANSACTION_NORMAL)
        s << tx.vExtraPayload;
}

/** The basic transaction that is broadcasted on the network and contained in
 * blocks.  A transaction can contain multiple inputs and outputs.
 */
class CTransaction
{
public:
    // Default transaction version.
    // TODO: confirm Exodus works with transaction v2 and change it to 2 here
    static const int32_t CURRENT_VERSION=1;

    // Changing the default transaction version requires a two step process: first
    // adapting relay policy by bumping MAX_STANDARD_VERSION, and then later date
    // bumping the default CURRENT_VERSION at which point both CURRENT_VERSION and
    // MAX_STANDARD_VERSION will be equal.
    static const int32_t MAX_STANDARD_VERSION=3;

    // The local variables are made const to prevent unintended modification
    // without updating the cached hash value. However, CTransaction is not
    // actually immutable; deserialization and assignment are implemented,
    // and bypass the constness. This is safe, as they update the entire
    // structure, including the hash.
    const int32_t nVersion;
    const int16_t nType;
    const std::vector<CTxIn> vin;
    const std::vector<CTxOut> vout;
    const uint32_t nLockTime;
    const std::vector<uint8_t> vExtraPayload; // only available for special transaction types

private:
    /** Memory only. */
    const uint256 hash;

    uint256 ComputeHash() const;

public:
    /** Construct a CTransaction that qualifies as IsNull() */
    CTransaction();

    /** Convert a CMutableTransaction into a CTransaction. */
    CTransaction(const CMutableTransaction &tx);
    CTransaction(CMutableTransaction &&tx);

    template <typename Stream>
    inline void Serialize(Stream& s) const {
        SerializeTransaction(*this, s);
    }

    /** This deserializing constructor is provided instead of an Unserialize method.
     *  Unserialize is not possible, since it would require overwriting const fields. */
    template <typename Stream>
    CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}


    // Compute modified tx size for priority calculation (optionally given tx size)
    unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;

    bool IsCoinBase() const
    {
    // GetValueIn() is a method on CCoinsViewCache, because
    // inputs must be known to compute value in.

    // Compute priority, given priority of inputs and (optionally) tx size
    double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const;

    // Compute modified tx size for priority calculation (optionally given tx size)
    unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;

    // Returns true, if this is any zerocoin transaction.
    bool IsZerocoinTransaction() const;

    // Returns true, if this is a V3 zerocoin mint or spend, made with sigma algorithm.
    bool IsZerocoinV3SigmaTransaction() const;

    bool IsLelantusTransaction() const;

    bool IsZerocoinSpend() const;
    bool IsZerocoinMint() const;

    bool IsSigmaSpend() const;
    bool IsSigmaMint() const;

    bool IsLelantusJoinSplit() const;
    bool IsLelantusMint() const;

    bool IsZerocoinRemint() const;

    bool HasNoRegularInputs() const;

    /**
     * Get the total transaction size in bytes, including witness data.
     * "Total Size" defined in BIP141 and BIP144.
     * @return Total transaction size in bytes
     */
    unsigned int GetTotalSize() const;

    bool IsCoinBase() const
    {
        return (vin.size() == 1 && vin[0].prevout.IsNull() && (vin[0].scriptSig.size() == 0
            || (vin[0].scriptSig[0] != OP_ZEROCOINSPEND
            && vin[0].scriptSig[0] != OP_ZEROCOINTOSIGMAREMINT
            && vin[0].scriptSig[0] != OP_LELANTUSJOINSPLIT
            && vin[0].scriptSig[0] != OP_LELANTUSJOINSPLITPAYLOAD)));
    }

    friend bool operator==(const CTransaction& a, const CTransaction& b)
    {
        return a.hash == b.hash;
    }

    friend bool operator!=(const CTransaction& a, const CTransaction& b)
    {
        return a.hash != b.hash;
    }

    std::string ToString() const;

    bool HasWitness() const
    {
        for (size_t i = 0; i < vin.size(); i++) {
            if (!vin[i].scriptWitness.IsNull()) {
                return true;
            }
        }
        return false;
    }
};

/** A mutable version of CTransaction. */
struct CMutableTransaction
{
    int32_t nVersion;
    int32_t nType;
    std::vector<CTxIn> vin;
    std::vector<CTxOut> vout;
    uint32_t nLockTime;
    std::vector<uint8_t> vExtraPayload; // only available for special transaction types

    CMutableTransaction();
    CMutableTransaction(const CTransaction& tx);

    template <typename Stream>
    inline void Serialize(Stream& s) const {
        SerializeTransaction(*this, s);
    }


    template <typename Stream>
    inline void Unserialize(Stream& s) {
        UnserializeTransaction(*this, s);
    }

    template <typename Stream>
    CMutableTransaction(deserialize_type, Stream& s) {
        Unserialize(s);
    }

    /** Compute the hash of this CMutableTransaction. This is computed on the
     * fly, as opposed to GetHash() in CTransaction, which uses a cached result.
     */
    uint256 GetHash() const;

    std::string ToString() const;
    friend bool operator==(const CMutableTransaction& a, const CMutableTransaction& b)
    {
        return a.GetHash() == b.GetHash();
    }

    friend bool operator!=(const CMutableTransaction& a, const CMutableTransaction& b)
    {
        return !(a == b);
    }

    bool HasWitness() const
    {
        for (size_t i = 0; i < vin.size(); i++) {
            if (!vin[i].scriptWitness.IsNull()) {
                return true;
            }
        }
        return false;
    }
};

typedef std::shared_ptr<const CTransaction> CTransactionRef;
static inline CTransactionRef MakeTransactionRef() { return std::make_shared<const CTransaction>(); }
template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }

/** Compute the weight of a transaction, as defined by BIP 141 */
int64_t GetTransactionWeight(const CTransaction &tx);

#endif // BITCOIN_PRIMITIVES_TRANSACTION_H

<MSG> Adding method GetTotalSize() to CTransaction

GetTotalSize() returns the total transaction size (including witness) in
bytes.

<DFF> @@ -415,6 +415,13 @@ public:
 
     // Compute modified tx size for priority calculation (optionally given tx size)
     unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;
+    
+    /**
+     * Get the total transaction size in bytes, including witness data.
+     * "Total Size" defined in BIP141 and BIP144.
+     * @return Total transaction size in bytes
+     */
+    unsigned int GetTotalSize() const;
 
     bool IsCoinBase() const
     {

{'commit': 'diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp\nindex 2fdc59ea0..4afbe99fd 100644\n--- a/src/primitives/transaction.cpp\n+++ b/src/primitives/transaction.cpp\n@@ -131,6 +131,11 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const\n     return nTxSize;\n }\n \n+unsigned int CTransaction::GetTotalSize() const\n+{\n+    return ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);\n+}\n+\n std::string CTransaction::ToString() const\n {\n     std::string str;\ndiff --git a/src/primitives/transaction.h b/src/primitives/transaction.h\nindex 5689d15bf..16c2e5c45 100644\n--- a/src/primitives/transaction.h\n+++ b/src/primitives/transaction.h\n@@ -415,6 +415,13 @@ public:\n \n     // Compute modified tx size for priority calculation (optionally given tx size)\n     unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;\n+    \n+    /**\n+     * Get the total transaction size in bytes, including witness data.\n+     * "Total Size" defined in BIP141 and BIP144.\n+     * @return Total transaction size in bytes\n+     */\n+    unsigned int GetTotalSize() const;\n \n     bool IsCoinBase() const\n     {\n', 'commit_subject': 'Adding method GetTotalSize() to CTransaction', 'repo_name': 'zcoinofficial/zcoin', 'committer': {'name': 'Hampus Sjöberg', 'email': '17ec53eea2e49add4df6f311acfe58bb5b4f55de@gmail.com', 'time_sec': '1473193830', 'tz_offset': '120', 'date': {'seconds': '1473193830'}}, 'commit_tree': 'c06d2747fcd2caa329a2ce514da1caa4264110cd', 'commit_message': 'Adding method GetTotalSize() to CTransaction\n\nGetTotalSize() returns the total transaction size (including witness) in\nbytes.\n', 'language_name': 'Rust', 'license': 'mit', 'hunks': '@@ -415,6 +415,13 @@ public:\n \n     // Compute modified tx size for priority calculation (optionally given tx size)\n     unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;\n+    \n+    /**\n+     * Get the total transaction size in bytes, including witness data.\n+     * "Total Size" defined in BIP141 and BIP144.\n+     * @return Total transaction size in bytes\n+     */\n+    unsigned int GetTotalSize() const;\n \n     bool IsCoinBase() const\n     {\n', 'addition_count': 7, 'deletion_count': 0, 'src_file': 'a/src/primitives/transaction.h', 'tgt_file': 'b/src/primitives/transaction.h', 'file_extension': '.h', 'before_file': '// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2016 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_PRIMITIVES_TRANSACTION_H\n#define BITCOIN_PRIMITIVES_TRANSACTION_H\n\n#include "amount.h"\n#include "script/script.h"\n#include "serialize.h"\n#include "uint256.h"\n\n#include <exception>\n\nstatic const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000;\n\nstatic const int WITNESS_SCALE_FACTOR = 4;\n\nclass CBadTxIn : public std::exception\n{\n};\n\nclass CBadSequence : public CBadTxIn\n{\n};\n\n/** Transaction types */\nenum {\n    TRANSACTION_NORMAL = 0,\n    TRANSACTION_PROVIDER_REGISTER = 1,\n    TRANSACTION_PROVIDER_UPDATE_SERVICE = 2,\n    TRANSACTION_PROVIDER_UPDATE_REGISTRAR = 3,\n    TRANSACTION_PROVIDER_UPDATE_REVOKE = 4,\n    TRANSACTION_COINBASE = 5,\n    TRANSACTION_QUORUM_COMMITMENT = 6,\n    TRANSACTION_SPORK = 7,\n    TRANSACTION_LELANTUS = 8\n};\n\n/** An outpoint - a combination of a transaction hash and an index n into its vout */\nclass COutPoint\n{\npublic:\n    uint256 hash;\n    uint32_t n;\n\n    COutPoint() { SetNull(); }\n    COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; }\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream& s, Operation ser_action) {\n        READWRITE(hash);\n        READWRITE(n);\n    }\n\n    void SetNull() { hash.SetNull(); n = (uint32_t) -1; }\n    bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -1); }\n\n    bool IsSigmaMintGroup() const { return hash.IsNull() && n >= 1; }\n\n    friend bool operator<(const COutPoint& a, const COutPoint& b)\n    {\n        int cmp = a.hash.Compare(b.hash);\n        return cmp < 0 || (cmp == 0 && a.n < b.n);\n    }\n\n    friend bool operator==(const COutPoint& a, const COutPoint& b)\n    {\n        return (a.hash == b.hash && a.n == b.n);\n    }\n\n    friend bool operator!=(const COutPoint& a, const COutPoint& b)\n    {\n        return !(a == b);\n    }\n\n    std::string ToString() const;\n    std::string ToStringShort() const;\n};\n\n/** An input of a transaction.  It contains the location of the previous\n * transaction\'s output that it claims and a signature that matches the\n * output\'s public key.\n */\nclass CTxIn\n{\npublic:\n    COutPoint prevout;\n    CScript scriptSig;\n    uint32_t nSequence;\n    CScript prevPubKey;\n    CScriptWitness scriptWitness; //! Only serialized through CTransaction\n\n    /* Setting nSequence to this value for every input in a transaction\n     * disables nLockTime. */\n    static const uint32_t SEQUENCE_FINAL = 0xffffffff;\n\n    /* Below flags apply in the context of BIP 68*/\n    /* If this flag set, CTxIn::nSequence is NOT interpreted as a\n     * relative lock-time. */\n    static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31);\n\n    /* If CTxIn::nSequence encodes a relative lock-time and this flag\n     * is set, the relative lock-time has units of 512 seconds,\n     * otherwise it specifies blocks with a granularity of 1. */\n    static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);\n\n    /* If CTxIn::nSequence encodes a relative lock-time, this mask is\n     * applied to extract that lock-time from the sequence field. */\n    static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;\n\n    /* In order to use the same number of bits to encode roughly the\n     * same wall-clock duration, and because blocks are naturally\n     * limited to occur every 600s on average, the minimum granularity\n     * for time-based relative lock-time is fixed at 512 seconds.\n     * Converting from CTxIn::nSequence to seconds is performed by\n     * multiplying by 512 = 2^9, or equivalently shifting up by\n     * 9 bits. */\n    static const int SEQUENCE_LOCKTIME_GRANULARITY = 9;\n\n    CTxIn()\n    {\n        nSequence = SEQUENCE_FINAL;\n    }\n\n    explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);\n    CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream& s, Operation ser_action) {\n        READWRITE(prevout);\n        READWRITE(*(CScriptBase*)(&scriptSig));\n        READWRITE(nSequence);\n    }\n\n    friend bool operator==(const CTxIn& a, const CTxIn& b)\n    {\n        return (a.prevout   == b.prevout &&\n                a.scriptSig == b.scriptSig &&\n                a.nSequence == b.nSequence);\n    }\n\n    friend bool operator!=(const CTxIn& a, const CTxIn& b)\n    {\n        return !(a == b);\n    }\n\n    friend bool operator<(const CTxIn& a, const CTxIn& b)\n    {\n        return a.prevout<b.prevout;\n    }\n\n    std::string ToString() const;\n    bool IsZerocoinSpend() const;\n    bool IsSigmaSpend() const;\n    bool IsLelantusJoinSplit() const;\n    bool IsZerocoinRemint() const;\n};\n\n/** An output of a transaction.  It contains the public key that the next input\n * must be able to sign with to claim it.\n */\nclass CTxOut\n{\npublic:\n    CAmount nValue;\n    CScript scriptPubKey;\n    int nRounds;\n\n    CTxOut()\n    {\n        SetNull();\n    }\n\n    CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream& s, Operation ser_action) {\n        READWRITE(nValue);\n        READWRITE(*(CScriptBase*)(&scriptPubKey));\n        if (ser_action.ForRead())\n            nRounds = -10;\n    }\n\n    void SetNull()\n    {\n        nValue = -1;\n        scriptPubKey.clear();\n        nRounds = -10; // an initial value, should be no way to get this by calculations\n    }\n\n    bool IsNull() const\n    {\n        return (nValue == -1);\n    }\n\n    CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const\n    {\n        // "Dust" is defined in terms of CTransaction::minRelayTxFee,\n        // which has units satoshis-per-kilobyte.\n        // If you\'d pay more than 1/3 in fees\n        // to spend something, then we consider it dust.\n        // A typical spendable non-segwit txout is 34 bytes big, and will\n        // need a CTxIn of at least 148 bytes to spend:\n        // so dust is a spendable txout less than\n        // 546*minRelayTxFee/1000 (in satoshis).\n        // A typical spendable segwit txout is 31 bytes big, and will\n        // need a CTxIn of at least 67 bytes to spend:\n        // so dust is a spendable txout less than\n        // 294*minRelayTxFee/1000 (in satoshis).\n        if (scriptPubKey.IsUnspendable())\n            return 0;\n\n        size_t nSize = GetSerializeSize(*this, SER_DISK, 0);\n        int witnessversion = 0;\n        std::vector<unsigned char> witnessprogram;\n\n        if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {\n            // sum the sizes of the parts of a transaction input\n            // with 75% segwit discount applied to the script size.\n            nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);\n        } else {\n            nSize += (32 + 4 + 1 + 107 + 4); // the 148 mentioned above\n        }\n\n        return 3 * minRelayTxFee.GetFee(nSize);\n    }\n\n    bool IsDust() const\n    {\n        return false;\n    }\n\n    bool IsDust(const CFeeRate &minRelayTxFee) const\n    {\n//        return (nValue < GetDustThreshold(minRelayTxFee));\n        //firo: disable dust\n        return false;\n    }\n\n    friend bool operator==(const CTxOut& a, const CTxOut& b)\n    {\n        return (a.nValue       == b.nValue &&\n                a.scriptPubKey == b.scriptPubKey);\n    }\n\n    friend bool operator!=(const CTxOut& a, const CTxOut& b)\n    {\n        return !(a == b);\n    }\n\n    friend bool operator<(const CTxOut& a, const CTxOut& b)\n    {\n        return a.nValue < b.nValue || (a.nValue == b.nValue && a.scriptPubKey < b.scriptPubKey);\n    }\n\n    uint256 GetHash() const { return SerializeHash(*this); }\n\n    std::string ToString() const;\n};\n\nstruct CMutableTransaction;\n\n/**\n * Basic transaction serialization format:\n * - int32_t nVersion\n * - std::vector<CTxIn> vin\n * - std::vector<CTxOut> vout\n * - uint32_t nLockTime\n *\n * Extended transaction serialization format:\n * - int32_t nVersion\n * - unsigned char dummy = 0x00\n * - unsigned char flags (!= 0)\n * - std::vector<CTxIn> vin\n * - std::vector<CTxOut> vout\n * - if (flags & 1):\n *   - CTxWitness wit;\n * - uint32_t nLockTime\n */\ntemplate<typename Stream, typename TxType>\ninline void UnserializeTransaction(TxType& tx, Stream& s) {\n    const bool fAllowWitness = !(s.GetVersion() & SERIALIZE_TRANSACTION_NO_WITNESS);\n\n    int32_t n32bitVersion;\n    s >> n32bitVersion;\n    tx.nVersion = (int16_t) (n32bitVersion & 0xffff);\n    tx.nType = (int16_t) ((n32bitVersion >> 16) & 0xffff);\n\n    unsigned char flags = 0;\n    tx.vin.clear();\n    tx.vout.clear();\n    /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */\n    s >> tx.vin;\n    if (tx.vin.size() == 0 && fAllowWitness) {\n        /* We read a dummy or an empty vin. */\n        s >> flags;\n        if (flags != 0) {\n            s >> tx.vin;\n            s >> tx.vout;\n        }\n    } else {\n        /* We read a non-empty vin. Assume a normal vout follows. */\n        s >> tx.vout;\n    }\n    if ((flags & 1) && fAllowWitness) {\n        /* The witness flag is present, and we support witnesses. */\n        flags ^= 1;\n        for (size_t i = 0; i < tx.vin.size(); i++) {\n            s >> tx.vin[i].scriptWitness.stack;\n        }\n    }\n    if (flags) {\n        /* Unknown flag in the serialization */\n        throw std::ios_base::failure("Unknown transaction optional data");\n    }\n    s >> tx.nLockTime;\n\n    if (tx.nVersion == 3 && tx.nType != TRANSACTION_NORMAL) {\n        s >> tx.vExtraPayload;\n    }\n}\n\ntemplate<typename Stream, typename TxType>\ninline void SerializeTransaction(const TxType& tx, Stream& s) {\n    const bool fAllowWitness = !(s.GetVersion() & SERIALIZE_TRANSACTION_NO_WITNESS);\n\n    int32_t n32bitVersion = tx.nVersion | (tx.nType << 16);\n    s << n32bitVersion;\n    unsigned char flags = 0;\n    // Consistency check\n    if (fAllowWitness) {\n        /* Check whether witnesses need to be serialized. */\n        if (tx.HasWitness()) {\n            flags |= 1;\n        }\n    }\n    if (flags) {\n        /* Use extended format in case witnesses are to be serialized. */\n        std::vector<CTxIn> vinDummy;\n        s << vinDummy;\n        s << flags;\n    }\n    s << tx.vin;\n    s << tx.vout;\n    if (flags & 1) {\n        for (size_t i = 0; i < tx.vin.size(); i++) {\n            s << tx.vin[i].scriptWitness.stack;\n        }\n    }\n    s << tx.nLockTime;\n    if (tx.nVersion == 3 && tx.nType != TRANSACTION_NORMAL)\n        s << tx.vExtraPayload;\n}\n\n/** The basic transaction that is broadcasted on the network and contained in\n * blocks.  A transaction can contain multiple inputs and outputs.\n */\nclass CTransaction\n{\npublic:\n    // Default transaction version.\n    // TODO: confirm Exodus works with transaction v2 and change it to 2 here\n    static const int32_t CURRENT_VERSION=1;\n\n    // Changing the default transaction version requires a two step process: first\n    // adapting relay policy by bumping MAX_STANDARD_VERSION, and then later date\n    // bumping the default CURRENT_VERSION at which point both CURRENT_VERSION and\n    // MAX_STANDARD_VERSION will be equal.\n    static const int32_t MAX_STANDARD_VERSION=3;\n\n    // The local variables are made const to prevent unintended modification\n    // without updating the cached hash value. However, CTransaction is not\n    // actually immutable; deserialization and assignment are implemented,\n    // and bypass the constness. This is safe, as they update the entire\n    // structure, including the hash.\n    const int32_t nVersion;\n    const int16_t nType;\n    const std::vector<CTxIn> vin;\n    const std::vector<CTxOut> vout;\n    const uint32_t nLockTime;\n    const std::vector<uint8_t> vExtraPayload; // only available for special transaction types\n\nprivate:\n    /** Memory only. */\n    const uint256 hash;\n\n    uint256 ComputeHash() const;\n\npublic:\n    /** Construct a CTransaction that qualifies as IsNull() */\n    CTransaction();\n\n    /** Convert a CMutableTransaction into a CTransaction. */\n    CTransaction(const CMutableTransaction &tx);\n    CTransaction(CMutableTransaction &&tx);\n\n    template <typename Stream>\n    inline void Serialize(Stream& s) const {\n        SerializeTransaction(*this, s);\n    }\n\n    /** This deserializing constructor is provided instead of an Unserialize method.\n     *  Unserialize is not possible, since it would require overwriting const fields. */\n    template <typename Stream>\n    CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}\n\n\n    // Compute modified tx size for priority calculation (optionally given tx size)\n    unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;\n\n    bool IsCoinBase() const\n    {\n    // GetValueIn() is a method on CCoinsViewCache, because\n    // inputs must be known to compute value in.\n\n    // Compute priority, given priority of inputs and (optionally) tx size\n    double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const;\n\n    // Compute modified tx size for priority calculation (optionally given tx size)\n    unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;\n\n    // Returns true, if this is any zerocoin transaction.\n    bool IsZerocoinTransaction() const;\n\n    // Returns true, if this is a V3 zerocoin mint or spend, made with sigma algorithm.\n    bool IsZerocoinV3SigmaTransaction() const;\n\n    bool IsLelantusTransaction() const;\n\n    bool IsZerocoinSpend() const;\n    bool IsZerocoinMint() const;\n\n    bool IsSigmaSpend() const;\n    bool IsSigmaMint() const;\n\n    bool IsLelantusJoinSplit() const;\n    bool IsLelantusMint() const;\n\n    bool IsZerocoinRemint() const;\n\n    bool HasNoRegularInputs() const;\n\n    /**\n     * Get the total transaction size in bytes, including witness data.\n     * "Total Size" defined in BIP141 and BIP144.\n     * @return Total transaction size in bytes\n     */\n    unsigned int GetTotalSize() const;\n\n    bool IsCoinBase() const\n    {\n        return (vin.size() == 1 && vin[0].prevout.IsNull() && (vin[0].scriptSig.size() == 0\n            || (vin[0].scriptSig[0] != OP_ZEROCOINSPEND\n            && vin[0].scriptSig[0] != OP_ZEROCOINTOSIGMAREMINT\n            && vin[0].scriptSig[0] != OP_LELANTUSJOINSPLIT\n            && vin[0].scriptSig[0] != OP_LELANTUSJOINSPLITPAYLOAD)));\n    }\n\n    friend bool operator==(const CTransaction& a, const CTransaction& b)\n    {\n        return a.hash == b.hash;\n    }\n\n    friend bool operator!=(const CTransaction& a, const CTransaction& b)\n    {\n        return a.hash != b.hash;\n    }\n\n    std::string ToString() const;\n\n    bool HasWitness() const\n    {\n        for (size_t i = 0; i < vin.size(); i++) {\n            if (!vin[i].scriptWitness.IsNull()) {\n                return true;\n            }\n        }\n        return false;\n    }\n};\n\n/** A mutable version of CTransaction. */\nstruct CMutableTransaction\n{\n    int32_t nVersion;\n    int32_t nType;\n    std::vector<CTxIn> vin;\n    std::vector<CTxOut> vout;\n    uint32_t nLockTime;\n    std::vector<uint8_t> vExtraPayload; // only available for special transaction types\n\n    CMutableTransaction();\n    CMutableTransaction(const CTransaction& tx);\n\n    template <typename Stream>\n    inline void Serialize(Stream& s) const {\n        SerializeTransaction(*this, s);\n    }\n\n\n    template <typename Stream>\n    inline void Unserialize(Stream& s) {\n        UnserializeTransaction(*this, s);\n    }\n\n    template <typename Stream>\n    CMutableTransaction(deserialize_type, Stream& s) {\n        Unserialize(s);\n    }\n\n    /** Compute the hash of this CMutableTransaction. This is computed on the\n     * fly, as opposed to GetHash() in CTransaction, which uses a cached result.\n     */\n    uint256 GetHash() const;\n\n    std::string ToString() const;\n    friend bool operator==(const CMutableTransaction& a, const CMutableTransaction& b)\n    {\n        return a.GetHash() == b.GetHash();\n    }\n\n    friend bool operator!=(const CMutableTransaction& a, const CMutableTransaction& b)\n    {\n        return !(a == b);\n    }\n\n    bool HasWitness() const\n    {\n        for (size_t i = 0; i < vin.size(); i++) {\n            if (!vin[i].scriptWitness.IsNull()) {\n                return true;\n            }\n        }\n        return false;\n    }\n};\n\ntypedef std::shared_ptr<const CTransaction> CTransactionRef;\nstatic inline CTransactionRef MakeTransactionRef() { return std::make_shared<const CTransaction>(); }\ntemplate <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }\n\n/** Compute the weight of a transaction, as defined by BIP 141 */\nint64_t GetTransactionWeight(const CTransaction &tx);\n\n#endif // BITCOIN_PRIMITIVES_TRANSACTION_H\n', 'message': 'Adding method GetTotalSize() to CTransaction\n\nGetTotalSize() returns the total transaction size (including witness) in\nbytes.\n', 'author_name': 'Hampus Sjöberg', 'lang': 'h'}