|
16 | 16 | create_coinbase,
|
17 | 17 | )
|
18 | 18 | from test_framework.test_framework import BitcoinTestFramework
|
19 |
| -from test_framework.util import assert_equal |
| 19 | +from test_framework.util import assert_equal, assert_raises_rpc_error |
20 | 20 | from test_framework.wallet import MiniWallet
|
21 | 21 |
|
22 | 22 | MAX_DISCONNECTED_TX_POOL_BYTES = 20_000_000
|
@@ -178,11 +178,45 @@ def test_max_disconnect_pool_bytes(self):
|
178 | 178 | assert_equal([tx["txid"] in mempool for tx in large_std_txs], [tx["txid"] in mempool for tx in small_child_txs])
|
179 | 179 | assert_equal([tx["txid"] in mempool for tx in large_std_txs], [True] * expected_parent_count + [False] * 2)
|
180 | 180 |
|
| 181 | + def test_chainlimits_exceeded(self): |
| 182 | + self.log.info('Check that too long chains on reorg are handled') |
| 183 | + |
| 184 | + wallet = MiniWallet(self.nodes[0]) |
| 185 | + self.generate(wallet, 101) |
| 186 | + |
| 187 | + assert_equal(self.nodes[0].getrawmempool(), []) |
| 188 | + |
| 189 | + # Prep fork |
| 190 | + fork_blocks = self.create_empty_fork(fork_length=10) |
| 191 | + |
| 192 | + # Two higher than default descendant count |
| 193 | + chain = wallet.create_self_transfer_chain(chain_length=27) |
| 194 | + for tx in chain[:-2]: |
| 195 | + self.nodes[0].sendrawtransaction(tx["hex"]) |
| 196 | + |
| 197 | + assert_raises_rpc_error(-26, "too-long-mempool-chain, too many descendants for tx", self.nodes[0].sendrawtransaction, chain[-2]["hex"]) |
| 198 | + |
| 199 | + # Mine a block with all but last transaction, non-standardly long chain |
| 200 | + self.generateblock(self.nodes[0], output="raw(42)", transactions=[tx["hex"] for tx in chain[:-1]]) |
| 201 | + assert_equal(self.nodes[0].getrawmempool(), []) |
| 202 | + |
| 203 | + # Last tx fits now |
| 204 | + self.nodes[0].sendrawtransaction(chain[-1]["hex"]) |
| 205 | + |
| 206 | + # Finally, reorg to empty chain kick everything back into mempool |
| 207 | + # at normal chain limits |
| 208 | + for block in fork_blocks: |
| 209 | + self.nodes[0].submitblock(block.serialize().hex()) |
| 210 | + mempool = self.nodes[0].getrawmempool() |
| 211 | + assert_equal(set(mempool), set([tx["txid"] for tx in chain[:-2]])) |
| 212 | + |
181 | 213 | def run_test(self):
|
182 | 214 | # Use batch size limited by DEFAULT_ANCESTOR_LIMIT = 25 to not fire "too many unconfirmed parents" error.
|
183 | 215 | self.transaction_graph_test(size=100, n_tx_to_mine=[25, 50, 75])
|
184 | 216 |
|
185 | 217 | self.test_max_disconnect_pool_bytes()
|
186 | 218 |
|
| 219 | + self.test_chainlimits_exceeded() |
| 220 | + |
187 | 221 | if __name__ == '__main__':
|
188 | 222 | MempoolUpdateFromBlockTest(__file__).main()
|
0 commit comments