Merge pull request #104 from blackjok3rtt/jl777

merge paymentsCC in
This commit is contained in:
blackjok3rtt
2019-05-02 20:29:08 +08:00
committed by GitHub
18 changed files with 966 additions and 269 deletions

View File

@@ -642,6 +642,102 @@ 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)
{
int reorglimit = 10; // CHANGE BACK TO 100 AFTER TESTING!
uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height,extraoffset;
if ( (extraoffset= height % KOMODO_SNAPSHOT_INTERVAL) != 0 )
{
// we are on chain init, and need to scan all the way back to the correct height, other wise our node will have a diffrent snapshot to online nodes.
// use the notarizationsDB to scan back from the consesnus height to get the offset we need.
std::string symbol; Notarisation nota;
symbol.assign(ASSETCHAINS_SYMBOL);
if ( ScanNotarisationsDB(height-extraoffset, symbol, 100, nota) == 0 )
undo_height = height-extraoffset-reorglimit;
else undo_height = nota.second.height;
//fprintf(stderr, "height.%i-extraoffset.%i = startscanfrom.%i to get undo_height.%i\n", height, extraoffset, height-extraoffset, undo_height);
}
else
{
// we are at the right height in connect block to scan back to last notarized height.
notarized_height = komodo_notarized_height(&prevMoMheight,&notarized_hash,&notarized_desttxid);
notarized_height > height-reorglimit ? undo_height = notarized_height : undo_height = height-reorglimit;
}
fprintf(stderr, "doing snapshot for height.%i undo_height.%i\n", height, undo_height);
// 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];
CTxDestination vDest;
// loop vouts reverse order, remove value recieved.
for (unsigned int k = tx.vout.size(); k-- > 0;)
{
const CTxOut &out = tx.vout[k];
if ( ExtractDestination(out.scriptPubKey, vDest) )
{
addressAmounts[CBitcoinAddress(vDest).ToString()] -= out.nValue;
if ( addressAmounts[CBitcoinAddress(vDest).ToString()] < 1 )
addressAmounts.erase(CBitcoinAddress(vDest).ToString());
//fprintf(stderr, "VOUT: address.%s remove_coins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), out.nValue);
}
}
// loop vins in reverse order, get prevout and return the sent balance.
for (unsigned int j = tx.vin.size(); j-- > 0;)
{
uint256 blockhash; CTransaction txin;
if ( !tx.IsCoinImport() && !tx.IsCoinBase() && myGetTransaction(tx.vin[j].prevout.hash,txin,blockhash) )
{
int vout = tx.vin[j].prevout.n;
if ( ExtractDestination(txin.vout[vout].scriptPubKey, vDest) )
{
//fprintf(stderr, "VIN: address.%s add_coins.%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());
//for (int j = 0; j < 50; j++)
// fprintf(stderr, "j.%i address.%s nValue.%li\n",j, CBitcoinAddress(vAddressSnapshot[j].second).ToString().c_str(), vAddressSnapshot[j].first );
// include only top 5000 address.
if ( vAddressSnapshot.size() > 3999 ) vAddressSnapshot.resize(3999);
lastSnapShotHeight = undo_height;
fprintf(stderr, "vAddressSnapshot.size.%li\n", vAddressSnapshot.size());
return true;
}
//////////////////////////////////////////////////////////////////////////////
//
// mapOrphanTransactions
@@ -3096,7 +3192,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)));
}
@@ -3497,8 +3592,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
fprintf(stderr,"valueout %.8f too big\n",(double)valueout/COIN);
return state.DoS(100, error("ConnectBlock(): GetValueOut too big"),REJECT_INVALID,"tx valueout is too big");
}
prevsum = voutsum;
voutsum += valueout;
//prevsum = voutsum;
//voutsum += valueout;
/*if ( KOMODO_VALUETOOBIG(voutsum) != 0 )
{
fprintf(stderr,"voutsum %.8f too big\n",(double)voutsum/COIN);
@@ -4163,6 +4258,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 && KOMODO_SNAPSHOT_INTERVAL != 0 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 && pindexNew->GetHeight() > KOMODO_SNAPSHOT_INTERVAL )
{
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;
}
@@ -6102,7 +6204,7 @@ 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);
return true;
}