Skip to content

Commit 16341cc

Browse files
committed
Merge pull request #5418
bba2216 RPC test for "#5418 Report missing inputs in sendrawtransaction" (Jonas Schnelli) de8e801 Report missing inputs in sendrawtransaction (Pieter Wuille)
2 parents 59305ce + bba2216 commit 16341cc

File tree

3 files changed

+78
-3
lines changed

3 files changed

+78
-3
lines changed

qa/pull-tester/rpc-tests.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ testScripts=(
2929
'zapwallettxes.py'
3030
'proxy_test.py'
3131
'merkle_blocks.py'
32+
'rawtransactions.py'
3233
# 'forknotify.py'
3334
'maxblocksinflight.py'
3435
'invalidblockrequest.py'

qa/rpc-tests/rawtransactions.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env python2
2+
# Copyright (c) 2014 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
#
7+
# Test re-org scenarios with a mempool that contains transactions
8+
# that spend (directly or indirectly) coinbase transactions.
9+
#
10+
11+
from test_framework import BitcoinTestFramework
12+
from util import *
13+
from pprint import pprint
14+
from time import sleep
15+
16+
# Create one-input, one-output, no-fee transaction:
17+
class RawTransactionsTest(BitcoinTestFramework):
18+
19+
def setup_chain(self):
20+
print("Initializing test directory "+self.options.tmpdir)
21+
initialize_chain_clean(self.options.tmpdir, 3)
22+
23+
def setup_network(self, split=False):
24+
self.nodes = start_nodes(3, self.options.tmpdir)
25+
26+
#connect to a local machine for debugging
27+
#url = "http://bitcoinrpc:DP6DvqZtqXarpeNWyN3LZTFchCCyCUuHwNF7E8pX99x1@%s:%d" % ('127.0.0.1', 18332)
28+
#proxy = AuthServiceProxy(url)
29+
#proxy.url = url # store URL on proxy for info
30+
#self.nodes.append(proxy)
31+
32+
connect_nodes_bi(self.nodes,0,1)
33+
connect_nodes_bi(self.nodes,1,2)
34+
connect_nodes_bi(self.nodes,0,2)
35+
36+
self.is_network_split=False
37+
self.sync_all()
38+
39+
def run_test(self):
40+
41+
#prepare some coins for multiple *rawtransaction commands
42+
self.nodes[2].generate(1)
43+
self.nodes[0].generate(101)
44+
self.sync_all()
45+
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5);
46+
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0);
47+
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0);
48+
self.sync_all()
49+
self.nodes[0].generate(5)
50+
self.sync_all()
51+
52+
#########################################
53+
# sendrawtransaction with missing input #
54+
#########################################
55+
inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1}] #won't exists
56+
outputs = { self.nodes[0].getnewaddress() : 4.998 }
57+
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
58+
rawtx = self.nodes[2].signrawtransaction(rawtx)
59+
60+
errorString = ""
61+
try:
62+
rawtx = self.nodes[2].sendrawtransaction(rawtx['hex'])
63+
except JSONRPCException,e:
64+
errorString = e.error['message']
65+
66+
assert_equal("Missing inputs" in errorString, True);
67+
68+
if __name__ == '__main__':
69+
RawTransactionsTest().main()

src/rpcrawtransaction.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -756,11 +756,16 @@ Value sendrawtransaction(const Array& params, bool fHelp)
756756
if (!fHaveMempool && !fHaveChain) {
757757
// push to local node and sync with wallets
758758
CValidationState state;
759-
if (!AcceptToMemoryPool(mempool, state, tx, false, NULL, !fOverrideFees)) {
760-
if(state.IsInvalid())
759+
bool fMissingInputs;
760+
if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
761+
if (state.IsInvalid()) {
761762
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
762-
else
763+
} else {
764+
if (fMissingInputs) {
765+
throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
766+
}
763767
throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
768+
}
764769
}
765770
} else if (fHaveChain) {
766771
throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");

0 commit comments

Comments
 (0)