mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-05 02:33:07 +02:00
Merge bitcoin/bitcoin#30844: RPC: improve SFFO arg parsing, error catching and coverage
cddcbaf81eRPC: improve SFFO arg parsing, error catching and coverage (furszy)4f4cd35319rpc: decouple sendtoaddress 'subtractfeefromamount' boolean parsing (furszy) Pull request description: Following changes were made: 1) Catch and signal error for duplicate string destinations. 2) Catch and signal error for invalid value type. 3) Catch and signal error for string destination not found in tx outputs. 4) Improved `InterpretSubtractFeeFromOutputInstructions()` code organization. 5) Added test coverage for all possible error failures. Also, fixed two PEP 8 warnings at the 'wallet_sendmany.py' file: - PEP 8: E302 expected 2 blank lines, found 1 at the SendmanyTest class declaration. - PEP 8: E303 too many blank lines (2) at skip_test_if_missing_module() and set_test_params() ACKs for top commit: achow101: ACKcddcbaf81emurchandamus: crACKcddcbaf81enaiyoma: TACK [cddcbaf81e) ismaelsadeeq: Code review and Tested ACKcddcbaf81eTree-SHA512: c9c15582b81101a93987458d155394ff2c9ca42864624c034ee808a31c3a7d7f55105dea98e86fce17d3c7b2c1a6b5b77942da66b287f8b8881a60cde78c1a3c
This commit is contained in:
@@ -68,29 +68,26 @@ std::set<int> InterpretSubtractFeeFromOutputInstructions(const UniValue& sffo_in
|
||||
{
|
||||
std::set<int> sffo_set;
|
||||
if (sffo_instructions.isNull()) return sffo_set;
|
||||
if (sffo_instructions.isBool()) {
|
||||
if (sffo_instructions.get_bool()) sffo_set.insert(0);
|
||||
return sffo_set;
|
||||
}
|
||||
|
||||
for (const auto& sffo : sffo_instructions.getValues()) {
|
||||
int pos{-1};
|
||||
if (sffo.isStr()) {
|
||||
for (size_t i = 0; i < destinations.size(); ++i) {
|
||||
if (sffo.get_str() == destinations.at(i)) {
|
||||
sffo_set.insert(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sffo.isNum()) {
|
||||
int pos = sffo.getInt<int>();
|
||||
if (sffo_set.contains(pos))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, duplicated position: %d", pos));
|
||||
if (pos < 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, negative position: %d", pos));
|
||||
if (pos >= int(destinations.size()))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, position too large: %d", pos));
|
||||
sffo_set.insert(pos);
|
||||
auto it = find(destinations.begin(), destinations.end(), sffo.get_str());
|
||||
if (it == destinations.end()) throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', destination %s not found in tx outputs", sffo.get_str()));
|
||||
pos = it - destinations.begin();
|
||||
} else if (sffo.isNum()) {
|
||||
pos = sffo.getInt<int>();
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', invalid value type: %s", uvTypeName(sffo.type())));
|
||||
}
|
||||
|
||||
if (sffo_set.contains(pos))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', duplicated position: %d", pos));
|
||||
if (pos < 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', negative position: %d", pos));
|
||||
if (pos >= int(destinations.size()))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', position too large: %d", pos));
|
||||
sffo_set.insert(pos);
|
||||
}
|
||||
return sffo_set;
|
||||
}
|
||||
@@ -310,10 +307,13 @@ RPCHelpMan sendtoaddress()
|
||||
UniValue address_amounts(UniValue::VOBJ);
|
||||
const std::string address = request.params[0].get_str();
|
||||
address_amounts.pushKV(address, request.params[1]);
|
||||
std::vector<CRecipient> recipients = CreateRecipients(
|
||||
ParseOutputs(address_amounts),
|
||||
InterpretSubtractFeeFromOutputInstructions(request.params[4], address_amounts.getKeys())
|
||||
);
|
||||
|
||||
std::set<int> sffo_set;
|
||||
if (!request.params[4].isNull() && request.params[4].get_bool()) {
|
||||
sffo_set.insert(0);
|
||||
}
|
||||
|
||||
std::vector<CRecipient> recipients{CreateRecipients(ParseOutputs(address_amounts), sffo_set)};
|
||||
const bool verbose{request.params[10].isNull() ? false : request.params[10].get_bool()};
|
||||
|
||||
return SendMoney(*pwallet, coin_control, recipients, mapValue, verbose);
|
||||
|
||||
Reference in New Issue
Block a user