-
Notifications
You must be signed in to change notification settings - Fork 35.7k
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
qa: testing for the year 2038 problem #21362
Conversation
test/functional/y2038.py
Outdated
EPOCH_2038_BEFORE = 2147440306 # (GMT): Monday, January 18, 2038 3:11:46 PM | ||
EPOCH_2038_AFTER = 2147613106 # (GMT): Wednesday, January 20, 2038 3:11:46 PM | ||
|
||
class Y2038EpochTest(BitcoinTestFramework): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A similar test for 2106 to handle an unsigned 32-bit time_t type. See https://en.bitcoin.it/wiki/Block_timestamp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be a better test that you set the time on the machine itself and let it test what value std::chrono::system_clock will generate? This way you can accually test when std::chrono is been updated and what the epoch value accually be and how much bits it uses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I'm going to take a stab at it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on the approach you end up using, it might be an interesting exercise to try writing this as one of the C++ unit tests, once you have it figured out in Python.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll work on the unit test. It will be interesting.
Thank you for the review @jonatack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚢
test/functional/test_runner.py
Outdated
@@ -201,6 +201,7 @@ | |||
'feature_backwards_compatibility.py --legacy-wallet', | |||
'feature_backwards_compatibility.py --descriptors', | |||
'wallet_txn_clone.py --mineblock', | |||
'y2038.py', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This naming convention doesn't work. Check out
bitcoin/test/functional/test_runner.py
Line 690 in a9335e4
good_prefixes_re = re.compile("^(example|feature|interface|mempool|mining|p2p|rpc|wallet|tool)_") |
to see a list of accepted prefixes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Thanks. I've prefixed the name with example_. However, there is only one there and this tells me the prefix should be something else.
I'm also wondering if this is the right approach to test this as the tests passes.
Thanks for picking this up @ivanacostarubio Friendly reminder that these 3 commits should be squashed. |
3217632
to
353aa84
Compare
353aa84
to
00f400b
Compare
@@ -201,6 +201,7 @@ | |||
'feature_backwards_compatibility.py --legacy-wallet', | |||
'feature_backwards_compatibility.py --descriptors', | |||
'wallet_txn_clone.py --mineblock', | |||
'example_y2038.py', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the file perms should be 755 (sudo chmod 755 test/functional/example_y2038.py
)
-rwxr-xr-x 1 9070 Mar 1 22:43 example_test.py*
-rw-r--r-- 1 1301 Mar 5 18:06 example_y2038.py
If this is intended to be a real test, ISTM it should have another file name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. What would you name a test like this @jonatack assuming this approach is correct ? (unit test may be better)
Tested ACK 00f400b Ran it on Ubuntu 20.04 nit: I think you could use something like |
|
||
EPOCH_2038_BEFORE = 2147440306 # (GMT): Monday, January 18, 2038 3:11:46 PM | ||
EPOCH_2038_AFTER = 2147613106 # (GMT): Wednesday, January 20, 2038 3:11:46 PM | ||
EPOCH_2106 = 4293404400000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is AD 138022, not AD 2038.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct. Thank you for pointing this out.
ƛ date -r 4293404400000 '+%m/%d/%Y'
07/27/138022
I'm going to change it to: 4293404400 to test for 2106. See the last sentence on: https://en.bitcoin.it/wiki/Block_timestamp
date -r 4293404400 '+%m/%d/%Y'
01/19/2106
self.nodes[1].setmocktime(epoch) | ||
|
||
# Generates a blocks | ||
self.nodes[0].generate(nblocks=1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the expected behaviour for AD 2106 and beyond is for all blocks to be invalid... This should fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah thats because there isnt not enough bits difined at specific parts of the code. It needs to be changed to uint64_t as example:
bitcoin/src/primitives/block.h
Line 27 in 4a54068
uint32_t nTime; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the type there is a hardfork. Also not a good approach (makes more sense to just allow it to wrap around).
Defining a hardfork goes beyond writing tests. A test should simply confirm such blocks are invalid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the type there is a hardfork. Also not a good approach (makes more sense to just allow it to wrap around).
Defining a hardfork goes beyond writing tests. A test should simply confirm such blocks are invalid.
Well a approach could be that you first implement this type change in a patch and distribute it but just not activate it yet. You just set a block-id when this update should be active. That its enough time to let the hole network been updated. You basicly keep using for the old blocks the old uint32_t type. But new blocks will be uint64_t after that.
Only requirement is that enough nodes in the network has to get the latest updated. Because this bug has a long time to trigger you can delay to active this feature/fix for really long time. Like you know that every node has the update over the next view years (say 2030). Also you have a lot of time to distribute this knowledge to the community like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. I'm going to change the test to reflect that. I also saw it failed at one of our CI checks (https://cirrus-ci.com/task/6103755461492736?command=ci#L5253), but not on the others https://cirrus-ci.com/task/4626011833761792?command=ci#L3610
node0 stderr miner.cpp:130:21: runtime error: implicit conversion from type 'int64_t' (aka 'long') of value 4293404400000 (64-bit, signed) to type 'uint32_t' (aka 'unsigned int') changed the value to 2732071296 (32-bit, unsigned)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests cedfabf using EPOCH_2106 = 4293404400
ran with no issues on Ubuntu 20.04.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with jon the example
prefix may not be the best fit. I would suggest p2p
as you are actually testing syncing blocks between 2 nodes.
tACK 00f400b on OSX 11.4
EPOCH_2106 = 4293404400000 | ||
|
||
|
||
class Y2038EpochTest(BitcoinTestFramework): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: All the naming (class, method, logs, file name) reference the year 2038 but it tests the year 2106 as well!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
Thanks for adding tests! Could you squash the three commits? Also I agree with previous comments that the naming of the test file could be improved, example_...
doesn't seem appropriate.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
Needs rebase due to silent merge conflict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(left a comment with the patch needed to fix the conflict)
self.nodes[1].setmocktime(epoch) | ||
|
||
# Generates a blocks | ||
self.nodes[0].generate(nblocks=1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.nodes[0].generate(nblocks=1) | |
self.generate(self.nodes[0], nblocks=1) |
@ivanacostarubio Did you want to follow up here? |
No follow up, so marking up for grabs, and closing for now. Leave a comment if you'd like this reopened etc. |
fafc96a test: Test year 2106 block timestamps (MacroFake) Pull request description: Alternative to bitcoin/bitcoin#21362 that closes bitcoin/bitcoin#21356 ACKs for top commit: Sjors: utACK fafc96a Tree-SHA512: 196d98f42d6f7f0222312b7bd1c68b3bd30cb6f0cbaccb900cfc5fcc689494adb2a7d7d6023c1ff1e8cf871047ec37eeca41386e31029d99cabf9343b4fd2a03
fafc96a test: Test year 2106 block timestamps (MacroFake) Pull request description: Alternative to bitcoin#21362 that closes bitcoin#21356 ACKs for top commit: Sjors: utACK fafc96a Tree-SHA512: 196d98f42d6f7f0222312b7bd1c68b3bd30cb6f0cbaccb900cfc5fcc689494adb2a7d7d6023c1ff1e8cf871047ec37eeca41386e31029d99cabf9343b4fd2a03
This is a functional tests to check for the Y2038 issue. See #21356 (comment)
More information: https://en.wikipedia.org/wiki/Year_2038_problem
I'm wondering If this approach is correct. Is so, I can extend it to check for the year 2106 #21356 (comment)