From cbce9f1f65a3bca9c373577178d6e6447d09dc90 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 14 Jul 2018 23:00:09 +0000 Subject: [PATCH 01/11] WIP debugging why leveldb iterator is broke --- src/main.cpp | 14 +++++++++++--- src/txdb.cpp | 18 ++++++++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b08d2e522..15d74adb2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -590,10 +590,18 @@ CBlockTreeDB *pblocktree = NULL; int64_t komodo_snapshot() { + fprintf(stderr,"komodo_snapshot\n"); int64_t total = -1; - if ( pblocktree != 0 ) - total = pblocktree->Snapshot(); - else fprintf(stderr,"null pblocktree start with -addressindex=true\n"); + if (fAddressIndex) { + if ( pblocktree != 0 ) { + total = pblocktree->Snapshot(); + } else { + fprintf(stderr,"null pblocktree start with -addressindex=true\n"); + } + } else { + fprintf(stderr,"getsnapshot requires -addressindex=true\n"); + } + fprintf(stderr,"total=%li\n", total); return(total); } diff --git a/src/txdb.cpp b/src/txdb.cpp index a0f764962..fa3766faf 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -402,18 +402,31 @@ int64_t CBlockTreeDB::Snapshot() { char chType; int64_t total = -1; std::string address; boost::scoped_ptr pcursor(NewIterator()); - pcursor->SeekToFirst(); + //boost::scoped_ptr pcursor(pdb->NewIterator(leveldb::ReadOptions()) ); + //boost::scoped_ptr pcursor(db->NewIterator()); + fprintf(stderr,"Snapshot\n"); + + //pcursor->SeekToFirst(); + pcursor->SeekToLast(); + fprintf(stderr,"SeekToLast\n"); + fprintf(stderr,"pcursor iterate\n"); while (pcursor->Valid()) { + fprintf(stderr,"pcursor valid\n"); boost::this_thread::interruption_point(); + fprintf(stderr,"about to try\n"); try { leveldb::Slice slKey = pcursor->key(); + fprintf(stderr,"made slice\n"); CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); + fprintf(stderr,"made ssKey\n"); CAddressIndexKey indexKey; ssKey >> chType; + fprintf(stderr,"made chType\n"); ssKey >> indexKey; + fprintf(stderr,"made indexKey\n"); fprintf(stderr,"chType.%d\n",chType); if ( chType == DB_ADDRESSINDEX ) { @@ -428,12 +441,13 @@ int64_t CBlockTreeDB::Snapshot() total = (int64_t)nValue; else total += (int64_t)nValue; //addressIndex.push_back(make_pair(indexKey, nValue)); - pcursor->Next(); + pcursor->Prev(); } catch (const std::exception& e) { return error("failed to get address index value"); } } else { break; } } catch (const std::exception& e) { + fprintf(stderr, "%s: LevelDB exception! - %s\n", __func__, e.what()); break; } } From d62d9d7889f7c647f19534f0986e0e9372db6377 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 17 Jul 2018 01:40:24 +0000 Subject: [PATCH 02/11] Almost working snapshot, we need to sum unspent outputs for each address and return to final snapshot data in json response --- src/txdb.cpp | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index fa3766faf..dfef647e6 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -400,36 +400,30 @@ bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &addr int64_t CBlockTreeDB::Snapshot() { - char chType; int64_t total = -1; std::string address; + char chType; int64_t total = 0; std::string address; boost::scoped_ptr pcursor(NewIterator()); - //boost::scoped_ptr pcursor(pdb->NewIterator(leveldb::ReadOptions()) ); - //boost::scoped_ptr pcursor(db->NewIterator()); - fprintf(stderr,"Snapshot\n"); - + //pcursor->SeekToFirst(); pcursor->SeekToLast(); - fprintf(stderr,"SeekToLast\n"); - fprintf(stderr,"pcursor iterate\n"); while (pcursor->Valid()) { - fprintf(stderr,"pcursor valid\n"); + //fprintf(stderr,"pcursor valid\n"); boost::this_thread::interruption_point(); - fprintf(stderr,"about to try\n"); try { leveldb::Slice slKey = pcursor->key(); - fprintf(stderr,"made slice\n"); CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); - fprintf(stderr,"made ssKey\n"); - CAddressIndexKey indexKey; + // CAddressIndexKey indexKey; + CAddressIndexIteratorKey indexKey; ssKey >> chType; - fprintf(stderr,"made chType\n"); ssKey >> indexKey; - fprintf(stderr,"made indexKey\n"); - fprintf(stderr,"chType.%d\n",chType); - if ( chType == DB_ADDRESSINDEX ) + //fprintf(stderr,"chType.%d\n",chType); + //fprintf(stderr,"dbindex prefix=%d\n",DB_ADDRESSINDEX); + //if ( chType == 'u' ) // chType == DB_ADDRESSINDEX ) + if ( chType == DB_ADDRESSUNSPENTINDEX ) // chType == DB_ADDRESSINDEX ) { + try { leveldb::Slice slValue = pcursor->value(); CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION); @@ -437,11 +431,9 @@ int64_t CBlockTreeDB::Snapshot() ssValue >> nValue; getAddressFromIndex(indexKey.type, indexKey.hashBytes, address); fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); - if ( total < 0 ) - total = (int64_t)nValue; - else total += (int64_t)nValue; + + total += (double) nValue / COIN; //addressIndex.push_back(make_pair(indexKey, nValue)); - pcursor->Prev(); } catch (const std::exception& e) { return error("failed to get address index value"); } @@ -450,6 +442,7 @@ int64_t CBlockTreeDB::Snapshot() fprintf(stderr, "%s: LevelDB exception! - %s\n", __func__, e.what()); break; } + pcursor->Prev(); } return(total); } From 920f9601222ad9d4d047e6242e75e539ed991f03 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 17 Jul 2018 06:05:36 +0000 Subject: [PATCH 03/11] Correctly print out snapshot data to stderr for now --- src/txdb.cpp | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index dfef647e6..00d3d276b 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -402,38 +402,46 @@ int64_t CBlockTreeDB::Snapshot() { char chType; int64_t total = 0; std::string address; boost::scoped_ptr pcursor(NewIterator()); + std::map addressAmounts; //pcursor->SeekToFirst(); pcursor->SeekToLast(); while (pcursor->Valid()) { - //fprintf(stderr,"pcursor valid\n"); boost::this_thread::interruption_point(); try { leveldb::Slice slKey = pcursor->key(); CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); - // CAddressIndexKey indexKey; CAddressIndexIteratorKey indexKey; ssKey >> chType; ssKey >> indexKey; - //fprintf(stderr,"chType.%d\n",chType); - //fprintf(stderr,"dbindex prefix=%d\n",DB_ADDRESSINDEX); - //if ( chType == 'u' ) // chType == DB_ADDRESSINDEX ) - if ( chType == DB_ADDRESSUNSPENTINDEX ) // chType == DB_ADDRESSINDEX ) - { + if ( chType == DB_ADDRESSUNSPENTINDEX ) + { try { leveldb::Slice slValue = pcursor->value(); CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION); CAmount nValue; ssValue >> nValue; + //if (!getAddressFromIndex(indexKey.type, indexKey.hashBytes, address)) { getAddressFromIndex(indexKey.type, indexKey.hashBytes, address); - fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); - total += (double) nValue / COIN; - //addressIndex.push_back(make_pair(indexKey, nValue)); + std::map ::iterator pos = addressAmounts.find(address); + if (pos == addressAmounts.end()) { + // insert new address + utxo amount + fprintf(stderr, "inserting new address %s with amount %li\n", address.c_str(), nValue); + addressAmounts[address] = nValue; + } else { + // update unspent tally for this address + addressAmounts[address] += nValue; + } + + //fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); + total += (double) nValue / COIN; + //addressIndex.push_back(make_pair(indexKey, nValue)); + //} } catch (const std::exception& e) { return error("failed to get address index value"); } @@ -442,8 +450,14 @@ int64_t CBlockTreeDB::Snapshot() fprintf(stderr, "%s: LevelDB exception! - %s\n", __func__, e.what()); break; } - pcursor->Prev(); + pcursor->Prev(); } + + for (map ::iterator it = addressAmounts.begin(); it != addressAmounts.end(); it++) + { + fprintf(stderr,"{\"%s\", %.8f},\n",it->first.c_str(),(double) it->second / COIN); + } + return(total); } From 7000ef1af3ddfc99bde07c185c781ea198d5eea5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 17 Jul 2018 05:26:34 -1100 Subject: [PATCH 04/11] Possible workaround for crash --- src/wallet/wallet.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ce5630fb6..e62c6e60b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1885,6 +1885,11 @@ void CWallet::ReacceptWalletTransactions() bool CWalletTx::RelayWalletTransaction() { + if ( pwallet == 0 ) + { + fprintf(stderr,"unexpected null pwallet in RelayWalletTransaction\n"); + return(false); + } assert(pwallet->GetBroadcastTransactions()); if (!IsCoinBase()) { @@ -2124,9 +2129,13 @@ std::vector CWallet::ResendWalletTransactionsBefore(int64_t nTime) } BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) { - CWalletTx& wtx = *item.second; - if (wtx.RelayWalletTransaction()) - result.push_back(wtx.GetHash()); + CWalletTx& wtx; + if ( item.second != 0 ) + { + wtx = *item.second; + if (wtx.RelayWalletTransaction()) + result.push_back(wtx.GetHash()); + } } return result; } From 3872e9cb59b99fbffc23ea9fa3587afbb68a524c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 17 Jul 2018 05:29:01 -1100 Subject: [PATCH 05/11] Fix --- src/wallet/wallet.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e62c6e60b..5100a2470 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2129,10 +2129,9 @@ std::vector CWallet::ResendWalletTransactionsBefore(int64_t nTime) } BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) { - CWalletTx& wtx; if ( item.second != 0 ) { - wtx = *item.second; + CWalletTx &wtx = *item.second; if (wtx.RelayWalletTransaction()) result.push_back(wtx.GetHash()); } From 92dc28a3c92a1b5fea3c5ccf69dd796c6664e7b6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 17 Jul 2018 18:42:30 +0000 Subject: [PATCH 06/11] Return snapshot info as JSON --- src/main.cpp | 9 ++++----- src/rpcmisc.cpp | 12 ++++++++---- src/txdb.cpp | 43 ++++++++++++++++++++++++------------------- src/txdb.h | 3 ++- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 15d74adb2..dfebfec4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -588,21 +588,20 @@ CBlockTreeDB *pblocktree = NULL; #define KOMODO_ZCASH #include "komodo.h" -int64_t komodo_snapshot() +UniValue komodo_snapshot() { - fprintf(stderr,"komodo_snapshot\n"); int64_t total = -1; + UniValue result(UniValue::VOBJ); if (fAddressIndex) { if ( pblocktree != 0 ) { - total = pblocktree->Snapshot(); + result = pblocktree->Snapshot(); } else { fprintf(stderr,"null pblocktree start with -addressindex=true\n"); } } else { fprintf(stderr,"getsnapshot requires -addressindex=true\n"); } - fprintf(stderr,"total=%li\n", total); - return(total); + return(result); } ////////////////////////////////////////////////////////////////////////////// diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index bf7f345d5..198b41090 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -1015,7 +1015,7 @@ UniValue getaddressbalance(const UniValue& params, bool fHelp) } -int32_t komodo_snapshot(); +UniValue komodo_snapshot(); UniValue getsnapshot(const UniValue& params, bool fHelp) { @@ -1026,9 +1026,13 @@ UniValue getsnapshot(const UniValue& params, bool fHelp) "getsnapshot\n" ); } - if ( (total= komodo_snapshot()) >= 0 ) - result.push_back(Pair("total", (double)total/COIN)); - else result.push_back(Pair("error", "no addressindex")); + result = komodo_snapshot(); + if ( result.size() > 0 ) { + // add timestamp, maybe block height? + result.push_back(Pair("time", time(NULL))); + } else { + result.push_back(Pair("error", "no addressindex")); + } return(result); } diff --git a/src/txdb.cpp b/src/txdb.cpp index 00d3d276b..63b640123 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -10,6 +10,7 @@ #include "main.h" #include "pow.h" #include "uint256.h" +#include "core_io.h" #include @@ -398,11 +399,12 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type, bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address); -int64_t CBlockTreeDB::Snapshot() +extern UniValue CBlockTreeDB::Snapshot() { - char chType; int64_t total = 0; std::string address; + char chType; int64_t total = 0; int64_t totalAddresses = 0; std::string address; boost::scoped_ptr pcursor(NewIterator()); std::map addressAmounts; + UniValue result(UniValue::VOBJ); //pcursor->SeekToFirst(); pcursor->SeekToLast(); @@ -425,23 +427,22 @@ int64_t CBlockTreeDB::Snapshot() CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION); CAmount nValue; ssValue >> nValue; - //if (!getAddressFromIndex(indexKey.type, indexKey.hashBytes, address)) { - getAddressFromIndex(indexKey.type, indexKey.hashBytes, address); - std::map ::iterator pos = addressAmounts.find(address); - if (pos == addressAmounts.end()) { - // insert new address + utxo amount - fprintf(stderr, "inserting new address %s with amount %li\n", address.c_str(), nValue); - addressAmounts[address] = nValue; - } else { - // update unspent tally for this address - addressAmounts[address] += nValue; - } + getAddressFromIndex(indexKey.type, indexKey.hashBytes, address); + std::map ::iterator pos = addressAmounts.find(address); + if (pos == addressAmounts.end()) { + // insert new address + utxo amount + fprintf(stderr, "inserting new address %s with amount %li\n", address.c_str(), nValue); + addressAmounts[address] = nValue; + totalAddresses++; + } else { + // update unspent tally for this address + addressAmounts[address] += nValue; + } - //fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); - total += (double) nValue / COIN; - //addressIndex.push_back(make_pair(indexKey, nValue)); - //} + //fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); + total += nValue; + //addressIndex.push_back(make_pair(indexKey, nValue)); } catch (const std::exception& e) { return error("failed to get address index value"); } @@ -453,12 +454,16 @@ int64_t CBlockTreeDB::Snapshot() pcursor->Prev(); } + // TODO: create addresses key with array of {address,amount} + + fprintf(stderr, "total=%f, totalAddresses=%li\n", (double) total / COIN, totalAddresses); for (map ::iterator it = addressAmounts.begin(); it != addressAmounts.end(); it++) { - fprintf(stderr,"{\"%s\", %.8f},\n",it->first.c_str(),(double) it->second / COIN); + fprintf(stderr,"{\"%s\", %.8f},\n",it->first.c_str(),(double) it->second / COIN); + result.push_back(make_pair( it->first.c_str(), (double) it->second / COIN ) ); } - return(total); + return(result); } bool CBlockTreeDB::WriteTimestampIndex(const CTimestampIndexKey ×tampIndex) { diff --git a/src/txdb.h b/src/txdb.h index cb4d6d19e..6c6b41917 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -13,6 +13,7 @@ #include #include #include +#include class CBlockFileInfo; class CBlockIndex; @@ -94,7 +95,7 @@ public: bool ReadFlag(const std::string &name, bool &fValue); bool LoadBlockIndexGuts(); bool blockOnchainActive(const uint256 &hash); - int64_t Snapshot(); + UniValue Snapshot(); }; #endif // BITCOIN_TXDB_H From 29a5aa99fd5090bf3ca1b1248a844807bcff377c Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 17 Jul 2018 19:39:55 +0000 Subject: [PATCH 07/11] Move address+amount data to addresses key in JSON; add some useful metadata to snapshot response --- src/txdb.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 63b640123..9170ceea0 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -454,15 +454,23 @@ extern UniValue CBlockTreeDB::Snapshot() pcursor->Prev(); } - // TODO: create addresses key with array of {address,amount} + UniValue addresses(UniValue::VARR); fprintf(stderr, "total=%f, totalAddresses=%li\n", (double) total / COIN, totalAddresses); for (map ::iterator it = addressAmounts.begin(); it != addressAmounts.end(); it++) { - fprintf(stderr,"{\"%s\", %.8f},\n",it->first.c_str(),(double) it->second / COIN); - result.push_back(make_pair( it->first.c_str(), (double) it->second / COIN ) ); + UniValue obj(UniValue::VOBJ); + fprintf(stderr,"{\"%s\", %.8f},\n",it->first.c_str(),(double) it->second / COIN); + obj.push_back( make_pair("addr", it->first.c_str() ) ); + obj.push_back( make_pair("amount", (double) it->second / COIN)); + addresses.push_back(obj); } + result.push_back(make_pair("addresses", addresses)); + result.push_back(make_pair("total", total / COIN )); + result.push_back(make_pair("average",(double) (total/COIN) / totalAddresses )); + result.push_back(make_pair("total_addresses", totalAddresses)); + result.push_back(make_pair("height", chainActive.Height())); return(result); } From 6e74fd25780d8ac14d20bd89d5ced6eb368e7440 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 17 Jul 2018 21:37:52 +0000 Subject: [PATCH 08/11] In memory sorting, add a few metadata fields; printing small floats correctly still not working --- src/txdb.cpp | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 9170ceea0..b4ea54f9b 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -409,6 +409,14 @@ extern UniValue CBlockTreeDB::Snapshot() //pcursor->SeekToFirst(); pcursor->SeekToLast(); + int64_t startingHeight = chainActive.Height(); + + // prevent any node updates so we can get a consistent snapshot at this height + // causes coredumps + // LOCK(cs_main); + // does not compile + //LOCK(cs_wallet); + while (pcursor->Valid()) { boost::this_thread::interruption_point(); @@ -442,7 +450,6 @@ extern UniValue CBlockTreeDB::Snapshot() //fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); total += nValue; - //addressIndex.push_back(make_pair(indexKey, nValue)); } catch (const std::exception& e) { return error("failed to get address index value"); } @@ -455,22 +462,39 @@ extern UniValue CBlockTreeDB::Snapshot() } UniValue addresses(UniValue::VARR); - fprintf(stderr, "total=%f, totalAddresses=%li\n", (double) total / COIN, totalAddresses); - for (map ::iterator it = addressAmounts.begin(); it != addressAmounts.end(); it++) - { - UniValue obj(UniValue::VOBJ); - fprintf(stderr,"{\"%s\", %.8f},\n",it->first.c_str(),(double) it->second / COIN); - obj.push_back( make_pair("addr", it->first.c_str() ) ); - obj.push_back( make_pair("amount", (double) it->second / COIN)); - addresses.push_back(obj); + + typedef std::function, std::pair)> Comparator; + Comparator compFunctor = [](std::pair elem1 ,std::pair elem2) { + return elem1.second > elem2.second; /* descending */ + }; + // This is our intermediate data structure that allows us to calculate addressSorted + std::set, Comparator> sortedSnapshot(addressAmounts.begin(), addressAmounts.end(), compFunctor); + + UniValue obj(UniValue::VOBJ); + UniValue addressesSorted(UniValue::VARR); + for (std::pair element : sortedSnapshot) { + UniValue obj(UniValue::VOBJ); + obj.push_back( make_pair("addr", element.first.c_str() ) ); + std::ostringstream strs; + strs << ((double) element.second/COIN); + std::string amount = strs.str(); + + //std::string amount = boost::lexical_cast((double) element.second/COIN); + //sprintf(amount, "%.8f", (double) element.second / COIN); + obj.push_back( make_pair("amount", amount) ); + addressesSorted.push_back(obj); } - result.push_back(make_pair("addresses", addresses)); + result.push_back(make_pair("addresses", addressesSorted)); result.push_back(make_pair("total", total / COIN )); result.push_back(make_pair("average",(double) (total/COIN) / totalAddresses )); + // Total number of addresses in this snaphot result.push_back(make_pair("total_addresses", totalAddresses)); - result.push_back(make_pair("height", chainActive.Height())); + // The snapshot began at this block height + result.push_back(make_pair("start_height", startingHeight)); + // The snapshot finished at this block height + result.push_back(make_pair("ending_height", chainActive.Height())); return(result); } From 3eb535b8b4c61e63027611aaf02f3a4dcae9626b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 17 Jul 2018 22:31:06 +0000 Subject: [PATCH 09/11] Include start_time+end_time and correctly format amount --- src/main.cpp | 1 + src/rpcmisc.cpp | 3 +-- src/txdb.cpp | 15 +++------------ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index dfebfec4f..11bc3a352 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -592,6 +592,7 @@ UniValue komodo_snapshot() { int64_t total = -1; UniValue result(UniValue::VOBJ); + if (fAddressIndex) { if ( pblocktree != 0 ) { result = pblocktree->Snapshot(); diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 198b41090..01bd813e6 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -1028,8 +1028,7 @@ UniValue getsnapshot(const UniValue& params, bool fHelp) } result = komodo_snapshot(); if ( result.size() > 0 ) { - // add timestamp, maybe block height? - result.push_back(Pair("time", time(NULL))); + result.push_back(Pair("end_time", time(NULL))); } else { result.push_back(Pair("error", "no addressindex")); } diff --git a/src/txdb.cpp b/src/txdb.cpp index b4ea54f9b..2360ed340 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -405,18 +405,13 @@ extern UniValue CBlockTreeDB::Snapshot() boost::scoped_ptr pcursor(NewIterator()); std::map addressAmounts; UniValue result(UniValue::VOBJ); + result.push_back(Pair("start_time", time(NULL))); //pcursor->SeekToFirst(); pcursor->SeekToLast(); int64_t startingHeight = chainActive.Height(); - // prevent any node updates so we can get a consistent snapshot at this height - // causes coredumps - // LOCK(cs_main); - // does not compile - //LOCK(cs_wallet); - while (pcursor->Valid()) { boost::this_thread::interruption_point(); @@ -476,12 +471,8 @@ extern UniValue CBlockTreeDB::Snapshot() for (std::pair element : sortedSnapshot) { UniValue obj(UniValue::VOBJ); obj.push_back( make_pair("addr", element.first.c_str() ) ); - std::ostringstream strs; - strs << ((double) element.second/COIN); - std::string amount = strs.str(); - - //std::string amount = boost::lexical_cast((double) element.second/COIN); - //sprintf(amount, "%.8f", (double) element.second / COIN); + char amount[32]; + sprintf(amount, "%.8f", (double) element.second / COIN); obj.push_back( make_pair("amount", amount) ); addressesSorted.push_back(obj); } From 539080b3a4109285dc1a3b77fb5a15e782d7cc7e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 17 Jul 2018 22:33:19 +0000 Subject: [PATCH 10/11] Less noise to stderr --- src/txdb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 2360ed340..cb0358403 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -435,7 +435,7 @@ extern UniValue CBlockTreeDB::Snapshot() std::map ::iterator pos = addressAmounts.find(address); if (pos == addressAmounts.end()) { // insert new address + utxo amount - fprintf(stderr, "inserting new address %s with amount %li\n", address.c_str(), nValue); + //fprintf(stderr, "inserting new address %s with amount %li\n", address.c_str(), nValue); addressAmounts[address] = nValue; totalAddresses++; } else { From 9ef7fec1efd4f45ca603fbd7a25aa2beae4a5f64 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 18 Jul 2018 06:54:43 +0000 Subject: [PATCH 11/11] Protect komodo_snapshot() by cs_main lock --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cpp b/src/main.cpp index 1376c3c7b..aa4435843 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -590,6 +590,7 @@ CBlockTreeDB *pblocktree = NULL; UniValue komodo_snapshot() { + LOCK(cs_main); int64_t total = -1; UniValue result(UniValue::VOBJ);