(self)
| 23 | ] |
| 24 | |
| 25 | def run_test(self): |
| 26 | wallet = MiniWallet(self.nodes[0]) |
| 27 | |
| 28 | # Start with a 200 block chain |
| 29 | assert_equal(self.nodes[0].getblockcount(), 200) |
| 30 | |
| 31 | self.log.info("Add 4 coinbase utxos to the miniwallet") |
| 32 | # Block 76 contains the first spendable coinbase txs. |
| 33 | first_block = 76 |
| 34 | wallet.rescan_utxos() |
| 35 | |
| 36 | # Three scenarios for re-orging coinbase spends in the memory pool: |
| 37 | # 1. Direct coinbase spend : spend_1 |
| 38 | # 2. Indirect (coinbase spend in chain, child in mempool) : spend_2 and spend_2_1 |
| 39 | # 3. Indirect (coinbase and child both in chain) : spend_3 and spend_3_1 |
| 40 | # Use invalidateblock to make all of the above coinbase spends invalid (immature coinbase), |
| 41 | # and make sure the mempool code behaves correctly. |
| 42 | b = [self.nodes[0].getblockhash(n) for n in range(first_block, first_block+4)] |
| 43 | coinbase_txids = [self.nodes[0].getblock(h)['tx'][0] for h in b] |
| 44 | utxo_1 = wallet.get_utxo(txid=coinbase_txids[1]) |
| 45 | utxo_2 = wallet.get_utxo(txid=coinbase_txids[2]) |
| 46 | utxo_3 = wallet.get_utxo(txid=coinbase_txids[3]) |
| 47 | self.log.info("Create three transactions spending from coinbase utxos: spend_1, spend_2, spend_3") |
| 48 | spend_1 = wallet.create_self_transfer(utxo_to_spend=utxo_1) |
| 49 | spend_2 = wallet.create_self_transfer(utxo_to_spend=utxo_2) |
| 50 | spend_3 = wallet.create_self_transfer(utxo_to_spend=utxo_3) |
| 51 | |
| 52 | self.log.info("Create another transaction which is time-locked to two blocks in the future") |
| 53 | utxo = wallet.get_utxo(txid=coinbase_txids[0]) |
| 54 | timelock_tx = wallet.create_self_transfer( |
| 55 | utxo_to_spend=utxo, |
| 56 | mempool_valid=False, |
| 57 | locktime=self.nodes[0].getblockcount() + 2 |
| 58 | )['hex'] |
| 59 | |
| 60 | self.log.info("Check that the time-locked transaction is too immature to spend") |
| 61 | assert_raises_rpc_error(-26, "non-final", self.nodes[0].sendrawtransaction, timelock_tx) |
| 62 | |
| 63 | self.log.info("Broadcast and mine spend_2 and spend_3") |
| 64 | wallet.sendrawtransaction(from_node=self.nodes[0], tx_hex=spend_2['hex']) |
| 65 | wallet.sendrawtransaction(from_node=self.nodes[0], tx_hex=spend_3['hex']) |
| 66 | self.log.info("Generate a block") |
| 67 | self.generate(self.nodes[0], 1) |
| 68 | self.log.info("Check that time-locked transaction is still too immature to spend") |
| 69 | assert_raises_rpc_error(-26, 'non-final', self.nodes[0].sendrawtransaction, timelock_tx) |
| 70 | |
| 71 | self.log.info("Create spend_2_1 and spend_3_1") |
| 72 | spend_2_utxo = wallet.get_utxo(txid=spend_2['txid']) |
| 73 | spend_2_1 = wallet.create_self_transfer(utxo_to_spend=spend_2_utxo) |
| 74 | spend_3_utxo = wallet.get_utxo(txid=spend_3['txid']) |
| 75 | spend_3_1 = wallet.create_self_transfer(utxo_to_spend=spend_3_utxo) |
| 76 | |
| 77 | self.log.info("Broadcast and mine spend_3_1") |
| 78 | spend_3_1_id = self.nodes[0].sendrawtransaction(spend_3_1['hex']) |
| 79 | self.log.info("Generate a block") |
| 80 | last_block = self.generate(self.nodes[0], 1) |
| 81 | # generate() implicitly syncs blocks, so that peer 1 gets the block before timelock_tx |
| 82 | # Otherwise, peer 1 would put the timelock_tx in m_recent_rejects |
nothing calls this directly
no test coverage detected