Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/rawtransaction.cpp
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | void TxToJSON(const CTransaction &tx, const uint256 hashBlock, | ||||
// | // | ||||
// Blockchain contextual information (confirmations and blocktime) is not | // Blockchain contextual information (confirmations and blocktime) is not | ||||
// available to code in bitcoin-common, so we query them here and push the | // available to code in bitcoin-common, so we query them here and push the | ||||
// data into the returned UniValue. | // data into the returned UniValue. | ||||
TxToUniv(tx, uint256(), entry, true, RPCSerializationFlags()); | TxToUniv(tx, uint256(), entry, true, RPCSerializationFlags()); | ||||
if (!hashBlock.IsNull()) { | if (!hashBlock.IsNull()) { | ||||
entry.pushKV("blockhash", hashBlock.GetHex()); | entry.pushKV("blockhash", hashBlock.GetHex()); | ||||
BlockMap::iterator mi = mapBlockIndex.find(hashBlock); | CBlockIndex *pindex = LookupBlockIndex(hashBlock); | ||||
if (mi != mapBlockIndex.end() && (*mi).second) { | if (pindex) { | ||||
CBlockIndex *pindex = (*mi).second; | |||||
if (chainActive.Contains(pindex)) { | if (chainActive.Contains(pindex)) { | ||||
entry.pushKV("confirmations", | entry.pushKV("confirmations", | ||||
1 + chainActive.Height() - pindex->nHeight); | 1 + chainActive.Height() - pindex->nHeight); | ||||
entry.pushKV("time", pindex->GetBlockTime()); | entry.pushKV("time", pindex->GetBlockTime()); | ||||
entry.pushKV("blocktime", pindex->GetBlockTime()); | entry.pushKV("blocktime", pindex->GetBlockTime()); | ||||
} else { | } else { | ||||
entry.pushKV("confirmations", 0); | entry.pushKV("confirmations", 0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | static UniValue getrawtransaction(const Config &config, | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
fVerbose = request.params[1].isNum() | fVerbose = request.params[1].isNum() | ||||
? (request.params[1].get_int() != 0) | ? (request.params[1].get_int() != 0) | ||||
: request.params[1].get_bool(); | : request.params[1].get_bool(); | ||||
} | } | ||||
if (!request.params[2].isNull()) { | if (!request.params[2].isNull()) { | ||||
uint256 blockhash = ParseHashV(request.params[2], "parameter 3"); | uint256 blockhash = ParseHashV(request.params[2], "parameter 3"); | ||||
if (!blockhash.IsNull()) { | blockindex = LookupBlockIndex(blockhash); | ||||
BlockMap::iterator it = mapBlockIndex.find(blockhash); | if (!blockindex) { | ||||
if (it == mapBlockIndex.end()) { | |||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
"Block hash not found"); | "Block hash not found"); | ||||
} | } | ||||
blockindex = it->second; | |||||
in_active_chain = chainActive.Contains(blockindex); | in_active_chain = chainActive.Contains(blockindex); | ||||
} | } | ||||
} | |||||
CTransactionRef tx; | CTransactionRef tx; | ||||
uint256 hash_block; | uint256 hash_block; | ||||
if (!GetTransaction(config, txid, tx, hash_block, true, blockindex)) { | if (!GetTransaction(config, txid, tx, hash_block, true, blockindex)) { | ||||
std::string errmsg; | std::string errmsg; | ||||
if (blockindex) { | if (blockindex) { | ||||
if (!blockindex->nStatus.hasData()) { | if (!blockindex->nStatus.hasData()) { | ||||
throw JSONRPCError(RPC_MISC_ERROR, "Block not available"); | throw JSONRPCError(RPC_MISC_ERROR, "Block not available"); | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | static UniValue gettxoutproof(const Config &config, | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CBlockIndex *pblockindex = nullptr; | CBlockIndex *pblockindex = nullptr; | ||||
uint256 hashBlock; | uint256 hashBlock; | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
hashBlock = uint256S(request.params[1].get_str()); | hashBlock = uint256S(request.params[1].get_str()); | ||||
if (!mapBlockIndex.count(hashBlock)) { | pblockindex = LookupBlockIndex(hashBlock); | ||||
if (!pblockindex) { | |||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); | ||||
} | } | ||||
pblockindex = mapBlockIndex[hashBlock]; | |||||
} else { | } else { | ||||
// Loop through txids and try to find which block they're in. Exit loop | // Loop through txids and try to find which block they're in. Exit loop | ||||
// once a block is found. | // once a block is found. | ||||
for (const auto &txid : setTxIds) { | for (const auto &txid : setTxIds) { | ||||
const Coin &coin = AccessByTxid(*pcoinsTip, txid); | const Coin &coin = AccessByTxid(*pcoinsTip, txid); | ||||
if (!coin.IsSpent()) { | if (!coin.IsSpent()) { | ||||
pblockindex = chainActive[coin.GetHeight()]; | pblockindex = chainActive[coin.GetHeight()]; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (pblockindex == nullptr) { | if (pblockindex == nullptr) { | ||||
CTransactionRef tx; | CTransactionRef tx; | ||||
if (!GetTransaction(config, oneTxId, tx, hashBlock, false) || | if (!GetTransaction(config, oneTxId, tx, hashBlock, false) || | ||||
hashBlock.IsNull()) { | hashBlock.IsNull()) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
"Transaction not yet in block"); | "Transaction not yet in block"); | ||||
} | } | ||||
if (!mapBlockIndex.count(hashBlock)) { | pblockindex = LookupBlockIndex(hashBlock); | ||||
if (!pblockindex) { | |||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt"); | throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt"); | ||||
} | } | ||||
pblockindex = mapBlockIndex[hashBlock]; | |||||
} | } | ||||
CBlock block; | CBlock block; | ||||
if (!ReadBlockFromDisk(block, pblockindex, config)) { | if (!ReadBlockFromDisk(block, pblockindex, config)) { | ||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); | throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); | ||||
} | } | ||||
unsigned int ntxFound = 0; | unsigned int ntxFound = 0; | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | static UniValue verifytxoutproof(const Config &config, | ||||
std::vector<unsigned int> vIndex; | std::vector<unsigned int> vIndex; | ||||
if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != | if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != | ||||
merkleBlock.header.hashMerkleRoot) { | merkleBlock.header.hashMerkleRoot) { | ||||
return res; | return res; | ||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || | const CBlockIndex *pindex = LookupBlockIndex(merkleBlock.header.GetHash()); | ||||
!chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()])) { | if (!pindex || !chainActive.Contains(pindex)) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
"Block not found in chain"); | "Block not found in chain"); | ||||
} | } | ||||
for (const uint256 &hash : vMatch) { | for (const uint256 &hash : vMatch) { | ||||
res.push_back(hash.GetHex()); | res.push_back(hash.GetHex()); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 979 Lines • Show Last 20 Lines |