src/validation.cpp
bool GetTransaction(const uint256& hash, CTransaction& txOut, const Consensus::Params& consensusParams, uint256& hashBlock, bool fAllowSlow, CBlockIndex* blockIndex)
{
    CBlockIndex* pindexSlow = blockIndex;

    LOCK(cs_main);

    if (!blockIndex) {
        CTransactionRef ptx = mempool.get(hash);
        if (ptx) {
            txOut = *ptx;
            return true;
        }

        if (fTxIndex) {
            CDiskTxPos postx;
            if (pblocktree->ReadTxIndex(hash, postx)) {
                CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
                if (file.IsNull())
                    return error("%s: OpenBlockFile failed", __func__);
                CBlockHeader header;
                try {
                    file >> header;
                    fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
                    file >> txOut;
                } catch (const std::exception& e) {
                    return error("%s: Deserialize or I/O error - %s", __func__, e.what());
                }
                hashBlock = header.GetHash();
                if (txOut.GetHash() != hash)
                    return error("%s: txid mismatch", __func__);
                return true;
            }

            // transaction not found in index, nothing more can be done
            return false;
        }

        // In case of non-validating mode, we may scan the wallet too.
        GetMainSignals().FindTransaction(hash, ptx);
        if (ptx)
        {
            txOut = *ptx;
            return true;
        }

        if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
            const Coin& coin = AccessByTxid(*pcoinsTip, hash);
            if (!coin.IsSpent()) pindexSlow = chainActive[coin.nHeight];
        }
    }

    if (pindexSlow) {
        CBlock block;
        if (ReadBlockFromDisk(block, pindexSlow, consensusParams)) {
            for (const auto& tx : block.vtx) {
                if (tx->GetHash() == hash) {
                    txOut = *tx;
                    hashBlock = pindexSlow->GetBlockHash();
                    return true;
                }
            }
        }
    }

    return false;
}
/** Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock */
Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock
Return transaction in txOut and if it was found inside a block its hash is placed in hashBlock
bool GetTransaction(const uint256& hash, CTransaction& txOut, const Consensus::Params& consensusParams, uint256& hashBlock, bool fAllowSlow, CBlockIndex* blockIndex)
{
    CBlockIndex* pindexSlow = blockIndex;
    LOCK(cs_main);
    if (!blockIndex) {
        CTransactionRef ptx = mempool.get(hash);
        if (ptx) {
            txOut = *ptx;
            return true;
        }
        if (fTxIndex) {
            CDiskTxPos postx;
            if (pblocktree->ReadTxIndex(hash, postx)) {
                CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
                if (file.IsNull())
                    return error("%s: OpenBlockFile failed", __func__);
                CBlockHeader header;
                try {
                    file >> header;
                    fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
                    file >> txOut;
                } catch (const std::exception& e) {
                    return error("%s: Deserialize or I/O error - %s", __func__, e.what());
                }
                hashBlock = header.GetHash();
                if (txOut.GetHash() != hash)
                    return error("%s: txid mismatch", __func__);
                return true;
            }
            return false;
        }
        GetMainSignals().FindTransaction(hash, ptx);
        if (ptx)
        {
            txOut = *ptx;
            return true;
        }
        if (fAllowSlow) { 
            const Coin& coin = AccessByTxid(*pcoinsTip, hash);
            if (!coin.IsSpent()) pindexSlow = chainActive[coin.nHeight];
        }
    }
    if (pindexSlow) {
        CBlock block;
        if (ReadBlockFromDisk(block, pindexSlow, consensusParams)) {
            for (const auto& tx : block.vtx) {
                if (tx->GetHash() == hash) {
                    txOut = *tx;
                    hashBlock = pindexSlow->GetBlockHash();
                    return true;
                }
            }
        }
    }
    return false;
}
bool GetTransaction ( const uint256 & hash , CTransaction & txOut , const Consensus :: Params & consensusParams , uint256 & hashBlock , bool fAllowSlow , CBlockIndex * blockIndex ) { CBlockIndex * pindexSlow = blockIndex ; LOCK ( cs_main ) ; if ( ! blockIndex ) { CTransactionRef ptx = mempool . get ( hash ) ; if ( ptx ) { txOut = * ptx ; return true ; } if ( fTxIndex ) { CDiskTxPos postx ; if ( pblocktree -> ReadTxIndex ( hash , postx ) ) { CAutoFile file ( OpenBlockFile ( postx , true ) , SER_DISK , CLIENT_VERSION ) ; if ( file . IsNull ( ) ) return error ( " " , __func__ ) ; CBlockHeader header ; try { file >> header ; fseek ( file . Get ( ) , postx . nTxOffset , SEEK_CUR ) ; file >> txOut ; } catch ( const std :: exception & e ) { return error ( " " , __func__ , e . what ( ) ) ; } hashBlock = header . GetHash ( ) ; if ( txOut . GetHash ( ) != hash ) return error ( " " , __func__ ) ; return true ; } return false ; } GetMainSignals ( ) . FindTransaction ( hash , ptx ) ; if ( ptx ) { txOut = * ptx ; return true ; } if ( fAllowSlow ) { const Coin & coin = AccessByTxid ( * pcoinsTip , hash ) ; if ( ! coin . IsSpent ( ) ) pindexSlow = chainActive [ coin . nHeight ] ; } } if ( pindexSlow ) { CBlock block ; if ( ReadBlockFromDisk ( block , pindexSlow , consensusParams ) ) { for ( const auto & tx : block . vtx ) { if ( tx -> GetHash ( ) == hash ) { txOut = * tx ; hashBlock = pindexSlow -> GetBlockHash ( ) ; return true ; } } } } return false ; }
Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock
Return transaction in txOut and if it was found inside a block its hash is placed in hashBlock
// transaction not found in index, nothing more can be done // In case of non-validating mode, we may scan the wallet too. // use coin database to locate block that contains transaction, and scan it