Skip to content

Commit f7384b9

Browse files
committed
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.
1 parent 6f569ac commit f7384b9

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

src/rpc/rawtransaction_util.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,41 +97,49 @@ UniValue NormalizeOutputs(const UniValue& outputs_in)
9797
return outputs;
9898
}
9999

100-
void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in)
100+
std::vector<std::pair<CTxDestination, CAmount>> ParseOutputs(const UniValue& outputs)
101101
{
102-
UniValue outputs(UniValue::VOBJ);
103-
outputs = NormalizeOutputs(outputs_in);
104-
105102
// Duplicate checking
106103
std::set<CTxDestination> destinations;
104+
std::vector<std::pair<CTxDestination, CAmount>> parsed_outputs;
107105
bool has_data{false};
108-
109106
for (const std::string& name_ : outputs.getKeys()) {
110107
if (name_ == "data") {
111108
if (has_data) {
112109
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, duplicate key: data");
113110
}
114111
has_data = true;
115112
std::vector<unsigned char> data = ParseHexV(outputs[name_].getValStr(), "Data");
116-
117-
CTxOut out(0, CScript() << OP_RETURN << data);
118-
rawTx.vout.push_back(out);
113+
CTxDestination destination{CNoDestination{CScript() << OP_RETURN << data}};
114+
CAmount amount{0};
115+
parsed_outputs.emplace_back(destination, amount);
119116
} else {
120-
CTxDestination destination = DecodeDestination(name_);
117+
CTxDestination destination{DecodeDestination(name_)};
118+
CAmount amount{AmountFromValue(outputs[name_])};
121119
if (!IsValidDestination(destination)) {
122120
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + name_);
123121
}
124122

125123
if (!destinations.insert(destination).second) {
126124
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
127125
}
126+
parsed_outputs.emplace_back(destination, amount);
127+
}
128+
}
129+
return parsed_outputs;
130+
}
128131

129-
CScript scriptPubKey = GetScriptForDestination(destination);
130-
CAmount nAmount = AmountFromValue(outputs[name_]);
132+
void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in)
133+
{
134+
UniValue outputs(UniValue::VOBJ);
135+
outputs = NormalizeOutputs(outputs_in);
131136

132-
CTxOut out(nAmount, scriptPubKey);
133-
rawTx.vout.push_back(out);
134-
}
137+
std::vector<std::pair<CTxDestination, CAmount>> parsed_outputs = ParseOutputs(outputs);
138+
for (const auto& [destination, nAmount] : parsed_outputs) {
139+
CScript scriptPubKey = GetScriptForDestination(destination);
140+
141+
CTxOut out(nAmount, scriptPubKey);
142+
rawTx.vout.push_back(out);
135143
}
136144
}
137145

src/rpc/rawtransaction_util.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#ifndef BITCOIN_RPC_RAWTRANSACTION_UTIL_H
66
#define BITCOIN_RPC_RAWTRANSACTION_UTIL_H
77

8+
#include <addresstype.h>
9+
#include <consensus/amount.h>
810
#include <map>
911
#include <string>
1012
#include <optional>
@@ -38,13 +40,15 @@ void SignTransactionResultToJSON(CMutableTransaction& mtx, bool complete, const
3840
*/
3941
void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins);
4042

41-
4243
/** Normalize univalue-represented inputs and add them to the transaction */
4344
void AddInputs(CMutableTransaction& rawTx, const UniValue& inputs_in, bool rbf);
4445

4546
/** Normalize univalue-represented outputs */
4647
UniValue NormalizeOutputs(const UniValue& outputs_in);
4748

49+
/** Parse normalized outputs into destination, amount tuples */
50+
std::vector<std::pair<CTxDestination, CAmount>> ParseOutputs(const UniValue& outputs);
51+
4852
/** Normalize, parse, and add outputs to the transaction */
4953
void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in);
5054

0 commit comments

Comments
 (0)