src/wallet/wallet.cpp
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate, bool fValidated)
{
    {
        AssertLockHeld(cs_wallet);

        if (posInBlock != -1) {
            for (const CTxIn& txin : tx.vin) {
                std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.prevout);
                while (range.first != range.second) {
                    if (range.first->second != tx.GetHash()) {
                        LogPrintf("Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.GetHash().ToString(), pIndex->GetBlockHash().ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n);
                        MarkConflicted(pIndex->GetBlockHash(), range.first->second);
                    }
                    range.first++;
                }
            }
        }

        bool fExisted = mapWallet.count(tx.GetHash()) != 0;
        if (fExisted && !fUpdate) return false;
        if (fExisted || IsMine(tx) || IsFromMe(tx))
        {
            /* Check if any keys in the wallet keypool that were supposed to be unused
             * have appeared in a new transaction. If so, remove those keys from the keypool.
             * This can happen when restoring an old wallet backup that does not contain
             * the mostly recently created transactions from newer versions of the wallet.
             */

            // loop though all outputs
            for (const CTxOut& txout: tx.vout) {
                // extract addresses and check if they match with an unused keypool key
                std::vector<CKeyID> vAffected;
                CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
                for (const CKeyID &keyid : vAffected) {
                    std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
                    if (mi != m_pool_key_to_index.end()) {
                        LogPrintf("%s: Detected a used keypool key, mark all keypool key up to this key as used\n", __func__);
                        MarkReserveKeysAsUsed(mi->second);

                        if (!TopUpKeyPool()) {
                            LogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
                        }
                    }
                }
            }

            CWalletTx wtx(this,tx);
            wtx.fValidated = fValidated;

            // Get merkle branch if transaction was found in a block
            if (posInBlock != -1)
                wtx.SetMerkleBranch(pIndex, posInBlock);

            return AddToWallet(wtx, false);
        }
    }
    return false;
}
/**
 * Add a transaction to the wallet, or update it.  pIndex and posInBlock should
 * be set when the transaction was known to be included in a block.  When
 * posInBlock = SYNC_TRANSACTION_NOT_IN_BLOCK (-1) , then wallet state is not
 * updated in AddToWallet, but notifications happen and cached balances are
 * marked dirty.
 * If fUpdate is true, existing transactions will be updated.
 * TODO: One exception to this is that the abandoned state is cleared under the
 * assumption that any further notification of a transaction that was considered
 * abandoned is an indication that it is not safe to be considered abandoned.
 * Abandoned state should probably be more carefuly tracked via different
 * posInBlock signals or by checking mempool presence when necessary.
 */
