From cccc7525697e7b8d99b545e34f0f504c78ffdb94 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 30 Aug 2020 10:28:42 +0200 Subject: [PATCH 1/2] rpc: Properly deserialize txs with witness before signing --- src/rpc/rawtransaction.cpp | 4 ++-- src/wallet/rpcwallet.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index d6988ee3ac..b0df6ec287 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -644,7 +644,7 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request) std::vector txVariants(txs.size()); for (unsigned int idx = 0; idx < txs.size(); idx++) { - if (!DecodeHexTx(txVariants[idx], txs[idx].get_str(), true)) { + if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d", idx)); } } @@ -766,7 +766,7 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); CMutableTransaction mtx; - if (!DecodeHexTx(mtx, request.params[0].get_str(), true)) { + if (!DecodeHexTx(mtx, request.params[0].get_str())) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 17512265b5..6978fc400a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3229,7 +3229,7 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request) RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VSTR}, true); CMutableTransaction mtx; - if (!DecodeHexTx(mtx, request.params[0].get_str(), true)) { + if (!DecodeHexTx(mtx, request.params[0].get_str())) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); } From 33330778230961cfbf2a24de36b5877e395cc596 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 13 Oct 2020 15:21:03 +0200 Subject: [PATCH 2/2] rpc: Adjust witness-tx deserialize error message --- src/rpc/mining.cpp | 2 +- src/rpc/rawtransaction.cpp | 12 ++++++------ src/wallet/rpcdump.cpp | 5 +++-- src/wallet/rpcwallet.cpp | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index d9cc6f8832..661181850b 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -346,7 +346,7 @@ static UniValue generateblock(const JSONRPCRequest& request) txs.push_back(MakeTransactionRef(std::move(mtx))); } else { - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("Transaction decode failed for %s", str)); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("Transaction decode failed for %s. Make sure the tx has at least one input.", str)); } } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index b0df6ec287..5354b4a681 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -645,7 +645,7 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request) for (unsigned int idx = 0; idx < txs.size(); idx++) { if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) { - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d", idx)); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d. Make sure the tx has at least one input.", idx)); } } @@ -767,7 +767,7 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) CMutableTransaction mtx; if (!DecodeHexTx(mtx, request.params[0].get_str())) { - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input."); } FillableSigningProvider keystore; @@ -831,10 +831,10 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) UniValueType(), // VNUM or VSTR, checked inside AmountFromValue() }); - // parse hex string from parameter CMutableTransaction mtx; - if (!DecodeHexTx(mtx, request.params[0].get_str())) - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + if (!DecodeHexTx(mtx, request.params[0].get_str())) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input."); + } CTransactionRef tx(MakeTransactionRef(std::move(mtx))); const CFeeRate max_raw_tx_fee_rate = request.params[1].isNull() ? @@ -905,7 +905,7 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request) CMutableTransaction mtx; if (!DecodeHexTx(mtx, request.params[0].get_array()[0].get_str())) { - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input."); } CTransactionRef tx(MakeTransactionRef(std::move(mtx))); const uint256& tx_hash = tx->GetHash(); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index e0c3a1287a..e343ef3bc3 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -334,8 +334,9 @@ UniValue importprunedfunds(const JSONRPCRequest& request) CWallet* const pwallet = wallet.get(); CMutableTransaction tx; - if (!DecodeHexTx(tx, request.params[0].get_str())) - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + if (!DecodeHexTx(tx, request.params[0].get_str())) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input."); + } uint256 hashTx = tx.GetHash(); CDataStream ssMB(ParseHexV(request.params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6978fc400a..c5d8053995 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3230,7 +3230,7 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request) CMutableTransaction mtx; if (!DecodeHexTx(mtx, request.params[0].get_str())) { - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input."); } // Sign the transaction