From 9156e07334f0718fa3fb82c5acec56f98e8370f9 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 16 Mar 2020 16:31:38 -0400 Subject: [PATCH] Merge #18350: test: Fix mining to an invalid target + ensure that a new block has the correct hash internally 7a6627ae87b637bf32c03122865402bd71adf0d1 Fix mining to an invalid target + ensure that a new block has the correct hash internally in Python tests (Samer Afach) Pull request description: Test with block 47 in the `feature_block.py` creates a block with a hash higher than the target, which is supposed to fail. Now two issues exist there, and both have low probability of showing up: 1. The creation is done with `while (hash < target)`, which is wrong, because hash = target is a valid mined value based on the code in the function `CheckProofOfWork()` that validates the mining target: ``` if (UintToArith256(hash) > bnTarget) return false; ``` 2. As we know the hash stored in CBlock class in Python is stateful, unlike how it's in C++, where calling `CBlock::GetHash()` will actively calculate the hash and not cache it anywhere. With this, blocks that come out of the method `next_block` can have incorrect hash value when `solve=False`. This is because the `next_block` is mostly used with `solve=True`, and solving does call the function `rehash()` which calculates the hash of the block, but with `solve=False`, nothing calls that method. And since the work to be done in regtests is very low, the probably of this problem showing up is very low, but it practically happens (well, with much higher probability compared to issue No. 1 above). This PR fixes both these issues. Top commit has no ACKs. Tree-SHA512: f3b54d18f5073d6f1c26eab89bfec78620dda4ac1e4dde4f1d69543f1b85a7989d64c907e091db63f3f062408f5ed1e111018b842819ba1a5f8348c7b01ade96 --- test/functional/feature_block.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py index 00ac4ba3df..8499344e1e 100755 --- a/test/functional/feature_block.py +++ b/test/functional/feature_block.py @@ -580,7 +580,7 @@ class FullBlockTest(BitcoinTestFramework): self.move_tip(44) b47 = self.next_block(47, solve=False) target = uint256_from_compact(b47.nBits) - while b47.sha256 < target: + while b47.sha256 <= target: b47.nNonce += 1 b47.rehash() self.send_blocks([b47], False, request_block=False) @@ -1257,6 +1257,8 @@ class FullBlockTest(BitcoinTestFramework): block.hashMerkleRoot = block.calc_merkle_root() if solve: block.solve() + else: + block.rehash() self.tip = block self.block_heights[block.sha256] = height assert number not in self.blocks