Add a transaction to the wallet, or update it.  pIndex and posInBlock should
be set when the transaction was known to be included in a block.  When
posInBlock = SYNC_TRANSACTION_NOT_IN_BLOCK (-1) , then wallet state is not
updated in AddToWallet, but notifications happen and cached balances are
marked dirty.
If fUpdate is true, existing transactions will be updated.
TODO: One exception to this is that the abandoned state is cleared under the
assumption that any further notification of a transaction that was considered
abandoned is an indication that it is not safe to be considered abandoned.
Abandoned state should probably be more carefuly tracked via different
posInBlock signals or by checking mempool presence when necessary.
Add a transaction to the wallet or update it . pIndex and posInBlock should be set when the transaction was known to be included in a block . When posInBlock = SYNC_TRANSACTION_NOT_IN_BLOCK ( - 1 ) then wallet state is not updated in AddToWallet but notifications happen and cached balances are marked dirty . If fUpdate is true existing transactions will be updated . TODO : One exception to this is that the abandoned state is cleared under the assumption that any further notification of a transaction that was considered abandoned is an indication that it is not safe to be considered abandoned . Abandoned state should probably be more carefuly tracked via different posInBlock signals or by checking mempool presence when necessary .
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate, bool fValidated)
{
    {
        AssertLockHeld(cs_wallet);
        if (posInBlock != -1) {
            for (const CTxIn& txin : tx.vin) {
                std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.prevout);
                while (range.first != range.second) {
                    if (range.first->second != tx.GetHash()) {
                        LogPrintf("Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.GetHash().ToString(), pIndex->GetBlockHash().ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n);
                        MarkConflicted(pIndex->GetBlockHash(), range.first->second);
                    }
                    range.first++;
                }
            }
        }
        bool fExisted = mapWallet.count(tx.GetHash()) != 0;
        if (fExisted && !fUpdate) return false;
        if (fExisted || IsMine(tx) || IsFromMe(tx))
        {
            for (const CTxOut& txout: tx.vout) {
                std::vector<CKeyID> vAffected;
                CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
                for (const CKeyID &keyid : vAffected) {
                    std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
                    if (mi != m_pool_key_to_index.end()) {
                        LogPrintf("%s: Detected a used keypool key, mark all keypool key up to this key as used\n", __func__);
                        MarkReserveKeysAsUsed(mi->second);
                        if (!TopUpKeyPool()) {
                            LogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
                        }
                    }
                }
            }
            CWalletTx wtx(this,tx);
            wtx.fValidated = fValidated;
            if (posInBlock != -1)
                wtx.SetMerkleBranch(pIndex, posInBlock);
            return AddToWallet(wtx, false);
        }
    }
    return false;
}
bool CWallet :: AddToWalletIfInvolvingMe ( const CTransaction & tx , const CBlockIndex * pIndex , int posInBlock , bool fUpdate , bool fValidated ) { { AssertLockHeld ( cs_wallet ) ; if ( posInBlock != -1 ) { for ( const CTxIn & txin : tx . vin ) { std :: pair < TxSpends :: const_iterator , TxSpends :: const_iterator > range = mapTxSpends . equal_range ( txin . prevout ) ; while ( range . first != range . second ) { if ( range . first -> second != tx . GetHash ( ) ) { LogPrintf ( " \n " , tx . GetHash ( ) . ToString ( ) , pIndex -> GetBlockHash ( ) . ToString ( ) , range . first -> second . ToString ( ) , range . first -> first . hash . ToString ( ) , range . first -> first . n ) ; MarkConflicted ( pIndex -> GetBlockHash ( ) , range . first -> second ) ; } range . first ++ ; } } } bool fExisted = mapWallet . count ( tx . GetHash ( ) ) != 0 ; if ( fExisted && ! fUpdate ) return false ; if ( fExisted || IsMine ( tx ) || IsFromMe ( tx ) ) { for ( const CTxOut & txout : tx . vout ) { std :: vector < CKeyID > vAffected ; CAffectedKeysVisitor ( * this , vAffected ) . Process ( txout . scriptPubKey ) ; for ( const CKeyID & keyid : vAffected ) { std :: map < CKeyID , int64_t > :: const_iterator mi = m_pool_key_to_index . find ( keyid ) ; if ( mi != m_pool_key_to_index . end ( ) ) { LogPrintf ( " \n " , __func__ ) ; MarkReserveKeysAsUsed ( mi -> second ) ; if ( ! TopUpKeyPool ( ) ) { LogPrintf ( " \n " , __func__ ) ; } } } } CWalletTx wtx ( this , tx ) ; wtx . fValidated = fValidated ; if ( posInBlock != -1 ) wtx . SetMerkleBranch ( pIndex , posInBlock ) ; return AddToWallet ( wtx , false ) ; } } return false ; }
Add a transaction to the wallet, or update it.
Add a transaction to the wallet or update it .
/* Check if any keys in the wallet keypool that were supposed to be unused
             * have appeared in a new transaction. If so, remove those keys from the keypool.
             * This can happen when restoring an old wallet backup that does not contain
             * the mostly recently created transactions from newer versions of the wallet.
             */ // loop though all outputs // extract addresses and check if they match with an unused keypool key // Get merkle branch if transaction was found in a block