11// Provides a cache of wallet balances and functionality for determining whether Omni state changes affected anything in the wallet
22#include " omnicore/omnicore.h"
3+
4+ #include " init.h"
5+ #include " wallet.h"
6+
7+ #include < boost/algorithm/string.hpp>
8+
39#include < map>
410#include < string>
511
612using std::map;
713using std::string;
814
15+ using boost::algorithm::token_compress_on;
16+
917using namespace mastercore ;
1018
11- std::map<string, CMPTally> walletCache;
19+ std::map<string, CMPTally> walletBalancesCache;
20+
21+ // ! Global vector of Omni transactions in the wallet
22+ std::vector<uint256> walletTXIDCache;
23+
24+ /* *
25+ * Adds a txid to the wallet txid cache, performing duplicate detection
26+ */
27+ void WalletTXIDCacheAdd (uint256 hash)
28+ {
29+ if (msc_debug_walletcache) PrintToLog (" WALLETTXIDCACHE: Adding tx to txid cache : %s\n " ,hash.GetHex ());
30+ if (std::find (walletTXIDCache.begin (), walletTXIDCache.end (), hash) != walletTXIDCache.end ()) {
31+ PrintToLog (" ERROR: Wallet TXID Cache blocked duplicate insertion for %s\n " ,hash.GetHex ());
32+ } else {
33+ walletTXIDCache.push_back (hash);
34+ }
35+ }
36+
37+ /* *
38+ * Performs initial population of the wallet txid cache
39+ */
40+ void WalletTXIDCacheInit ()
41+ {
42+ if (msc_debug_walletcache) PrintToLog (" WALLETTXIDCACHE: WalletTXIDCacheInit requested\n " );
43+ // Prepare a few items and get lock
44+ CWallet *wallet = pwalletMain;
45+ LOCK (wallet->cs_wallet );
46+ std::list<CAccountingEntry> acentries;
47+ CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems (acentries, " *" );
48+
49+ // STO has no inbound transaction, use STO receipts to insert an STO into the wallet txid cache
50+ string mySTOReceipts = s_stolistdb->getMySTOReceipts (" " );
51+ std::vector<std::string> vecReceipts;
52+ boost::split (vecReceipts, mySTOReceipts, boost::is_any_of (" ," ), token_compress_on);
53+ int64_t lastTXBlock = 999999 ;
54+
55+ // Iterate through the wallet, checking if each transaction is Omni (via levelDB)
56+ for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin (); it != txOrdered.rend (); ++it) {
57+ CWalletTx *const pwtx = (*it).second .first ;
58+ if (pwtx != 0 ) {
59+ uint256 blockHash = pwtx->hashBlock ;
60+ if ((0 == blockHash) || (NULL == GetBlockIndex (blockHash))) continue ;
61+ CBlockIndex* pBlockIndex = GetBlockIndex (blockHash);
62+ if (NULL == pBlockIndex) continue ;
63+ int blockHeight = pBlockIndex->nHeight ;
64+
65+ // look for an STO receipt to see if we need to insert it into txid cache
66+ for (uint32_t i = 0 ; i<vecReceipts.size (); i++) {
67+ if (!vecReceipts[i].empty ()) {
68+ std::vector<std::string> svstr;
69+ boost::split (svstr, vecReceipts[i], boost::is_any_of (" :" ), token_compress_on);
70+ if (svstr.size () != 4 ) {
71+ PrintToLog (" ERROR: Unexpected number of tokens enumerating STO receipt %s\n " , vecReceipts[i]);
72+ continue ;
73+ }
74+ if ((atoi (svstr[1 ]) < lastTXBlock) && (atoi (svstr[1 ]) > blockHeight)) {
75+ uint256 hash;
76+ hash.SetHex (svstr[0 ]);
77+ if (msc_debug_walletcache) PrintToLog (" WALLETTXIDCACHE: Adding STO to txid cache : %s\n " ,hash.GetHex ());
78+ walletTXIDCache.push_back (hash);
79+ }
80+ }
81+ }
82+
83+ // get the hash of the transaction and check leveldb to see if this is an Omni tx, if so add to cache
84+ uint256 hash = pwtx->GetHash ();
85+ if (p_txlistdb->exists (hash)) {
86+ walletTXIDCache.push_back (hash);
87+ if (msc_debug_walletcache) PrintToLog (" WALLETTXIDCACHE: Adding tx to txid cache : %s\n " ,hash.GetHex ());
88+ }
89+ lastTXBlock = blockHeight;
90+ }
91+ }
92+ }
1293
1394/* *
1495 * Updates the cache with the latest state, returning true if changes were made to wallet addresses (including watch only)
@@ -37,11 +118,11 @@ int WalletCacheUpdate()
37118 tally.init ();
38119
39120 // check cache for miss on address
40- std::map<std::string, CMPTally>::iterator search_it = walletCache .find (address);
41- if (search_it == walletCache .end ()) { // cache miss, new address
121+ std::map<std::string, CMPTally>::iterator search_it = walletBalancesCache .find (address);
122+ if (search_it == walletBalancesCache .end ()) { // cache miss, new address
42123 ++numChanges;
43124 changedAddresses.insert (address);
44- walletCache .insert (std::make_pair (address,tally));
125+ walletBalancesCache .insert (std::make_pair (address,tally));
45126 if (msc_debug_walletcache) PrintToLog (" WALLETCACHE: *CACHE MISS* - %s not in cache\n " , address);
46127 continue ;
47128 }
@@ -57,8 +138,8 @@ int WalletCacheUpdate()
57138 tally.getMoney (propertyId, METADEX_RESERVE) != cacheTally.getMoney (propertyId, METADEX_RESERVE)) { // cache miss, balance
58139 ++numChanges;
59140 changedAddresses.insert (address);
60- walletCache .erase (search_it);
61- walletCache .insert (std::make_pair (address,tally));
141+ walletBalancesCache .erase (search_it);
142+ walletBalancesCache .insert (std::make_pair (address,tally));
62143 if (msc_debug_walletcache) PrintToLog (" WALLETCACHE: *CACHE MISS* - %s balance for property %d differs\n " , address, propertyId);
63144 break ;
64145 }
0 commit comments