Merge branch 'jl777' into example0

This commit is contained in:
jl777
2018-07-18 01:16:16 -11:00
5 changed files with 96 additions and 26 deletions

View File

@@ -588,13 +588,22 @@ CBlockTreeDB *pblocktree = NULL;
#define KOMODO_ZCASH #define KOMODO_ZCASH
#include "komodo.h" #include "komodo.h"
int64_t komodo_snapshot() UniValue komodo_snapshot()
{ {
LOCK(cs_main);
int64_t total = -1; int64_t total = -1;
if ( pblocktree != 0 ) UniValue result(UniValue::VOBJ);
total = pblocktree->Snapshot();
else fprintf(stderr,"null pblocktree start with -addressindex=true\n"); if (fAddressIndex) {
return(total); if ( pblocktree != 0 ) {
result = pblocktree->Snapshot();
} else {
fprintf(stderr,"null pblocktree start with -addressindex=true\n");
}
} else {
fprintf(stderr,"getsnapshot requires -addressindex=true\n");
}
return(result);
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@@ -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) UniValue getsnapshot(const UniValue& params, bool fHelp)
{ {
@@ -1026,9 +1026,12 @@ UniValue getsnapshot(const UniValue& params, bool fHelp)
"getsnapshot\n" "getsnapshot\n"
); );
} }
if ( (total= komodo_snapshot()) >= 0 ) result = komodo_snapshot();
result.push_back(Pair("total", (double)total/COIN)); if ( result.size() > 0 ) {
else result.push_back(Pair("error", "no addressindex")); result.push_back(Pair("end_time", time(NULL)));
} else {
result.push_back(Pair("error", "no addressindex"));
}
return(result); return(result);
} }

View File

@@ -10,6 +10,7 @@
#include "main.h" #include "main.h"
#include "pow.h" #include "pow.h"
#include "uint256.h" #include "uint256.h"
#include "core_io.h"
#include <stdint.h> #include <stdint.h>
@@ -398,12 +399,19 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type,
bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address); 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<leveldb::Iterator> pcursor(NewIterator()); boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator());
std::map <std::string, CAmount> addressAmounts;
UniValue result(UniValue::VOBJ);
result.push_back(Pair("start_time", time(NULL)));
//pcursor->SeekToFirst();
pcursor->SeekToLast(); pcursor->SeekToLast();
fprintf(stderr,"pcursor iterate\n");
int64_t startingHeight = chainActive.Height();
while (pcursor->Valid()) while (pcursor->Valid())
{ {
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
@@ -411,33 +419,74 @@ int64_t CBlockTreeDB::Snapshot()
{ {
leveldb::Slice slKey = pcursor->key(); leveldb::Slice slKey = pcursor->key();
CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
CAddressIndexKey indexKey; CAddressIndexIteratorKey indexKey;
ssKey >> chType; ssKey >> chType;
ssKey >> indexKey; ssKey >> indexKey;
fprintf(stderr,"chType.%d\n",chType);
if ( chType == DB_ADDRESSINDEX ) if ( chType == DB_ADDRESSUNSPENTINDEX )
{ {
try { try {
leveldb::Slice slValue = pcursor->value(); leveldb::Slice slValue = pcursor->value();
CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION); CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
CAmount nValue; CAmount nValue;
ssValue >> nValue; ssValue >> nValue;
getAddressFromIndex(indexKey.type, indexKey.hashBytes, address);
fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); getAddressFromIndex(indexKey.type, indexKey.hashBytes, address);
if ( total < 0 ) std::map <std::string, CAmount>::iterator pos = addressAmounts.find(address);
total = (int64_t)nValue; if (pos == addressAmounts.end()) {
else total += (int64_t)nValue; // insert new address + utxo amount
//addressIndex.push_back(make_pair(indexKey, nValue)); //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 += nValue;
} catch (const std::exception& e) { } catch (const std::exception& e) {
return error("failed to get address index value"); return error("failed to get address index value");
} }
} else { break; } } else { break; }
} catch (const std::exception& e) { } catch (const std::exception& e) {
fprintf(stderr, "%s: LevelDB exception! - %s\n", __func__, e.what());
break; break;
} }
pcursor->Prev(); pcursor->Prev();
} }
return(total);
UniValue addresses(UniValue::VARR);
fprintf(stderr, "total=%f, totalAddresses=%li\n", (double) total / COIN, totalAddresses);
typedef std::function<bool(std::pair<std::string, CAmount>, std::pair<std::string, CAmount>)> Comparator;
Comparator compFunctor = [](std::pair<std::string, CAmount> elem1 ,std::pair<std::string, CAmount> elem2) {
return elem1.second > elem2.second; /* descending */
};
// This is our intermediate data structure that allows us to calculate addressSorted
std::set<std::pair<std::string, CAmount>, Comparator> sortedSnapshot(addressAmounts.begin(), addressAmounts.end(), compFunctor);
UniValue obj(UniValue::VOBJ);
UniValue addressesSorted(UniValue::VARR);
for (std::pair<std::string, CAmount> element : sortedSnapshot) {
UniValue obj(UniValue::VOBJ);
obj.push_back( make_pair("addr", element.first.c_str() ) );
char amount[32];
sprintf(amount, "%.8f", (double) element.second / COIN);
obj.push_back( make_pair("amount", amount) );
addressesSorted.push_back(obj);
}
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));
// 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);
} }
bool CBlockTreeDB::WriteTimestampIndex(const CTimestampIndexKey &timestampIndex) { bool CBlockTreeDB::WriteTimestampIndex(const CTimestampIndexKey &timestampIndex) {

View File

@@ -13,6 +13,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <univalue.h>
class CBlockFileInfo; class CBlockFileInfo;
class CBlockIndex; class CBlockIndex;
@@ -94,7 +95,7 @@ public:
bool ReadFlag(const std::string &name, bool &fValue); bool ReadFlag(const std::string &name, bool &fValue);
bool LoadBlockIndexGuts(); bool LoadBlockIndexGuts();
bool blockOnchainActive(const uint256 &hash); bool blockOnchainActive(const uint256 &hash);
int64_t Snapshot(); UniValue Snapshot();
}; };
#endif // BITCOIN_TXDB_H #endif // BITCOIN_TXDB_H

View File

@@ -1885,6 +1885,11 @@ void CWallet::ReacceptWalletTransactions()
bool CWalletTx::RelayWalletTransaction() bool CWalletTx::RelayWalletTransaction()
{ {
if ( pwallet == 0 )
{
fprintf(stderr,"unexpected null pwallet in RelayWalletTransaction\n");
return(false);
}
assert(pwallet->GetBroadcastTransactions()); assert(pwallet->GetBroadcastTransactions());
if (!IsCoinBase()) if (!IsCoinBase())
{ {
@@ -2124,9 +2129,12 @@ std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime)
} }
BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
{ {
CWalletTx& wtx = *item.second; if ( item.second != 0 )
if (wtx.RelayWalletTransaction()) {
result.push_back(wtx.GetHash()); CWalletTx &wtx = *item.second;
if (wtx.RelayWalletTransaction())
result.push_back(wtx.GetHash());
}
} }
return result; return result;
} }