private void processTransaction(TransactionBlockInfo blockInfo, ITransactionReader tx, PreprocessInfo info) { List <TransactionOutputInformationIn> emptyOutputs = new List <TransactionOutputInformationIn>(); List <ITransfersContainer> transactionContainers = new List <ITransfersContainer>(); m_logger.functorMethod(TRACE) << "Process transaction, block " << (int)blockInfo.height << ", transaction index " << (int)blockInfo.transactionIndex << ", hash " << tx.GetTransactionHash(); bool someContainerUpdated = false; foreach (var kv in m_subscriptions) { var it = info.outputs.find(kv.first); //C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops: auto subscriptionOutputs = (it == info.outputs.end()) ? emptyOutputs : it.second; bool containerContainsTx; bool containerUpdated; processOutputs(blockInfo, *kv.second, tx, subscriptionOutputs, info.globalIdxs, ref containerContainsTx, ref containerUpdated); someContainerUpdated = someContainerUpdated || containerUpdated; if (containerContainsTx) { transactionContainers.emplace_back(kv.second.getContainer()); } } if (someContainerUpdated) { m_logger.functorMethod(TRACE) << "Transaction updated some containers, hash " << tx.GetTransactionHash(); m_observerManager.notify(IBlockchainConsumerObserver.onTransactionUpdated, this, tx.GetTransactionHash(), transactionContainers); } else { m_logger.functorMethod(TRACE) << "Transaction doesn't updated any container, hash " << tx.GetTransactionHash(); } }
public override std::error_code addUnconfirmedTransaction(ITransactionReader transaction) { TransactionBlockInfo unconfirmedBlockInfo = new TransactionBlockInfo(); unconfirmedBlockInfo.height = GlobalMembers.WALLET_UNCONFIRMED_TRANSACTION_HEIGHT; unconfirmedBlockInfo.timestamp = 0; unconfirmedBlockInfo.transactionIndex = 0; return(processTransaction(unconfirmedBlockInfo, transaction)); }
private std::error_code preprocessOutputs(TransactionBlockInfo blockInfo, ITransactionReader tx, PreprocessInfo info) { Dictionary <PublicKey, List <uint> > outputs = new Dictionary <PublicKey, List <uint> >(); try { GlobalMembers.findMyOutputs(tx, m_viewSecret, m_spendKeys, outputs); } catch (System.Exception e) { m_logger.functorMethod(WARNING, BRIGHT_RED) << "Failed to process transaction: " << e.Message << ", transaction hash " << Common.GlobalMembers.podToHex(tx.GetTransactionHash()); return(std::error_code()); } if (outputs.Count == 0) { return(std::error_code()); } std::error_code errorCode = new std::error_code(); var txHash = tx.GetTransactionHash(); if (blockInfo.height != GlobalMembers.WALLET_UNCONFIRMED_TRANSACTION_HEIGHT) { //C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#: //C++ TO C# CONVERTER TODO TASK: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created: //ORIGINAL LINE: errorCode = getGlobalIndices(reinterpret_cast<const Hash&>(txHash), info.globalIdxs); errorCode.CopyFrom(getGlobalIndices(reinterpret_cast <const Hash&>(txHash), info.globalIdxs)); if (errorCode != null) { return(errorCode); } } foreach (var kv in outputs) { var it = m_subscriptions.find(kv.first); //C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops: if (it != m_subscriptions.end()) { auto transfers = info.outputs[kv.first]; //C++ TO C# CONVERTER TODO TASK: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created: //ORIGINAL LINE: errorCode = createTransfers(it->second->getKeys(), blockInfo, tx, kv.second, info.globalIdxs, transfers, m_logger); //C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops: errorCode.CopyFrom(CryptoNote.GlobalMembers.createTransfers(it.second.getKeys(), blockInfo, tx, kv.second, info.globalIdxs, transfers, m_logger.functorMethod)); if (errorCode != null) { return(errorCode); } } } return(std::error_code()); }
public bool addTransaction(TransactionBlockInfo blockInfo, ITransactionReader tx, List <TransactionOutputInformationIn> transfersList) { bool added = transfers.addTransaction(blockInfo, tx, transfersList); if (added) { logger.functorMethod(TRACE) << "Transaction updates balance of wallet " << m_address << ", hash " << tx.GetTransactionHash(); m_observerManager.notify(ITransfersObserver.onTransactionUpdated, this, tx.GetTransactionHash()); } return(added); }
private std::error_code processTransaction(TransactionBlockInfo blockInfo, ITransactionReader tx) { PreprocessInfo info = new PreprocessInfo(); var ec = preprocessOutputs(blockInfo, tx, info); if (ec != null) { return(ec); } processTransaction(blockInfo, tx, info); return(std::error_code()); }
public override std::future <std::error_code> addUnconfirmedTransaction(ITransactionReader transaction) { m_logger.functorMethod(INFO, BRIGHT_WHITE) << "Adding unconfirmed transaction, hash " << transaction.GetTransactionHash(); std::unique_lock <object> @lock = new std::unique_lock <object>(m_stateMutex); if (m_currentState == State.stopped || m_futureState == State.stopped) { var message = "Failed to add unconfirmed transaction: not stopped"; m_logger.functorMethod(ERROR, BRIGHT_RED) << message << ", hash " << transaction.GetTransactionHash(); throw new System.Exception(message); } std::promise <std::error_code> promise = new std::promise <std::error_code>(); var future = promise.get_future(); m_addTransactionTasks.emplace_back(transaction, std::move(promise)); m_hasWork.notify_one(); return(future); }
private void processOutputs(TransactionBlockInfo blockInfo, TransfersSubscription sub, ITransactionReader tx, List <TransactionOutputInformationIn> transfers, List <uint> globalIdxs, ref bool contains, ref bool updated) { TransactionInformation subscribtionTxInfo = new TransactionInformation(); contains = sub.getContainer().getTransactionInformation(tx.GetTransactionHash(), subscribtionTxInfo); updated = false; if (contains) { if (subscribtionTxInfo.blockHeight == GlobalMembers.WALLET_UNCONFIRMED_TRANSACTION_HEIGHT && blockInfo.height != GlobalMembers.WALLET_UNCONFIRMED_TRANSACTION_HEIGHT) { try { // pool->blockchain sub.markTransactionConfirmed(blockInfo, tx.GetTransactionHash(), globalIdxs); updated = true; } catch { m_logger.functorMethod(ERROR, BRIGHT_RED) << "markTransactionConfirmed failed, throw MarkTransactionConfirmedException"; throw new MarkTransactionConfirmedException(tx.GetTransactionHash()); } } else { Debug.Assert(subscribtionTxInfo.blockHeight == blockInfo.height); } } else { updated = sub.addTransaction(blockInfo, tx, transfers); contains = updated; } }