Skip to content
This repository

gettransaction RPC for non-wallet transactions #841

Merged
merged 1 commit into from about 2 years ago

5 participants

Pieter Wuille Jeff Garzik Gavin Andresen Luke-Jr Gregory Maxwell
Pieter Wuille
Collaborator

Works for wallet transactions, memory-pool transaction and block chain
transactions.

Available for all:

  • txid
  • version
  • locktime
  • size
  • coinbase/inputs/outputs
  • confirmations

Available only for wallet transactions:

  • amount
  • fee
  • details
  • blockindex

Available for wallet transactions and block chain transactions:

  • blockhash
  • time
Jeff Garzik
Collaborator

visual ACK

Gavin Andresen

Sanity tested OK; would be nice if it checked the memory pool for 0-confirmation "other people's" transactions.

Pieter Wuille
Collaborator
src/bitcoinrpc.cpp
((29 lines not shown))
1487 1487
1488   - Array details;
1489   - ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
1490   - entry.push_back(Pair("details", details));
  1488 + Array details;
  1489 + ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
  1490 + entry.push_back(Pair("details", details));
  1491 + }
  1492 + else
  1493 + {
  1494 + CTxDB txdb("r");
  1495 + CTransaction tx;
  1496 + CTxIndex txindex;
  1497 + if (!tx.ReadFromDisk(txdb, COutPoint(hash, 0), txindex))
1
Gavin Andresen Owner

Doesn't this ReadFromDisk() fail for memory pool transactions? I could've sworn memory pool txns weren't written to disk until they were included in a block...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Pieter Wuille
Collaborator

Much more complete and totally reworked version pushed.

Luke-Jr

Needs rebasing. Sipa broke everything using locks. >_<

Luke-Jr

This needs rebasing (merges clean, but won't build)

Pieter Wuille sipa gettransaction RPC for non-wallet transactions
Works for wallet transactions, memory-pool transaction and block chain
transactions.

Available for all:
 * txid
 * version
 * locktime
 * size
 * coinbase/inputs/outputs
 * confirmations

Available only for wallet transactions:
 * amount
 * fee
 * details
 * blockindex

Available for wallet transactions and block chain transactions:
 * blockhash
 * time
c73ba23
Pieter Wuille
Collaborator
sipa commented

rebased

Gregory Maxwell gmaxwell merged commit 2f1dca6 into from
Gregory Maxwell gmaxwell closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Apr 18, 2012
Pieter Wuille sipa gettransaction RPC for non-wallet transactions
Works for wallet transactions, memory-pool transaction and block chain
transactions.

Available for all:
 * txid
 * version
 * locktime
 * size
 * coinbase/inputs/outputs
 * confirmations

Available only for wallet transactions:
 * amount
 * fee
 * details
 * blockindex

Available for wallet transactions and block chain transactions:
 * blockhash
 * time
c73ba23
This page is out of date. Refresh to see the latest.

Showing 3 changed files with 107 additions and 16 deletions. Show diff stats Hide diff stats

  1. +81 14 src/bitcoinrpc.cpp
  2. +25 1 src/main.cpp
  3. +1 1  src/main.h
95 src/bitcoinrpc.cpp
@@ -130,6 +130,40 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
130 130 entry.push_back(Pair(item.first, item.second));
131 131 }
132 132
  133 +void TxToJSON(const CTransaction &tx, Object& entry)
  134 +{
  135 + entry.push_back(Pair("version", tx.nVersion));
  136 + entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime));
  137 + entry.push_back(Pair("size", (boost::int64_t)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)));
  138 + Array vin;
  139 + BOOST_FOREACH(const CTxIn& txin, tx.vin)
  140 + {
  141 + Object in;
  142 + if (tx.IsCoinBase())
  143 + in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
  144 + else
  145 + {
  146 + Object prevout;
  147 + prevout.push_back(Pair("hash", txin.prevout.hash.GetHex()));
  148 + prevout.push_back(Pair("n", (boost::int64_t)txin.prevout.n));
  149 + in.push_back(Pair("prevout", prevout));
  150 + in.push_back(Pair("scriptSig", txin.scriptSig.ToString()));
  151 + }
  152 + in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence));
  153 + vin.push_back(in);
  154 + }
  155 + entry.push_back(Pair("vin", vin));
  156 + Array vout;
  157 + BOOST_FOREACH(const CTxOut& txout, tx.vout)
  158 + {
  159 + Object out;
  160 + out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
  161 + out.push_back(Pair("scriptPubKey", txout.scriptPubKey.ToString()));
  162 + vout.push_back(out);
  163 + }
  164 + entry.push_back(Pair("vout", vout));
  165 +}
  166 +
