diff options
author | josibake <josibake@protonmail.com> | 2023-12-22 11:27:53 +0100 |
---|---|---|
committer | josibake <josibake@protonmail.com> | 2024-01-19 15:04:56 +0100 |
commit | f7384b921c3460c7a3cc7827a68b2c613bd98f8e (patch) | |
tree | fa2a0221ac6afb4c038b0cd3df2179675f2d726f | |
parent | 6f569ac903e5ddaac275996a5d0c31b2220b7b81 (diff) |
refactor: move parsing to new function
Move the parsing and validation out of `AddOutputs` into its own function,
`ParseOutputs`. This allows us to re-use this logic in `ParseRecipients` in a
later commit, where the code is currently duplicated.
The new `ParseOutputs` function returns a CTxDestination,CAmount tuples.
This allows the caller to then translate the validated outputs into
either CRecipients or CTxOuts.
-rw-r--r-- | src/rpc/rawtransaction_util.cpp | 36 | ||||
-rw-r--r-- | src/rpc/rawtransaction_util.h | 6 |
2 files changed, 27 insertions, 15 deletions
diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp index eb8067cc23..a9e11622a7 100644 --- a/src/rpc/rawtransaction_util.cpp +++ b/src/rpc/rawtransaction_util.cpp @@ -97,15 +97,12 @@ UniValue NormalizeOutputs(const UniValue& outputs_in) return outputs; } -void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in) +std::vector<std::pair<CTxDestination, CAmount>> ParseOutputs(const UniValue& outputs) { - UniValue outputs(UniValue::VOBJ); - outputs = NormalizeOutputs(outputs_in); - // Duplicate checking std::set<CTxDestination> destinations; + std::vector<std::pair<CTxDestination, CAmount>> parsed_outputs; bool has_data{false}; - for (const std::string& name_ : outputs.getKeys()) { if (name_ == "data") { if (has_data) { @@ -113,11 +110,12 @@ void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in) } has_data = true; std::vector<unsigned char> data = ParseHexV(outputs[name_].getValStr(), "Data"); - - CTxOut out(0, CScript() << OP_RETURN << data); - rawTx.vout.push_back(out); + CTxDestination destination{CNoDestination{CScript() << OP_RETURN << data}}; + CAmount amount{0}; + parsed_outputs.emplace_back(destination, amount); } else { - CTxDestination destination = DecodeDestination(name_); + CTxDestination destination{DecodeDestination(name_)}; + CAmount amount{AmountFromValue(outputs[name_])}; if (!IsValidDestination(destination)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + name_); } @@ -125,13 +123,23 @@ void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in) if (!destinations.insert(destination).second) { throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_); } + parsed_outputs.emplace_back(destination, amount); + } + } + return parsed_outputs; +} - CScript scriptPubKey = GetScriptForDestination(destination); - CAmount nAmount = AmountFromValue(outputs[name_]); +void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in) +{ + UniValue outputs(UniValue::VOBJ); + outputs = NormalizeOutputs(outputs_in); - CTxOut out(nAmount, scriptPubKey); - rawTx.vout.push_back(out); - } + std::vector<std::pair<CTxDestination, CAmount>> parsed_outputs = ParseOutputs(outputs); + for (const auto& [destination, nAmount] : parsed_outputs) { + CScript scriptPubKey = GetScriptForDestination(destination); + + CTxOut out(nAmount, scriptPubKey); + rawTx.vout.push_back(out); } } diff --git a/src/rpc/rawtransaction_util.h b/src/rpc/rawtransaction_util.h index f3d5c3616e..964d0b095b 100644 --- a/src/rpc/rawtransaction_util.h +++ b/src/rpc/rawtransaction_util.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_RPC_RAWTRANSACTION_UTIL_H #define BITCOIN_RPC_RAWTRANSACTION_UTIL_H +#include <addresstype.h> +#include <consensus/amount.h> #include <map> #include <string> #include <optional> @@ -38,13 +40,15 @@ void SignTransactionResultToJSON(CMutableTransaction& mtx, bool complete, const */ void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins); - /** Normalize univalue-represented inputs and add them to the transaction */ void AddInputs(CMutableTransaction& rawTx, const UniValue& inputs_in, bool rbf); /** Normalize univalue-represented outputs */ UniValue NormalizeOutputs(const UniValue& outputs_in); +/** Parse normalized outputs into destination, amount tuples */ +std::vector<std::pair<CTxDestination, CAmount>> ParseOutputs(const UniValue& outputs); + /** Normalize, parse, and add outputs to the transaction */ void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in); |