aboutsummaryrefslogtreecommitdiff
path: root/src/validation.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2017-12-06 12:10:16 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2017-12-06 12:10:21 +0100
commit497d0e014cc79d46531d570e74e4aeae72db602d (patch)
tree7b31b3067439d0f4406ab0e7c6f0ca526e35d0fa /src/validation.cpp
parenta13e44385147aa8789a4992fa6d162ffec04c9ae (diff)
parent434526aba680cb73208e018a02827d51a71cfff6 (diff)
Merge #10275: [rpc] Allow fetching tx directly from specified block in getrawtransaction
434526a [test] Add tests for getrawtransaction with block hash. (Karl-Johan Alm) b167951 [rpc] Allow getrawtransaction to take optional blockhash to fetch transaction from a block directly. (Karl-Johan Alm) a5f5a2c [rpc] Fix fVerbose parsing (remove excess if cases). (Karl-Johan Alm) Pull request description: [Reviewer hint: use [?w=1](https://github.com/bitcoin/bitcoin/pull/10275/files?w=1) to avoid seeing a bunch of indentation changes.] Presuming a user knows the block hash of the block containing a given transaction, this PR allows them to fetch the raw transaction, even without `-txindex`. It also enables support for getting transactions that are in orphaned blocks. Note that supplying a block hash will override mempool and txindex support in `GetTransaction`. The rationale behind this is that a transaction may be in multiple places (orphaned blocks) and if the user supplies an explicit block hash it should be adhered to. ```Bash $ # a41.. is a tx inside an orphan block ..3c6f.. -- first try getting it normally $ ./bitcoin-cli getrawtransaction a41e66ee1341aa9fb9475b98cfdc1fe1261faa56c0a49254f33065ec90f7cd79 1 error code: -5 error message: No such mempool transaction. Use -txindex to enable blockchain transaction queries. Use gettransaction for wallet transactions. $ # now try with block hash $ ./bitcoin-cli getrawtransaction a41e66ee1341aa9fb9475b98cfdc1fe1261faa56c0a49254f33065ec90f7cd79 1 0000000000000000003c6fe479122bfa4a9187493937af1734e1e5cd9f198ec7 { "hex": "01000000014e7e81144e42f6d65550e59b715d470c9301fd7ac189[...]90488ac00000000", "inMainChain": false, "txid": "a41e66ee1341aa9fb9475b98cfdc1fe1261faa56c0a49254f33065ec90f7cd79", "hash": "a41e66ee1341aa9fb9475b98cfdc1fe1261faa56c0a49254f33065ec90f7cd79", "size": 225, [...] } $ # another tx 6c66... in block 462000 $ ./bitcoin-cli getrawtransaction 6c66b98191e9d6cc671f6817142152ebf6c5cab2ef008397b5a71ac13255a735 1 00000000000000000217f2c12922e321f6d4aa933ce88005a9a493c503054a40 { "hex": "0200000004d157[...]88acaf0c0700", "inMainChain": true, "txid": "6c66b98191e9d6cc671f6817142152ebf6c5cab2ef008397b5a71ac13255a735", "hash": "6c66b98191e9d6cc671f6817142152ebf6c5cab2ef008397b5a71ac13255a735", "size": 666, [...] } $ ``` Tree-SHA512: 279be3818141edd3cc194a9ee65929331920afb30297ab2d6da07293a2d7311afee5c8b00c6457477d9f1f86e86786a9b56878ea3ee19fa2629b829d042d0cda
Diffstat (limited to 'src/validation.cpp')
-rw-r--r--src/validation.cpp70
1 files changed, 37 insertions, 33 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index 98db699566..986052771c 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -926,47 +926,51 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
return AcceptToMemoryPoolWithTime(chainparams, pool, state, tx, pfMissingInputs, GetTime(), plTxnReplaced, bypass_limits, nAbsurdFee);
}
-/** Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock */
-bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow)
+/**
+ * Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock.
+ * If blockIndex is provided, the transaction is fetched from the corresponding block.
+ */
+bool GetTransaction(const uint256& hash, CTransactionRef& txOut, const Consensus::Params& consensusParams, uint256& hashBlock, bool fAllowSlow, CBlockIndex* blockIndex)
{
- CBlockIndex *pindexSlow = nullptr;
+ CBlockIndex* pindexSlow = blockIndex;
LOCK(cs_main);
- 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__);
+ if (!blockIndex) {
+ CTransactionRef ptx = mempool.get(hash);
+ if (ptx) {
+ txOut = ptx;
return true;
}
- // transaction not found in index, nothing more can be done
- return false;
- }
+ 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;
+ }
- 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];
+ // transaction not found in index, nothing more can be done
+ return false;
+ }
+
+ 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) {