Author

Topic: Going backward in time (Read 236 times)

jr. member
Activity: 34
Merit: 87
October 15, 2021, 12:10:33 PM
#12
Quote
I can reproduce the same error messages in 22.0
Yes, it was the newest official release 22.0 for Windows.
hero member
Activity: 813
Merit: 1944
October 14, 2021, 05:05:53 AM
#11
Quote
so the problem is on Bitcoin Core implementation
This is true if we talk about reaching 0x80000000 and higher values. However, if I understand that correctly, the whole chain will halt after reaching median time 0xffffffff, so producing any new blocks after year 2106 will be impossible, because of currently used consensus rules.

Quote
For reference, what Bitcoin Core version did you use?
I can reproduce the same error messages in 22.0, so I guess all recent versions are affected, maybe some older version handled that differently, but I think many clients will crash in 2038, including custom software used by miners. Also, I cannot produce any valid block after reaching 0xffffffff median time, I tried many different 32-bit values, but each time Bitcoin Core thinks that the time is too old.
jr. member
Activity: 31
Merit: 10
October 13, 2021, 06:12:27 PM
#10
2038y problem was reported in March 4th, on this issue:

https://github.com/bitcoin/bitcoin/issues/21356


It seems we'll be fine if we use an updated version of std::chrono.
jr. member
Activity: 34
Merit: 87
October 12, 2021, 11:42:29 PM
#9
It seems that Bitcoin Core is affected by 2038 year problem, I set my clock to 0x7fffffff and the client is halted with this assertion, because when reaching 0x80000000 it is treated as a negative value.
Code:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Assertion failed!

Program: C:\Program Files\Bitcoin\bitcoin-qt.exe
File: util/time.cpp
Line: 97

Expression: now.count() > 0

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts

(Press Retry to debug the application - JIT must be enabled)
---------------------------
Abort   Retry   Ignore  
---------------------------

Edit: It seems that I was right and when median time will reach 0xffffffff, it will be impossible to create any new blocks in such chain. Then, modifying the chain is no longer possible without chain reorganization, because the timestamp of the next block has to be greater than 0xffffffff, so there is no 32-bit value that can meet this rule.
Code:
submitblock 0100000006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f3663c0de115e2239e05df4df9c4bfa01b8e843aaf5dae590cac1d9bac0d44c0fffffffffffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a010000001976a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000
null
generatetoaddress 1 mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt
CreateNewBlock: TestBlockValidity failed: time-too-old, block's timestamp is too early (code -1)
legendary
Activity: 3472
Merit: 10611
October 12, 2021, 10:49:40 PM
#8
Standard unix time uses a signed 4-byte integer. If I remember correctly, Bitcoin blocks use an unsigned 4-byte integer. This allows an additional 68 years before it becomes a problem.

I'm not sure if the overflow has been addressed in code yet, but if it hasn't, then we've got about 85 more years to take care of it.
In block header the value can be either signed or unsigned since it is just a byte stream (bitcoin core uses unsigned Int32) but when it comes to comparison it will be cast to (signed) Int64 then compared to address the overflows.
legendary
Activity: 3472
Merit: 4794
October 12, 2021, 08:22:15 PM
#7
I have another time-related question: will the chain be halted when reaching median time equal to 0xffffffff? Or maybe we have some kind of overflow bug here, as it was in Value Overflow Incident, but time-related, so is it possible to jump back from 0xffffffff to 0x00000000?

Standard unix time uses a signed 4-byte integer. If I remember correctly, Bitcoin blocks use an unsigned 4-byte integer. This allows an additional 68 years before it becomes a problem.

It seems I did not remember correctly. See the next 2 comments below.

I'm not sure if the overflow has been addressed in code yet, but if it hasn't, then we've got about 85 more years to take care of it.

It appears it has not been.  See below.
jr. member
Activity: 34
Merit: 87
October 12, 2021, 04:33:36 PM
#6
I tested some values by starting from zero unix time and saw that it always can only go forward, because it always has to be greater than the median time of the last 11 blocks. But I have another time-related question: will the chain be halted when reaching median time equal to 0xffffffff? Or maybe we have some kind of overflow bug here, as it was in Value Overflow Incident, but time-related, so is it possible to jump back from 0xffffffff to 0x00000000?
legendary
Activity: 3472
Merit: 4794
October 12, 2021, 03:59:41 PM
#5
The answer to your question is no, in multiple ways.

