wallet2: fix rescanning tx via scan_tx

- Detach & re-process txs >= lowest scan height
- ensures that if a user calls scan_tx(tx1) after scanning tx2,
the wallet correctly processes tx1 and tx2
- if a user provides a tx with a height higher than the wallet's
last scanned height, the wallet will scan starting from that tx's
height
- scan_tx requires trusted daemon iff need to re-process existing
txs: in addition to querying a daemon for txids, if a user
provides a txid of a tx with height *lower* than any *already*
scanned txs in the wallet, then the wallet will also query the
daemon for all the *higher* txs as well. This is likely
unexpected behavior to a caller, and so to protect a caller from
revealing txid's to an untrusted daemon in an unexpected way,
require the daemon be trusted.
This commit is contained in:
j-berman 2022-09-09 20:34:18 -06:00
parent 94e67bf96b
commit e6b86af931
12 changed files with 628 additions and 65 deletions

View file

@ -3173,7 +3173,7 @@ namespace tools
return false;
}
std::vector<crypto::hash> txids;
std::unordered_set<crypto::hash> txids;
std::list<std::string>::const_iterator i = req.txids.begin();
while (i != req.txids.end())
{
@ -3186,11 +3186,15 @@ namespace tools
}
crypto::hash txid = *reinterpret_cast<const crypto::hash*>(txid_blob.data());
txids.push_back(txid);
txids.insert(txid);
}
try {
m_wallet->scan_tx(txids);
} catch (const tools::error::wont_reprocess_recent_txs_via_untrusted_daemon &e) {
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
er.message = e.what() + std::string(". Either connect to a trusted daemon or rescan the chain.");
return false;
} catch (const std::exception &e) {
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;