AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Moderate 59 Bitcoin

Merge bitcoin/bitcoin#36032: rpc: avoid quadratic output lookups

Public commit record

What the developer wrote

Authored by Ava Chow

91/100 · Strong
Merge bitcoin/bitcoin#36032: rpc: avoid quadratic output lookups

747cff842481153357199bf9a81b5a4d82ea91fb rpc: avoid quadratic output lookups (Lőrinc)

Pull request description:

**Problem:** Transaction-creation RPCs currently take quadratic time to parse outputs.
An authenticated RPC client can therefore tie up a worker with a large request.
`sendmany` also holds the wallet lock while parsing, delaying other operations on the same wallet.

**Fix:** Parse transaction outputs in linear time by reading corresponding keys and values by index instead of looking up each value by key.

**Reproducer:** Run `time build/bin/test_bitcoin --run_test=rpc_tests/parse_outputs` before and after the fix:
<details>
<summary>parse_outputs test in `rpc_tests.cpp`</summary>

```cpp
BOOST_AUTO_TEST_CASE(parse_outputs)
{
constexpr size_t OUTPUT_COUNT{10'000};
UniValue outputs{UniValue::VOBJ};
for (size_t i{0}; i < OUTPUT_COUNT; ++i) {
auto destination{EncodeDestination(WitnessV0ScriptHash{CScript{} << i})};
outputs.pushKVEnd(destination, ValueFromAmount(i + 1));
}

const auto parsed_outputs{ParseOutputs(outputs)};
BOOST_REQUIRE_EQUAL(parsed_outputs.size(), OUTPUT_COUNT);
for (size_t i{OUTPUT_COUNT}; i > 0; --i) {
std::pair expected{CTxDestination{WitnessV0ScriptHash{CScript{} << (i - 1)}}, static_cast<CAmount>(i)};
BOOST_CHECK(parsed_outputs[i - 1] == expected);
}
}
```
</details>
E.g. on my M4 Max with `debug` build:

```python
Before ████████████████████ 1.80 s
After █████▒░░░░░░░░░░░░░░ 0.50 s -72%
```
Related to #35889

ACKs for top commit:
achow101:
ACK 747cff842481153357199bf9a81b5a4d82ea91fb
jonatack:
ACK 747cff842481153357199bf9a81b5a4d82ea91fb
jeanpablojp:
tACK 747cff842481153357199bf9a81b5a4d82ea91fb
hodlinator:
ACK 747cff842481153357199bf9a81b5a4d82ea91fb

Tree-SHA512: 154c9f583f6e7f4154882aeb1ae11c40b327d0ef04147e12a0fee749494ae95314cdfc56baad78723f3383f225d752654be0ae9ed7458b1c73f7a6a80922e3ef
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
The short version

What changed, and why it matters

This change fixes a performance bug in Bitcoin Core's RPC (remote procedure call) handling where creating a transaction with many outputs could take much longer than necessary. An authenticated RPC user could send a specially crafted request with thousands of outputs and temporarily slow down or stall a server worker. The fix makes the output parsing run in linear time instead of quadratic time, and removes a wallet-lock delay in the `sendmany` RPC. It is a denial-of-service improvement rather than a code-execution or theft bug.

Recommended action

Treat as a routine performance and DoS-hardening fix. No emergency response is warranted. Users running RPC services should include this fix in their normal upgrade cycle, especially if they expose RPC to multiple authenticated clients.

Security signals we found

01

Denial-of-service vector: authenticated RPC client can tie up a worker with a large request

02

Algorithmic complexity reduction from quadratic to linear output parsing

03

Wallet lock contention reduction for `sendmany`

04

No memory safety, authentication bypass, or confidentiality impact evident

Risk score

Why this scored 59/100

Our methodology →
Potential impact 12/30
Exploitability 14/25
Stealth signal 10/15
Affected reach 11/15
Confidence 8/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.