First of all, you couldn't create a valid block that precedes the origin block in position in the chain (or even one that closely follows the origin block) without re-performing proof-of-work on EVERY BLOCK that has been created since.  This is because each block contains the hash of its immediately preceding block.  To create a block that precedes any given block, you'd have to create a block that hashes to the EXACT value that is already stored in the block that you are trying to immediately precede.  Since this is effectively impossible, the only alternative is to re-perform the proof-of-work on the block that immediately follows yours using the hash of your block as the "previous block" for your re-hashing attempt.  Unfortunately, this will change the value of that block, so you'll need to re-perform proof-of-work on the block that follows it, and so on.  That's WHY it's called a "blockCHAIN".

Alternately, if you wanted to create a block that just gets placed at the most recent end of the chain as a new "most recently created block", you'll be bound by the rule that any valid block cannot have a timestamp earlier than the median of the timestamps in the 11 blocks that immediately precede it. As such, you can't create a block that is added to the tip of the chain with a date older than a few hours ago.
legendary
Activity: 1512
Merit: 7340
Farewell, Leo
October 12, 2021, 03:01:05 PM
#4
Imagine that some transaction have NLockTime set in October 2021. Does it mean that if such transaction is included in the chain, then it is impossible to create any next block with any timestamp below that NLockTime? How it is checked?
You sound like myself, couple of months ago when I had a similar query. Read Re: Strange Timestamp Argument.

If you have a new block header, is it compared with some globally stored max(NLockTimeTx1,NLockTimeTx2,...,NLockTimeTxN)?
Are you asking if it's possible to include a transaction whose timestamp is greater than the block's? Whether it does or does not (I honestly don't know, it is required to check the source code), but what does this have to do with your questioning?

The difficulty isn't affected from the transactions' timestamp, but from the blocks'.

For example: an adversary miner could start producing blocks with future timestamps to drop difficulty, then jump back in time (if it is possible and if that does not require dealing with endlessly growing difficulty)
That's true if he's the only miner. As long as there're other miners and an honest majority, willing to play by the rules, it's impossible. What you describe cannot happen due to the median time limitation that is calculated from the comparison of the last 11 blocks. It's written in the nLockTime wiki page.

In other words, one cannot manipulate the timestamp without having the majority of the computational power. The other miners will sooner or later get ahead him.
jr. member
Activity: 34
Merit: 87
October 12, 2021, 11:28:41 AM
#3
Quote
Why does it matter?
Because if doing so is possible, then another kind of attack is possible. For example: an adversary miner could start producing blocks with future timestamps to drop difficulty, then jump back in time (if it is possible and if that does not require dealing with endlessly growing difficulty), and then create a deep reorganization, because a lot of blocks with smaller difficulty could create a sum of chainwork greater than the honest chain. That attack could be of course noticed by anyone, but if it matches consensus rules, then it will be accepted by existing clients. Also, there are some altcoins with different difficulty adjustment algorithms, if the same way of checking time is repeated in other coins, then that altcoins could be potentially easier attacked in this way, because their difficulty can be changed sooner than for example every two weeks.

Edit:
Quote
Because of NLockTime. (Going to continue, gotta go)
Imagine that some transaction have NLockTime set in October 2021. Does it mean that if such transaction is included in the chain, then it is impossible to create any next block with any timestamp below that NLockTime? How it is checked? If you have a new block header, is it compared with some globally stored max(NLockTimeTx1,NLockTimeTx2,...,NLockTimeTxN)?
legendary
Activity: 1512
Merit: 7340
Farewell, Leo
October 12, 2021, 11:18:11 AM
#2
If you started from the very first block, then I don't know, I'll have to look into the code, but: Why does it matter? If a new person wanted to start another chain, they'd mine themselves the first block(s).

If you didn't start from the first block, then no. Because of NLockTime.
jr. member
Activity: 34
Merit: 87
October 12, 2021, 11:07:10 AM
#1
Is it possible to go back in time in a chain? For example, starting from 2009 is it possible to produce blocks with earlier and earlier timestamps and for example reach 2005? Or is there any strict requirement that block timestamps have to go forward? Because if there are three sources of time: local time, time from other nodes and time from block headers, if the first two will be faked, is it possible to also fake block timestamps and set any date, if the whole chain will be long enough?
Jump to: