|
1 | | -// The fetch functions provide a sorted list of transaction hashes ordered by block, position in block and position in wallet including STO receipts |
| 1 | +/** |
| 2 | + * @file fetchwallettx.cpp |
| 3 | + * |
| 4 | + * The fetch functions provide a sorted list of transaction hashes ordered by block, |
| 5 | + * position in block and position in wallet including STO receipts. |
| 6 | + */ |
| 7 | + |
2 | 8 | #include "omnicore/fetchwallettx.h" |
3 | 9 |
|
| 10 | +#include "omnicore/log.h" |
4 | 11 | #include "omnicore/omnicore.h" |
5 | 12 | #include "omnicore/pending.h" |
6 | 13 | #include "omnicore/utilsbitcoin.h" |
7 | 14 |
|
8 | 15 | #include "init.h" |
9 | | -#include "wallet.h" |
| 16 | +#include "main.h" |
10 | 17 | #include "sync.h" |
| 18 | +#include "tinyformat.h" |
| 19 | +#include "txdb.h" |
| 20 | +#ifdef ENABLE_WALLET |
| 21 | +#include "wallet.h" |
| 22 | +#endif |
11 | 23 |
|
12 | | -#include <stdint.h> |
| 24 | +#include <boost/algorithm/string.hpp> |
13 | 25 |
|
14 | | -#include <set> |
| 26 | +#include <stdint.h> |
| 27 | +#include <list> |
15 | 28 | #include <map> |
| 29 | +#include <set> |
16 | 30 | #include <string> |
| 31 | +#include <utility> |
| 32 | +#include <vector> |
17 | 33 |
|
18 | | -#include <boost/algorithm/string.hpp> |
| 34 | +namespace mastercore |
| 35 | +{ |
| 36 | +/** |
| 37 | + * Gets the byte offset of a transaction from the transaction index. |
| 38 | + */ |
| 39 | +unsigned int GetTransactionByteOffset(const uint256& txid) |
| 40 | +{ |
| 41 | + LOCK(cs_main); |
| 42 | + |
| 43 | + CDiskTxPos position; |
| 44 | + if (pblocktree->ReadTxIndex(txid, position)) { |
| 45 | + return position.nTxOffset; |
| 46 | + } |
19 | 47 |
|
20 | | -using namespace mastercore; |
| 48 | + return 0; |
| 49 | +} |
21 | 50 |
|
22 | 51 | /** |
23 | | - * Returns an ordered list of Omni transactions including STO receipts that are relevant to the wallet |
24 | | - * Ignores order in the wallet (which can be skewed by watch addresses) and utilizes block height and position within block |
25 | | - */ |
26 | | -std::map<std::string,uint256> FetchWalletOmniTransactions(int count, int startBlock, int endBlock) |
| 52 | + * Returns an ordered list of Omni transactions including STO receipts that are relevant to the wallet. |
| 53 | + * |
| 54 | + * Ignores order in the wallet (which can be skewed by watch addresses) and utilizes block height and position within block. |
| 55 | + */ |
| 56 | +std::map<std::string, uint256> FetchWalletOmniTransactions(unsigned int count, int startBlock, int endBlock) |
27 | 57 | { |
28 | | - // Iterate backwards through wallet transactions until we have count items to return: |
29 | | - std::map<std::string,uint256> mapResponse; |
| 58 | + std::map<std::string, uint256> mapResponse; |
| 59 | +#ifdef ENABLE_WALLET |
| 60 | + if (pwalletMain == NULL) { |
| 61 | + return mapResponse; |
| 62 | + } |
30 | 63 | std::set<uint256> seenHashes; |
31 | 64 | std::list<CAccountingEntry> acentries; |
32 | 65 | CWallet::TxItems txOrdered; |
33 | 66 | { |
34 | 67 | LOCK(pwalletMain->cs_wallet); |
35 | 68 | txOrdered = pwalletMain->OrderedTxItems(acentries, "*"); |
36 | 69 | } |
| 70 | + // Iterate backwards through wallet transactions until we have count items to return: |
37 | 71 | for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { |
38 | | - CWalletTx *const pwtx = (*it).second.first; |
39 | | - if (pwtx == 0) continue; |
40 | | - uint256 txHash = pwtx->GetHash(); |
| 72 | + const CWalletTx* pwtx = it->second.first; |
| 73 | + if (pwtx == NULL) continue; |
| 74 | + const uint256& txHash = pwtx->GetHash(); |
41 | 75 | { |
42 | 76 | LOCK(cs_tally); |
43 | 77 | if (!p_txlistdb->exists(txHash)) continue; |
44 | 78 | } |
45 | | - uint256 blockHash = pwtx->hashBlock; |
| 79 | + const uint256& blockHash = pwtx->hashBlock; |
46 | 80 | if ((0 == blockHash) || (NULL == GetBlockIndex(blockHash))) continue; |
47 | | - CBlockIndex* pBlockIndex = GetBlockIndex(blockHash); |
| 81 | + const CBlockIndex* pBlockIndex = GetBlockIndex(blockHash); |
48 | 82 | if (NULL == pBlockIndex) continue; |
49 | 83 | int blockHeight = pBlockIndex->nHeight; |
50 | 84 | if (blockHeight < startBlock || blockHeight > endBlock) continue; |
51 | 85 | int blockPosition = GetTransactionByteOffset(txHash); |
52 | 86 | std::string sortKey = strprintf("%06d%010d", blockHeight, blockPosition); |
53 | 87 | mapResponse.insert(std::make_pair(sortKey, txHash)); |
54 | 88 | seenHashes.insert(txHash); |
55 | | - if ((int)mapResponse.size() >= count) break; |
| 89 | + if (mapResponse.size() >= count) break; |
56 | 90 | } |
57 | 91 |
|
58 | 92 | // Insert STO receipts - receiving an STO has no inbound transaction to the wallet, so we will insert these manually into the response |
@@ -82,34 +116,27 @@ std::map<std::string,uint256> FetchWalletOmniTransactions(int count, int startBl |
82 | 116 | } |
83 | 117 |
|
84 | 118 | // Insert pending transactions (sets block as 999999 and position as wallet position) |
85 | | - for (PendingMap::iterator it = my_pending.begin(); it != my_pending.end(); ++it) { |
86 | | - uint256 txHash = it->first; |
| 119 | + // TODO: resolve potential deadlock caused by cs_wallet, cs_pending |
| 120 | + // LOCK(cs_pending); |
| 121 | + for (PendingMap::const_iterator it = my_pending.begin(); it != my_pending.end(); ++it) { |
| 122 | + const uint256& txHash = it->first; |
87 | 123 | int blockHeight = 999999; |
88 | 124 | if (blockHeight < startBlock || blockHeight > endBlock) continue; |
89 | 125 | int blockPosition = 0; |
90 | 126 | { |
91 | 127 | LOCK(pwalletMain->cs_wallet); |
92 | 128 | std::map<uint256, CWalletTx>::const_iterator walletIt = pwalletMain->mapWallet.find(txHash); |
93 | 129 | if (walletIt != pwalletMain->mapWallet.end()) { |
94 | | - const CWalletTx* pendingWTx = &(*walletIt).second; |
95 | | - blockPosition = pendingWTx->nOrderPos; |
| 130 | + const CWalletTx& wtx = walletIt->second; |
| 131 | + blockPosition = wtx.nOrderPos; |
96 | 132 | } |
97 | 133 | } |
98 | 134 | std::string sortKey = strprintf("%06d%010d", blockHeight, blockPosition); |
99 | 135 | mapResponse.insert(std::make_pair(sortKey, txHash)); |
100 | 136 | } |
101 | | - |
| 137 | +#endif |
102 | 138 | return mapResponse; |
103 | 139 | } |
104 | 140 |
|
105 | | -/** Gets the byte offset of a transaction from the tx index |
106 | | - */ |
107 | | -uint64_t GetTransactionByteOffset(const uint256& txid) |
108 | | -{ |
109 | | - LOCK(cs_main); |
110 | | - CDiskTxPos position; |
111 | | - if (pblocktree->ReadTxIndex(txid, position)) { |
112 | | - return position.nTxOffset; |
113 | | - } |
114 | | - return 0; |
115 | | -} |
| 141 | + |
| 142 | +} // namespace mastercore |
0 commit comments