diff --git a/src/daemon/MoneroDaemonModel.cpp b/src/daemon/MoneroDaemonModel.cpp index 891743c..bc665d3 100644 --- a/src/daemon/MoneroDaemonModel.cpp +++ b/src/daemon/MoneroDaemonModel.cpp @@ -6,6 +6,8 @@ /** * Public library interface. + * + * TODO: separate per model class like wallet (cleanup) */ namespace monero { @@ -161,6 +163,11 @@ namespace monero { //txIds = MoneroUtils::reconcile(txIds, otherBlock->txIds); // TODO: implement } + boost::optional MoneroTx::getHeight() const { + if (block == boost::none) return boost::none; + return *((*block)->height); + } + void MoneroTx::merge(const shared_ptr& self, const shared_ptr& other) { if (this != self.get()) throw runtime_error("this != self"); if (self == other) return; diff --git a/src/daemon/MoneroDaemonModel.h b/src/daemon/MoneroDaemonModel.h index 005ad42..4c0762b 100644 --- a/src/daemon/MoneroDaemonModel.h +++ b/src/daemon/MoneroDaemonModel.h @@ -143,10 +143,7 @@ namespace monero { vector signatures; boost::property_tree::ptree toPropertyTree() const; - boost::optional getHeight() const { - if (block == boost::none) return boost::none; - return *((*block)->height); - } + boost::optional getHeight() const; void merge(const shared_ptr& self, const shared_ptr& other); }; diff --git a/src/wallet/MoneroWalletModel.cpp b/src/wallet/MoneroWalletModel.cpp index 7ce262f..1a9f7ed 100644 --- a/src/wallet/MoneroWalletModel.cpp +++ b/src/wallet/MoneroWalletModel.cpp @@ -65,6 +65,14 @@ namespace monero { return node; } + bool MoneroTxWallet::getIsIncoming() const { + return outgoingTransfer != boost::none; + } + + bool MoneroTxWallet::getIsOutgoing() const { + return !incomingTransfers.empty(); + } + //boost::property_tree::ptree MoneroUtils::txWalletToPropertyTree(const MoneroTxWallet& tx) { // cout << "txWalletToPropertyTree(tx)" << endl; // boost::property_tree::ptree txNode = txToPropertyTree(tx); @@ -95,7 +103,60 @@ namespace monero { } bool MoneroTxRequest::meetsCriteria(MoneroTxWallet* tx) const { - throw runtime_error("MoneroTxRequest meetsCriteria() not implemented"); + if (tx == nullptr) return false; + + // filter on tx + if (id != boost::none && *id != *tx->id) return false; + if (paymentId != boost::none && *paymentId != *tx->paymentId) return false; + if (isConfirmed != boost::none && *isConfirmed != *tx->isConfirmed) return false; + if (inTxPool != boost::none && *inTxPool != *tx->inTxPool) return false; + if (doNotRelay != boost::none && *doNotRelay != *tx->doNotRelay) return false; + if (isFailed != boost::none && *isFailed != *tx->isFailed) return false; + if (isCoinbase != boost::none && *isCoinbase != *tx->isCoinbase) return false; + + // at least one transfer must meet transfer request if defined + if (transferRequest != boost::none) { + bool matchFound = false; + if (outgoingTransfer != boost::none && (*transferRequest)->meetsCriteria((*tx->outgoingTransfer).get())) matchFound = true; + else if (!incomingTransfers.empty()) { + for (const shared_ptr& incomingTransfer : tx->incomingTransfers) { + if ((*transferRequest)->meetsCriteria(incomingTransfer.get())) { + matchFound = true; + break; + } + } + } + if (!matchFound) return false; + } + + // filter on having a payment id + if (hasPaymentId != boost::none) { + if (*hasPaymentId && tx->paymentId == boost::none) return false; + if (!*hasPaymentId && tx->paymentId != boost::none) return false; + } + + // filter on incoming + if (isIncoming != boost::none) { + if (*isIncoming && !tx->getIsIncoming()) return false; + if (!*isIncoming && tx->getIsIncoming()) return false; + } + + // filter on outgoing + if (isOutgoing != boost::none) { + if (*isOutgoing && !tx->getIsOutgoing()) return false; + if (!*isOutgoing && tx->getIsOutgoing()) return false; + } + + // filter on remaining fields + boost::optional txHeight = tx->block == boost::none ? boost::none : (*tx->block)->height; + if (!txIds.empty() && find(txIds.begin(), txIds.end(), *tx->id) == txIds.end()) return false; + if (!paymentIds.empty() && find(paymentIds.begin(), paymentIds.end(), *tx->paymentId) == paymentIds.end()) return false; + if (getHeight() != boost::none && *txHeight != *getHeight()) return false; + if (minHeight != boost::none && (txHeight == boost::none || *txHeight < *minHeight)) return false; + if (maxHeight != boost::none && (txHeight == boost::none || *txHeight > *maxHeight)) return false; + + // transaction meets request criteria + return true; } //boost::property_tree::ptree MoneroUtils::txRequestToPropertyTree(const MoneroTxRequest& tx) { diff --git a/src/wallet/MoneroWalletModel.h b/src/wallet/MoneroWalletModel.h index 0e35e3f..5c3ecc4 100644 --- a/src/wallet/MoneroWalletModel.h +++ b/src/wallet/MoneroWalletModel.h @@ -165,6 +165,8 @@ namespace monero { boost::optional> outgoingTransfer; boost::optional note; + bool getIsIncoming() const; + bool getIsOutgoing() const; boost::property_tree::ptree toPropertyTree() const; }; @@ -184,7 +186,6 @@ namespace monero { boost::optional includeOutputs; boost::optional> transferRequest; - boost::optional getHeight() { return block == boost::none ? boost::none : (*block)->height; } boost::property_tree::ptree toPropertyTree() const; bool meetsCriteria(MoneroTxWallet* tx) const; };