(self)
| 228 | assert_greater_than(550, usage) |
| 229 | |
| 230 | def reorg_back(self): |
| 231 | # Verify that a block on the old main chain fork has been pruned away |
| 232 | assert_raises_rpc_error(-1, "Block not available (pruned data)", self.nodes[2].getblock, self.forkhash) |
| 233 | with self.nodes[2].assert_debug_log(expected_msgs=['block verification stopping at height', '(pruning, no data)']): |
| 234 | self.nodes[2].verifychain(checklevel=4, nblocks=0) |
| 235 | self.log.info(f"Will need to redownload block {self.forkheight}") |
| 236 | |
| 237 | # Verify that we have enough history to reorg back to the fork point |
| 238 | # Although this is more than 288 blocks, because this chain was written more recently |
| 239 | # and only its other 299 small and 220 large blocks are in the block files after it, |
| 240 | # it is expected to still be retained |
| 241 | self.nodes[2].getblock(self.nodes[2].getblockhash(self.forkheight)) |
| 242 | |
| 243 | first_reorg_height = self.nodes[2].getblockcount() |
| 244 | curchainhash = self.nodes[2].getblockhash(self.mainchainheight) |
| 245 | self.nodes[2].invalidateblock(curchainhash) |
| 246 | goalbestheight = self.mainchainheight |
| 247 | goalbesthash = self.mainchainhash2 |
| 248 | |
| 249 | # As of 0.10 the current block download logic is not able to reorg to the original chain created in |
| 250 | # create_chain_with_stale_blocks because it doesn't know of any peer that's on that chain from which to |
| 251 | # redownload its missing blocks. |
| 252 | # Invalidate the reorg_test chain in node 0 as well, it can successfully switch to the original chain |
| 253 | # because it has all the block data. |
| 254 | # However it must mine enough blocks to have a more work chain than the reorg_test chain in order |
| 255 | # to trigger node 2's block download logic. |
| 256 | # At this point node 2 is within 288 blocks of the fork point so it will preserve its ability to reorg |
| 257 | if self.nodes[2].getblockcount() < self.mainchainheight: |
| 258 | blocks_to_mine = first_reorg_height + 1 - self.mainchainheight |
| 259 | self.log.info(f"Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed: {blocks_to_mine}") |
| 260 | self.nodes[0].invalidateblock(curchainhash) |
| 261 | assert_equal(self.nodes[0].getblockcount(), self.mainchainheight) |
| 262 | assert_equal(self.nodes[0].getbestblockhash(), self.mainchainhash2) |
| 263 | goalbesthash = self.generate(self.nodes[0], blocks_to_mine, sync_fun=self.no_op)[-1] |
| 264 | goalbestheight = first_reorg_height + 1 |
| 265 | |
| 266 | self.log.info("Verify node 2 reorged back to the main chain, some blocks of which it had to redownload") |
| 267 | # Wait for Node 2 to reorg to proper height |
| 268 | self.wait_until(lambda: self.nodes[2].getblockcount() >= goalbestheight, timeout=900) |
| 269 | assert_equal(self.nodes[2].getbestblockhash(), goalbesthash) |
| 270 | # Verify we can now have the data for a block previously pruned |
| 271 | assert_equal(self.nodes[2].getblock(self.forkhash)["height"], self.forkheight) |
| 272 | |
| 273 | def manual_test(self, node_number, use_timestamp): |
| 274 | # at this point, node has 995 blocks and has not yet run in prune mode |
no test coverage detected