Skip to content
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

consensus/beacon: reenable checking for timestamps #24140

Conversation

MariusVanDerWijden
Copy link
Member

Reenables checking of timestamps in verifyHeader, thanks to @sunce86 for noticing

@@ -192,6 +195,12 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa
if header.UncleHash != types.EmptyUncleHash {
return errInvalidUncleHash
}
if header.Time > uint64(time.Now().Unix()+allowedFutureBlockTimeSeconds) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to check the timestamp here? It's passed by CL and we should always assume CL will verify it, like it's not older than parent.

Regarding the future block, it's indeed possible that the given timestamp is in future because CL and EL can in different machine. But does it really matter? And why do we have this 1 second allowance?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Yes that was how the spec used to be. Now it changed a bit and left this underspecified. During engine_executePayload we check that the timestamp matches, however we don't do it for historical blocks passed by sync.

  2. The 1 second allowance is exactly for that, if two machines are on slightly different clocks. Again, the CL should check it, but I think it is better to not rely on the CL for that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what's the side effect for receiving the "invalid timestamp"?

  • if the timestamp is even older than parent, then a consensus error is returned and the given block is rejected(looks correct)
  • if the timestamp is in the future, the block is supposed to be added into the future queue. But PoS blocks are not allowed caching in the future queue. So eventually the block is ignored silently? (also looks correct). And next time the block sync will fill the gap I think.

Copy link
Contributor

@holiman holiman Dec 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get this change. I'm perfectly fine with

if header.Time <= parent.Time {
		return errOlderBlockTime
	}

But why do we also require the child block to be within one second from whatever the local time happens to be?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, traditionally, we've always saved ErrFutureBlock for last, so that it basically means "everything checks out, except the timestamp is a bit off". We should not change that logic, so please move it last

Copy link
Member

@rjl493456442 rjl493456442 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally OK for me, the chain behavior is still expected. Just really not sure we should verify the timestamp by ourselves.

The assumption is held that CL should verify all these consensus fields. It's OK to verify more in EL, but the corresponding action is not defined in the spec, like how should we act to future blocks.

@@ -175,7 +178,7 @@ func (beacon *Beacon) VerifyUncles(chain consensus.ChainReader, block *types.Blo
// - nonce is expected to be 0
// - unclehash is expected to be Hash(emptyHeader)
// to be the desired constants
// (b) the timestamp is not verified anymore
// (b) the timestamp is older than it's parent and not in the future
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the timestamp is not older than it's parent.

@@ -192,6 +195,12 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa
if header.UncleHash != types.EmptyUncleHash {
return errInvalidUncleHash
}
if header.Time > uint64(time.Now().Unix()+allowedFutureBlockTimeSeconds) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what's the side effect for receiving the "invalid timestamp"?

  • if the timestamp is even older than parent, then a consensus error is returned and the given block is rejected(looks correct)
  • if the timestamp is in the future, the block is supposed to be added into the future queue. But PoS blocks are not allowed caching in the future queue. So eventually the block is ignored silently? (also looks correct). And next time the block sync will fill the gap I think.

@MariusVanDerWijden
Copy link
Member Author

PR #24236 already implemented checking for timestamps
We decided not to restrict future timestamps after discussions with Mikhail and Danny on discord

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants