<NME> wallet.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_WALLET_WALLET_H
#define BITCOIN_WALLET_WALLET_H

#include "amount.h"
#include "../sigma/coin.h"
#include "../liblelantus/coin.h"
#include "streams.h"
#include "tinyformat.h"
#include "ui_interface.h"
#include "utilstrencodings.h"
#include "validationinterface.h"
#include "script/ismine.h"
#include "script/sign.h"
#include "wallet/crypter.h"
#include "wallet/walletdb.h"
#include "wallet/rpcwallet.h"
#include "wallet/mnemoniccontainer.h"
#include "../base58.h"
#include "firo_params.h"
#include "univalue.h"

#include "hdmint/tracker.h"
#include "hdmint/wallet.h"

#include "primitives/mint_spend.h"

#include "bip47/paymentcode.h"


#include <algorithm>
#include <atomic>
#include <map>
#include <set>
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>

#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>

extern CWallet* pwalletMain;

/**
 * Settings
 */
extern CFeeRate payTxFee;
extern unsigned int nTxConfirmTarget;
extern bool bSpendZeroConfChange;
extern bool fSendFreeTransactions;
extern bool fWalletRbf;

static const unsigned int DEFAULT_KEYPOOL_SIZE = 100;
//! -paytxfee default
static const CAmount DEFAULT_TRANSACTION_FEE = 0;
//! -fallbackfee default
static const CAmount DEFAULT_FALLBACK_FEE = 20000;
//! -mintxfee default
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
//! minimum recommended increment for BIP 125 replacement txs
static const CAmount WALLET_INCREMENTAL_RELAY_FEE = 5000;
//! target minimum change amount
static const CAmount MIN_CHANGE = CENT;
//! final minimum change amount after paying for fees
static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE/2;
//! Default for -spendzeroconfchange
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true;
//! Default for -sendfreetransactions
static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false;
//! Default for -walletrejectlongchains
static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS = false;
//! -txconfirmtarget default
static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 6;
//! -walletrbf default
static const bool DEFAULT_WALLET_RBF = false;
//! Largest (in bytes) free transaction we're willing to create
static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;
static const bool DEFAULT_WALLETBROADCAST = true;
static const bool DEFAULT_DISABLE_WALLET = false;

static const bool DEFAULT_UPGRADE_CHAIN = false;

//! if set, all keys will be derived by using BIP32
static const bool DEFAULT_USE_HD_WALLET = true;

//! if set, all keys will be derived by using BIP39
static const bool DEFAULT_USE_MNEMONIC = true;

extern const char * DEFAULT_WALLET_DAT;

const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
const uint32_t BIP44_INDEX = 0x2C;
const uint32_t BIP44_TEST_INDEX = 0x1;   // https://github.com/satoshilabs/slips/blob/master/slip-0044.md#registered-coin-types
const uint32_t BIP44_FIRO_INDEX = 0x88; // https://github.com/satoshilabs/slips/blob/master/slip-0044.md#registered-coin-types
const uint32_t BIP44_MINT_INDEX = 0x2;
#ifdef ENABLE_ELYSIUM
const uint32_t BIP44_ELYSIUM_MINT_INDEX_V0 = 0x3;
const uint32_t BIP44_ELYSIUM_MINT_INDEX_V1 = 0x4;
#endif
const uint32_t BIP44_MINT_VALUE_INDEX = 0x5;

class CBlockIndex;
class CCoinControl;
class COutput;
class CReserveKey;
class CScript;
class CTxMemPool;
class CWalletTx;
namespace bip47 {
class CPaymentChannel;
}


namespace bip47 {
    class CPaymentCode;
    class CWallet;
}

/** (client) version numbers for particular wallet features */
enum WalletFeature
{
    FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo's clientversion output)

    FEATURE_WALLETCRYPT = 40000, // wallet encryption
    FEATURE_COMPRPUBKEY = 60000, // compressed public keys

    FEATURE_HD = 130000, // Hierarchical key derivation after BIP32 (HD Wallet)
    FEATURE_LATEST = FEATURE_COMPRPUBKEY // HD is optional, use FEATURE_COMPRPUBKEY as latest version
};

struct CompactTallyItem
{
    CBitcoinAddress address;
    CAmount nAmount;
    std::vector<CTxIn> vecTxIn;
    CompactTallyItem()
    {
        nAmount = 0;
    }
};


/** A key pool entry */
class CKeyPool
{
public:
    int64_t nTime;
    CPubKey vchPubKey;

    CKeyPool();
    CKeyPool(const CPubKey& vchPubKeyIn);

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        int nVersion = s.GetVersion();
        if (!(s.GetType() & SER_GETHASH))
            READWRITE(nVersion);
        READWRITE(nTime);
        READWRITE(vchPubKey);
    }
};

/** Address book data */
class CAddressBookData
{
public:
    std::string name;
    std::string purpose;

    CAddressBookData()
    {
        purpose = "unknown";
    }

    typedef std::map<std::string, std::string> StringMap;
    StringMap destdata;
};

struct CRecipient
{
    CScript scriptPubKey;
    CAmount nAmount;
    bool fSubtractFeeFromAmount;
};

typedef std::map<std::string, std::string> mapValue_t;


static inline void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
{
    if (!mapValue.count("n"))
    {
        nOrderPos = -1; // TODO: calculate elsewhere
        return;
    }
    nOrderPos = atoi64(mapValue["n"].c_str());
}


static inline void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
{
    if (nOrderPos == -1)
        return;
    mapValue["n"] = i64tostr(nOrderPos);
}

struct COutputEntry
{
    CTxDestination destination;
    CAmount amount;
    int vout;
};

/** A transaction with a merkle branch linking it to the block chain. */
class CMerkleTx
{
private:
  /** Constant used in hashBlock to indicate tx has been abandoned */
    static const uint256 ABANDON_HASH;

public:
    CTransactionRef tx;
    uint256 hashBlock;

    /* An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest
     * block in the chain we know this or any in-wallet dependency conflicts
     * with. Older clients interpret nIndex == -1 as unconfirmed for backward
     * compatibility.
     */
    int nIndex;

    CMerkleTx()
    {
        SetTx(MakeTransactionRef());
        Init();
    }

    CMerkleTx(CTransactionRef arg)
    {
        SetTx(std::move(arg));
        Init();
    }

    /** Helper conversion operator to allow passing CMerkleTx where CTransaction is expected.
     *  TODO: adapt callers and remove this operator. */
    operator const CTransaction&() const { return *tx; }

    void Init()
    {
        hashBlock = uint256();
        nIndex = -1;
    }

    void SetTx(CTransactionRef arg)
    {
        tx = std::move(arg);
    }

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        std::vector<uint256> vMerkleBranch; // For compatibility with older versions.
        READWRITE(tx);
        READWRITE(hashBlock);
        READWRITE(vMerkleBranch);
        READWRITE(nIndex);
    }

    void SetMerkleBranch(const CBlockIndex* pIndex, int posInBlock);

    /**
     * Return depth of transaction in blockchain:
     * <0  : conflicts with a transaction this deep in the blockchain
     *  0  : in memory pool, waiting to be included in a block
     * >=1 : this many blocks deep in the main chain
     */
    int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;
    int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }

    int GetDepthInMainChain(const CBlockIndex* &pindexRet, bool enableIX) const;
    int GetDepthInMainChain(bool enableIX) const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet, enableIX); }

    bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; }
    bool IsLockedByLLMQInstantSend() const;
    bool IsChainLocked() const;
    int GetBlocksToMaturity() const;

    bool AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state);
    bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
    bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
    void setAbandoned() { hashBlock = ABANDON_HASH; }

    const uint256& GetHash() const { return tx->GetHash(); }
    bool IsCoinBase() const { return tx->IsCoinBase(); }
};

/**
 * A transaction with a bunch of additional info that only the owner cares about.
 * It includes any unrecorded transactions needed to link it back to the block chain.
 */
class CWalletTx : public CMerkleTx
{
private:
    const CWallet* pwallet;

public:
    mapValue_t mapValue;
    std::vector<std::pair<std::string, std::string> > vOrderForm;
    unsigned int fTimeReceivedIsTxTime;
    unsigned int nTimeReceived; //!< time received by this node
    unsigned int nTimeSmart;
    /**
     * From me flag is set to 1 for transactions that were created by the wallet
     * on this bitcoin node, and set to 0 for transactions that were created
     * externally and came in through the network or sendrawtransaction RPC.
     */
    char fFromMe;
    std::string strFromAccount;
    int64_t nOrderPos; //!< position in ordered transaction list
    std::unordered_set<uint32_t> changes; //!< positions of changes in vout

    // memory only
    mutable bool fDebitCached;
    mutable bool fCreditCached;
    mutable bool fImmatureCreditCached;
    mutable bool fAvailableCreditCached;
    mutable bool fWatchDebitCached;
    mutable bool fWatchCreditCached;
    mutable bool fImmatureWatchCreditCached;
    mutable bool fAvailableWatchCreditCached;
    mutable bool fChangeCached;
    mutable CAmount nDebitCached;
    mutable CAmount nCreditCached;
    mutable CAmount nImmatureCreditCached;
    mutable CAmount nAvailableCreditCached;
    mutable CAmount nWatchDebitCached;
    mutable CAmount nWatchCreditCached;
    mutable CAmount nImmatureWatchCreditCached;
    mutable CAmount nAvailableWatchCreditCached;
    mutable CAmount nChangeCached;

    CWalletTx()
    {
        Init(NULL);
    }

    CWalletTx(const CWallet* pwalletIn, CTransactionRef arg) : CMerkleTx(std::move(arg))
    {
        Init(pwalletIn);
    }

    void Init(const CWallet* pwalletIn)
    {
        pwallet = pwalletIn;
        mapValue.clear();
        vOrderForm.clear();
        fTimeReceivedIsTxTime = false;
        nTimeReceived = 0;
        nTimeSmart = 0;
        fFromMe = false;
        strFromAccount.clear();
        fDebitCached = false;
        fCreditCached = false;
        fImmatureCreditCached = false;
        fAvailableCreditCached = false;
        fWatchDebitCached = false;
        fWatchCreditCached = false;
        fImmatureWatchCreditCached = false;
        fAvailableWatchCreditCached = false;
        fChangeCached = false;
        nDebitCached = 0;
        nCreditCached = 0;
        nImmatureCreditCached = 0;
        nAvailableCreditCached = 0;
        nWatchDebitCached = 0;
        nWatchCreditCached = 0;
        nAvailableWatchCreditCached = 0;
        nImmatureWatchCreditCached = 0;
        nChangeCached = 0;
        nOrderPos = -1;
        changes.clear();
    }

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        constexpr uint32_t FLAG_WITH_CHANGES = 0x00000001;

        if (ser_action.ForRead())
            Init(NULL);

        char fSpent = false;
        uint32_t flags = 0;

        if (!ser_action.ForRead())
        {
            flags = FLAG_WITH_CHANGES;

            mapValue["fromaccount"] = strFromAccount;
            mapValue["flags"] = strprintf("0x%x", flags);

            WriteOrderPos(nOrderPos, mapValue);

            if (nTimeSmart)
                mapValue["timesmart"] = strprintf("%u", nTimeSmart);
        }

        READWRITE(*(CMerkleTx*)this);
        std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev
        READWRITE(vUnused);
        READWRITE(mapValue);
        READWRITE(vOrderForm);
        READWRITE(fTimeReceivedIsTxTime);
        READWRITE(nTimeReceived);
        READWRITE(fFromMe);
        READWRITE(fSpent);

        if (ser_action.ForRead())
        {
            strFromAccount = mapValue["fromaccount"];

            ReadOrderPos(nOrderPos, mapValue);

            nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;

            auto it = mapValue.find("flags");
            if (it != mapValue.end()) {
                flags = static_cast<uint32_t>(std::strtoul(it->second.c_str(), nullptr, 0));
            }
        }

        if (flags & FLAG_WITH_CHANGES) {
            READWRITE(changes);
        }

        mapValue.erase("fromaccount");
        mapValue.erase("version");
        mapValue.erase("spent");
        mapValue.erase("n");
        mapValue.erase("timesmart");
        mapValue.erase("flags");
    }

    //! make sure balances are recalculated
    void MarkDirty()
    {
        fCreditCached = false;
        fAvailableCreditCached = false;
        fImmatureCreditCached = false;
        fWatchDebitCached = false;
        fWatchCreditCached = false;
        fAvailableWatchCreditCached = false;
        fImmatureWatchCreditCached = false;
        fDebitCached = false;
        fChangeCached = false;
    }

    void BindWallet(CWallet *pwalletIn)
    {
        pwallet = pwalletIn;
        MarkDirty();
    }

    //! filter decides which addresses will count towards the debit
    CAmount GetDebit(const isminefilter& filter) const;
    CAmount GetCredit(const isminefilter& filter) const;
    CAmount GetImmatureCredit(bool fUseCache=true) const;
    CAmount GetAvailableCredit(bool fUseCache=true, bool fExcludeLocked = false) const;
    CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const;
    CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const;
    CAmount GetAnonymizedCredit(bool fUseCache=true) const;
    CAmount GetChange() const;

    void GetAmounts(std::list<COutputEntry>& listReceived,
                    std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const;

    bool IsFromMe(const isminefilter& filter) const
    {
        return (GetDebit(filter) > 0);
    }

    // True if only scriptSigs are different
    bool IsEquivalentTo(const CWalletTx& tx) const;

    bool InMempool() const;
    bool InStempool() const;
    bool IsTrusted() const;

    bool IsChange(uint32_t out) const;
    bool IsChange(const CTxOut& out) const;

    int64_t GetTxTime() const;
    int GetRequestCount() const;

    bool RelayWalletTransaction(CConnman* connman);

    std::set<uint256> GetConflicts() const;
};




