@@ -35,22 +35,30 @@ def setUpClass(cls):
35
35
cls .proxy = bitcoin .rpc .Proxy ()
36
36
37
37
@classmethod
38
- def tearDownClass (cls ):
39
- # Make sure mining works
38
+ def mine_mempool (cls ):
39
+ """Mine until mempool is empty"""
40
40
mempool_size = 1
41
41
while mempool_size :
42
- cls .proxy .call ('generate' ,1 )
42
+ cls .proxy .call ('generate' , 1 )
43
43
new_mempool_size = len (cls .proxy .getrawmempool ())
44
44
45
45
# It's possible to get stuck in a loop here if the mempool has
46
46
# transactions that can't be mined.
47
47
assert (new_mempool_size != mempool_size )
48
48
mempool_size = new_mempool_size
49
49
50
- def make_txout (self , amount , scriptPubKey = CScript ([1 ])):
50
+ @classmethod
51
+ def tearDownClass (cls ):
52
+ # Make sure mining works
53
+ cls .mine_mempool ()
54
+
55
+ def make_txout (self , amount , confirmed = True , scriptPubKey = CScript ([1 ])):
51
56
"""Create a txout with a given amount and scriptPubKey
52
57
53
58
Mines coins as needed.
59
+
60
+ confirmed - txouts created will be confirmed in the blockchain;
61
+ unconfirmed otherwise.
54
62
"""
55
63
fee = 1 * COIN
56
64
while self .proxy .getbalance () < amount + fee :
@@ -72,6 +80,10 @@ def make_txout(self, amount, scriptPubKey=CScript([1])):
72
80
73
81
tx2_txid = self .proxy .sendrawtransaction (tx2 , True )
74
82
83
+ # If requested, ensure txouts are confirmed.
84
+ if confirmed :
85
+ self .mine_mempool ()
86
+
75
87
return COutPoint (tx2_txid , 0 )
76
88
77
89
def test_simple_doublespend (self ):
@@ -276,5 +288,24 @@ def test_spends_of_conflicting_outputs(self):
276
288
else :
277
289
self .fail ()
278
290
291
+ def test_new_unconfirmed_inputs (self ):
292
+ """Replacements that add new unconfirmed inputs are rejected"""
293
+ confirmed_utxo = self .make_txout (1.1 * COIN )
294
+ unconfirmed_utxo = self .make_txout (0.1 * COIN , False )
295
+
296
+ tx1 = CTransaction ([CTxIn (confirmed_utxo )],
297
+ [CTxOut (1.0 * COIN , CScript ([b'a' ]))])
298
+ tx1_txid = self .proxy .sendrawtransaction (tx1 , True )
299
+
300
+ tx2 = CTransaction ([CTxIn (confirmed_utxo ), CTxIn (unconfirmed_utxo )],
301
+ tx1 .vout )
302
+
303
+ try :
304
+ tx2_txid = self .proxy .sendrawtransaction (tx2 , True )
305
+ except bitcoin .rpc .JSONRPCException as exp :
306
+ self .assertEqual (exp .error ['code' ], - 26 )
307
+ else :
308
+ self .fail ()
309
+
279
310
if __name__ == '__main__' :
280
311
unittest .main ()
0 commit comments