ckb
In the current CKB version, the block timestamp is considered valid if
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.
In Bitcoin, the block timestamp is considered valid if
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
-maxtimeadjustment
.
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 vTimeOffsets
when 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.
#4521 reported the issue and #4526 submitted the fix. But the pull request was rejected.
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:
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.
"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.
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.
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:
This only works for dApps. The paper also mentioned a working service OpenTimestamps.