mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-12 05:32:22 +02:00
rpc: avoid quadratic output lookups
`ParseOutputs` iterates a `UniValue` object's keys and looks up each value by key. Each lookup scans the key vector from the beginning, making the lookup work quadratic. Walk the parallel key and value vectors together to avoid repeated scans. This preserves output order and validation behavior.
This commit is contained in:
@@ -105,19 +105,23 @@ std::vector<std::pair<CTxDestination, CAmount>> ParseOutputs(const UniValue& out
|
||||
std::set<CTxDestination> destinations;
|
||||
std::vector<std::pair<CTxDestination, CAmount>> parsed_outputs;
|
||||
bool has_data{false};
|
||||
for (const std::string& name_ : outputs.getKeys()) {
|
||||
const auto& keys{outputs.getKeys()};
|
||||
const auto& values{outputs.getValues()};
|
||||
for (size_t i{0}; i < keys.size(); ++i) {
|
||||
const auto& name_{keys[i]};
|
||||
const auto& value{values[i]};
|
||||
if (name_ == "data") {
|
||||
if (has_data) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, duplicate key: data");
|
||||
}
|
||||
has_data = true;
|
||||
std::vector<unsigned char> data = ParseHexV(outputs[name_].getValStr(), "Data");
|
||||
std::vector<unsigned char> data = ParseHexV(value.getValStr(), "Data");
|
||||
CTxDestination destination{CNoDestination{CScript() << OP_RETURN << data}};
|
||||
CAmount amount{0};
|
||||
parsed_outputs.emplace_back(destination, amount);
|
||||
} else {
|
||||
CTxDestination destination{DecodeDestination(name_)};
|
||||
CAmount amount{AmountFromValue(outputs[name_])};
|
||||
CAmount amount{AmountFromValue(value)};
|
||||
if (!IsValidDestination(destination)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + name_);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user