class COutput
{
public:
    const CWalletTx *tx;
    int i;
    int nDepth;
    bool fSpendable;
    bool fSolvable;

    COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn, bool fSolvableIn)
    {
        tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; fSolvable = fSolvableIn;
    }

    std::string ToString() const;
};




/** Private key that includes an expiration date in case it never gets used. */
class CWalletKey
{
public:
    CPrivKey vchPrivKey;
    int64_t nTimeCreated;
    int64_t nTimeExpires;
    std::string strComment;
    //! todo: add something to note what created it (user, getnewaddress, change)
    //!   maybe should have a map<string, string> property map

    CWalletKey(int64_t nExpires=0);

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        int nVersion = s.GetVersion();
        if (!(s.GetType() & SER_GETHASH))
            READWRITE(nVersion);
        READWRITE(vchPrivKey);
        READWRITE(nTimeCreated);
        READWRITE(nTimeExpires);
        READWRITE(LIMITED_STRING(strComment, 65536));
    }
};

/**
 * Internal transfers.
 * Database key is acentry<account><counter>.
 */
class CAccountingEntry
{
public:
    std::string strAccount;
    CAmount nCreditDebit;
    int64_t nTime;
    std::string strOtherAccount;
    std::string strComment;
    mapValue_t mapValue;
    int64_t nOrderPos; //!< position in ordered transaction list
    uint64_t nEntryNo;

    CAccountingEntry()
    {
        SetNull();
    }

    void SetNull()
    {
        nCreditDebit = 0;
        nTime = 0;
        strAccount.clear();
        strOtherAccount.clear();
        strComment.clear();
        nOrderPos = -1;
        nEntryNo = 0;
    }

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        int nVersion = s.GetVersion();
        if (!(s.GetType() & SER_GETHASH))
            READWRITE(nVersion);
        //! Note: strAccount is serialized as part of the key, not here.
        READWRITE(nCreditDebit);
        READWRITE(nTime);
        READWRITE(LIMITED_STRING(strOtherAccount, 65536));

        if (!ser_action.ForRead())
        {
            WriteOrderPos(nOrderPos, mapValue);

            if (!(mapValue.empty() && _ssExtra.empty()))
            {
                CDataStream ss(s.GetType(), s.GetVersion());
                ss.insert(ss.begin(), '\0');
                ss << mapValue;
                ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end());
                strComment.append(ss.str());
            }
        }

        READWRITE(LIMITED_STRING(strComment, 65536));

        size_t nSepPos = strComment.find("\0", 0, 1);
        if (ser_action.ForRead())
        {
            mapValue.clear();
            if (std::string::npos != nSepPos)
            {
                CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), s.GetType(), s.GetVersion());
                ss >> mapValue;
                _ssExtra = std::vector<char>(ss.begin(), ss.end());
            }
            ReadOrderPos(nOrderPos, mapValue);
        }
        if (std::string::npos != nSepPos)
            strComment.erase(nSepPos);

        mapValue.erase("n");
    }

private:
    std::vector<char> _ssExtra;
};

class LelantusJoinSplitBuilder;

/**
 * A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
 * and provides the ability to create new transactions.
 */
class CWallet : public CCryptoKeyStore, public CValidationInterface
{
private:
    static std::atomic<bool> fFlushThreadRunning;

    /**
     * Select a set of coins such that nValueRet >= nTargetValue and at least
     * all coins from coinControl are selected; Never select unconfirmed coins
     * if they are not ours
     */
    bool SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL, bool fForUseInInstantSend = true) const;

    CWalletDB *pwalletdbEncryption;

    //! the current wallet version: clients below this version are not able to load the wallet
    int nWalletVersion;

    //! the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
    int nWalletMaxVersion;

    int64_t nNextResend;
    int64_t nLastResend;
    bool fBroadcastTransactions;

    mutable bool fAnonymizableTallyCached;
    mutable std::vector<CompactTallyItem> vecAnonymizableTallyCached;
    mutable bool fAnonymizableTallyCachedNonDenom;
    mutable std::vector<CompactTallyItem> vecAnonymizableTallyCachedNonDenom;

    /**
     * Used to keep track of spent outpoints, and
     * detect and report conflicts (double-spends or
     * mutated transactions where the mutant gets mined).
     */
    typedef std::multimap<COutPoint, uint256> TxSpends;
    TxSpends mapTxSpends;
    void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);
    void AddToSpends(const uint256& wtxid);

    std::set<COutPoint> setWalletUTXO;
    void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);
    void AddToSpends(const uint256& wtxid);

    /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */
    void MarkConflicted(const uint256& hashBlock, const uint256& hashTx);

    MnemonicContainer mnemonicContainer;

    bool fFileBacked;

    std::set<int64_t> setKeyPool;

    std::map<CKeyID, int64_t> m_pool_key_to_index;

    int64_t nTimeFirstKey;

    std::shared_ptr<bip47::CWallet> bip47wallet;

    /**
     * Private version of AddWatchOnly method which does not accept a
     * timestamp, and which will reset the wallet's nTimeFirstKey value to 1 if
     * the watch key did not previously have a timestamp associated with it.
     * Because this is an inherited virtual method, it is accessible despite
     * being marked private, but it is marked private anyway to encourage use
     * of the other AddWatchOnly which accepts a timestamp and sets
     * nTimeFirstKey more intelligently for more efficient rescans.
     */
    bool AddWatchOnly(const CScript& dest) override;

