/* Update our model of the wallet incrementally, to synchronize our model of the wallet with that of the core. Call with list of hashes of transactions that were added, removed or changed. */ void updateWallet(const QList<uint256> &updated) { // Walk through updated transactions, update model as needed. #ifdef WALLET_UPDATE_DEBUG qDebug() << "updateWallet"; #endif // Sort update list, and iterate through it in reverse, so that model updates // can be emitted from end to beginning (so that earlier updates will not influence // the indices of latter ones). QList<uint256> updated_sorted = updated; qSort(updated_sorted); { LOCK(wallet->cs_wallet); for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx) { const uint256 &hash = updated_sorted.at(update_idx); // Find transaction in wallet std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash); bool inWallet = mi != wallet->mapWallet.end(); // Find bounds of this transaction in model QList<TransactionRecord>::iterator lower = qLowerBound( cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); QList<TransactionRecord>::iterator upper = qUpperBound( cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); int lowerIndex = (lower - cachedWallet.begin()); int upperIndex = (upper - cachedWallet.begin()); // Determine if transaction is in model already bool inModel = false; if(lower != upper) { inModel = true; } #ifdef WALLET_UPDATE_DEBUG qDebug() << " " << QString::fromStdString(hash.ToString()) << inWallet << " " << inModel << lowerIndex << "-" << upperIndex; #endif if(inWallet && !inModel) { if(!mapBlockIndex.count(mi->second.hashBlock)) continue; CBlockIndex *pindex = mapBlockIndex[mi->second.hashBlock]; if(!pindex) continue; // Added -- insert at the right position QList<TransactionRecord> toInsert = TransactionRecord::decomposeTransaction(wallet, mi->second, pindex->IsProofOfBurn()); if(!toInsert.isEmpty()) /* only if something to insert */ { parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); int insert_idx = lowerIndex; foreach(const TransactionRecord &rec, toInsert) { cachedWallet.insert(insert_idx, rec); insert_idx += 1; } parent->endInsertRows(); } } else if(!inWallet && inModel)
bool CTxDB::LoadBlockIndex() { // Get database cursor Dbc* pcursor = GetCursor(); if (!pcursor) return false; // Load mapBlockIndex unsigned int fFlags = DB_SET_RANGE; for(;;) { // Read next record CDataStream ssKey(SER_DISK, CLIENT_VERSION); if (fFlags == DB_SET_RANGE) ssKey << make_pair(string("blockindex"), uint256(0)); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); fFlags = DB_NEXT; if (ret == DB_NOTFOUND) break; else if (ret != 0) return false; // Unserialize try { string strType; ssKey >> strType; if (strType == "blockindex" && !fRequestShutdown) { CDiskBlockIndex diskindex; ssValue >> diskindex; uint256 blockHash = diskindex.GetBlockHash(); // Construct block index object CBlockIndex* pindexNew = InsertBlockIndex(blockHash); pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); pindexNew->nFile = diskindex.nFile; pindexNew->nBlockPos = diskindex.nBlockPos; pindexNew->nHeight = diskindex.nHeight; pindexNew->nMint = diskindex.nMint; pindexNew->nMoneySupply = diskindex.nMoneySupply; pindexNew->nFlags = diskindex.nFlags; pindexNew->nStakeModifier = diskindex.nStakeModifier; pindexNew->prevoutStake = diskindex.prevoutStake; pindexNew->nStakeTime = diskindex.nStakeTime; pindexNew->hashProofOfStake = diskindex.hashProofOfStake; pindexNew->nVersion = diskindex.nVersion; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; //Load Proof of Burn switch and indexes pindexNew->fProofOfBurn = diskindex.fProofOfBurn; pindexNew->burnHash = diskindex.burnHash; pindexNew->burnBlkHeight = diskindex.burnBlkHeight; pindexNew->burnCTx = diskindex.burnCTx; pindexNew->burnCTxOut = diskindex.burnCTxOut; pindexNew->nEffectiveBurnCoins = diskindex.nEffectiveBurnCoins; pindexNew->nBurnBits = diskindex.nBurnBits; // Watch for genesis block if (pindexGenesisBlock == NULL && blockHash == hashGenesisBlock) pindexGenesisBlock = pindexNew; if (!pindexNew->CheckIndex()) return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight); // ppcoin: build setStakeSeen if (pindexNew->IsProofOfStake()) setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); else if(pindexNew->IsProofOfBurn()) //build the setBurnSeen setBurnSeen.insert(pindexNew->GetProofOfBurn()); } else { break; // if shutdown requested or finished loading block index } } // try catch (std::exception &e) {