attempt at daily snapshot
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "CCinclude.h"
|
||||
|
||||
#define PAYMENTS_TXFEE 10000
|
||||
bool komodo_snapshot2(std::map <std::string, CAmount> &addressAmounts);
|
||||
|
||||
bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
@@ -28,6 +29,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr);
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ get the payment fund scriptpubkey hex from vout 0: (the split it at OP_CHECKCRYP
|
||||
put the second half into an OP_RETURN: (the remaining part of the the above scriptpubkey) eg.
|
||||
./komodo-cli -ac_name=TESTHC opreturn_burn 1 2a0401f00101246a22f046337db779358deaa69b9af053e27d85cb8e8e48b0b13805c084b04f87be6577ee75
|
||||
opret_burn takes any burn amount and arbitrary hex string. (RPC works, but may have bugs, likely use this for LABS too with some fixes)
|
||||
this gives a raw hex. Decode it and check the OP_RETURN is right before sending (using this RPC currently adds 3 extra bytes to the front (6a2d2c), which is truncated later on, this should be fixed if possible before making any real chains as its consensus code. Need to try diffrent methods to decode the hex correctly.)
|
||||
this gives a raw hex. Decode it and check the OP_RETURN is right before sending.
|
||||
-earlytxid=810bd62fb8353fad20267ff2050684b8829affa3edf6b366633931530791dfce
|
||||
restart the chain with earlytxid param before height 100 on all nodes (if not using -testnode=1)
|
||||
./komodod -ac_name=TESTHC -ac_supply=1000000 -ac_reward=100000000000 -ac_cc=2 -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 -ac_founders=150 -ac_blocktime=20 -ac_nk=96,5 -earlytxid=810bd62fb8353fad20267ff2050684b8829affa3edf6b366633931530791dfce
|
||||
|
||||
@@ -16,6 +16,18 @@
|
||||
#include "CCPayments.h"
|
||||
|
||||
/*
|
||||
payments airdrop:
|
||||
- extra RPC to merge all payments inputs to a single utxo, this must be called first and be confirmed before payments release,
|
||||
or tx will be too big, we can check add payments inputs is only 1 input, at RPC and in validation very early on.
|
||||
- do getsnapshot2 every 1440 blocks and save the result into some global sorted vector or DB?
|
||||
-this allows any address balance to be calculated by only iterating each 1439 blocks maximum.
|
||||
- calculate scriptpubkey to pay from each address, set allocations from balance of each address. allocation = balance?
|
||||
|
||||
payments airdrop paying a token: ( maybe this is more reasonable speed wise? )
|
||||
- tokenid, top number of tokens to pay, list of pubkeys to exclude as optional param
|
||||
- add vector of tokenids to getsnapshot2 - then sort each tokenid by balance.
|
||||
put the pubkey to pay to as scriptpubkey in the saved vector.
|
||||
|
||||
0) txidopret <- allocation, scriptPubKey, opret
|
||||
1) create <- locked_blocks, minrelease, list of txidopret
|
||||
|
||||
@@ -781,76 +793,14 @@ UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr)
|
||||
return(result);
|
||||
}
|
||||
|
||||
extern bool komodo_dailysnapshot(int32_t height);
|
||||
|
||||
UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
// need to code: exclude list of tokenid, dust threshold, maxpayees, excluded pubkeys[]
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ); CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::vector<uint256> txidoprets; uint256 hashBlock; int32_t i,n,numoprets=0,lockedblocks,minrelease; std::string rawtx; int64_t totalallocations = 0;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
if ( params != 0 && n >= 4 )
|
||||
{
|
||||
lockedblocks = juint(jitem(params,0),0);
|
||||
minrelease = juint(jitem(params,1),0);
|
||||
if ( lockedblocks < 0 || minrelease < 0 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
for (i=0; i<n-2; i++)
|
||||
txidoprets.push_back(payments_juint256(jitem(params,2+i)));
|
||||
for (i=0; i<txidoprets.size(); i++)
|
||||
{
|
||||
std::vector<uint8_t> scriptPubKey,opret; int64_t allocation;
|
||||
if ( myGetTransaction(txidoprets[i],tx,hashBlock) != 0 && tx.vout.size() > 1 && DecodePaymentsTxidOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' )
|
||||
{
|
||||
totalallocations += allocation;
|
||||
if ( opret.size() > 0 )
|
||||
numoprets++;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","invalid txidopret"));
|
||||
result.push_back(Pair("txid",txidoprets[i].GetHex()));
|
||||
result.push_back(Pair("txi",(int64_t)i));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
}
|
||||
if ( numoprets > 1 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","too many opreturns"));
|
||||
result.push_back(Pair("numoprets",(int64_t)numoprets));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsOpRet(lockedblocks,minrelease,totalallocations,txidoprets));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(payments_rawtxresult(result,rawtx,1));
|
||||
}
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","not enough normal funds"));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
uint64_t start = time(NULL);
|
||||
komodo_dailysnapshot(chainActive.Height());
|
||||
//CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
return(time(NULL)-start);
|
||||
}
|
||||
|
||||
UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define ASSETCHAINS_MINHEIGHT 128
|
||||
#define ASSETCHAINS_MAX_ERAS 3
|
||||
#define KOMODO_ELECTION_GAP 2000
|
||||
#define KOMODO_SNAPSHOT_INTERVAL 1440 // 1440 is approx 1 day. Maybe this can be -ac param to allow for diffrent block times etc.?
|
||||
#define ROUNDROBIN_DELAY 61
|
||||
#define KOMODO_ASSETCHAIN_MAXLEN 65
|
||||
#define KOMODO_LIMITED_NETWORKSIZE 4
|
||||
|
||||
107
src/main.cpp
107
src/main.cpp
@@ -642,6 +642,96 @@ UniValue komodo_snapshot(int top)
|
||||
return(result);
|
||||
}
|
||||
|
||||
bool komodo_snapshot2(std::map <std::string, CAmount> &addressAmounts)
|
||||
{
|
||||
if ( fAddressIndex && pblocktree != 0 )
|
||||
{
|
||||
return pblocktree->Snapshot2(addressAmounts, 0);
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
int32_t lastSnapShotHeight = 0;
|
||||
std::vector <std::pair<CAmount, CTxDestination>> vAddressSnapshot;
|
||||
|
||||
bool komodo_dailysnapshot(int32_t height)
|
||||
{
|
||||
uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height;
|
||||
notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid);
|
||||
if ( notarized_height > height-100 )
|
||||
{
|
||||
// notarized height is higher than 100 blocks before this height, so snapshot the notarized height.
|
||||
undo_height = notarized_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
//snapshot 100 blocks ago. Could still be reorged but very unlikley and expensive to carry out constantly.
|
||||
undo_height = height-100;
|
||||
}
|
||||
fprintf(stderr, "doing snapshot for height.%i lastSnapShotHeight.%i\n", undo_height, lastSnapShotHeight);
|
||||
// if we already did this height dont bother doing it again, this is just a reorg. The actual snapshot height cannot be reorged.
|
||||
if ( undo_height == lastSnapShotHeight )
|
||||
return true;
|
||||
std::map <std::string, int64_t> addressAmounts;
|
||||
if ( !komodo_snapshot2(addressAmounts) )
|
||||
return false;
|
||||
|
||||
// undo blocks in reverse order
|
||||
for (int32_t n = height; n > undo_height; n--)
|
||||
{
|
||||
//fprintf(stderr, "undoing block.%i\n",n);
|
||||
CBlockIndex *pindex; CBlock block;
|
||||
if ( (pindex= komodo_chainactive(n)) == 0 || komodo_blockload(block, pindex) != 0 )
|
||||
return false;
|
||||
// undo transactions in reverse order
|
||||
for (int32_t i = block.vtx.size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CTransaction &tx = block.vtx[i];
|
||||
uint256 hash = tx.GetHash();
|
||||
CTxDestination vDest;
|
||||
//fprintf(stderr, "undong tx.%s\n",hash.GetHex().c_str());
|
||||
// loop vouts reverse order
|
||||
for (unsigned int k = tx.vout.size(); k-- > 0;)
|
||||
{
|
||||
const CTxOut &out = tx.vout[k];
|
||||
//fprintf(stderr, "scriptpubkey.%s\n",out.scriptPubKey.ToString().c_str() );
|
||||
if ( ExtractDestination(out.scriptPubKey, vDest) )
|
||||
{
|
||||
// add outputs to destination
|
||||
addressAmounts[CBitcoinAddress(vDest).ToString()] += out.nValue;
|
||||
//fprintf(stderr, "address.%s addcoins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), out.nValue);
|
||||
}
|
||||
}
|
||||
// loop vins in reverse order, get prevout and remove the balance from its destination
|
||||
for (unsigned int j = tx.vin.size(); j-- > 0;)
|
||||
{
|
||||
uint256 blockhash; CTransaction txin;
|
||||
if ( !tx.IsCoinImport() && !tx.IsCoinBase() && GetTransaction(tx.vin[j].prevout.hash,txin,blockhash,false) ) // myGetTransaction!
|
||||
{
|
||||
int vout = tx.vin[j].prevout.n;
|
||||
if ( ExtractDestination(txin.vout[vout].scriptPubKey, vDest) )
|
||||
{
|
||||
// remove outputs from destination
|
||||
//fprintf(stderr, "address.%s removecoins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), txin.vout[vout].nValue);
|
||||
addressAmounts[CBitcoinAddress(vDest).ToString()] -= txin.vout[vout].nValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vAddressSnapshot.clear(); // clear existing snapshot
|
||||
// convert address string to destination for easier conversion to what ever is required, eg, scriptPubKey.
|
||||
for ( auto element : addressAmounts)
|
||||
vAddressSnapshot.push_back(make_pair(element.second, DecodeDestination(element.first)));
|
||||
// sort the vector by amount, highest at top.
|
||||
std::sort(vAddressSnapshot.rbegin(), vAddressSnapshot.rend());
|
||||
// include only top 5000 address.
|
||||
if ( vAddressSnapshot.size() > 5000 ) vAddressSnapshot.resize(5000);
|
||||
lastSnapShotHeight = undo_height;
|
||||
fprintf(stderr, "vAddressSnapshot.size.%li\n", vAddressSnapshot.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// mapOrphanTransactions
|
||||
@@ -3096,7 +3186,6 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
||||
uint160 addrHash = addr.size() == 20 ? uint160(addr) : Hash160(addr);
|
||||
// undo spending activity
|
||||
addressIndex.push_back(make_pair(CAddressIndexKey(keyType, addrHash, pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
|
||||
|
||||
// restore unspent index
|
||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(keyType, addrHash, input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
|
||||
}
|
||||
@@ -4156,6 +4245,13 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
||||
komodo_pricesupdate(pindexNew->GetHeight(),pblock);
|
||||
if ( ASSETCHAINS_SAPLING <= 0 && pindexNew->nTime > KOMODO_SAPLING_ACTIVATION - 24*3600 )
|
||||
komodo_activate_sapling(pindexNew);
|
||||
if ( ASSETCHAINS_CC != 0 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 )
|
||||
{
|
||||
uint64_t start = time(NULL);
|
||||
if ( !komodo_dailysnapshot(pindexNew->GetHeight()) )
|
||||
fprintf(stderr, "daily snapshot failed, please reindex your chain\n"); // maybe force shutdown here?
|
||||
fprintf(stderr, "snapshot completed in: %lu seconds\n", time(NULL)-start);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6095,7 +6191,14 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
|
||||
}
|
||||
|
||||
LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->GetHeight(), nGoodTransactions);
|
||||
|
||||
|
||||
if ( ASSETCHAINS_CC != 0 && lastSnapShotHeight == 0 )
|
||||
{
|
||||
int32_t init_SS_height = chainActive.Height() - (chainActive.Height() % KOMODO_SNAPSHOT_INTERVAL);
|
||||
if ( !komodo_dailysnapshot(init_SS_height) )
|
||||
fprintf(stderr, "daily snapshot failed, please reindex your chain\n"); // maybe force shutdown here?
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -480,12 +480,13 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "marmara", "marmaralock", &marmara_lock, true },
|
||||
|
||||
// Payments
|
||||
{ "payments", "paymentsaddress", &paymentsaddress, true },
|
||||
{ "payments", "paymentstxidopret", &payments_txidopret, true },
|
||||
{ "payments", "paymentscreate", &payments_create, true },
|
||||
{ "payments", "paymentslist", &payments_list, true },
|
||||
{ "payments", "paymentsinfo", &payments_info, true },
|
||||
{ "payments", "paymentsfund", &payments_fund, true },
|
||||
{ "payments", "paymentsaddress", &paymentsaddress, true },
|
||||
{ "payments", "paymentstxidopret", &payments_txidopret, true },
|
||||
{ "payments", "paymentscreate", &payments_create, true },
|
||||
{ "payments", "paymentsairdrop", &payments_airdrop, true },
|
||||
{ "payments", "paymentslist", &payments_list, true },
|
||||
{ "payments", "paymentsinfo", &payments_info, true },
|
||||
{ "payments", "paymentsfund", &payments_fund, true },
|
||||
{ "payments", "paymentsrelease", &payments_release, true },
|
||||
|
||||
{ "CClib", "cclibaddress", &cclibaddress, true },
|
||||
|
||||
@@ -287,6 +287,7 @@ extern UniValue payments_release(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_fund(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_txidopret(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_create(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_airdrop(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_info(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_list(const UniValue& params, bool fHelp);
|
||||
|
||||
|
||||
89
src/txdb.cpp
89
src/txdb.cpp
@@ -458,13 +458,13 @@ uint32_t komodo_segid32(char *coinaddr);
|
||||
{"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY", 1} \
|
||||
};
|
||||
|
||||
int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector <std::pair<CAmount, std::string>> &vaddr, UniValue *ret)
|
||||
bool CBlockTreeDB::Snapshot2(std::map <std::string, CAmount> &addressAmounts, UniValue *ret)
|
||||
{
|
||||
int64_t total = 0; int64_t totalAddresses = 0; std::string address;
|
||||
int64_t utxos = 0; int64_t ignoredAddresses = 0, cryptoConditionsUTXOs = 0, cryptoConditionsTotals = 0;
|
||||
DECLARE_IGNORELIST
|
||||
boost::scoped_ptr<CDBIterator> iter(NewIterator());
|
||||
std::map <std::string, CAmount> addressAmounts;
|
||||
//std::map <std::string, CAmount> addressAmounts;
|
||||
for (iter->SeekToLast(); iter->Valid(); iter->Prev())
|
||||
{
|
||||
boost::this_thread::interruption_point();
|
||||
@@ -486,40 +486,39 @@ int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector
|
||||
{
|
||||
cryptoConditionsUTXOs++;
|
||||
cryptoConditionsTotals += nValue;
|
||||
total += nValue;
|
||||
continue;
|
||||
}
|
||||
if ( nValue > dustthreshold )
|
||||
std::map <std::string, int>::iterator ignored = ignoredMap.find(address);
|
||||
if (ignored != ignoredMap.end())
|
||||
{
|
||||
std::map <std::string, int>::iterator ignored = ignoredMap.find(address);
|
||||
if (ignored != ignoredMap.end())
|
||||
{
|
||||
fprintf(stderr,"ignoring %s\n", address.c_str());
|
||||
ignoredAddresses++;
|
||||
continue;
|
||||
}
|
||||
std::map <std::string, CAmount>::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
|
||||
//fprintf(stderr, "updating address %s with new utxo amount %li\n", address.c_str(), nValue);
|
||||
addressAmounts[address] += nValue;
|
||||
}
|
||||
//fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN);
|
||||
// total += nValue;
|
||||
utxos++;
|
||||
} //else fprintf(stderr,"ignoring amount=0 UTXO for %s\n", address.c_str());
|
||||
fprintf(stderr,"ignoring %s\n", address.c_str());
|
||||
ignoredAddresses++;
|
||||
continue;
|
||||
}
|
||||
std::map <std::string, CAmount>::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
|
||||
//fprintf(stderr, "updating address %s with new utxo amount %li\n", address.c_str(), nValue);
|
||||
addressAmounts[address] += nValue;
|
||||
}
|
||||
//fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN);
|
||||
// total += nValue;
|
||||
utxos++;
|
||||
total += nValue;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
fprintf(stderr, "DONE %s: LevelDB addressindex exception! - %s\n", __func__, e.what());
|
||||
break;
|
||||
return false; //break; this means failiure of DB? we need to exit here if so for consensus code!
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -530,30 +529,18 @@ int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector
|
||||
}
|
||||
}
|
||||
//fprintf(stderr, "total=%f, totalAddresses=%li, utxos=%li, ignored=%li\n", (double) total / COIN, totalAddresses, utxos, ignoredAddresses);
|
||||
for (std::pair<std::string, CAmount> element : addressAmounts)
|
||||
vaddr.push_back( make_pair(element.second, element.first) );
|
||||
std::sort(vaddr.rbegin(), vaddr.rend());
|
||||
int topN = 0;
|
||||
for (std::vector<std::pair<CAmount, std::string>>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it)
|
||||
{
|
||||
total += it->first;
|
||||
topN++;
|
||||
// If requested, only show top N addresses in output JSON
|
||||
if ( top == topN )
|
||||
break;
|
||||
}
|
||||
|
||||
// this is for the snapshot RPC, you can skip this by passing a 0 as the last argument.
|
||||
if (ret)
|
||||
{
|
||||
// Total amount in this snapshot, which is less than circulating supply if top parameter is used
|
||||
// Use the address_total for a total of all address included when using top parameter.
|
||||
ret->push_back(make_pair("total", (double) (total+cryptoConditionsTotals)/ COIN ));
|
||||
// Total circulating supply without CC vouts.
|
||||
ret->push_back(make_pair("total", (double) (total)/ COIN ));
|
||||
// Average amount in each address of this snapshot
|
||||
ret->push_back(make_pair("average",(double) (total/COIN) / totalAddresses ));
|
||||
// Total number of utxos processed in this snaphot
|
||||
ret->push_back(make_pair("utxos", utxos));
|
||||
// Total number of addresses in this snaphot
|
||||
ret->push_back(make_pair("total_addresses", top ? top : totalAddresses ));
|
||||
ret->push_back(make_pair("total_addresses", totalAddresses ));
|
||||
// Total number of ignored addresses in this snaphot
|
||||
ret->push_back(make_pair("ignored_addresses", ignoredAddresses));
|
||||
// Total number of crypto condition utxos we skipped
|
||||
@@ -561,22 +548,28 @@ int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector
|
||||
// Total value of skipped crypto condition utxos
|
||||
ret->push_back(make_pair("cc_utxo_value", (double) cryptoConditionsTotals / COIN));
|
||||
// total of all the address's, does not count coins in CC vouts.
|
||||
ret->push_back(make_pair("address_total", (double) total/ COIN ));
|
||||
ret->push_back(make_pair("total_includeCCvouts", (double) (total+cryptoConditionsTotals)/ COIN ));
|
||||
// The snapshot finished at this block height
|
||||
ret->push_back(make_pair("ending_height", chainActive.Height()));
|
||||
}
|
||||
return(topN);
|
||||
return true;
|
||||
}
|
||||
|
||||
UniValue CBlockTreeDB::Snapshot(int top)
|
||||
{
|
||||
int topN = 0;
|
||||
std::vector <std::pair<CAmount, std::string>> vaddr;
|
||||
//std::vector <std::vector <std::pair<CAmount, CScript>>> tokenids;
|
||||
std::map <std::string, CAmount> addressAmounts;
|
||||
UniValue result(UniValue::VOBJ);
|
||||
UniValue addressesSorted(UniValue::VARR);
|
||||
result.push_back(Pair("start_time", (int) time(NULL)));
|
||||
if ( Snapshot2(0,top,vaddr,&result) != 0 )
|
||||
if ( Snapshot2(addressAmounts,&result) )
|
||||
{
|
||||
for (std::pair<std::string, CAmount> element : addressAmounts)
|
||||
vaddr.push_back( make_pair(element.second, element.first) );
|
||||
std::sort(vaddr.rbegin(), vaddr.rend());
|
||||
int topN = 0;
|
||||
for (std::vector<std::pair<CAmount, std::string>>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it)
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
|
||||
@@ -116,7 +116,7 @@ public:
|
||||
bool LoadBlockIndexGuts();
|
||||
bool blockOnchainActive(const uint256 &hash);
|
||||
UniValue Snapshot(int top);
|
||||
int32_t Snapshot2(int64_t dustthreshold, int32_t top,std::vector <std::pair<CAmount, std::string>> &vaddr, UniValue *ret);
|
||||
bool Snapshot2(std::map <std::string, CAmount> &addressAmounts, UniValue *ret);
|
||||
};
|
||||
|
||||
#endif // BITCOIN_TXDB_H
|
||||
|
||||
@@ -5629,6 +5629,19 @@ UniValue payments_create(const UniValue& params, bool fHelp)
|
||||
return(PaymentsCreate(cp,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_airdrop(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
//if ( fHelp || params.size() != 1 )
|
||||
// throw runtime_error("paymentscreate \"[lockedblocks,minamount,%22paytxid0%22,...,%22paytxidN%22]\"\n");
|
||||
//if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 )
|
||||
// throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
//const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
//cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
return(PaymentsAirdrop(0,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_info(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
|
||||
Reference in New Issue
Block a user