aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjosibake <josibake@protonmail.com>2023-12-22 11:27:53 +0100
committerjosibake <josibake@protonmail.com>2024-01-19 15:04:56 +0100
commitf7384b921c3460c7a3cc7827a68b2c613bd98f8e (patch)
treefa2a0221ac6afb4c038b0cd3df2179675f2d726f
parent6f569ac903e5ddaac275996a5d0c31b2220b7b81 (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.cpp36
-rw-r--r--src/rpc/rawtransaction_util.h6
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);