Skip to content

Commit 40f7e27

Browse files
committed
Merge #9650: Better handle invalid parameters to signrawtransaction
6dbfe08 [qa] test signrawtransaction merge with missing inputs (Matt Corallo) ec4f7e4 [qa] Add second input to signrawtransaction test case (Matt Corallo) 691710a [qa] Test that decoderawtransaction throws with extra data appended (Matt Corallo) 922bea9 Better handle invalid parameters to signrawtransaction (Matt Corallo) 7ea0ad5 Fail in DecodeHexTx if there is extra data at the end (Matt Corallo)
2 parents 09e0c28 + 6dbfe08 commit 40f7e27

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

qa/rpc-tests/signrawtransactions.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ def successful_signing_test(self):
2626
2727
1) The transaction has a complete set of signatures
2828
2) No script verification error occurred"""
29-
privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N']
29+
privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N', 'cVKpPfVKSJxKqVpE9awvXNWuLHCa5j5tiE7K6zbUSptFpTEtiFrA']
3030

3131
inputs = [
32-
# Valid pay-to-pubkey script
32+
# Valid pay-to-pubkey scripts
3333
{'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0,
34-
'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'}
34+
'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'},
35+
{'txid': '83a4f6a6b73660e13ee6cb3c6063fa3759c50c9b7521d0536022961898f4fb02', 'vout': 0,
36+
'scriptPubKey': '76a914669b857c03a5ed269d5d85a1ffac9ed5d663072788ac'},
3537
]
3638

3739
outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1}
@@ -46,6 +48,22 @@ def successful_signing_test(self):
4648
# 2) No script verification error occurred
4749
assert 'errors' not in rawTxSigned
4850

51+
# Check that signrawtransaction doesn't blow up on garbage merge attempts
52+
dummyTxInconsistent = self.nodes[0].createrawtransaction([inputs[0]], outputs)
53+
rawTxUnsigned = self.nodes[0].signrawtransaction(rawTx + dummyTxInconsistent, inputs)
54+
55+
assert 'complete' in rawTxUnsigned
56+
assert_equal(rawTxUnsigned['complete'], False)
57+
58+
# Check that signrawtransaction properly merges unsigned and signed txn, even with garbage in the middle
59+
rawTxSigned2 = self.nodes[0].signrawtransaction(rawTxUnsigned["hex"] + dummyTxInconsistent + rawTxSigned["hex"], inputs)
60+
61+
assert 'complete' in rawTxSigned2
62+
assert_equal(rawTxSigned2['complete'], True)
63+
64+
assert 'errors' not in rawTxSigned2
65+
66+
4967
def script_verification_error_test(self):
5068
"""Creates and signs a raw transaction with valid (vin 0), invalid (vin 1) and one missing (vin 2) input script.
5169
@@ -78,6 +96,16 @@ def script_verification_error_test(self):
7896
outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1}
7997

8098
rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
99+
100+
# Make sure decoderawtransaction is at least marginally sane
101+
decodedRawTx = self.nodes[0].decoderawtransaction(rawTx)
102+
for i, inp in enumerate(inputs):
103+
assert_equal(decodedRawTx["vin"][i]["txid"], inp["txid"])
104+
assert_equal(decodedRawTx["vin"][i]["vout"], inp["vout"])
105+
106+
# Make sure decoderawtransaction throws if there is extra data
107+
assert_raises(JSONRPCException, self.nodes[0].decoderawtransaction, rawTx + "00")
108+
81109
rawTxSigned = self.nodes[0].signrawtransaction(rawTx, scripts, privKeys)
82110

83111
# 3) The transaction has no complete set of signatures

src/core_read.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ bool DecodeHexTx(CMutableTransaction& tx, const std::string& strHexTx, bool fTry
111111
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
112112
try {
113113
ssData >> tx;
114+
if (!ssData.empty())
115+
return false;
114116
}
115117
catch (const std::exception&) {
116118
return false;

src/rpc/rawtransaction.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,9 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
835835

836836
// ... and merge in other signatures:
837837
BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
838-
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i));
838+
if (txv.vin.size() > i) {
839+
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i));
840+
}
839841
}
840842

841843
UpdateTransaction(mergedTx, i, sigdata);

0 commit comments

Comments
 (0)