public:
    /*
     * Main wallet lock.
     * This lock protects all the fields added by CWallet
     *   except for:
     *      fFileBacked (immutable after instantiation)
     *      strWalletFile (immutable after instantiation)
     */
    mutable CCriticalSection cs_wallet;

    const std::string strWalletFile;

    void LoadKeyPool(int nIndex, const CKeyPool &keypool)
    {
        setKeyPool.insert(nIndex);

        m_pool_key_to_index[keypool.vchPubKey.GetID()] = nIndex;
        // If no metadata exists yet, create a default with the pool key's
        // creation time. Note that this may be overwritten by actually
        // stored metadata for that key later, which is fine.
        CKeyID keyid = keypool.vchPubKey.GetID();
        if (mapKeyMetadata.count(keyid) == 0)
            mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);
    }

    // Map from Key ID (for regular keys) or Script ID (for watch-only keys) to
    // key metadata.
    std::map<CTxDestination, CKeyMetadata> mapKeyMetadata;
    //znode
    int64_t nKeysLeftSinceAutoBackup;

    typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
    MasterKeyMap mapMasterKeys;
    unsigned int nMasterKeyMaxID;

    std::unique_ptr<CHDMintWallet> zwallet;

    CWallet()
    {
        SetNull();
    }

    CWallet(const std::string& strWalletFileIn) : strWalletFile(strWalletFileIn)
    {
        SetNull();
        fFileBacked = true;
    }

    ~CWallet()
    {
        delete pwalletdbEncryption;
        pwalletdbEncryption = NULL;
    }

    void SetNull()
    {
        nWalletVersion = FEATURE_BASE;
        nWalletMaxVersion = FEATURE_BASE;
        fFileBacked = false;
        nMasterKeyMaxID = 0;
        pwalletdbEncryption = NULL;
        nOrderPosNext = 0;
        nNextResend = 0;
        nLastResend = 0;
        nTimeFirstKey = 0;
        fBroadcastTransactions = false;
        fAnonymizableTallyCached = false;
        fAnonymizableTallyCachedNonDenom = false;
        vecAnonymizableTallyCached.clear();
        vecAnonymizableTallyCachedNonDenom.clear();
        zwallet = NULL;
        bip47wallet.reset();
    }

    std::map<uint256, CWalletTx> mapWallet;
    std::list<CAccountingEntry> laccentries;
    bool EraseFromWallet(uint256 hash);
    typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
    typedef std::multimap<int64_t, TxPair > TxItems;
    TxItems wtxOrdered;

    int64_t nOrderPosNext;
    std::map<uint256, int> mapRequestCount;

    std::map<CTxDestination, CAddressBookData> mapAddressBook;
    std::multimap<std::string, std::string> mapCustomKeyValues;

    CPubKey vchDefaultKey;

    std::set<COutPoint> setLockedCoins;

    const CWalletTx* GetWalletTx(const uint256& hash) const;

    //! check whether we are allowed to upgrade (or already support) to the named feature
    bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }

    /**
     * populate vCoins with vector of available COutputs.
     */
    void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL, bool fIncludeZeroValue=false, bool fForUseInInstantSend = false) const;

    void AvailableCoinsForLMint(std::vector<std::pair<CAmount, std::vector<COutput>>>& valueAndUTXO, const CCoinControl *coinControl) const;

    bool IsHDSeedAvailable() { return !hdChain.masterKeyID.IsNull(); }

    /**
     * Shuffle and select coins until nTargetValue is reached while avoiding
     * small change; This method is stochastic for some inputs and upon
     * completion the coin set and corresponding actual target value is
     * assembled
     */
    bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, uint64_t nMaxAncestors, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, bool fForUseInInstantSend = false) const;

    bool IsSpent(const uint256& hash, unsigned int n) const;

    bool IsLockedCoin(uint256 hash, unsigned int n) const;
    void LockCoin(const COutPoint& output);
    void UnlockCoin(const COutPoint& output);
    void UnlockAllCoins();
    void ListLockedCoins(std::vector<COutPoint>& vOutpts);
    void ListProTxCoins(std::vector<COutPoint>& vOutpts);

    bool HasMasternode();

    // znode
    /// Get 1000 FIRO output and keys which can be used for the Znode
    bool GetZnodeVinAndKeys(CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet, std::string strTxHash = "", std::string strOutputIndex = "");
    /// Extract txin information and keys from output
    bool GetVinAndKeysFromOutput(COutput out, CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet);

    CPubKey GetKeyFromKeypath(uint32_t nChange, uint32_t nChild, CKey& secret);
    /**
     * keystore implementation
     * Generate a new key
     */
    CPubKey GenerateNewKey(uint32_t nChange=0, bool fWriteChain=true);
    void DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret);
    //! Adds a key to the store, and saves it to disk.
    bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;
    //! Adds a key to the store, without saving it to disk (used by LoadWallet)
    bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
    //! Load metadata (used by LoadWallet)
    bool LoadKeyMetadata(const CTxDestination& pubKey, const CKeyMetadata &metadata);

    bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
    void UpdateTimeFirstKey(int64_t nCreateTime);

    //! Adds an encrypted key to the store, and saves it to disk.
    bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) override;
    //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
    bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
    bool AddCScript(const CScript& redeemScript) override;
    bool LoadCScript(const CScript& redeemScript);

    //! Adds a destination data tuple to the store, and saves it to disk
    bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value);
    //! Erases a destination data tuple in the store and on disk
    bool EraseDestData(const CTxDestination &dest, const std::string &key);
    //! Adds a destination data tuple to the store, without saving it to disk
    bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value);
    //! Look up a destination data tuple in the store, return true if found false otherwise
    bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const;

    //! Adds a watch-only address to the store, and saves it to disk.
    bool AddWatchOnly(const CScript& dest, int64_t nCreateTime);
    bool RemoveWatchOnly(const CScript &dest) override;
    //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
    bool LoadWatchOnly(const CScript &dest);

    //! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock().
    int64_t nRelockTime;

    bool Unlock(const SecureString& strWalletPassphrase, const bool& fFirstUnlock=false);
    bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
    bool EncryptWallet(const SecureString& strWalletPassphrase);

    void GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const;

    /**
     * Increment the next transaction order id
     * @return next transaction order id
     */
    int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL);
    DBErrors ReorderTransactions();
    bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = "");
    bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew = false);

    void MarkDirty();
    bool AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose=true);
    bool LoadToWallet(const CWalletTx& wtxIn);
    void SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, int posInBlock) override;
    bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate);
    CBlockIndex* ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false, bool fRecoverMnemonic = false);
    void ReacceptWalletTransactions();
    void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) override;
    std::vector<uint256> ResendWalletTransactionsBefore(int64_t nTime, CConnman* connman);
    CAmount GetBalance(bool fExcludeLocked = false) const;
    std::pair<CAmount, CAmount> GetPrivateBalance() const;
    std::pair<CAmount, CAmount> GetPrivateBalance(size_t &confirmed, size_t &unconfirmed) const;
    CAmount GetUnconfirmedBalance() const;
    CAmount GetImmatureBalance() const;
    CAmount GetWatchOnlyBalance() const;
    CAmount GetUnconfirmedWatchOnlyBalance() const;
    CAmount GetImmatureWatchOnlyBalance() const;
    CAmount GetLegacyBalance(const isminefilter& filter, int minDepth, const std::string* account, bool fAddLocked = false) const;

    static std::vector<CRecipient> CreateSigmaMintRecipients(
        std::vector<sigma::PrivateCoin>& coins,
        std::vector<CHDMint>& vDMints);

    static CRecipient CreateLelantusMintRecipient(
        lelantus::PrivateCoin& coin,
        CHDMint& vDMint,
        bool generate = true);

    static int GetRequiredCoinCountForAmount(
        const CAmount& required,
        const std::vector<sigma::CoinDenomination>& denominations);

    static CAmount SelectMintCoinsForAmount(
        const CAmount& required,
        const std::vector<sigma::CoinDenomination>& denominations,
        std::vector<sigma::CoinDenomination>& coinsOut);

    static CAmount SelectSpendCoinsForAmount(
        const CAmount& required,
        const std::list<CSigmaEntry>& coinsIn,
        std::vector<CSigmaEntry>& coinsOut);

    // Returns a list of unspent and verified coins, I.E. coins which are ready
    // to be spent.
    std::list<CSigmaEntry> GetAvailableCoins(const CCoinControl *coinControl = NULL, bool includeUnsafe = false, bool forEstimation = false) const;

    std::list<CLelantusEntry> GetAvailableLelantusCoins(const CCoinControl *coinControl = NULL, bool includeUnsafe = false, bool forEstimation = false) const;

    std::vector<unsigned char> EncryptMintAmount(uint64_t amount, const secp_primitives::GroupElement& pubcoin) const;

    bool DecryptMintAmount(const std::vector<unsigned char>& encryptedValue, const secp_primitives::GroupElement& pubcoin, uint64_t& amount) const;


    /** \brief Selects coins to spend, and coins to re-mint based on the required amount to spend, provided by the user. As the lower denomination now is 0.1 firo, user's request will be rounded up to the nearest 0.1. This difference between the user's requested value, and the actually spent value will be left to the miners as a fee.
     * \param[in] required Required amount to spend.
     * \param[out] coinsToSpend_out Coins which user needs to spend.
     * \param[out] coinsToMint_out Coins which will be re-minted by the user to get the change back.
     * \returns true, if it was possible to spend exactly required(rounded up to 0.1 firo) amount using coins we have.
     */
    bool GetCoinsToSpend(
        CAmount required,
        std::vector<CSigmaEntry>& coinsToSpend_out,
        std::vector<sigma::CoinDenomination>& coinsToMint_out,
        std::list<CSigmaEntry>& coins,
        const size_t coinsLimit = SIZE_MAX,
        const CAmount amountLimit = MAX_MONEY,
        const CCoinControl *coinControl = NULL) const;

    bool GetCoinsToJoinSplit(
            CAmount required,
            std::vector<CLelantusEntry>& coinsToSpend_out,
            CAmount& changeToMint,
            std::list<CLelantusEntry> coins,
            const size_t coinsToSpendLimit = SIZE_MAX,
            const CAmount amountToSpendLimit = MAX_MONEY,
            const CCoinControl *coinControl = NULL) const;

    /**
     * Insert additional inputs into the transaction by
     * calling CreateTransaction();
     */
    bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool overrideEstimatedFeeRate, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, bool keepReserveKey = true, const CTxDestination& destChange = CNoDestination());

    /**
     * Create a new transaction paying the recipients with a set of coins
     * selected by SelectCoins(); Also create the change output, when needed
     * @note passing nChangePosInOut as -1 will result in setting a random position
     */
    bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
                           std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true, int nExtraPayloadSize = 0, bool fUseInstantSend=false);

    /**
     * Add Mint and Spend functions
     */
    void ListAvailableSigmaMintCoins(std::vector <COutput> &vCoins, bool fOnlyConfirmed) const;
    void ListAvailableLelantusMintCoins(std::vector<COutput> &vCoins, bool fOnlyConfirmed) const;

    bool CreateMintTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
                           std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true);
    bool CreateMintTransaction(CScript pubCoin, int64_t nValue,
                                       CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl=NULL);
    bool CreateLelantusMintTransactions(CAmount valueToMint, std::vector<std::pair<CWalletTx, CAmount>>& wtxAndFee,
                                        CAmount& nAllFeeRet, std::vector<CHDMint>& dMints,
                                        std::list<CReserveKey>& reservekeys, int& nChangePosInOut,
                                        std::string& strFailReason, const CCoinControl *coinControl, bool autoMintAll = false, bool sign = true);

    CWalletTx CreateSigmaSpendTransaction(
        const std::vector<CRecipient>& recipients,
        CAmount& fee,
        std::vector<CSigmaEntry>& selected,
        std::vector<CHDMint>& changes,
        bool& fChangeAddedToFee,
        const CCoinControl *coinControl = NULL);

    CWalletTx CreateLelantusJoinSplitTransaction(
        const std::vector<CRecipient>& recipients,
        CAmount& fee,
        const std::vector<CAmount>& newMints,
        std::vector<CLelantusEntry>& spendCoins,
        std::vector<CSigmaEntry>& sigmaSpendCoins,
        std::vector<CHDMint>& mintCoins,
        const CCoinControl *coinControl = NULL,
        std::function<void(CTxOut & , LelantusJoinSplitBuilder const &)> modifier = nullptr);

    bool CommitSigmaTransaction(CWalletTx& wtxNew, std::vector<CSigmaEntry>& selectedCoins, std::vector<CHDMint>& changes);
    bool CommitLelantusTransaction(CWalletTx& wtxNew, std::vector<CLelantusEntry>& spendCoins, std::vector<CSigmaEntry>& sigmaSpendCoins, std::vector<CHDMint>& mintCoins);
    std::string SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew, bool fAskFee=false);
    std::string SendMoneyToDestination(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew, bool fAskFee=false);

    std::string MintAndStoreSigma(
        const std::vector<CRecipient>& vecSend,
        const std::vector<sigma::PrivateCoin>& privCoins,
        std::vector<CHDMint> vDMints,
        CWalletTx &wtxNew,
        bool fAskFee=false,
        const CCoinControl *coinControl = NULL);

    std::string MintAndStoreLelantus(
            const CAmount& value,
            std::vector<std::pair<CWalletTx, CAmount>>& wtxAndFee,
            std::vector<CHDMint>& mints,
            bool autoMintAll = false,
            bool fAskFee = false,
            const CCoinControl *coinControl = NULL);

    std::vector<CSigmaEntry> SpendSigma(const std::vector<CRecipient>& recipients, CWalletTx& result);
    std::vector<CSigmaEntry> SpendSigma(const std::vector<CRecipient>& recipients, CWalletTx& result, CAmount& fee);

    std::vector<CLelantusEntry> JoinSplitLelantus(const std::vector<CRecipient>& recipients, const std::vector<CAmount>& newMints, CWalletTx& result);

    std::pair<CAmount, unsigned int> EstimateJoinSplitFee(CAmount required, bool subtractFeeFromAmount, std::list<CSigmaEntry> sigmaCoins, std::list<CLelantusEntry> coins, const CCoinControl *coinControl);

    bool GetMint(const uint256& hashSerial, CSigmaEntry& sigmaEntry, bool forEstimation = false) const;

    bool GetMint(const uint256& hashSerial, CLelantusEntry& mint, bool forEstimation = false) const;

    bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state);


    bool CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason);
    bool ConvertList(std::vector<CTxIn> vecTxIn, std::vector<CAmount>& vecAmounts);

    void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);
    bool AddAccountingEntry(const CAccountingEntry&);
    bool AddAccountingEntry(const CAccountingEntry&, CWalletDB *pwalletdb);
    template <typename ContainerType>
    bool DummySignTx(CMutableTransaction &txNew, const ContainerType &coins);

    static CFeeRate minTxFee;
    static CFeeRate fallbackFee;
    /**
     * Estimate the minimum fee considering user set parameters
     * and the required fee
     */
    static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool);
    /**
     * Estimate the minimum fee considering required fee and targetFee or if 0
     * then fee estimation for nConfirmTarget
     */
    static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, CAmount targetFee);
    /**
     * Return the minimum required fee taking into account the
     * floating relay fee and user set minimum transaction fee
     */
    static CAmount GetRequiredFee(unsigned int nTxBytes);

    bool NewKeyPool();
    bool TopUpKeyPool(unsigned int kpSize = 0);
    void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool);
    void KeepKey(int64_t nIndex);
    void ReturnKey(int64_t nIndex, const CPubKey& pubkey);
    bool GetKeyFromPool(CPubKey &key);
    int64_t GetOldestKeyPoolTime();
    /**
     * Marks all keys in the keypool up to and including reserve_key as used.
     */
    void MarkReserveKeysAsUsed(int64_t keypool_id);
    const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; }

    std::set< std::set<CTxDestination> > GetAddressGroupings();
    std::map<CTxDestination, CAmount> GetAddressBalances();

    std::set<CTxDestination> GetAccountAddresses(const std::string& strAccount) const;

    isminetype IsMine(const CTxIn& txin, const CTransaction& tx) const;
    /**
     * Returns amount of debit if the input matches the
     * filter, otherwise returns 0
     */
    CAmount GetDebit(const CTxIn& txin, const CTransaction&tx, const isminefilter& filter) const;
    isminetype IsMine(const CTxOut& txout) const;
    CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const;
    bool IsChange(const uint256& tx, const CTxOut& txout) const;
    CAmount GetChange(const uint256& tx, const CTxOut& txout) const;
    bool IsMine(const CTransaction& tx) const;
    /** should probably be renamed to IsRelevantToMe */
    bool IsFromMe(const CTransaction& tx) const;
    CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const;
    /** Returns whether all of the inputs match the filter */
    bool IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const;
    CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const;
    CAmount GetChange(const CTransaction& tx) const;
    void SetBestChain(const CBlockLocator& loc) override;

    DBErrors LoadWallet(bool& fFirstRunRet);
    void AutoLockMasternodeCollaterals();
    DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx);
    DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut);

    // Remove all CSigmaEntry and CHDMint objects from WalletDB.
    DBErrors ZapSigmaMints();
    // Remove all Lelantus HDMint objects from WalletDB
    DBErrors ZapLelantusMints();

    bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose);

    bool DelAddressBook(const CTxDestination& address);

    bool UpdatedTransaction(const uint256 &hashTx) override;
    const std::string& GetAccountName(const CScript& scriptPubKey) const;

    void Inventory(const uint256 &hash) override
    {
        {
            LOCK(cs_wallet);
            std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
            if (mi != mapRequestCount.end())
                (*mi).second++;
        }
    }

    void GetScriptForMining(boost::shared_ptr<CReserveScript> &script) override;
    void ResetRequestCount(const uint256 &hash) override
    {
        LOCK(cs_wallet);
        mapRequestCount[hash] = 0;
    };

    unsigned int GetKeyPoolSize()
    {
        AssertLockHeld(cs_wallet); // setKeyPool
        return setKeyPool.size();
    }

    bool SetDefaultKey(const CPubKey &vchPubKey);

    //! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
    bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);

    //! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
    bool SetMaxVersion(int nVersion);

    //! get the current wallet format (the oldest client version guaranteed to understand this wallet)
    int GetVersion() { LOCK(cs_wallet); return nWalletVersion; }

    //! Get wallet transactions that conflict with given transaction (spend same outputs)
    std::set<uint256> GetConflicts(const uint256& txid) const;

    //! Check if a given transaction has any of its outputs spent by another transaction in the wallet
    bool HasWalletSpend(const uint256& txid) const;

    //! Flush wallet (bitdb flush)
    void Flush(bool shutdown=false);

    //! Verify the wallet database and perform salvage if required
    static bool Verify();

    /**
     * Address book entry changed.
     * @note called with lock cs_wallet held.
     */
    boost::signals2::signal<void (CWallet *wallet, const CTxDestination
            &address, const std::string &label, bool isMine,
            const std::string &purpose,
            ChangeType status)> NotifyAddressBookChanged;

    /**
     * Wallet transaction added, removed or updated.
     * @note called with lock cs_wallet held.
     */
    boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx,
            ChangeType status)> NotifyTransactionChanged;
    /**
     * sigma/lelantus entry changed.
     * @note called with lock cs_wallet held.
     */
    boost::signals2::signal<void (CWallet *wallet, const std::string &pubCoin, const std::string &isUsed, ChangeType status)> NotifyZerocoinChanged;


    /** Show progress e.g. for rescan */
    boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;

    /** Watch-only address added */
    boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;

    /** Payment code added */
    boost::signals2::signal<void (bip47::CPaymentCodeDescription)> NotifyPcodeCreated;

    /** Payment code labeled */
    boost::signals2::signal<void (std::string pcode, std::string label, bool removed)> NotifyPcodeLabeled;

    /** Unlock required (for example for adding a privkey to the wallet),  */
    boost::signals2::signal<void (int receiverAccountNum, CBlockIndex* pBlockIndex)> NotifyBip47KeysChanged;

    /** IS-lock received */
    boost::signals2::signal<void ()> NotifyISLockReceived;

    /** ChainLock received */
    boost::signals2::signal<void (int height)> NotifyChainLockReceived;

    /** Inquire whether this wallet broadcasts transactions. */
    bool GetBroadcastTransactions() const { return fBroadcastTransactions; }
    /** Set whether this wallet broadcasts transactions. */
    void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; }

    /* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */
    bool AbandonTransaction(const uint256& hashTx);

    /** Mark a transaction as replaced by another transaction (e.g., BIP 125). */
    bool MarkReplaced(const uint256& originalHash, const uint256& newHash);

    /* Returns the wallets help message */
    static std::string GetWalletHelpString(bool showDebug);

    /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */
    static CWallet* CreateWalletFromFile(const std::string walletFile);
    static bool InitLoadWallet();

    /**
     * Wallet post-init setup
     * Gives the wallet a chance to register repetitive tasks and complete post-init tasks
     */
    void postInitProcess(boost::thread_group& threadGroup);

    /* Wallets parameter interaction */
    static bool ParameterInteraction();

    bool BackupWallet(const std::string& strDest);

    /* Set the HD chain model (chain child index counters) */
    bool SetHDChain(const CHDChain& chain, bool memonly, bool& upgradeChain, bool genNewKeyPool = true);
    bool SetHDChain(const CHDChain& chain, bool memonly) { bool upgradeChain = DEFAULT_UPGRADE_CHAIN; return SetHDChain(chain, memonly, upgradeChain); }
    const CHDChain& GetHDChain() { return hdChain; }

    bool SetMnemonicContainer(const MnemonicContainer& mnContainer, bool memonly);
    const MnemonicContainer& GetMnemonicContainer() { return mnemonicContainer; }

    bool EncryptMnemonicContainer(const CKeyingMaterial& vMasterKeyIn);
    bool DecryptMnemonicContainer(MnemonicContainer& mnContainer);

    void GenerateNewMnemonic();

    /* Returns true if HD is enabled */
    bool IsHDEnabled();

    /* Generates a new HD master key (will not be activated) */
    CPubKey GenerateNewHDMasterKey();

    /* Set the current HD master key (will reset the chain child index counters) */
    bool SetHDMasterKey(const CPubKey& key, const int cHDChainVersion=CHDChain().CURRENT_VERSION);

    /**************************************************************************/
    /* bip47 */
    /* Generates and strores a new payment code for receiving*/
    bip47::CPaymentCode GeneratePcode(std::string const & label);

    /*Prepares and sends a notification tx using Lelantus facilities*/
    CWalletTx PrepareAndSendNotificationTx(bip47::CPaymentCode const & theirPcode);

    /* Lists all receiving pcodes as tuples of (pcode, label, notification address) */
    std::vector<bip47::CPaymentCodeDescription> ListPcodes();

    /* Creates a payment channel for their payment code. */
    bip47::CPaymentChannel & SetupPchannel(bip47::CPaymentCode const & theirPcode);

    /* Stores the notification tx id into the wallet database */
    void SetNotificationTxId(bip47::CPaymentCode const & theirPcode, uint256 const & txid);

    /* Returns next unused address for their payment code. Throws if no payment channel was setup */
    CBitcoinAddress GetTheirNextAddress(bip47::CPaymentCode const & theirPcode) const;

    /* Returns and stores a next unused address for their payment code. Throws if no payment channel was setup */
    CBitcoinAddress GenerateTheirNextAddress(bip47::CPaymentCode const & theirPcode);

    /*Loads previously stored bip47 accounts */
    void LoadBip47Wallet();

    std::shared_ptr<bip47::CWallet const>  GetBip47Wallet() const;

    boost::optional<bip47::CPaymentCodeDescription> FindPcode(bip47::CPaymentCode const & pcode) const;
    boost::optional<bip47::CPaymentCodeDescription> FindPcode(CBitcoinAddress const & address) const;

    /*Marks address as used for a receiving bip47 account. Returns the account if found*/
    bip47::CAccountReceiver const * AddressUsed(CBitcoinAddress const & address);

    /*Checks if this is a BIP47 transaction and handles it. May send an unlock request if wallet is locked.*/
    void HandleBip47Transaction(CWalletTx const & wtx);

    /*Attaches a new label to a sending payment code.*/
    void LabelSendingPcode(bip47::CPaymentCode const & pcode, std::string const & label, bool remove = false);
    std::string GetSendingPcodeLabel(bip47::CPaymentCode const & pcode) const;

    /*Relabels an existing receiving payment code*/
    void LabelReceivingPcode(bip47::CPaymentCode const & pcode, std::string const & label);

    /*Sets used address number for a sending or receiving payment channel*/
    size_t SetUsedAddressNumber(bip47::CPaymentCode const & pcode, size_t number);

    void NotifyTransactionLock(const CTransaction &tx) override;
    void NotifyChainLock(const CBlockIndex* pindexChainLock) override;
};

