In the current CKB version, the block timestamp is considered valid if
- it is greater than the median of previous 37 blocks,
- and is less than or equal to the node local time plus 15 seconds.
CKB does not use network time from peers. If the local time diverges from other peers, the node will be isolated. CKB does sample the timestamps from peers, but it only prints a warning on detected time issues.
What does Bitcoin do?
In Bitcoin, the block timestamp is considered valid if
- it is greater than the median of previous 11 blocks,
- and is less than or equal to the node adjusted time plus 2 hours.
Bitcoin uses the median timestamp from peers to adjust the local time. See source code timedata.cpp.
It samples the first 200 different peers. For each peer, only the timestamp offset observed on the first connection is sampled.
Set the time offset to the median if
- There are at least 5 peers.
- The time offset is within 70 minutes, which is user-configurable via
If the median offset exceeds 70 minutes, show a warning if there are no sampled offsets are within 5 minutes.
The source code also check
nOffset != 0, because a zero is inserted into
vTimeOffsetswhen it is initialized.
After sampled 200 peers, the time offset adjustment will never change until the node restarts.
There is a weird behavior in the source code. The offset is only updated when there are odd samples (
vTimeOffsets.size() % 2 == 1). When the sample number reaches the limit 200, the adjustment is never updated.
but in this case, the ‘bug’ is protective against some attacks (and may actually explain why we’ve never seen the one I’m thinking of exploited, which had surprised me…).
So I think we should hold off on fixing this and just clean it up as a result of some timing cleanup the strengthens it in a number of other ways. I should have some time to work on this soon.
the problem is that the naive ways to fix this bug would make it even easier to convince a node it has the wrong time offset at any time. At least now the ‘vulnerability’ is limited to a window after startup. This bug should be fixed, but as a by-effect of rewriting the time offset determination code.
#6545 finally adds a branch to early return when
setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES since the extra samples are useless.
An attempted hack would create a perceived time gap between the mining machines and node targeted, by lagging part of the system until one of three things occur: either an unaffected node or the target itself creates a block, clocks are reset, or operators intervene. As such, valid blocks could be dropped, and money could be lost or stolen.
culubas: Timejacking and BitCoin demonstrated the details of the attack, and proposed several solutions:
- Disable network time adjustment and relying on the node maintainer to synchronize the machine time.
- Tighten the acceptable time adjustment, for example, to 30 minutes.
- Only connect to trusted peers.
- Use only previous block timestamps to validate the timestamp of the new block.
Bitcoin’s Block Timestamp Protection Rules from BitMEX Blog presented a point that Bitcoin is less prone to the timejacking attack because the default 2h limit on future blocks is only 0.6% of the two weeks difficulty adjustment cycle.
What we can do?
Adjust the valid timestamp range.
“it is not less than the median of previous 37 blocks,”
This requires a fork.
It has a limited effect because miners can ensure the new block timestamp is at least the median time plus 1.
“and is less than the node local time plus 15 seconds.”
Use 0.6% of the difficulty adjustment cycle is a good reference.
- 4 hours x 0.6% = 86s
Implement the network time adjustment feature.
What the default max time adjustment? Base on the analysis above, just below the half of the max allowed future timestamp offset is a good choice. However, half of 86s is about 40s, which can do little to help users fix the local time issues.
I would recommend not to implement it, but find a way to deliver messages that requires user attention.
Other stuff related to the timestamp
2018 - Szalachowski - (Short paper) towards more reliable bitcoin timestamps
This paper introduces trust external TSAs to sign the block hash with a timestamp and save the signature in the chain via a transaction. From these transactions, users can verify the signature. And if users trust the TSA, they can use these signatures in two ways:
- If there is a timestamped signature (B, T), users know the block B is created before the time T.
- If a block contains the timestamped signature (*, T), users know the block is created after the time T.
This only works for dApps. The paper also mentioned a working service OpenTimestamps.