133 167 string AccountFromValue(const Value& value)
134 168 {
135 169 string strAccount = value.get_str();
@@ -1472,24 +1506,57 @@ Value gettransaction(const Array& params, bool fHelp)
1472 1506
1473 1507 Object entry;
1474 1508
1475   - if (!pwalletMain->mapWallet.count(hash))
1476   - throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
1477   - const CWalletTx& wtx = pwalletMain->mapWallet[hash];
  1509 + if (pwalletMain->mapWallet.count(hash))
  1510 + {
  1511 + const CWalletTx& wtx = pwalletMain->mapWallet[hash];
  1512 +
  1513 + TxToJSON(wtx, entry);
1478 1514
1479   - int64 nCredit = wtx.GetCredit();
1480   - int64 nDebit = wtx.GetDebit();
1481   - int64 nNet = nCredit - nDebit;
1482   - int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
  1515 + int64 nCredit = wtx.GetCredit();
  1516 + int64 nDebit = wtx.GetDebit();
  1517 + int64 nNet = nCredit - nDebit;
  1518 + int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
1483 1519
1484   - entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
1485   - if (wtx.IsFromMe())
1486   - entry.push_back(Pair("fee", ValueFromAmount(nFee)));
  1520 + entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
  1521 + if (wtx.IsFromMe())
  1522 + entry.push_back(Pair("fee", ValueFromAmount(nFee)));
1487 1523
1488   - WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
  1524 + WalletTxToJSON(wtx, entry);
1489 1525
1490   - Array details;
1491   - ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
1492   - entry.push_back(Pair("details", details));
  1526 + Array details;
  1527 + ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
  1528 + entry.push_back(Pair("details", details));
  1529 + }
  1530 + else
  1531 + {
  1532 + CTransaction tx;
  1533 + uint256 hashBlock = 0;
  1534 + if (GetTransaction(hash, tx, hashBlock))
  1535 + {
  1536 + entry.push_back(Pair("txid", hash.GetHex()));
  1537 + TxToJSON(tx, entry);
  1538 + if (hashBlock == 0)
  1539 + entry.push_back(Pair("confirmations", 0));
  1540 + else
  1541 + {
  1542 + entry.push_back(Pair("blockhash", hashBlock.GetHex()));
  1543 + map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
  1544 + if (mi != mapBlockIndex.end() && (*mi).second)
  1545 + {
  1546 + CBlockIndex* pindex = (*mi).second;
  1547 + if (pindex->IsInMainChain())
  1548 + {
  1549 + entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight));
  1550 + entry.push_back(Pair("time", (boost::int64_t)pindex->nTime));
  1551 + }
  1552 + else
  1553 + entry.push_back(Pair("confirmations", 0));
  1554 + }
  1555 + }
  1556 + }
  1557 + else
  1558 + throw JSONRPCError(-5, "No information available about transaction");
  1559 + }
1493 1560
1494 1561 return entry;
1495 1562 }
26 src/main.cpp
@@ -733,7 +733,31 @@ int CTxIndex::GetDepthInMainChain() const
733 733 return 1 + nBestHeight - pindex->nHeight;
734 734 }
735 735
736   -
  736 +// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
  737 +bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock)
  738 +{
  739 + {
  740 + LOCK(cs_main);
  741 + {
  742 + LOCK(mempool.cs);
  743 + if (mempool.exists(hash))
  744 + {
  745 + tx = mempool.lookup(hash);
  746 + return true;
  747 + }
  748 + }
  749 + CTxDB txdb("r");
  750 + CTxIndex txindex;
  751 + if (tx.ReadFromDisk(txdb, COutPoint(hash, 0), txindex))
  752 + {
  753 + CBlock block;
  754 + if (block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
  755 + hashBlock = block.GetHash();
  756 + return true;
  757 + }
  758 + }
  759 + return false;
  760 +}
737 761
738 762
739 763
2  src/main.h
@@ -101,7 +101,7 @@ unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
101 101 int GetNumBlocksOfPeers();
102 102 bool IsInitialBlockDownload();
103 103 std::string GetWarnings(std::string strFor);
104   -
  104 +bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock);
105 105
106 106
107 107

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.