/** A key allocated from the key pool. */
class CReserveKey : public CReserveScript
{
protected:
    CWallet* pwallet;
    int64_t nIndex;
    CPubKey vchPubKey;
public:
    CReserveKey(CWallet* pwalletIn)
    {
        nIndex = -1;
        pwallet = pwalletIn;
    }

    ~CReserveKey()
    {
        ReturnKey();
    }

    void ReturnKey();
    bool GetReservedKey(CPubKey &pubkey);
    void KeepKey();
    void KeepScript() { KeepKey(); }
};


/**
 * Account information.
 * Stored in wallet with key "acc"+string account name.
 */
class CAccount
{
public:
    CPubKey vchPubKey;

    CAccount()
    {
        SetNull();
    }

    void SetNull()
    {
        vchPubKey = CPubKey();
    }

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        int nVersion = s.GetVersion();
        if (!(s.GetType() & SER_GETHASH))
            READWRITE(nVersion);
        READWRITE(vchPubKey);
    }
};

bool CompSigmaHeight(const CSigmaEntry& a, const CSigmaEntry& b);
bool CompSigmaID(const CSigmaEntry& a, const CSigmaEntry& b);

// Helper for producing a bunch of max-sized low-S signatures (eg 72 bytes)
// ContainerType is meant to hold pair<CWalletTx *, int>, and be iterable
// so that each entry corresponds to each vIn, in order.
template <typename ContainerType>
bool CWallet::DummySignTx(CMutableTransaction &txNew, const ContainerType &coins)
{
    // Fill in dummy signatures for fee calculation.
    int nIn = 0;
    for (const auto& coin : coins)
    {
        const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey;
        SignatureData sigdata;

        if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata))
        {
            return false;
        } else {
            UpdateTransaction(txNew, nIn, sigdata);
        }

        nIn++;
    }
    return true;
}

CWalletTx PrepareAndSendNotificationTx(CWallet* pwallet, bip47::CPaymentCode const & theirPcode);

#endif // BITCOIN_WALLET_WALLET_H

<MSG> Fixing bitcoin API change problems due to PR merges part #3

<DFF> @@ -688,6 +688,8 @@ private:
     void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);
     void AddToSpends(const uint256& wtxid);
 
+    std::set<COutPoint> setWalletUTXO;
+
     /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */
     void MarkConflicted(const uint256& hashBlock, const uint256& hashTx);
 

