tx req meetsCriteria() correctly filters on given transfers

This commit is contained in:
woodser
2019-06-25 10:12:36 -04:00
parent a3011fd334
commit 771d3e270a
2 changed files with 51 additions and 10 deletions
+24 -8
View File
@@ -545,7 +545,7 @@ namespace monero {
// fetch all transfers that meet tx request
MoneroTransferRequest tempTransferReq;
tempTransferReq.txRequest = shared_ptr<MoneroTxRequest>(&request);
tempTransferReq.txRequest = make_shared<MoneroTxRequest>(request);
vector<shared_ptr<MoneroTransfer>> transfers = getTransfers(tempTransferReq);
// collect unique txs from transfers while retaining order
@@ -567,7 +567,7 @@ namespace monero {
// fetch and merge outputs if requested
MoneroOutputRequest tempOutputReq;
tempOutputReq.txRequest = shared_ptr<MoneroTxRequest>(&request);
tempOutputReq.txRequest = make_shared<MoneroTxRequest>(request);
if (request.includeOutputs != boost::none && *request.includeOutputs) {
// fetch outputs
@@ -626,17 +626,23 @@ namespace monero {
vector<shared_ptr<MoneroTransfer>> MoneroWallet::getTransfers(const MoneroTransferRequest& request) const {
cout << "MoneroWallet::getTransfers(request)" << endl;
// print request
cout << "Transfer request: " << request.serialize() << endl;
if (request.txRequest != boost::none) {
if ((*request.txRequest)->block == boost::none) cout << "Transfer request's tx request rooted at [tx]:" << (*request.txRequest)->serialize() << endl;
else cout << "Transfer request's tx request rooted at [block]: " << (*(*request.txRequest)->block)->serialize() << endl;
}
//cout << "1" << endl;
// // print request
// cout << "Transfer request: " << request.serialize() << endl;
// if (request.txRequest != boost::none) {
// if ((*request.txRequest)->block == boost::none) cout << "Transfer request's tx request rooted at [tx]:" << (*request.txRequest)->serialize() << endl;
// else cout << "Transfer request's tx request rooted at [block]: " << (*(*request.txRequest)->block)->serialize() << endl;
// }
// normalize request
// TODO: this will modify original request, construct copy? add test
MoneroTxRequest txReq = *(request.txRequest != boost::none ? *request.txRequest : shared_ptr<MoneroTxRequest>(new MoneroTxRequest()));
// print request
//cout << "Tx request: " << txReq.serialize() << endl;
//cout << "2" << endl;
// build parameters for wallet2->get_payments()
uint64_t minHeight = txReq.minHeight == boost::none ? 0 : *txReq.minHeight;
uint64_t maxHeight = txReq.maxHeight == boost::none ? CRYPTONOTE_MAX_BLOCK_NUMBER : min((uint64_t) CRYPTONOTE_MAX_BLOCK_NUMBER, *txReq.maxHeight);
@@ -647,6 +653,8 @@ namespace monero {
subaddressIndices.insert(request.subaddressIndices[i]);
}
//cout << "3" << endl;
// translate from MoneroTxRequest to in, out, pending, pool, failed terminology used by monero-wallet-rpc
bool canBeConfirmed = !boolEquals(false, txReq.isConfirmed) && !boolEquals(true, txReq.inTxPool) && !boolEquals(true, txReq.isFailed) && !boolEquals(false, txReq.isRelayed);
bool canBeInTxPool = !boolEquals(true, txReq.isConfirmed) && !boolEquals(false, txReq.inTxPool) && !boolEquals(true, txReq.isFailed) && !boolEquals(false, txReq.isRelayed) && txReq.getHeight() == boost::none && txReq.minHeight == boost::none;
@@ -658,6 +666,8 @@ namespace monero {
bool isPool = canBeIncoming && canBeInTxPool;
bool isFailed = !boolEquals(false, txReq.isFailed) && !boolEquals(true, txReq.isConfirmed) && !boolEquals(true, txReq.inTxPool);
//cout << "4" << endl;
// collect unique txs and blocks
map<string, shared_ptr<MoneroTxWallet>> txMap;
map<uint64_t, shared_ptr<MoneroBlock>> blockMap;
@@ -672,6 +682,8 @@ namespace monero {
}
}
//cout << "5" << endl;
// get confirmed outgoing transfers
if (isOut) {
std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>> payments;
@@ -682,6 +694,8 @@ namespace monero {
}
}
//cout << "6" << endl;
// get unconfirmed outgoing transfers
if (isPending || isFailed) {
//throw runtime_error("isPending || isFailed not implemented");
@@ -712,6 +726,8 @@ namespace monero {
}
}
}
//cout << "7" << endl;
cout << "MoneroWallet.cpp getTransfers() returning " << transfers.size() << " transfers" << endl;
return transfers;
}
+27 -2
View File
@@ -103,6 +103,10 @@ namespace monero {
bool MoneroTxRequest::meetsCriteria(MoneroTxWallet* tx) const {
if (tx == nullptr) return false;
//cout << "MoneroTxRequest::meetsCriteria()" << endl;
//cout << "Testing tx: " << tx->serialize() << endl;
//cout << "1" << endl;
// filter on tx
if (id != boost::none && *id != *tx->id) return false;
if (paymentId != boost::none && *paymentId != *tx->paymentId) return false;
@@ -112,11 +116,13 @@ namespace monero {
if (isFailed != boost::none && *isFailed != *tx->isFailed) return false;
if (isCoinbase != boost::none && *isCoinbase != *tx->isCoinbase) return false;
//cout << "2" << endl;
// 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()) {
if (tx->outgoingTransfer != boost::none && (*transferRequest)->meetsCriteria((*tx->outgoingTransfer).get())) matchFound = true;
else if (!tx->incomingTransfers.empty()) {
for (const shared_ptr<MoneroIncomingTransfer>& incomingTransfer : tx->incomingTransfers) {
if ((*transferRequest)->meetsCriteria(incomingTransfer.get())) {
matchFound = true;
@@ -127,24 +133,32 @@ namespace monero {
if (!matchFound) return false;
}
//cout << "3" << endl;
// 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;
}
//cout << "4" << endl;
// filter on incoming
if (isIncoming != boost::none) {
if (*isIncoming && !tx->getIsIncoming()) return false;
if (!*isIncoming && tx->getIsIncoming()) return false;
}
//cout << "5" << endl;
// filter on outgoing
if (isOutgoing != boost::none) {
if (*isOutgoing && !tx->getIsOutgoing()) return false;
if (!*isOutgoing && tx->getIsOutgoing()) return false;
}
//cout << "6" << endl;
// filter on remaining fields
boost::optional<uint64_t> txHeight = tx->getHeight();
if (!txIds.empty() && find(txIds.begin(), txIds.end(), *tx->id) == txIds.end()) return false;
@@ -153,6 +167,8 @@ namespace monero {
if (minHeight != boost::none && (txHeight == boost::none || *txHeight < *minHeight)) return false;
if (maxHeight != boost::none && (txHeight == boost::none || *txHeight > *maxHeight)) return false;
//cout << "7" << endl;
// transaction meets request criteria
return true;
}
@@ -236,15 +252,20 @@ namespace monero {
}
bool MoneroTransferRequest::meetsCriteria(MoneroTransfer* transfer) const {
//cout << "MoneroTransferRequest::meetsCriteria()" << endl;
if (transfer == nullptr) throw runtime_error("transfer is null"); // TODO: port to java/js
if (txRequest != boost::none && (*txRequest)->transferRequest != boost::none) throw runtime_error("Transfer request's tx request cannot have a circular transfer request"); // TODO: port to java/js
//cout << "1" << endl;
// filter on common fields
if (getIsIncoming() != boost::none && *getIsIncoming() != *transfer->getIsIncoming()) return false;
if (getIsOutgoing() != boost::none && getIsOutgoing() != transfer->getIsOutgoing()) return false;
if (amount != boost::none && *amount != *transfer->amount) return false;
if (accountIndex != boost::none && *accountIndex != *transfer->accountIndex) return false;
//cout << "2" << endl;
// filter on incoming fields
MoneroIncomingTransfer* inTransfer = dynamic_cast<MoneroIncomingTransfer*>(transfer);
if (inTransfer != nullptr) {
@@ -255,6 +276,8 @@ namespace monero {
if (!subaddressIndices.empty() && find(subaddressIndices.begin(), subaddressIndices.end(), *inTransfer->subaddressIndex) == subaddressIndices.end()) return false;
}
//cout << "3" << endl;
// filter on outgoing fields
MoneroOutgoingTransfer* outTransfer = dynamic_cast<MoneroOutgoingTransfer*>(transfer);
if (outTransfer != nullptr) {
@@ -299,6 +322,8 @@ namespace monero {
// if (this.getDestionations() != null && this.getDestionations() != transfer.getDestionations()) return false;
}
//cout << "4" << endl;
// validate type
if (inTransfer == nullptr && outTransfer == nullptr) throw runtime_error("Transfer must be MoneroIncomingTransfer or MoneroOutgoingTransfer");