<commit_before>// Copyright (c) 2009-2010 <NAME>
// 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"

static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000;

static const int WITNESS_SCALE_FACTOR = 4;

static const CFeeRate withdrawLockTxFee = CFeeRate(5460);

/**
 * Confidential assets, values, and nonces all share enough code in common
 * that it makes sense to define a common abstract base class. */
template<size_t ExplicitSize, unsigned char PrefixA, unsigned char PrefixB>
class CConfidentialCommitment
{
public:
    static const size_t nExplicitSize = ExplicitSize;
    static const size_t nCommittedSize = 33;

    std::vector<unsigned char> vchCommitment;

    CConfidentialCommitment() { SetNull(); }

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        unsigned char version = vchCommitment.empty()? 0: vchCommitment[0];
        READWRITE(version);
        if (ser_action.ForRead()) {
            switch (version) {
                /* Null */
                case 0:
                    vchCommitment.clear();
                    return;
                /* Explicit value */
                case 1:
                /* Trust-me! asset generation */
                case 0xff:
                    vchCommitment.resize(nExplicitSize);
                    break;
                /* Confidential commitment */
                case PrefixA:
                case PrefixB:
                    vchCommitment.resize(nCommittedSize);
                    break;
                /* Invalid serialization! */
                default:
                    throw std::ios_base::failure("Unrecognized serialization prefix");
            }
            vchCommitment[0] = version;
        }
        if (vchCommitment.size() > 1)
            READWRITE(REF(CFlatData(&vchCommitment[1], &vchCommitment[vchCommitment.size()])));
    }

    /* Null is the default state when no explicit asset or confidential
     * asset commitment has been set. */
    bool IsNull() const { return vchCommitment.empty(); }
    void SetNull() { vchCommitment.clear(); }

    bool IsExplicit() const
    {
        return vchCommitment.size()==nExplicitSize && vchCommitment[0]==1;
    }

    bool IsCommitment() const
    {
        return vchCommitment.size()==nCommittedSize && (vchCommitment[0]==PrefixA || vchCommitment[0]==PrefixB);
    }

    bool IsValid() const
    {
        return IsNull() || IsExplicit() || IsCommitment()
            || (vchCommitment.size()==nExplicitSize && vchCommitment[0]==0xff);
    }

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

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

/** A commitment to a blinded asset, or an explicit asset NUMS identifier */
class CConfidentialAsset : public CConfidentialCommitment<33, 10, 11>
{
public:
    CConfidentialAsset() { SetNull(); }
    CConfidentialAsset(CAsset asset) { SetToAsset(asset); }

    /* An explicit asset identifier is a 256-bit nothing-up-my-sleeve number
     * that used as auxiliary input to the Pedersen commitment setup to create
     * a generator which acts as the asset tag. */
    const CAsset& GetAsset() const
    {
        assert(IsExplicit());
        return *reinterpret_cast<const CAsset*>(&vchCommitment[1]);
    }
    void SetToAsset(const CAsset& asset);

};

/** A 33-byte commitment to a confidential value, or a 64-bit explicit value. */
class CConfidentialValue : public CConfidentialCommitment<9, 8, 9>
{
public:
    CConfidentialValue() { SetNull(); }
    CConfidentialValue(CAmount nAmount) { SetToAmount(nAmount); }

    /* An explicit value is called an amount. The first byte indicates it is
     * an explicit value, and the remaining 8 bytes is the value serialized as
     * a 64-bit big-endian integer. */
    CAmount GetAmount() const
    {
        assert(IsExplicit());;
        return ReadBE64(&vchCommitment[1]);
    }
    void SetToAmount(CAmount nAmount);
};

/**
 * An 33-byte data field that typically is used to convey to the
 * recipient the ECDH ephemeral key (an EC point) for deriving the
 * transaction output blinding factor. */
class CConfidentialNonce : public CConfidentialCommitment<33, 2, 3>
{
public:
    CConfidentialNonce() { SetNull(); }
};

/** 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:
    CConfidentialAsset nAsset;
    std::vector<unsigned char> vchSurjectionproof;
    CConfidentialValue nValue;
    std::vector<unsigned char> vchRangeproof;
    CConfidentialNonce nNonce;
    CScript scriptPubKey;

    // FIXME: Inventory the places this constructor is called, and make sure
    //        that `nAsset` is being set appropriately.
    CTxOut()
    {
        SetNull();
    }

    // FIXME: Add `const CTxOutAsset& nAssetIn` as first parameter. This will
    //        (rightfully) break all code that calls this constructor, which
    //        will need to be fixed to be asset aware.
    CTxOut(const CConfidentialAsset& nAssetIn, const CConfidentialValue& nValueIn, CScript scriptPubKeyIn);

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        READWRITE(nAsset);
        // The surjection proof is serialized as part of the witness data
        READWRITE(nValue);
        // The range proof is serialized as part of the witness data
        READWRITE(*(CScriptBase*)(&scriptPubKey));
    }

    void SetNull()
    {
        nAsset.SetNull();
        vchSurjectionproof.clear();
        nValue.SetNull();
        vchRangeproof.clear();
        nNonce.SetNull();
        scriptPubKey.clear();
    }

    bool IsNull() const
    {
        return nAsset.IsNull() && vchSurjectionproof.empty() && nValue.IsNull() && vchRangeproof.empty() && nNonce.IsNull() && scriptPubKey.empty();<commit_msg>CA: Remove TODO note that has already been done<commit_after>// Copyright (c) 2009-2010 <NAME>
// 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"

static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000;

static const int WITNESS_SCALE_FACTOR = 4;

static const CFeeRate withdrawLockTxFee = CFeeRate(5460);

/**
 * Confidential assets, values, and nonces all share enough code in common
 * that it makes sense to define a common abstract base class. */
