Skip to content

Commit

Permalink
Merge #19836: rpc: Properly deserialize txs with witness before signing
Browse files Browse the repository at this point in the history
3333077 rpc: Adjust witness-tx deserialize error message (MarcoFalke)
cccc752 rpc: Properly deserialize txs with witness before signing (MarcoFalke)

Pull request description:

  Signing a transaction can only happen when the transaction has inputs. A transaction with inputs can always be deserialized as witness-transaction. If `try_no_witness` decoding is attempted, this will lead to rare intermittent failures.

  Fixes #18803

ACKs for top commit:
  achow101:
    ACK 3333077
  ajtowns:
    ACK 3333077

Tree-SHA512: 73f8a5cdfe03fb0e68908d2fa09752c346406f455694a020ec0dd1267ef8f0a583b8e84063ea74aac127106dd193b72623ca6d81469a94b3f5b3c766ebf2c42b
  • Loading branch information
fanquake committed Oct 16, 2020
2 parents 9ad7cd2 + 3333077 commit cbb5f3a
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ static RPCHelpMan generateblock()
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));
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,8 +656,8 @@ static RPCHelpMan combinerawtransaction()
std::vector<CMutableTransaction> txVariants(txs.size());

for (unsigned int idx = 0; idx < txs.size(); idx++) {
if (!DecodeHexTx(txVariants[idx], txs[idx].get_str(), true)) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d", idx));
if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d. Make sure the tx has at least one input.", idx));
}
}

Expand Down Expand Up @@ -780,8 +780,8 @@ static RPCHelpMan signrawtransactionwithkey()
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);

CMutableTransaction mtx;
if (!DecodeHexTx(mtx, request.params[0].get_str(), true)) {
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.");
}

FillableSigningProvider keystore;
Expand Down Expand Up @@ -847,10 +847,10 @@ static RPCHelpMan sendrawtransaction()
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() ?
Expand Down Expand Up @@ -928,7 +928,7 @@ static RPCHelpMan testmempoolaccept()

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();
Expand Down
5 changes: 3 additions & 2 deletions src/wallet/rpcdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,9 @@ RPCHelpMan importprunedfunds()
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);
Expand Down
4 changes: 2 additions & 2 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3331,8 +3331,8 @@ RPCHelpMan signrawtransactionwithwallet()
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VSTR}, true);

CMutableTransaction mtx;
if (!DecodeHexTx(mtx, request.params[0].get_str(), true)) {
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.");
}

// Sign the transaction
Expand Down

0 comments on commit cbb5f3a

Please sign in to comment.