Skip to content

Commit c734aaa

Browse files
committed
Split DecodePSBT into Base64 and Raw versions
Split up DecodePSBT, which both decodes base64 and then deserializes a PartiallySignedTransaction, into two functions: DecodeBase64PSBT, which retains the old behavior, and DecodeRawPSBT, which only performs the deserialization. Add a test for base64 decoding failure.
1 parent 162ffef commit c734aaa

File tree

5 files changed

+25
-8
lines changed

5 files changed

+25
-8
lines changed

src/core_io.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
3737
*/
3838
bool ParseHashStr(const std::string& strHex, uint256& result);
3939
std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
40-
NODISCARD bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error);
40+
41+
//! Decode a base64ed PSBT into a PartiallySignedTransaction
42+
NODISCARD bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error);
43+
//! Decode a raw (binary blob) PSBT into a PartiallySignedTransaction
44+
NODISCARD bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, const std::string& raw_psbt, std::string& error);
4145
int ParseSighashString(const UniValue& sighash);
4246

4347
// core_write.cpp

src/core_read.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,20 @@ bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk)
176176
return true;
177177
}
178178

179-
bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error)
179+
bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error)
180180
{
181-
std::vector<unsigned char> tx_data = DecodeBase64(base64_tx.c_str());
182-
CDataStream ss_data(tx_data, SER_NETWORK, PROTOCOL_VERSION);
181+
bool invalid;
182+
std::string tx_data = DecodeBase64(base64_tx, &invalid);
183+
if (invalid) {
184+
error = "invalid base64";
185+
return false;
186+
}
187+
return DecodeRawPSBT(psbt, tx_data, error);
188+
}
189+
190+
bool DecodeRawPSBT(PartiallySignedTransaction& psbt, const std::string& tx_data, std::string& error)
191+
{
192+
CDataStream ss_data(tx_data.data(), tx_data.data() + tx_data.size(), SER_NETWORK, PROTOCOL_VERSION);
183193
try {
184194
ss_data >> psbt;
185195
if (!ss_data.empty()) {

src/rpc/rawtransaction.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,7 @@ UniValue decodepsbt(const JSONRPCRequest& request)
13231323
// Unserialize the transactions
13241324
PartiallySignedTransaction psbtx;
13251325
std::string error;
1326-
if (!DecodePSBT(psbtx, request.params[0].get_str(), error)) {
1326+
if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
13271327
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
13281328
}
13291329

@@ -1524,7 +1524,7 @@ UniValue combinepsbt(const JSONRPCRequest& request)
15241524
for (unsigned int i = 0; i < txs.size(); ++i) {
15251525
PartiallySignedTransaction psbtx;
15261526
std::string error;
1527-
if (!DecodePSBT(psbtx, txs[i].get_str(), error)) {
1527+
if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
15281528
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
15291529
}
15301530
psbtxs.push_back(psbtx);
@@ -1581,7 +1581,7 @@ UniValue finalizepsbt(const JSONRPCRequest& request)
15811581
// Unserialize the transactions
15821582
PartiallySignedTransaction psbtx;
15831583
std::string error;
1584-
if (!DecodePSBT(psbtx, request.params[0].get_str(), error)) {
1584+
if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
15851585
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
15861586
}
15871587

src/wallet/rpcwallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4046,7 +4046,7 @@ UniValue walletprocesspsbt(const JSONRPCRequest& request)
40464046
// Unserialize the transaction
40474047
PartiallySignedTransaction psbtx;
40484048
std::string error;
4049-
if (!DecodePSBT(psbtx, request.params[0].get_str(), error)) {
4049+
if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
40504050
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
40514051
}
40524052

test/functional/rpc_psbt.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,5 +293,8 @@ def run_test(self):
293293
psbt = self.nodes[1].walletcreatefundedpsbt([], [{p2pkh : 1}], 0, {"includeWatching" : True}, True)
294294
self.nodes[0].decodepsbt(psbt['psbt'])
295295

296+
# Test decoding error: invalid base64
297+
assert_raises_rpc_error(-22, "TX decode failed invalid base64", self.nodes[0].decodepsbt, ";definitely not base64;")
298+
296299
if __name__ == '__main__':
297300
PSBTTest().main()

0 commit comments

Comments
 (0)