template<size_t ExplicitSize, unsigned char PrefixA, unsigned char PrefixB>
class CConfidentialCommitment
{
public:
    static const size_t nExplicitSize = ExplicitSize;
    static const size_t nCommittedSize = 33;

    std::vector<unsigned char> vchCommitment;

    CConfidentialCommitment() { SetNull(); }

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        unsigned char version = vchCommitment.empty()? 0: vchCommitment[0];
        READWRITE(version);
        if (ser_action.ForRead()) {
            switch (version) {
                /* Null */
                case 0:
                    vchCommitment.clear();
                    return;
                /* Explicit value */
                case 1:
                /* Trust-me! asset generation */
                case 0xff:
                    vchCommitment.resize(nExplicitSize);
                    break;
                /* Confidential commitment */
                case PrefixA:
                case PrefixB:
                    vchCommitment.resize(nCommittedSize);
                    break;
                /* Invalid serialization! */
                default:
                    throw std::ios_base::failure("Unrecognized serialization prefix");
            }
            vchCommitment[0] = version;
        }
        if (vchCommitment.size() > 1)
            READWRITE(REF(CFlatData(&vchCommitment[1], &vchCommitment[vchCommitment.size()])));
    }

    /* Null is the default state when no explicit asset or confidential
     * asset commitment has been set. */
    bool IsNull() const { return vchCommitment.empty(); }
    void SetNull() { vchCommitment.clear(); }

    bool IsExplicit() const
    {
        return vchCommitment.size()==nExplicitSize && vchCommitment[0]==1;
    }

    bool IsCommitment() const
    {
        return vchCommitment.size()==nCommittedSize && (vchCommitment[0]==PrefixA || vchCommitment[0]==PrefixB);
    }

    bool IsValid() const
    {
        return IsNull() || IsExplicit() || IsCommitment()
            || (vchCommitment.size()==nExplicitSize && vchCommitment[0]==0xff);
    }

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

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

/** A commitment to a blinded asset, or an explicit asset NUMS identifier */
class CConfidentialAsset : public CConfidentialCommitment<33, 10, 11>
{
public:
    CConfidentialAsset() { SetNull(); }
    CConfidentialAsset(CAsset asset) { SetToAsset(asset); }

    /* An explicit asset identifier is a 256-bit nothing-up-my-sleeve number
     * that used as auxiliary input to the Pedersen commitment setup to create
     * a generator which acts as the asset tag. */
    const CAsset& GetAsset() const
    {
        assert(IsExplicit());
        return *reinterpret_cast<const CAsset*>(&vchCommitment[1]);
    }
    void SetToAsset(const CAsset& asset);

};

/** A 33-byte commitment to a confidential value, or a 64-bit explicit value. */
class CConfidentialValue : public CConfidentialCommitment<9, 8, 9>
{
public:
    CConfidentialValue() { SetNull(); }
    CConfidentialValue(CAmount nAmount) { SetToAmount(nAmount); }

    /* An explicit value is called an amount. The first byte indicates it is
     * an explicit value, and the remaining 8 bytes is the value serialized as
     * a 64-bit big-endian integer. */
    CAmount GetAmount() const
    {
        assert(IsExplicit());;
        return ReadBE64(&vchCommitment[1]);
    }
    void SetToAmount(CAmount nAmount);
};

/**
 * An 33-byte data field that typically is used to convey to the
 * recipient the ECDH ephemeral key (an EC point) for deriving the
 * transaction output blinding factor. */
class CConfidentialNonce : public CConfidentialCommitment<33, 2, 3>
{
public:
    CConfidentialNonce() { SetNull(); }
};

/** 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:
    CConfidentialAsset nAsset;
    std::vector<unsigned char> vchSurjectionproof;
    CConfidentialValue nValue;
    std::vector<unsigned char> vchRangeproof;
    CConfidentialNonce nNonce;
    CScript scriptPubKey;

    // FIXME: Inventory the places this constructor is called, and make sure
    //        that `nAsset` is being set appropriately.
    CTxOut()
    {
        SetNull();
    }

    CTxOut(const CConfidentialAsset& nAssetIn, const CConfidentialValue& nValueIn, CScript scriptPubKeyIn);

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        READWRITE(nAsset);
        // The surjection proof is serialized as part of the witness data
        READWRITE(nValue);
        // The range proof is serialized as part of the witness data
        READWRITE(*(CScriptBase*)(&scriptPubKey));
    }

    void SetNull()
    {
        nAsset.SetNull();
        vchSurjectionproof.clear();
        nValue.SetNull();
        vchRangeproof.clear();
        nNonce.SetNull();
        scriptPubKey.clear();
    }

    bool IsNull() const
    {
        return nAsset.IsNull() && vchSurjectionproof.empty() && nValue.IsNull() && vchRangeproof.empty() && nNonce.IsNull() && scriptPubKey.empty();
{'fraction_non_alphanumeric': 0.09802073515551367, 'fraction_numerical': 0.012252591894439209, 'mean_word_length': 2.778338278931751, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6512569', 'n_tokens_mistral': 3828, 'n_tokens_neox': 3714, 'n_words': 1065}