TransactionRecord *index(int idx) { if(idx >= 0 && idx < cachedWallet.size()) { TransactionRecord *rec = &cachedWallet[idx]; // Get required locks upfront. This avoids the GUI from getting // stuck if the core is holding the locks for a longer time - for // example, during a wallet rescan. // // If a status update is needed (blocks came in since last check), // update the status of this transaction from the wallet. Otherwise, // simply re-use the cached status. TRY_LOCK(cs_main, lockMain); if(lockMain) { TRY_LOCK(wallet->cs_wallet, lockWallet); if(lockWallet && rec->statusUpdateNeeded()) { std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash); if(mi != wallet->mapWallet.end()) { rec->updateStatus(mi->second); } } } return rec; } return 0; }
void WriteBehindFrontendLogger::WriteTransactionLogRecord( TransactionRecord txn_log_record) { txn_log_record.Serialize(output_buffer); fwrite(txn_log_record.GetMessage(), sizeof(char), txn_log_record.GetMessageLength(), log_file); // Then, flush int ret = fflush(log_file); if (ret != 0) { LOG_ERROR("Error occured in fflush(%d)", ret); } // Finally, sync ret = fsync(log_file_fd); if (ret != 0) { LOG_ERROR("Error occured in fsync(%d)", ret); } }
void balanceWallet(bool sortRequired = false) { if (sortRequired) { { LOCK(wallet->cs_wallet); // We need updated status for all the transaction records for (int i = 0 ; i < cachedWallet.size(); i++) { TransactionRecord *rec = &cachedWallet[i]; rec->presort_i = i; rec->balance = 0; std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash); if(mi != wallet->mapWallet.end()) { rec->updateStatus(mi->second); } } } keySortedWallet.clear(); keySortedWallet = cachedWallet; qSort(keySortedWallet.begin(), keySortedWallet.end(), TxLessThanKey()); } int64 balance=0; for( int i=0; i<keySortedWallet.count(); ++i ) { TransactionRecord *rec = &keySortedWallet[i]; TransactionRecord *wtx = &cachedWallet[rec->presort_i]; if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature) { balance += wtx->debit; } else { balance += (wtx->credit + wtx->debit); } wtx->balance = balance; rec->balance = balance; } }
TransactionRecord *index(interfaces::Wallet& wallet, int idx) { if(idx >= 0 && idx < cachedWallet.size()) { TransactionRecord *rec = &cachedWallet[idx]; // Get required locks upfront. This avoids the GUI from getting // stuck if the core is holding the locks for a longer time - for // example, during a wallet rescan. // // If a status update is needed (blocks came in since last check), // update the status of this transaction from the wallet. Otherwise, // simply re-use the cached status. interfaces::WalletTxStatus wtx; int numBlocks; int64_t adjustedTime; if (wallet.tryGetTxStatus(rec->hash, wtx, numBlocks, adjustedTime) && rec->statusUpdateNeeded(numBlocks)) { rec->updateStatus(wtx, numBlocks, adjustedTime); } return rec; } return 0; }
/** * @brief Read TransactionRecord * @param txn_record */ bool ReadTransactionRecordHeader(TransactionRecord &txn_record, FILE *log_file, size_t log_file_size) { // Check if frame is broken auto header_size = GetNextFrameSize(log_file, log_file_size); if (header_size == 0) { return false; } // Read header char header[header_size]; size_t ret = fread(header, 1, sizeof(header), log_file); if (ret <= 0) { LOG_ERROR("Error occured in fread "); } CopySerializeInputBE txn_header(header, header_size); txn_record.Deserialize(txn_header); return true; }
QVariant TransactionTableModel::data(const QModelIndex &index, int role) const { if(!index.isValid()) return QVariant(); TransactionRecord *rec = static_cast<TransactionRecord*>(index.internalPointer()); switch(role) { case RawDecorationRole: switch(index.column()) { case Status: return txStatusDecoration(rec); case Watchonly: return txWatchonlyDecoration(rec); case ToAddress: return txAddressDecoration(rec); } break; case Qt::DecorationRole: { QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole)); return platformStyle->TextColorIcon(icon); } case Qt::DisplayRole: switch(index.column()) { case Date: return formatTxDate(rec); case Type: return formatTxType(rec); case ToAddress: return formatTxToAddress(rec, false); case Amount: return formatTxAmount(rec, true, DoriancoinUnits::separatorAlways); } break; case Qt::EditRole: // Edit role is used for sorting, so return the unformatted values switch(index.column()) { case Status: return QString::fromStdString(rec->status.sortKey); case Date: return rec->time; case Type: return formatTxType(rec); case Watchonly: return (rec->involvesWatchAddress ? 1 : 0); case ToAddress: return formatTxToAddress(rec, true); case Amount: return qint64(rec->credit + rec->debit); } break; case Qt::ToolTipRole: return formatTooltip(rec); case Qt::TextAlignmentRole: return column_alignments[index.column()]; case Qt::ForegroundRole: // Use the "danger" color for abandoned transactions if(rec->status.status == TransactionStatus::Abandoned) { return COLOR_TX_STATUS_DANGER; } // Non-confirmed (but not immature) as transactions are grey if(!rec->status.countsForBalance && rec->status.status != TransactionStatus::Immature) { return COLOR_UNCONFIRMED; } if(index.column() == Amount && (rec->credit+rec->debit) < 0) { return COLOR_NEGATIVE; } if(index.column() == ToAddress) { return addressColor(rec); } break; case TypeRole: return rec->type; case DateRole: return QDateTime::fromTime_t(static_cast<uint>(rec->time)); case WatchonlyRole: return rec->involvesWatchAddress; case WatchonlyDecorationRole: return txWatchonlyDecoration(rec); case LongDescriptionRole: return priv->describe(rec, walletModel->getOptionsModel()->getDisplayUnit()); case AddressRole: return QString::fromStdString(rec->address); case LabelRole: return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); case AmountRole: return qint64(rec->credit + rec->debit); case TxIDRole: return rec->getTxID(); case TxHashRole: return QString::fromStdString(rec->hash.ToString()); case TxHexRole: return priv->getTxHex(rec); case TxPlainTextRole: { QString details; QDateTime date = QDateTime::fromTime_t(static_cast<uint>(rec->time)); QString txLabel = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); details.append(date.toString("M/d/yy HH:mm")); details.append(" "); details.append(formatTxStatus(rec)); details.append(". "); if(!formatTxType(rec).isEmpty()) { details.append(formatTxType(rec)); details.append(" "); } if(!rec->address.empty()) { if(txLabel.isEmpty()) details.append(tr("(no label)") + " "); else { details.append("("); details.append(txLabel); details.append(") "); } details.append(QString::fromStdString(rec->address)); details.append(" "); } details.append(formatTxAmount(rec, false, DoriancoinUnits::separatorNever)); return details; } case ConfirmedRole: return rec->status.countsForBalance; case FormattedAmountRole: // Used for copy/export, so don't include separators return formatTxAmount(rec, false, DoriancoinUnits::separatorNever); case StatusRole: return rec->status.status; } return QVariant(); }