Skip to content

Commit fad42e8

Browse files
committed
Merge #13547: Make signrawtransaction* give an error when amount is needed but missing
685d1d8 [tests] Check signrawtransaction* errors on missing prevtx info (Anthony Towns) a3b065b Error on missing amount in signrawtransaction* (Anthony Towns) Pull request description: Signatures using segregated witness commit to the amount being spent, so that value must be passed into signrawtransactionwithkey and signrawtransactionwithwallet. This ensures an error is issued if that doesn't happen, rather than just assuming the value is 0 and producing a signature that is almost certainly invalid. Based on Ben Woosley's #12458, Fixes: #12429. Tree-SHA512: 8e2ff89d5bcf79548e569210af0d850028bc98d86c149b92207c9300ab1d63664a7e2b222c1be403a15941aa5cf36ccc3c0d570ee1c1466f3496b4fe06c17e11
2 parents b05ded1 + 685d1d8 commit fad42e8

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

src/rpc/rawtransaction.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
811811
}
812812
Coin newcoin;
813813
newcoin.out.scriptPubKey = scriptPubKey;
814-
newcoin.out.nValue = 0;
814+
newcoin.out.nValue = MAX_MONEY;
815815
if (prevOut.exists("amount")) {
816816
newcoin.out.nValue = AmountFromValue(find_value(prevOut, "amount"));
817817
}
@@ -883,6 +883,11 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
883883

884884
UpdateInput(txin, sigdata);
885885

886+
// amount must be specified for valid segwit signature
887+
if (amount == MAX_MONEY && !txin.scriptWitness.IsNull()) {
888+
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing amount for %s", coin.out.ToString()));
889+
}
890+
886891
ScriptError serror = SCRIPT_ERR_OK;
887892
if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), &serror)) {
888893
if (serror == SCRIPT_ERR_INVALID_STACK_OPERATION) {

test/functional/rpc_rawtransaction.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,61 @@ def run_test(self):
137137
self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=[{address: 99}, {'data': '99'}, {'data': '99'}]),
138138
)
139139

140+
for type in ["bech32", "p2sh-segwit", "legacy"]:
141+
addr = self.nodes[0].getnewaddress("", type)
142+
addrinfo = self.nodes[0].getaddressinfo(addr)
143+
pubkey = addrinfo["scriptPubKey"]
144+
145+
self.log.info('sendrawtransaction with missing prevtx info (%s)' %(type))
146+
147+
# Test `signrawtransactionwithwallet` invalid `prevtxs`
148+
inputs = [ {'txid' : txid, 'vout' : 3, 'sequence' : 1000}]
149+
outputs = { self.nodes[0].getnewaddress() : 1 }
150+
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
151+
152+
prevtx = dict(txid=txid, scriptPubKey=pubkey, vout=3, amount=1)
153+
succ = self.nodes[0].signrawtransactionwithwallet(rawtx, [prevtx])
154+
assert succ["complete"]
155+
if type == "legacy":
156+
del prevtx["amount"]
157+
succ = self.nodes[0].signrawtransactionwithwallet(rawtx, [prevtx])
158+
assert succ["complete"]
159+
160+
if type != "legacy":
161+
assert_raises_rpc_error(-3, "Missing amount", self.nodes[0].signrawtransactionwithwallet, rawtx, [
162+
{
163+
"txid": txid,
164+
"scriptPubKey": pubkey,
165+
"vout": 3,
166+
}
167+
])
168+
169+
assert_raises_rpc_error(-3, "Missing vout", self.nodes[0].signrawtransactionwithwallet, rawtx, [
170+
{
171+
"txid": txid,
172+
"scriptPubKey": pubkey,
173+
"amount": 1,
174+
}
175+
])
176+
assert_raises_rpc_error(-3, "Missing txid", self.nodes[0].signrawtransactionwithwallet, rawtx, [
177+
{
178+
"scriptPubKey": pubkey,
179+
"vout": 3,
180+
"amount": 1,
181+
}
182+
])
183+
assert_raises_rpc_error(-3, "Missing scriptPubKey", self.nodes[0].signrawtransactionwithwallet, rawtx, [
184+
{
185+
"txid": txid,
186+
"vout": 3,
187+
"amount": 1
188+
}
189+
])
190+
191+
#########################################
192+
# sendrawtransaction with missing input #
193+
#########################################
194+
140195
self.log.info('sendrawtransaction with missing input')
141196
inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1}] #won't exists
142197
outputs = { self.nodes[0].getnewaddress() : 4.998 }

0 commit comments

Comments
 (0)