-
Notifications
You must be signed in to change notification settings - Fork 37.7k
test: Fix mining to an invalid target + ensure that a new block has the correct hash internally #18350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
correct hash internally in Python tests
If this was ever the cause of a test failure, it probably means our assumption about hash functions is broken. Still, ACK. I don't mind fixing it. |
Concept ACK fixing issue 1. Like @MarcoFalke says, the probability of this ever causing a failure is negligible, but it's better that the test's assumptions are accurate. For issue 2 ( |
Actually you're right about the first fix, but the second one has a much higher likelihood to happen. I was able to simulate it by putting it on the tip of the block 1 and it happened always within a loop of 1000 tests that repeat b47's test case. |
@TheQuantumPhysicist let me know if you want to address @jnewbery 's feedback or not |
@MarcoFalke Do you mean implement it? If so, I don't mind. I just need a confirmation that this is the solution we wanna go for. In my opinion, the solve option should remain, because solving and hashing are different requirements. But I don't mind either way. |
I think in tests we aim for simplicity, even if that comes at a trivial cost like a few hashes. So I see @jnewbery 's point. I am happy to merge either version. |
If you don't mind either way, please merge it as it's, and anyone is welcome to change it, since it's correct in its current form. If I see the majority over here insisting on changing it to remove solve, I'm all for it. I'm just too lazy to run more and test more spontaneously 😄 |
I really don't like the second commit. I think it adds complexity for no good reason, and without commenting it makes the code less clear instead of more. |
This has been merged, but anyone who feels that the logic needs commenting or a refactor, may open a follow-up pull request. |
…hat a new block has the correct hash internally 7a6627a 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
- doc: fix git add argument bitcoin#18513 - build: Fix libevent linking for bench_bitcoin binary bitcoin#18397 - script: fix SCRIPT_ERR_SIG_PUSHONLY error string bitcoin#18412 - doc: Comment fix merkle.cpp bitcoin#18379 - log: Fix UB with bench on genesis block bitcoin#15283 - test: Fix mining to an invalid target + ensure that a new block has the correct hash internally bitcoin#18350 - Fix missing header in sync.h bitcoin#18357 - refactor: Fix implicit value conversion in formatPingTime bitcoin#18260 - Fix .gitignore policy in build_msvc directory bitcoin#18108 - build: Fix behavior when ALLOW_HOST_PACKAGES unset bitcoin#18051 - test: Fix p2p_invalid_messages failing in Python 3.8 because of warning bitcoin#17931 - qa: Fix double-negative arg test bitcoin#17893 - build: Fix configure report about qr bitcoin#17547 - log: Fix log message for -par=1 bitcoin#17325 - bench: Fix negative values and zero for -evals flag bitcoin#17267 - depends: fix boost mac cross build with clang 9+ bitcoin#17231 - doc: Fix broken bitcoin-cli examples bitcoin#17119 - doc: fix Makefile target in benchmarking.md bitcoin#17081 - contrib: fix minor typos in makeseeds.py bitcoin#17042 - test: Fix Python Docstring to include all Args. bitcoin#17030 - doc: Fix some misspellings bitcoin#17351 - doc: Doxygen-friendly script/descriptor.h comments bitcoin#16947 - doc: Fix doxygen errors bitcoin#17945 - doc: Doxygen-friendly CuckooCache comments bitcoin#16986 - doc: Add to Doxygen documentation guidelines bitcoin#17873
- doc: fix git add argument bitcoin#18513 - build: Fix libevent linking for bench_bitcoin binary bitcoin#18397 - script: fix SCRIPT_ERR_SIG_PUSHONLY error string bitcoin#18412 - doc: Comment fix merkle.cpp bitcoin#18379 - log: Fix UB with bench on genesis block bitcoin#15283 - test: Fix mining to an invalid target + ensure that a new block has the correct hash internally bitcoin#18350 - Fix missing header in sync.h bitcoin#18357 - refactor: Fix implicit value conversion in formatPingTime bitcoin#18260 - Fix .gitignore policy in build_msvc directory bitcoin#18108 - build: Fix behavior when ALLOW_HOST_PACKAGES unset bitcoin#18051 - test: Fix p2p_invalid_messages failing in Python 3.8 because of warning bitcoin#17931 - qa: Fix double-negative arg test bitcoin#17893 - build: Fix configure report about qr bitcoin#17547 - log: Fix log message for -par=1 bitcoin#17325 - bench: Fix negative values and zero for -evals flag bitcoin#17267 - depends: fix boost mac cross build with clang 9+ bitcoin#17231 - doc: Fix broken bitcoin-cli examples bitcoin#17119 - doc: fix Makefile target in benchmarking.md bitcoin#17081 - contrib: fix minor typos in makeseeds.py bitcoin#17042 - test: Fix Python Docstring to include all Args. bitcoin#17030 - doc: Fix some misspellings bitcoin#17351 - doc: Doxygen-friendly script/descriptor.h comments bitcoin#16947 - doc: Fix doxygen errors bitcoin#17945 - doc: Doxygen-friendly CuckooCache comments bitcoin#16986 - doc: Add to Doxygen documentation guidelines bitcoin#17873 - depends: Consistent use of package variable bitcoin#17928 - init: Replace URL_WEBSITE with PACKAGE_URL bitcoin#18503 - doc: Add missed copyright headers bitcoin#17691
…hat a new block has the correct hash internally 7a6627a 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
…rect hash internally in Python tests Summary: > 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: > > - 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 > - 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. This is a backport of Core [[bitcoin/bitcoin#18350 | PR18350]] Test Plan: ninja && test/functional/test_runner.py feature_block Reviewers: #bitcoin_abc, deadalnix Reviewed By: #bitcoin_abc, deadalnix Differential Revision: https://reviews.bitcoinabc.org/D8846
…hat a new block has the correct hash internally 7a6627a 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
…hat a new block has the correct hash internally 7a6627a 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
…hat a new block has the correct hash internally 7a6627a 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
…hat a new block has the correct hash internally 7a6627a 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
…hat a new block has the correct hash internally 7a6627a 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
…hat a new block has the correct hash internally 7a6627a 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 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:while (hash < target)
, which is wrong, because hash = target is a valid mined value based on the code in the functionCheckProofOfWork()
that validates the mining target:CBlock::GetHash()
will actively calculate the hash and not cache it anywhere. With this, blocks that come out of the methodnext_block
can have incorrect hash value whensolve=False
. This is because thenext_block
is mostly used withsolve=True
, and solving does call the functionrehash()
which calculates the hash of the block, but withsolve=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.