{'commit': 'diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp\nindex fd6afe1e4..476a92416 100644\n--- a/src/qt/bitcoingui.cpp\n+++ b/src/qt/bitcoingui.cpp\n@@ -593,7 +593,7 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel)\n         setNumBlocks(_clientModel->getNumBlocks(), _clientModel->getLastBlockDate(), _clientModel->getVerificationProgress(NULL), false);\n         connect(_clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool)));\n \n-        connect(clientModel, SIGNAL(additionalDataSyncProgressChanged(int, double)), this, SLOT(setAdditionalDataSyncProgress(int, double)));\n+        connect(clientModel, SIGNAL(additionalDataSyncProgressChanged(double)), this, SLOT(setAdditionalDataSyncProgress(double)));\n \n         // Receive and report messages from client model\n         connect(_clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));\n@@ -1046,7 +1046,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer\n }\n \n \n-void BitcoinGUI::setAdditionalDataSyncProgress(int count, double nSyncProgress)\n+void BitcoinGUI::setAdditionalDataSyncProgress(double nSyncProgress)\n {\n     if(!clientModel)\n         return;\n@@ -1055,7 +1055,10 @@ void BitcoinGUI::setAdditionalDataSyncProgress(int count, double nSyncProgress)\n     statusBar()->clearMessage();\n \n     QString tooltip;\n-    tooltip = tr("Processed %n block(s) of transaction history.", "", count);\n+\n+    // Set icon state: spinning if catching up, tick otherwise\n+    QString strSyncStatus;\n+    tooltip = tr("Up to date") + QString(".<br>") + tooltip;\n \n     // Set icon state: spinning if catching up, tick otherwise\n \ndiff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h\nindex cdf615978..0747bb362 100644\n--- a/src/qt/bitcoingui.h\n+++ b/src/qt/bitcoingui.h\n@@ -174,7 +174,7 @@ public Q_SLOTS:\n     /** Set number of blocks and last block date shown in the UI */\n     void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers);\n     /** Set additional data sync status shown in the UI */\n-    void setAdditionalDataSyncProgress(int count, double nSyncProgress);\n+    void setAdditionalDataSyncProgress(double nSyncProgress);\n \n     /** Notify the user of an event from the core network or transaction handling code.\n        @param[in] title     the message box / notification title\ndiff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp\nindex 69c9d6437..687c81467 100644\n--- a/src/qt/clientmodel.cpp\n+++ b/src/qt/clientmodel.cpp\n@@ -341,9 +341,9 @@ static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConn\n                               Q_ARG(int, newNumConnections));\n }\n \n-static void NotifyAdditionalDataSyncProgressChanged(ClientModel *clientmodel, int count, double nSyncProgress)\n+static void NotifyAdditionalDataSyncProgressChanged(ClientModel *clientmodel, double nSyncProgress)\n {\n-    QMetaObject::invokeMethod(clientmodel, "additionalDataSyncProgressChanged", Qt::QueuedConnection, Q_ARG(int, count),\n+    QMetaObject::invokeMethod(clientmodel, "additionalDataSyncProgressChanged", Qt::QueuedConnection,\n                               Q_ARG(double, nSyncProgress));\n }\n \n@@ -403,7 +403,7 @@ void ClientModel::subscribeToCoreSignals()\n     uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));\n     uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false));\n     uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true));\n-    uiInterface.NotifyAdditionalDataSyncProgressChanged.connect(boost::bind(NotifyAdditionalDataSyncProgressChanged, this, _1, _2));\n+    uiInterface.NotifyAdditionalDataSyncProgressChanged.connect(boost::bind(NotifyAdditionalDataSyncProgressChanged, this, _1));\n \n     // Connect Exodus signals\n     uiInterface.ExodusStateChanged.connect(boost::bind(ExodusStateChanged, this));\n@@ -422,7 +422,7 @@ void ClientModel::unsubscribeFromCoreSignals()\n     uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));\n     uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false));\n     uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true));\n-    uiInterface.NotifyAdditionalDataSyncProgressChanged.disconnect(boost::bind(NotifyAdditionalDataSyncProgressChanged, this, _1, _2));\n+    uiInterface.NotifyAdditionalDataSyncProgressChanged.disconnect(boost::bind(NotifyAdditionalDataSyncProgressChanged, this, _1));\n \n     // Disconnect Exodus signals\n     uiInterface.ExodusStateChanged.disconnect(boost::bind(ExodusStateChanged, this));\ndiff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h\nindex 902aec5dd..bf477cb64 100644\n--- a/src/qt/clientmodel.h\n+++ b/src/qt/clientmodel.h\n@@ -112,7 +112,7 @@ Q_SIGNALS:\n     void networkActiveChanged(bool networkActive);\n     void alertsChanged(const QString &warnings);\n     void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);\n-    void additionalDataSyncProgressChanged(int count, double nSyncProgress);\n+    void additionalDataSyncProgressChanged(double nSyncProgress);\n \n     // Additional Exodus signals\n     void reinitExodusState();\ndiff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp\nindex 5e8a5789d..4e53ce64c 100644\n--- a/src/qt/walletmodel.cpp\n+++ b/src/qt/walletmodel.cpp\n@@ -844,9 +844,14 @@ bool WalletModel::rebroadcastTransaction(uint256 hash)\n         return false;\n \n     CCoinsViewCache &view = *pcoinsTip;\n-    const CCoins* existingCoins = view.AccessCoins(hash);\n+    bool fHaveChain = false;\n+    for (size_t i=0; i<wtx->tx->vout.size() && !fHaveChain; i++) {\n+        if (view.HaveCoin(COutPoint(hash, i)))\n+            fHaveChain = true;\n+    }\n+\n     bool fHaveMempool = mempool.exists(hash);\n-    bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;\n+\n     if (!fHaveMempool && !fHaveChain) {\n         // push to local node and sync with wallets\n         CValidationState state;\ndiff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp\nindex 16252232a..def526908 100644\n--- a/src/wallet/wallet.cpp\n+++ b/src/wallet/wallet.cpp\n@@ -8360,9 +8360,6 @@ int CMerkleTx::GetDepthInMainChain(const CBlockIndex *&pindexRet, bool enableIX)\n         }\n     }\n \n-    if (enableIX && nResult < 6 && instantsend.IsLockedInstantSendTransaction(GetHash()))\n-        return nInstantSendDepth + nResult;\n-\n     return nResult;\n }\n \ndiff --git a/src/wallet/wallet.h b/src/wallet/wallet.h\nindex 8071d899b..aabf25558 100644\n--- a/src/wallet/wallet.h\n+++ b/src/wallet/wallet.h\n@@ -688,6 +688,8 @@ private:\n     void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);\n     void AddToSpends(const uint256& wtxid);\n \n+    std::set<COutPoint> setWalletUTXO;\n+\n     /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */\n     void MarkConflicted(const uint256& hashBlock, const uint256& hashTx);\n \ndiff --git a/src/znode-sync.cpp b/src/znode-sync.cpp\nindex 077b47a75..5128e724f 100644\n--- a/src/znode-sync.cpp\n+++ b/src/znode-sync.cpp\n@@ -259,7 +259,7 @@ void CZnodeSync::ProcessTick() {\n     // INITIAL SYNC SETUP / LOG REPORTING\n     double nSyncProgress = double(nRequestedZnodeAttempt + (nRequestedZnodeAssets - 1) * 8) / (8 * 4);\n     LogPrint("ProcessTick", "CZnodeSync::ProcessTick -- nTick %d nRequestedZnodeAssets %d nRequestedZnodeAttempt %d nSyncProgress %f\\n", nTick, nRequestedZnodeAssets, nRequestedZnodeAttempt, nSyncProgress);\n-    uiInterface.NotifyAdditionalDataSyncProgressChanged(pCurrentBlockIndex->nHeight, nSyncProgress);\n+    uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress);\n \n     // RESET SYNCING INCASE OF FAILURE\n     {\n', 'commit_subject': 'Fixing bitcoin API change problems due to PR merges part #3', 'repo_name': 'zcoinofficial/zcoin', 'committer': {'name': 'Peter Shugalev', 'email': '4b8373d016f277527198385ba72fda0feb5da015@shugalev.com', 'time_sec': '1584344608', 'tz_offset': '180', 'date': {'seconds': '1584344608'}}, 'commit_tree': 'bdf28c6781c0dd16984744b3adce03018952e293', 'commit_message': 'Fixing bitcoin API change problems due to PR merges part #3\n', 'language_name': 'C++', 'license': 'mit', 'hunks': '@@ -688,6 +688,8 @@ private:\n     void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);\n     void AddToSpends(const uint256& wtxid);\n \n+    std::set<COutPoint> setWalletUTXO;\n+\n     /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */\n     void MarkConflicted(const uint256& hashBlock, const uint256& hashTx);\n \n', 'addition_count': 2, 'deletion_count': 0, 'src_file': 'a/src/wallet/wallet.h', 'tgt_file': 'b/src/wallet/wallet.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_WALLET_WALLET_H\n#define BITCOIN_WALLET_WALLET_H\n\n#include "amount.h"\n#include "../sigma/coin.h"\n#include "../liblelantus/coin.h"\n#include "streams.h"\n#include "tinyformat.h"\n#include "ui_interface.h"\n#include "utilstrencodings.h"\n#include "validationinterface.h"\n#include "script/ismine.h"\n#include "script/sign.h"\n#include "wallet/crypter.h"\n#include "wallet/walletdb.h"\n#include "wallet/rpcwallet.h"\n#include "wallet/mnemoniccontainer.h"\n#include "../base58.h"\n#include "firo_params.h"\n#include "univalue.h"\n\n#include "hdmint/tracker.h"\n#include "hdmint/wallet.h"\n\n#include "primitives/mint_spend.h"\n\n#include "bip47/paymentcode.h"\n\n\n#include <algorithm>\n#include <atomic>\n#include <map>\n#include <set>\n#include <stdexcept>\n#include <stdint.h>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include <boost/shared_ptr.hpp>\n#include <boost/thread.hpp>\n\nextern CWallet* pwalletMain;\n\n/**\n * Settings\n */\nextern CFeeRate payTxFee;\nextern unsigned int nTxConfirmTarget;\nextern bool bSpendZeroConfChange;\nextern bool fSendFreeTransactions;\nextern bool fWalletRbf;\n\nstatic const unsigned int DEFAULT_KEYPOOL_SIZE = 100;\n//! -paytxfee default\nstatic const CAmount DEFAULT_TRANSACTION_FEE = 0;\n//! -fallbackfee default\nstatic const CAmount DEFAULT_FALLBACK_FEE = 20000;\n//! -mintxfee default\nstatic const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;\n//! minimum recommended increment for BIP 125 replacement txs\nstatic const CAmount WALLET_INCREMENTAL_RELAY_FEE = 5000;\n//! target minimum change amount\nstatic const CAmount MIN_CHANGE = CENT;\n//! final minimum change amount after paying for fees\nstatic const CAmount MIN_FINAL_CHANGE = MIN_CHANGE/2;\n//! Default for -spendzeroconfchange\nstatic const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true;\n//! Default for -sendfreetransactions\nstatic const bool DEFAULT_SEND_FREE_TRANSACTIONS = false;\n//! Default for -walletrejectlongchains\nstatic const bool DEFAULT_WALLET_REJECT_LONG_CHAINS = false;\n//! -txconfirmtarget default\nstatic const unsigned int DEFAULT_TX_CONFIRM_TARGET = 6;\n//! -walletrbf default\nstatic const bool DEFAULT_WALLET_RBF = false;\n//! Largest (in bytes) free transaction we\'re willing to create\nstatic const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;\nstatic const bool DEFAULT_WALLETBROADCAST = true;\nstatic const bool DEFAULT_DISABLE_WALLET = false;\n\nstatic const bool DEFAULT_UPGRADE_CHAIN = false;\n\n//! if set, all keys will be derived by using BIP32\nstatic const bool DEFAULT_USE_HD_WALLET = true;\n\n//! if set, all keys will be derived by using BIP39\nstatic const bool DEFAULT_USE_MNEMONIC = true;\n\nextern const char * DEFAULT_WALLET_DAT;\n\nconst uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;\nconst uint32_t BIP44_INDEX = 0x2C;\nconst uint32_t BIP44_TEST_INDEX = 0x1;   // https://github.com/satoshilabs/slips/blob/master/slip-0044.md#registered-coin-types\nconst uint32_t BIP44_FIRO_INDEX = 0x88; // https://github.com/satoshilabs/slips/blob/master/slip-0044.md#registered-coin-types\nconst uint32_t BIP44_MINT_INDEX = 0x2;\n#ifdef ENABLE_ELYSIUM\nconst uint32_t BIP44_ELYSIUM_MINT_INDEX_V0 = 0x3;\nconst uint32_t BIP44_ELYSIUM_MINT_INDEX_V1 = 0x4;\n#endif\nconst uint32_t BIP44_MINT_VALUE_INDEX = 0x5;\n\nclass CBlockIndex;\nclass CCoinControl;\nclass COutput;\nclass CReserveKey;\nclass CScript;\nclass CTxMemPool;\nclass CWalletTx;\nnamespace bip47 {\nclass CPaymentChannel;\n}\n\n\nnamespace bip47 {\n    class CPaymentCode;\n    class CWallet;\n}\n\n/** (client) version numbers for particular wallet features */\nenum WalletFeature\n{\n    FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo\'s clientversion output)\n\n    FEATURE_WALLETCRYPT = 40000, // wallet encryption\n    FEATURE_COMPRPUBKEY = 60000, // compressed public keys\n\n    FEATURE_HD = 130000, // Hierarchical key derivation after BIP32 (HD Wallet)\n    FEATURE_LATEST = FEATURE_COMPRPUBKEY // HD is optional, use FEATURE_COMPRPUBKEY as latest version\n};\n\nstruct CompactTallyItem\n{\n    CBitcoinAddress address;\n    CAmount nAmount;\n    std::vector<CTxIn> vecTxIn;\n    CompactTallyItem()\n    {\n        nAmount = 0;\n    }\n};\n\n\n/** A key pool entry */\nclass CKeyPool\n{\npublic:\n    int64_t nTime;\n    CPubKey vchPubKey;\n\n    CKeyPool();\n    CKeyPool(const CPubKey& vchPubKeyIn);\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream& s, Operation ser_action) {\n        int nVersion = s.GetVersion();\n        if (!(s.GetType() & SER_GETHASH))\n            READWRITE(nVersion);\n        READWRITE(nTime);\n        READWRITE(vchPubKey);\n    }\n};\n\n/** Address book data */\nclass CAddressBookData\n{\npublic:\n    std::string name;\n    std::string purpose;\n\n    CAddressBookData()\n    {\n        purpose = "unknown";\n    }\n\n    typedef std::map<std::string, std::string> StringMap;\n    StringMap destdata;\n};\n\nstruct CRecipient\n{\n    CScript scriptPubKey;\n    CAmount nAmount;\n    bool fSubtractFeeFromAmount;\n};\n\ntypedef std::map<std::string, std::string> mapValue_t;\n\n\nstatic inline void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)\n{\n    if (!mapValue.count("n"))\n    {\n        nOrderPos = -1; // TODO: calculate elsewhere\n        return;\n    }\n    nOrderPos = atoi64(mapValue["n"].c_str());\n}\n\n\nstatic inline void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)\n{\n    if (nOrderPos == -1)\n        return;\n    mapValue["n"] = i64tostr(nOrderPos);\n}\n\nstruct COutputEntry\n{\n    CTxDestination destination;\n    CAmount amount;\n    int vout;\n};\n\n/** A transaction with a merkle branch linking it to the block chain. */\nclass CMerkleTx\n{\nprivate:\n  /** Constant used in hashBlock to indicate tx has been abandoned */\n    static const uint256 ABANDON_HASH;\n\npublic:\n    CTransactionRef tx;\n    uint256 hashBlock;\n\n    /* An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest\n     * block in the chain we know this or any in-wallet dependency conflicts\n     * with. Older clients interpret nIndex == -1 as unconfirmed for backward\n     * compatibility.\n     */\n    int nIndex;\n\n    CMerkleTx()\n    {\n        SetTx(MakeTransactionRef());\n        Init();\n    }\n\n    CMerkleTx(CTransactionRef arg)\n    {\n        SetTx(std::move(arg));\n        Init();\n    }\n\n    /** Helper conversion operator to allow passing CMerkleTx where CTransaction is expected.\n     *  TODO: adapt callers and remove this operator. */\n    operator const CTransaction&() const { return *tx; }\n\n    void Init()\n    {\n        hashBlock = uint256();\n        nIndex = -1;\n    }\n\n    void SetTx(CTransactionRef arg)\n    {\n        tx = std::move(arg);\n    }\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream& s, Operation ser_action) {\n        std::vector<uint256> vMerkleBranch; // For compatibility with older versions.\n        READWRITE(tx);\n        READWRITE(hashBlock);\n        READWRITE(vMerkleBranch);\n        READWRITE(nIndex);\n    }\n\n    void SetMerkleBranch(const CBlockIndex* pIndex, int posInBlock);\n\n    /**\n     * Return depth of transaction in blockchain:\n     * <0  : conflicts with a transaction this deep in the blockchain\n     *  0  : in memory pool, waiting to be included in a block\n     * >=1 : this many blocks deep in the main chain\n     */\n    int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;\n    int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }\n\n    int GetDepthInMainChain(const CBlockIndex* &pindexRet, bool enableIX) const;\n    int GetDepthInMainChain(bool enableIX) const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet, enableIX); }\n\n    bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; }\n    bool IsLockedByLLMQInstantSend() const;\n    bool IsChainLocked() const;\n    int GetBlocksToMaturity() const;\n\n    bool AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state);\n    bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }\n    bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }\n    void setAbandoned() { hashBlock = ABANDON_HASH; }\n\n    const uint256& GetHash() const { return tx->GetHash(); }\n    bool IsCoinBase() const { return tx->IsCoinBase(); }\n};\n\n/**\n * A transaction with a bunch of additional info that only the owner cares about.\n * It includes any unrecorded transactions needed to link it back to the block chain.\n */\nclass CWalletTx : public CMerkleTx\n{\nprivate:\n    const CWallet* pwallet;\n\npublic:\n    mapValue_t mapValue;\n    std::vector<std::pair<std::string, std::string> > vOrderForm;\n    unsigned int fTimeReceivedIsTxTime;\n    unsigned int nTimeReceived; //!< time received by this node\n    unsigned int nTimeSmart;\n    /**\n     * From me flag is set to 1 for transactions that were created by the wallet\n     * on this bitcoin node, and set to 0 for transactions that were created\n     * externally and came in through the network or sendrawtransaction RPC.\n     */\n    char fFromMe;\n    std::string strFromAccount;\n    int64_t nOrderPos; //!< position in ordered transaction list\n    std::unordered_set<uint32_t> changes; //!< positions of changes in vout\n\n    // memory only\n    mutable bool fDebitCached;\n    mutable bool fCreditCached;\n    mutable bool fImmatureCreditCached;\n    mutable bool fAvailableCreditCached;\n    mutable bool fWatchDebitCached;\n    mutable bool fWatchCreditCached;\n    mutable bool fImmatureWatchCreditCached;\n    mutable bool fAvailableWatchCreditCached;\n    mutable bool fChangeCached;\n    mutable CAmount nDebitCached;\n    mutable CAmount nCreditCached;\n    mutable CAmount nImmatureCreditCached;\n    mutable CAmount nAvailableCreditCached;\n    mutable CAmount nWatchDebitCached;\n    mutable CAmount nWatchCreditCached;\n    mutable CAmount nImmatureWatchCreditCached;\n    mutable CAmount nAvailableWatchCreditCached;\n    mutable CAmount nChangeCached;\n\n    CWalletTx()\n    {\n        Init(NULL);\n    }\n\n    CWalletTx(const CWallet* pwalletIn, CTransactionRef arg) : CMerkleTx(std::move(arg))\n    {\n        Init(pwalletIn);\n    }\n\n    void Init(const CWallet* pwalletIn)\n    {\n        pwallet = pwalletIn;\n        mapValue.clear();\n        vOrderForm.clear();\n        fTimeReceivedIsTxTime = false;\n        nTimeReceived = 0;\n        nTimeSmart = 0;\n        fFromMe = false;\n        strFromAccount.clear();\n        fDebitCached = false;\n        fCreditCached = false;\n        fImmatureCreditCached = false;\n        fAvailableCreditCached = false;\n        fWatchDebitCached = false;\n        fWatchCreditCached = false;\n        fImmatureWatchCreditCached = false;\n        fAvailableWatchCreditCached = false;\n        fChangeCached = false;\n        nDebitCached = 0;\n        nCreditCached = 0;\n        nImmatureCreditCached = 0;\n        nAvailableCreditCached = 0;\n        nWatchDebitCached = 0;\n        nWatchCreditCached = 0;\n        nAvailableWatchCreditCached = 0;\n        nImmatureWatchCreditCached = 0;\n        nChangeCached = 0;\n        nOrderPos = -1;\n        changes.clear();\n    }\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream& s, Operation ser_action) {\n        constexpr uint32_t FLAG_WITH_CHANGES = 0x00000001;\n\n        if (ser_action.ForRead())\n            Init(NULL);\n\n        char fSpent = false;\n        uint32_t flags = 0;\n\n        if (!ser_action.ForRead())\n        {\n            flags = FLAG_WITH_CHANGES;\n\n            mapValue["fromaccount"] = strFromAccount;\n            mapValue["flags"] = strprintf("0x%x", flags);\n\n            WriteOrderPos(nOrderPos, mapValue);\n\n            if (nTimeSmart)\n                mapValue["timesmart"] = strprintf("%u", nTimeSmart);\n        }\n\n        READWRITE(*(CMerkleTx*)this);\n        std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev\n        READWRITE(vUnused);\n        READWRITE(mapValue);\n        READWRITE(vOrderForm);\n        READWRITE(fTimeReceivedIsTxTime);\n        READWRITE(nTimeReceived);\n        READWRITE(fFromMe);\n        READWRITE(fSpent);\n\n        if (ser_action.ForRead())\n        {\n            strFromAccount = mapValue["fromaccount"];\n\n            ReadOrderPos(nOrderPos, mapValue);\n\n            nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;\n\n            auto it = mapValue.find("flags");\n            if (it != mapValue.end()) {\n                flags = static_cast<uint32_t>(std::strtoul(it->second.c_str(), nullptr, 0));\n            }\n        }\n\n        if (flags & FLAG_WITH_CHANGES) {\n            READWRITE(changes);\n        }\n\n        mapValue.erase("fromaccount");\n        mapValue.erase("version");\n        mapValue.erase("spent");\n        mapValue.erase("n");\n        mapValue.erase("timesmart");\n        mapValue.erase("flags");\n    }\n\n    //! make sure balances are recalculated\n    void MarkDirty()\n    {\n        fCreditCached = false;\n        fAvailableCreditCached = false;\n        fImmatureCreditCached = false;\n        fWatchDebitCached = false;\n        fWatchCreditCached = false;\n        fAvailableWatchCreditCached = false;\n        fImmatureWatchCreditCached = false;\n        fDebitCached = false;\n        fChangeCached = false;\n    }\n\n    void BindWallet(CWallet *pwalletIn)\n    {\n        pwallet = pwalletIn;\n        MarkDirty();\n    }\n\n    //! filter decides which addresses will count towards the debit\n    CAmount GetDebit(const isminefilter& filter) const;\n    CAmount GetCredit(const isminefilter& filter) const;\n    CAmount GetImmatureCredit(bool fUseCache=true) const;\n    CAmount GetAvailableCredit(bool fUseCache=true, bool fExcludeLocked = false) const;\n    CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const;\n    CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const;\n    CAmount GetAnonymizedCredit(bool fUseCache=true) const;\n    CAmount GetChange() const;\n\n    void GetAmounts(std::list<COutputEntry>& listReceived,\n                    std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const;\n\n    bool IsFromMe(const isminefilter& filter) const\n    {\n        return (GetDebit(filter) > 0);\n    }\n\n    // True if only scriptSigs are different\n    bool IsEquivalentTo(const CWalletTx& tx) const;\n\n    bool InMempool() const;\n    bool InStempool() const;\n    bool IsTrusted() const;\n\n    bool IsChange(uint32_t out) const;\n    bool IsChange(const CTxOut& out) const;\n\n    int64_t GetTxTime() const;\n    int GetRequestCount() const;\n\n    bool RelayWalletTransaction(CConnman* connman);\n\n    std::set<uint256> GetConflicts() const;\n};\n\n\n\n\nclass COutput\n{\npublic:\n    const CWalletTx *tx;\n    int i;\n    int nDepth;\n    bool fSpendable;\n    bool fSolvable;\n\n    COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn, bool fSolvableIn)\n    {\n        tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; fSolvable = fSolvableIn;\n    }\n\n    std::string ToString() const;\n};\n\n\n\n\n/** Private key that includes an expiration date in case it never gets used. */\nclass CWalletKey\n{\npublic:\n    CPrivKey vchPrivKey;\n    int64_t nTimeCreated;\n    int64_t nTimeExpires;\n    std::string strComment;\n    //! todo: add something to note what created it (user, getnewaddress, change)\n    //!   maybe should have a map<string, string> property map\n\n    CWalletKey(int64_t nExpires=0);\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream& s, Operation ser_action) {\n        int nVersion = s.GetVersion();\n        if (!(s.GetType() & SER_GETHASH))\n            READWRITE(nVersion);\n        READWRITE(vchPrivKey);\n        READWRITE(nTimeCreated);\n        READWRITE(nTimeExpires);\n        READWRITE(LIMITED_STRING(strComment, 65536));\n    }\n};\n\n/**\n * Internal transfers.\n * Database key is acentry<account><counter>.\n */\nclass CAccountingEntry\n{\npublic:\n    std::string strAccount;\n    CAmount nCreditDebit;\n    int64_t nTime;\n    std::string strOtherAccount;\n    std::string strComment;\n    mapValue_t mapValue;\n    int64_t nOrderPos; //!< position in ordered transaction list\n    uint64_t nEntryNo;\n\n    CAccountingEntry()\n    {\n        SetNull();\n    }\n\n    void SetNull()\n    {\n        nCreditDebit = 0;\n        nTime = 0;\n        strAccount.clear();\n        strOtherAccount.clear();\n        strComment.clear();\n        nOrderPos = -1;\n        nEntryNo = 0;\n    }\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream& s, Operation ser_action) {\n        int nVersion = s.GetVersion();\n        if (!(s.GetType() & SER_GETHASH))\n            READWRITE(nVersion);\n        //! Note: strAccount is serialized as part of the key, not here.\n        READWRITE(nCreditDebit);\n        READWRITE(nTime);\n        READWRITE(LIMITED_STRING(strOtherAccount, 65536));\n\n        if (!ser_action.ForRead())\n        {\n            WriteOrderPos(nOrderPos, mapValue);\n\n            if (!(mapValue.empty() && _ssExtra.empty()))\n            {\n                CDataStream ss(s.GetType(), s.GetVersion());\n                ss.insert(ss.begin(), \'\\0\');\n                ss << mapValue;\n                ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end());\n                strComment.append(ss.str());\n            }\n        }\n\n        READWRITE(LIMITED_STRING(strComment, 65536));\n\n        size_t nSepPos = strComment.find("\\0", 0, 1);\n        if (ser_action.ForRead())\n        {\n            mapValue.clear();\n            if (std::string::npos != nSepPos)\n            {\n                CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), s.GetType(), s.GetVersion());\n                ss >> mapValue;\n                _ssExtra = std::vector<char>(ss.begin(), ss.end());\n            }\n            ReadOrderPos(nOrderPos, mapValue);\n        }\n        if (std::string::npos != nSepPos)\n            strComment.erase(nSepPos);\n\n        mapValue.erase("n");\n    }\n\nprivate:\n    std::vector<char> _ssExtra;\n};\n\nclass LelantusJoinSplitBuilder;\n\n/**\n * A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,\n * and provides the ability to create new transactions.\n */\nclass CWallet : public CCryptoKeyStore, public CValidationInterface\n{\nprivate:\n    static std::atomic<bool> fFlushThreadRunning;\n\n    /**\n     * Select a set of coins such that nValueRet >= nTargetValue and at least\n     * all coins from coinControl are selected; Never select unconfirmed coins\n     * if they are not ours\n     */\n    bool SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL, bool fForUseInInstantSend = true) const;\n\n    CWalletDB *pwalletdbEncryption;\n\n    //! the current wallet version: clients below this version are not able to load the wallet\n    int nWalletVersion;\n\n    //! the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded\n    int nWalletMaxVersion;\n\n    int64_t nNextResend;\n    int64_t nLastResend;\n    bool fBroadcastTransactions;\n\n    mutable bool fAnonymizableTallyCached;\n    mutable std::vector<CompactTallyItem> vecAnonymizableTallyCached;\n    mutable bool fAnonymizableTallyCachedNonDenom;\n    mutable std::vector<CompactTallyItem> vecAnonymizableTallyCachedNonDenom;\n\n    /**\n     * Used to keep track of spent outpoints, and\n     * detect and report conflicts (double-spends or\n     * mutated transactions where the mutant gets mined).\n     */\n    typedef std::multimap<COutPoint, uint256> TxSpends;\n    TxSpends mapTxSpends;\n    void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);\n    void AddToSpends(const uint256& wtxid);\n\n    std::set<COutPoint> setWalletUTXO;\n    void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);\n    void AddToSpends(const uint256& wtxid);\n\n    /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */\n    void MarkConflicted(const uint256& hashBlock, const uint256& hashTx);\n\n    MnemonicContainer mnemonicContainer;\n\n    bool fFileBacked;\n\n    std::set<int64_t> setKeyPool;\n\n    std::map<CKeyID, int64_t> m_pool_key_to_index;\n\n    int64_t nTimeFirstKey;\n\n    std::shared_ptr<bip47::CWallet> bip47wallet;\n\n    /**\n     * Private version of AddWatchOnly method which does not accept a\n     * timestamp, and which will reset the wallet\'s nTimeFirstKey value to 1 if\n     * the watch key did not previously have a timestamp associated with it.\n     * Because this is an inherited virtual method, it is accessible despite\n     * being marked private, but it is marked private anyway to encourage use\n     * of the other AddWatchOnly which accepts a timestamp and sets\n     * nTimeFirstKey more intelligently for more efficient rescans.\n     */\n    bool AddWatchOnly(const CScript& dest) override;\n\npublic:\n    /*\n     * Main wallet lock.\n     * This lock protects all the fields added by CWallet\n     *   except for:\n     *      fFileBacked (immutable after instantiation)\n     *      strWalletFile (immutable after instantiation)\n     */\n    mutable CCriticalSection cs_wallet;\n\n    const std::string strWalletFile;\n\n    void LoadKeyPool(int nIndex, const CKeyPool &keypool)\n    {\n        setKeyPool.insert(nIndex);\n\n        m_pool_key_to_index[keypool.vchPubKey.GetID()] = nIndex;\n        // If no metadata exists yet, create a default with the pool key\'s\n        // creation time. Note that this may be overwritten by actually\n        // stored metadata for that key later, which is fine.\n        CKeyID keyid = keypool.vchPubKey.GetID();\n        if (mapKeyMetadata.count(keyid) == 0)\n            mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);\n    }\n\n    // Map from Key ID (for regular keys) or Script ID (for watch-only keys) to\n    // key metadata.\n    std::map<CTxDestination, CKeyMetadata> mapKeyMetadata;\n    //znode\n    int64_t nKeysLeftSinceAutoBackup;\n\n    typedef std::map<unsigned int, CMasterKey> MasterKeyMap;\n    MasterKeyMap mapMasterKeys;\n    unsigned int nMasterKeyMaxID;\n\n    std::unique_ptr<CHDMintWallet> zwallet;\n\n    CWallet()\n    {\n        SetNull();\n    }\n\n    CWallet(const std::string& strWalletFileIn) : strWalletFile(strWalletFileIn)\n    {\n        SetNull();\n        fFileBacked = true;\n    }\n\n    ~CWallet()\n    {\n        delete pwalletdbEncryption;\n        pwalletdbEncryption = NULL;\n    }\n\n    void SetNull()\n    {\n        nWalletVersion = FEATURE_BASE;\n        nWalletMaxVersion = FEATURE_BASE;\n        fFileBacked = false;\n        nMasterKeyMaxID = 0;\n        pwalletdbEncryption = NULL;\n        nOrderPosNext = 0;\n        nNextResend = 0;\n        nLastResend = 0;\n        nTimeFirstKey = 0;\n        fBroadcastTransactions = false;\n        fAnonymizableTallyCached = false;\n        fAnonymizableTallyCachedNonDenom = false;\n        vecAnonymizableTallyCached.clear();\n        vecAnonymizableTallyCachedNonDenom.clear();\n        zwallet = NULL;\n        bip47wallet.reset();\n    }\n\n    std::map<uint256, CWalletTx> mapWallet;\n    std::list<CAccountingEntry> laccentries;\n    bool EraseFromWallet(uint256 hash);\n    typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;\n    typedef std::multimap<int64_t, TxPair > TxItems;\n    TxItems wtxOrdered;\n\n    int64_t nOrderPosNext;\n    std::map<uint256, int> mapRequestCount;\n\n    std::map<CTxDestination, CAddressBookData> mapAddressBook;\n    std::multimap<std::string, std::string> mapCustomKeyValues;\n\n    CPubKey vchDefaultKey;\n\n    std::set<COutPoint> setLockedCoins;\n\n    const CWalletTx* GetWalletTx(const uint256& hash) const;\n\n    //! check whether we are allowed to upgrade (or already support) to the named feature\n    bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }\n\n    /**\n     * populate vCoins with vector of available COutputs.\n     */\n    void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL, bool fIncludeZeroValue=false, bool fForUseInInstantSend = false) const;\n\n    void AvailableCoinsForLMint(std::vector<std::pair<CAmount, std::vector<COutput>>>& valueAndUTXO, const CCoinControl *coinControl) const;\n\n    bool IsHDSeedAvailable() { return !hdChain.masterKeyID.IsNull(); }\n\n    /**\n     * Shuffle and select coins until nTargetValue is reached while avoiding\n     * small change; This method is stochastic for some inputs and upon\n     * completion the coin set and corresponding actual target value is\n     * assembled\n     */\n    bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, uint64_t nMaxAncestors, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, bool fForUseInInstantSend = false) const;\n\n    bool IsSpent(const uint256& hash, unsigned int n) const;\n\n    bool IsLockedCoin(uint256 hash, unsigned int n) const;\n    void LockCoin(const COutPoint& output);\n    void UnlockCoin(const COutPoint& output);\n    void UnlockAllCoins();\n    void ListLockedCoins(std::vector<COutPoint>& vOutpts);\n    void ListProTxCoins(std::vector<COutPoint>& vOutpts);\n\n    bool HasMasternode();\n\n    // znode\n    /// Get 1000 FIRO output and keys which can be used for the Znode\n    bool GetZnodeVinAndKeys(CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet, std::string strTxHash = "", std::string strOutputIndex = "");\n    /// Extract txin information and keys from output\n    bool GetVinAndKeysFromOutput(COutput out, CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet);\n\n    CPubKey GetKeyFromKeypath(uint32_t nChange, uint32_t nChild, CKey& secret);\n    /**\n     * keystore implementation\n     * Generate a new key\n     */\n    CPubKey GenerateNewKey(uint32_t nChange=0, bool fWriteChain=true);\n    void DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret);\n    //! Adds a key to the store, and saves it to disk.\n    bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;\n    //! Adds a key to the store, without saving it to disk (used by LoadWallet)\n    bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }\n    //! Load metadata (used by LoadWallet)\n    bool LoadKeyMetadata(const CTxDestination& pubKey, const CKeyMetadata &metadata);\n\n    bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }\n    void UpdateTimeFirstKey(int64_t nCreateTime);\n\n    //! Adds an encrypted key to the store, and saves it to disk.\n    bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) override;\n    //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)\n    bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);\n    bool AddCScript(const CScript& redeemScript) override;\n    bool LoadCScript(const CScript& redeemScript);\n\n    //! Adds a destination data tuple to the store, and saves it to disk\n    bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value);\n    //! Erases a destination data tuple in the store and on disk\n    bool EraseDestData(const CTxDestination &dest, const std::string &key);\n    //! Adds a destination data tuple to the store, without saving it to disk\n    bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value);\n    //! Look up a destination data tuple in the store, return true if found false otherwise\n    bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const;\n\n    //! Adds a watch-only address to the store, and saves it to disk.\n    bool AddWatchOnly(const CScript& dest, int64_t nCreateTime);\n    bool RemoveWatchOnly(const CScript &dest) override;\n    //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)\n    bool LoadWatchOnly(const CScript &dest);\n\n    //! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock().\n    int64_t nRelockTime;\n\n    bool Unlock(const SecureString& strWalletPassphrase, const bool& fFirstUnlock=false);\n    bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);\n    bool EncryptWallet(const SecureString& strWalletPassphrase);\n\n    void GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const;\n\n    /**\n     * Increment the next transaction order id\n     * @return next transaction order id\n     */\n    int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL);\n    DBErrors ReorderTransactions();\n    bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = "");\n    bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew = false);\n\n    void MarkDirty();\n    bool AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose=true);\n    bool LoadToWallet(const CWalletTx& wtxIn);\n    void SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, int posInBlock) override;\n    bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate);\n    CBlockIndex* ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false, bool fRecoverMnemonic = false);\n    void ReacceptWalletTransactions();\n    void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) override;\n    std::vector<uint256> ResendWalletTransactionsBefore(int64_t nTime, CConnman* connman);\n    CAmount GetBalance(bool fExcludeLocked = false) const;\n    std::pair<CAmount, CAmount> GetPrivateBalance() const;\n    std::pair<CAmount, CAmount> GetPrivateBalance(size_t &confirmed, size_t &unconfirmed) const;\n    CAmount GetUnconfirmedBalance() const;\n    CAmount GetImmatureBalance() const;\n    CAmount GetWatchOnlyBalance() const;\n    CAmount GetUnconfirmedWatchOnlyBalance() const;\n    CAmount GetImmatureWatchOnlyBalance() const;\n    CAmount GetLegacyBalance(const isminefilter& filter, int minDepth, const std::string* account, bool fAddLocked = false) const;\n\n    static std::vector<CRecipient> CreateSigmaMintRecipients(\n        std::vector<sigma::PrivateCoin>& coins,\n        std::vector<CHDMint>& vDMints);\n\n    static CRecipient CreateLelantusMintRecipient(\n        lelantus::PrivateCoin& coin,\n        CHDMint& vDMint,\n        bool generate = true);\n\n    static int GetRequiredCoinCountForAmount(\n        const CAmount& required,\n        const std::vector<sigma::CoinDenomination>& denominations);\n\n    static CAmount SelectMintCoinsForAmount(\n        const CAmount& required,\n        const std::vector<sigma::CoinDenomination>& denominations,\n        std::vector<sigma::CoinDenomination>& coinsOut);\n\n    static CAmount SelectSpendCoinsForAmount(\n        const CAmount& required,\n        const std::list<CSigmaEntry>& coinsIn,\n        std::vector<CSigmaEntry>& coinsOut);\n\n    // Returns a list of unspent and verified coins, I.E. coins which are ready\n    // to be spent.\n    std::list<CSigmaEntry> GetAvailableCoins(const CCoinControl *coinControl = NULL, bool includeUnsafe = false, bool forEstimation = false) const;\n\n    std::list<CLelantusEntry> GetAvailableLelantusCoins(const CCoinControl *coinControl = NULL, bool includeUnsafe = false, bool forEstimation = false) const;\n\n    std::vector<unsigned char> EncryptMintAmount(uint64_t amount, const secp_primitives::GroupElement& pubcoin) const;\n\n    bool DecryptMintAmount(const std::vector<unsigned char>& encryptedValue, const secp_primitives::GroupElement& pubcoin, uint64_t& amount) const;\n\n\n    /** \\brief Selects coins to spend, and coins to re-mint based on the required amount to spend, provided by the user. As the lower denomination now is 0.1 firo, user\'s request will be rounded up to the nearest 0.1. This difference between the user\'s requested value, and the actually spent value will be left to the miners as a fee.\n     * \\param[in] required Required amount to spend.\n     * \\param[out] coinsToSpend_out Coins which user needs to spend.\n     * \\param[out] coinsToMint_out Coins which will be re-minted by the user to get the change back.\n     * \\returns true, if it was possible to spend exactly required(rounded up to 0.1 firo) amount using coins we have.\n     */\n    bool GetCoinsToSpend(\n        CAmount required,\n        std::vector<CSigmaEntry>& coinsToSpend_out,\n        std::vector<sigma::CoinDenomination>& coinsToMint_out,\n        std::list<CSigmaEntry>& coins,\n        const size_t coinsLimit = SIZE_MAX,\n        const CAmount amountLimit = MAX_MONEY,\n        const CCoinControl *coinControl = NULL) const;\n\n    bool GetCoinsToJoinSplit(\n            CAmount required,\n            std::vector<CLelantusEntry>& coinsToSpend_out,\n            CAmount& changeToMint,\n            std::list<CLelantusEntry> coins,\n            const size_t coinsToSpendLimit = SIZE_MAX,\n            const CAmount amountToSpendLimit = MAX_MONEY,\n            const CCoinControl *coinControl = NULL) const;\n\n    /**\n     * Insert additional inputs into the transaction by\n     * calling CreateTransaction();\n     */\n    bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool overrideEstimatedFeeRate, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, bool keepReserveKey = true, const CTxDestination& destChange = CNoDestination());\n\n    /**\n     * Create a new transaction paying the recipients with a set of coins\n     * selected by SelectCoins(); Also create the change output, when needed\n     * @note passing nChangePosInOut as -1 will result in setting a random position\n     */\n    bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,\n                           std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true, int nExtraPayloadSize = 0, bool fUseInstantSend=false);\n\n    /**\n     * Add Mint and Spend functions\n     */\n    void ListAvailableSigmaMintCoins(std::vector <COutput> &vCoins, bool fOnlyConfirmed) const;\n    void ListAvailableLelantusMintCoins(std::vector<COutput> &vCoins, bool fOnlyConfirmed) const;\n\n    bool CreateMintTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,\n                           std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true);\n    bool CreateMintTransaction(CScript pubCoin, int64_t nValue,\n                                       CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl=NULL);\n    bool CreateLelantusMintTransactions(CAmount valueToMint, std::vector<std::pair<CWalletTx, CAmount>>& wtxAndFee,\n                                        CAmount& nAllFeeRet, std::vector<CHDMint>& dMints,\n                                        std::list<CReserveKey>& reservekeys, int& nChangePosInOut,\n                                        std::string& strFailReason, const CCoinControl *coinControl, bool autoMintAll = false, bool sign = true);\n\n    CWalletTx CreateSigmaSpendTransaction(\n        const std::vector<CRecipient>& recipients,\n        CAmount& fee,\n        std::vector<CSigmaEntry>& selected,\n        std::vector<CHDMint>& changes,\n        bool& fChangeAddedToFee,\n        const CCoinControl *coinControl = NULL);\n\n    CWalletTx CreateLelantusJoinSplitTransaction(\n        const std::vector<CRecipient>& recipients,\n        CAmount& fee,\n        const std::vector<CAmount>& newMints,\n        std::vector<CLelantusEntry>& spendCoins,\n        std::vector<CSigmaEntry>& sigmaSpendCoins,\n        std::vector<CHDMint>& mintCoins,\n        const CCoinControl *coinControl = NULL,\n        std::function<void(CTxOut & , LelantusJoinSplitBuilder const &)> modifier = nullptr);\n\n    bool CommitSigmaTransaction(CWalletTx& wtxNew, std::vector<CSigmaEntry>& selectedCoins, std::vector<CHDMint>& changes);\n    bool CommitLelantusTransaction(CWalletTx& wtxNew, std::vector<CLelantusEntry>& spendCoins, std::vector<CSigmaEntry>& sigmaSpendCoins, std::vector<CHDMint>& mintCoins);\n    std::string SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew, bool fAskFee=false);\n    std::string SendMoneyToDestination(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew, bool fAskFee=false);\n\n    std::string MintAndStoreSigma(\n        const std::vector<CRecipient>& vecSend,\n        const std::vector<sigma::PrivateCoin>& privCoins,\n        std::vector<CHDMint> vDMints,\n        CWalletTx &wtxNew,\n        bool fAskFee=false,\n        const CCoinControl *coinControl = NULL);\n\n    std::string MintAndStoreLelantus(\n            const CAmount& value,\n            std::vector<std::pair<CWalletTx, CAmount>>& wtxAndFee,\n            std::vector<CHDMint>& mints,\n            bool autoMintAll = false,\n            bool fAskFee = false,\n            const CCoinControl *coinControl = NULL);\n\n    std::vector<CSigmaEntry> SpendSigma(const std::vector<CRecipient>& recipients, CWalletTx& result);\n    std::vector<CSigmaEntry> SpendSigma(const std::vector<CRecipient>& recipients, CWalletTx& result, CAmount& fee);\n\n    std::vector<CLelantusEntry> JoinSplitLelantus(const std::vector<CRecipient>& recipients, const std::vector<CAmount>& newMints, CWalletTx& result);\n\n    std::pair<CAmount, unsigned int> EstimateJoinSplitFee(CAmount required, bool subtractFeeFromAmount, std::list<CSigmaEntry> sigmaCoins, std::list<CLelantusEntry> coins, const CCoinControl *coinControl);\n\n    bool GetMint(const uint256& hashSerial, CSigmaEntry& sigmaEntry, bool forEstimation = false) const;\n\n    bool GetMint(const uint256& hashSerial, CLelantusEntry& mint, bool forEstimation = false) const;\n\n    bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state);\n\n\n    bool CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason);\n    bool ConvertList(std::vector<CTxIn> vecTxIn, std::vector<CAmount>& vecAmounts);\n\n    void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);\n    bool AddAccountingEntry(const CAccountingEntry&);\n    bool AddAccountingEntry(const CAccountingEntry&, CWalletDB *pwalletdb);\n    template <typename ContainerType>\n    bool DummySignTx(CMutableTransaction &txNew, const ContainerType &coins);\n\n    static CFeeRate minTxFee;\n    static CFeeRate fallbackFee;\n    /**\n     * Estimate the minimum fee considering user set parameters\n     * and the required fee\n     */\n    static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool);\n    /**\n     * Estimate the minimum fee considering required fee and targetFee or if 0\n     * then fee estimation for nConfirmTarget\n     */\n    static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, CAmount targetFee);\n    /**\n     * Return the minimum required fee taking into account the\n     * floating relay fee and user set minimum transaction fee\n     */\n    static CAmount GetRequiredFee(unsigned int nTxBytes);\n\n    bool NewKeyPool();\n    bool TopUpKeyPool(unsigned int kpSize = 0);\n    void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool);\n    void KeepKey(int64_t nIndex);\n    void ReturnKey(int64_t nIndex, const CPubKey& pubkey);\n    bool GetKeyFromPool(CPubKey &key);\n    int64_t GetOldestKeyPoolTime();\n    /**\n     * Marks all keys in the keypool up to and including reserve_key as used.\n     */\n    void MarkReserveKeysAsUsed(int64_t keypool_id);\n    const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; }\n\n    std::set< std::set<CTxDestination> > GetAddressGroupings();\n    std::map<CTxDestination, CAmount> GetAddressBalances();\n\n    std::set<CTxDestination> GetAccountAddresses(const std::string& strAccount) const;\n\n    isminetype IsMine(const CTxIn& txin, const CTransaction& tx) const;\n    /**\n     * Returns amount of debit if the input matches the\n     * filter, otherwise returns 0\n     */\n    CAmount GetDebit(const CTxIn& txin, const CTransaction&tx, const isminefilter& filter) const;\n    isminetype IsMine(const CTxOut& txout) const;\n    CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const;\n    bool IsChange(const uint256& tx, const CTxOut& txout) const;\n    CAmount GetChange(const uint256& tx, const CTxOut& txout) const;\n    bool IsMine(const CTransaction& tx) const;\n    /** should probably be renamed to IsRelevantToMe */\n    bool IsFromMe(const CTransaction& tx) const;\n    CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const;\n    /** Returns whether all of the inputs match the filter */\n    bool IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const;\n    CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const;\n    CAmount GetChange(const CTransaction& tx) const;\n    void SetBestChain(const CBlockLocator& loc) override;\n\n    DBErrors LoadWallet(bool& fFirstRunRet);\n    void AutoLockMasternodeCollaterals();\n    DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx);\n    DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut);\n\n    // Remove all CSigmaEntry and CHDMint objects from WalletDB.\n    DBErrors ZapSigmaMints();\n    // Remove all Lelantus HDMint objects from WalletDB\n    DBErrors ZapLelantusMints();\n\n    bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose);\n\n    bool DelAddressBook(const CTxDestination& address);\n\n    bool UpdatedTransaction(const uint256 &hashTx) override;\n    const std::string& GetAccountName(const CScript& scriptPubKey) const;\n\n    void Inventory(const uint256 &hash) override\n    {\n        {\n            LOCK(cs_wallet);\n            std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);\n            if (mi != mapRequestCount.end())\n                (*mi).second++;\n        }\n    }\n\n    void GetScriptForMining(boost::shared_ptr<CReserveScript> &script) override;\n    void ResetRequestCount(const uint256 &hash) override\n    {\n        LOCK(cs_wallet);\n        mapRequestCount[hash] = 0;\n    };\n\n    unsigned int GetKeyPoolSize()\n    {\n        AssertLockHeld(cs_wallet); // setKeyPool\n        return setKeyPool.size();\n    }\n\n    bool SetDefaultKey(const CPubKey &vchPubKey);\n\n    //! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower\n    bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);\n\n    //! change which version we\'re allowed to upgrade to (note that this does not immediately imply upgrading to that format)\n    bool SetMaxVersion(int nVersion);\n\n    //! get the current wallet format (the oldest client version guaranteed to understand this wallet)\n    int GetVersion() { LOCK(cs_wallet); return nWalletVersion; }\n\n    //! Get wallet transactions that conflict with given transaction (spend same outputs)\n    std::set<uint256> GetConflicts(const uint256& txid) const;\n\n    //! Check if a given transaction has any of its outputs spent by another transaction in the wallet\n    bool HasWalletSpend(const uint256& txid) const;\n\n    //! Flush wallet (bitdb flush)\n    void Flush(bool shutdown=false);\n\n    //! Verify the wallet database and perform salvage if required\n    static bool Verify();\n\n    /**\n     * Address book entry changed.\n     * @note called with lock cs_wallet held.\n     */\n    boost::signals2::signal<void (CWallet *wallet, const CTxDestination\n            &address, const std::string &label, bool isMine,\n            const std::string &purpose,\n            ChangeType status)> NotifyAddressBookChanged;\n\n    /**\n     * Wallet transaction added, removed or updated.\n     * @note called with lock cs_wallet held.\n     */\n    boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx,\n            ChangeType status)> NotifyTransactionChanged;\n    /**\n     * sigma/lelantus entry changed.\n     * @note called with lock cs_wallet held.\n     */\n    boost::signals2::signal<void (CWallet *wallet, const std::string &pubCoin, const std::string &isUsed, ChangeType status)> NotifyZerocoinChanged;\n\n\n    /** Show progress e.g. for rescan */\n    boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;\n\n    /** Watch-only address added */\n    boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;\n\n    /** Payment code added */\n    boost::signals2::signal<void (bip47::CPaymentCodeDescription)> NotifyPcodeCreated;\n\n    /** Payment code labeled */\n    boost::signals2::signal<void (std::string pcode, std::string label, bool removed)> NotifyPcodeLabeled;\n\n    /** Unlock required (for example for adding a privkey to the wallet),  */\n    boost::signals2::signal<void (int receiverAccountNum, CBlockIndex* pBlockIndex)> NotifyBip47KeysChanged;\n\n    /** IS-lock received */\n    boost::signals2::signal<void ()> NotifyISLockReceived;\n\n    /** ChainLock received */\n    boost::signals2::signal<void (int height)> NotifyChainLockReceived;\n\n    /** Inquire whether this wallet broadcasts transactions. */\n    bool GetBroadcastTransactions() const { return fBroadcastTransactions; }\n    /** Set whether this wallet broadcasts transactions. */\n    void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; }\n\n    /* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */\n    bool AbandonTransaction(const uint256& hashTx);\n\n    /** Mark a transaction as replaced by another transaction (e.g., BIP 125). */\n    bool MarkReplaced(const uint256& originalHash, const uint256& newHash);\n\n    /* Returns the wallets help message */\n    static std::string GetWalletHelpString(bool showDebug);\n\n    /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */\n    static CWallet* CreateWalletFromFile(const std::string walletFile);\n    static bool InitLoadWallet();\n\n    /**\n     * Wallet post-init setup\n     * Gives the wallet a chance to register repetitive tasks and complete post-init tasks\n     */\n    void postInitProcess(boost::thread_group& threadGroup);\n\n    /* Wallets parameter interaction */\n    static bool ParameterInteraction();\n\n    bool BackupWallet(const std::string& strDest);\n\n    /* Set the HD chain model (chain child index counters) */\n    bool SetHDChain(const CHDChain& chain, bool memonly, bool& upgradeChain, bool genNewKeyPool = true);\n    bool SetHDChain(const CHDChain& chain, bool memonly) { bool upgradeChain = DEFAULT_UPGRADE_CHAIN; return SetHDChain(chain, memonly, upgradeChain); }\n    const CHDChain& GetHDChain() { return hdChain; }\n\n    bool SetMnemonicContainer(const MnemonicContainer& mnContainer, bool memonly);\n    const MnemonicContainer& GetMnemonicContainer() { return mnemonicContainer; }\n\n    bool EncryptMnemonicContainer(const CKeyingMaterial& vMasterKeyIn);\n    bool DecryptMnemonicContainer(MnemonicContainer& mnContainer);\n\n    void GenerateNewMnemonic();\n\n    /* Returns true if HD is enabled */\n    bool IsHDEnabled();\n\n    /* Generates a new HD master key (will not be activated) */\n    CPubKey GenerateNewHDMasterKey();\n\n    /* Set the current HD master key (will reset the chain child index counters) */\n    bool SetHDMasterKey(const CPubKey& key, const int cHDChainVersion=CHDChain().CURRENT_VERSION);\n\n    /**************************************************************************/\n    /* bip47 */\n    /* Generates and strores a new payment code for receiving*/\n    bip47::CPaymentCode GeneratePcode(std::string const & label);\n\n    /*Prepares and sends a notification tx using Lelantus facilities*/\n    CWalletTx PrepareAndSendNotificationTx(bip47::CPaymentCode const & theirPcode);\n\n    /* Lists all receiving pcodes as tuples of (pcode, label, notification address) */\n    std::vector<bip47::CPaymentCodeDescription> ListPcodes();\n\n    /* Creates a payment channel for their payment code. */\n    bip47::CPaymentChannel & SetupPchannel(bip47::CPaymentCode const & theirPcode);\n\n    /* Stores the notification tx id into the wallet database */\n    void SetNotificationTxId(bip47::CPaymentCode const & theirPcode, uint256 const & txid);\n\n    /* Returns next unused address for their payment code. Throws if no payment channel was setup */\n    CBitcoinAddress GetTheirNextAddress(bip47::CPaymentCode const & theirPcode) const;\n\n    /* Returns and stores a next unused address for their payment code. Throws if no payment channel was setup */\n    CBitcoinAddress GenerateTheirNextAddress(bip47::CPaymentCode const & theirPcode);\n\n    /*Loads previously stored bip47 accounts */\n    void LoadBip47Wallet();\n\n    std::shared_ptr<bip47::CWallet const>  GetBip47Wallet() const;\n\n    boost::optional<bip47::CPaymentCodeDescription> FindPcode(bip47::CPaymentCode const & pcode) const;\n    boost::optional<bip47::CPaymentCodeDescription> FindPcode(CBitcoinAddress const & address) const;\n\n    /*Marks address as used for a receiving bip47 account. Returns the account if found*/\n    bip47::CAccountReceiver const * AddressUsed(CBitcoinAddress const & address);\n\n    /*Checks if this is a BIP47 transaction and handles it. May send an unlock request if wallet is locked.*/\n    void HandleBip47Transaction(CWalletTx const & wtx);\n\n    /*Attaches a new label to a sending payment code.*/\n    void LabelSendingPcode(bip47::CPaymentCode const & pcode, std::string const & label, bool remove = false);\n    std::string GetSendingPcodeLabel(bip47::CPaymentCode const & pcode) const;\n\n    /*Relabels an existing receiving payment code*/\n    void LabelReceivingPcode(bip47::CPaymentCode const & pcode, std::string const & label);\n\n    /*Sets used address number for a sending or receiving payment channel*/\n    size_t SetUsedAddressNumber(bip47::CPaymentCode const & pcode, size_t number);\n\n    void NotifyTransactionLock(const CTransaction &tx) override;\n    void NotifyChainLock(const CBlockIndex* pindexChainLock) override;\n};\n\n/** A key allocated from the key pool. */\nclass CReserveKey : public CReserveScript\n{\nprotected:\n    CWallet* pwallet;\n    int64_t nIndex;\n    CPubKey vchPubKey;\npublic:\n    CReserveKey(CWallet* pwalletIn)\n    {\n        nIndex = -1;\n        pwallet = pwalletIn;\n    }\n\n    ~CReserveKey()\n    {\n        ReturnKey();\n    }\n\n    void ReturnKey();\n    bool GetReservedKey(CPubKey &pubkey);\n    void KeepKey();\n    void KeepScript() { KeepKey(); }\n};\n\n\n/**\n * Account information.\n * Stored in wallet with key "acc"+string account name.\n */\nclass CAccount\n{\npublic:\n    CPubKey vchPubKey;\n\n    CAccount()\n    {\n        SetNull();\n    }\n\n    void SetNull()\n    {\n        vchPubKey = CPubKey();\n    }\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream& s, Operation ser_action) {\n        int nVersion = s.GetVersion();\n        if (!(s.GetType() & SER_GETHASH))\n            READWRITE(nVersion);\n        READWRITE(vchPubKey);\n    }\n};\n\nbool CompSigmaHeight(const CSigmaEntry& a, const CSigmaEntry& b);\nbool CompSigmaID(const CSigmaEntry& a, const CSigmaEntry& b);\n\n// Helper for producing a bunch of max-sized low-S signatures (eg 72 bytes)\n// ContainerType is meant to hold pair<CWalletTx *, int>, and be iterable\n// so that each entry corresponds to each vIn, in order.\ntemplate <typename ContainerType>\nbool CWallet::DummySignTx(CMutableTransaction &txNew, const ContainerType &coins)\n{\n    // Fill in dummy signatures for fee calculation.\n    int nIn = 0;\n    for (const auto& coin : coins)\n    {\n        const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey;\n        SignatureData sigdata;\n\n        if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata))\n        {\n            return false;\n        } else {\n            UpdateTransaction(txNew, nIn, sigdata);\n        }\n\n        nIn++;\n    }\n    return true;\n}\n\nCWalletTx PrepareAndSendNotificationTx(CWallet* pwallet, bip47::CPaymentCode const & theirPcode);\n\n#endif // BITCOIN_WALLET_WALLET_H\n', 'message': 'Fixing bitcoin API change problems due to PR merges part #3\n', 'author_name': 'Peter Shugalev', 'lang': 'h'}