aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2021-07-15 17:25:07 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2021-07-15 17:25:07 +0000
commit0c6e1d343e8d696ed2be79284e6fcf76f2a0e6ff (patch)
tree20a30753b9aaa4adc02d417b06b3ebebb58e88b1 /src
parentMerge pull request #7764 (diff)
downloadmonero-0c6e1d343e8d696ed2be79284e6fcf76f2a0e6ff.tar.xz
wallet2: chunk get_outs.bin calls to avoid sanity limits
Diffstat (limited to 'src')
-rw-r--r--src/wallet/wallet2.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 05fe0a1ad..ccc9f6b30 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -8587,18 +8587,30 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
}
// get the keys for those
- req.get_txid = false;
-
+ // the response can get large and end up rejected by the anti DoS limits, so chunk it if needed
+ size_t offset = 0;
+ while (offset < req.outputs.size())
{
+ static const size_t chunk_size = 1000;
+ COMMAND_RPC_GET_OUTPUTS_BIN::request chunk_req = AUTO_VAL_INIT(chunk_req);
+ COMMAND_RPC_GET_OUTPUTS_BIN::response chunk_daemon_resp = AUTO_VAL_INIT(chunk_daemon_resp);
+ chunk_req.get_txid = false;
+ for (size_t i = 0; i < std::min<size_t>(req.outputs.size() - offset, chunk_size); ++i)
+ chunk_req.outputs.push_back(req.outputs[offset + i]);
+
const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex};
uint64_t pre_call_credits = m_rpc_payment_state.credits;
- req.client = get_client_signature();
- bool r = epee::net_utils::invoke_http_bin("/get_outs.bin", req, daemon_resp, *m_http_client, rpc_timeout);
- THROW_ON_RPC_RESPONSE_ERROR(r, {}, daemon_resp, "get_outs.bin", error::get_outs_error, get_rpc_status(daemon_resp.status));
- THROW_WALLET_EXCEPTION_IF(daemon_resp.outs.size() != req.outputs.size(), error::wallet_internal_error,
+ chunk_req.client = get_client_signature();
+ bool r = epee::net_utils::invoke_http_bin("/get_outs.bin", chunk_req, chunk_daemon_resp, *m_http_client, rpc_timeout);
+ THROW_ON_RPC_RESPONSE_ERROR(r, {}, chunk_daemon_resp, "get_outs.bin", error::get_outs_error, get_rpc_status(chunk_daemon_resp.status));
+ THROW_WALLET_EXCEPTION_IF(chunk_daemon_resp.outs.size() != chunk_req.outputs.size(), error::wallet_internal_error,
"daemon returned wrong response for get_outs.bin, wrong amounts count = " +
- std::to_string(daemon_resp.outs.size()) + ", expected " + std::to_string(req.outputs.size()));
- check_rpc_cost("/get_outs.bin", daemon_resp.credits, pre_call_credits, daemon_resp.outs.size() * COST_PER_OUT);
+ std::to_string(chunk_daemon_resp.outs.size()) + ", expected " + std::to_string(chunk_req.outputs.size()));
+ check_rpc_cost("/get_outs.bin", chunk_daemon_resp.credits, pre_call_credits, chunk_daemon_resp.outs.size() * COST_PER_OUT);
+
+ offset += chunk_size;
+ for (size_t i = 0; i < chunk_daemon_resp.outs.size(); ++i)
+ daemon_resp.outs.push_back(std::move(chunk_daemon_resp.outs[i]));
}
std::unordered_map<uint64_t, uint64_t> scanty_outs;