Skip to content

l2geth: update timestamp logic#1982

Merged
tynes merged 4 commits intodevelopfrom
feat/sequencer-timestamp
Jan 10, 2022
Merged

l2geth: update timestamp logic#1982
tynes merged 4 commits intodevelopfrom
feat/sequencer-timestamp

Conversation

@tynes
Copy link
Copy Markdown
Contributor

@tynes tynes commented Jan 5, 2022

Description
This commit updates the timestamp updating logic
such that time.Now is used instead of relying on
L1 timestamps. This gives a higher fidelity for the
TIMESTAMP opcode as well as makes the time on L2
be closer to the time on L1.

L1 to L2 transactions no longer have the property of
having the same timestamp on L2 as the timestamp
of the L1 block they were included in.

This should be able to be turned on without needing
hardfork logic as replicas should always accept the
timestamp that the sequencer sets. The sequencer is
a trusted entity in the existing implementation and
it is expected that the sequencer will become more
trustless in future iterations of the protocol.

This change is added to improve both UX and devex.
Users are confused by the timestamps on Etherscan
being ~15 minutes behind. This is due to the timestamps
being set based on L1 block numbers, and the system
only pulls L1 data once a secure amount of PoW
is placed on top. Developers would like the timestamps
to have a higher fidelity and be closer to the timestamps
on L1.

Metadata

  • Fixes INT-379
  • Fixes INT-445

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Jan 5, 2022

🦋 Changeset detected

Latest commit: dad6fd9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@eth-optimism/l2geth Patch
@eth-optimism/integration-tests Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Jan 5, 2022

Codecov Report

Merging #1982 (77a81b1) into develop (f393872) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #1982   +/-   ##
========================================
  Coverage    74.42%   74.42%           
========================================
  Files           79       79           
  Lines         2545     2545           
  Branches       397      397           
========================================
  Hits          1894     1894           
  Misses         651      651           
Flag Coverage Δ
batch-submitter 62.50% <ø> (ø)
contracts 90.48% <ø> (ø)
core-utils 57.50% <ø> (ø)
data-transport-layer 38.64% <ø> (ø)
message-relayer 70.86% <ø> (ø)
sdk 87.06% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f393872...77a81b1. Read the comment docs.

@tynes tynes force-pushed the feat/sequencer-timestamp branch 3 times, most recently from 0ef4e81 to 9d30e0e Compare January 6, 2022 01:32
@github-actions github-actions bot added the A-integration Area: integration tests label Jan 6, 2022
@tynes tynes force-pushed the feat/sequencer-timestamp branch from e8e9e8d to 77a81b1 Compare January 6, 2022 02:24
@tynes tynes requested a review from smartcontracts January 6, 2022 02:25
@tynes
Copy link
Copy Markdown
Contributor Author

tynes commented Jan 6, 2022

This is now ready for review and includes tests. I need to double check two things before this is ready to merge:

  • This code can run as a replica on mainnet now without a network split
  • This code can run as a sequencer on a devnet with an older node (pre this PR) can run as a replica without a network split

@tynes
Copy link
Copy Markdown
Contributor Author

tynes commented Jan 6, 2022

  • Try to trigger a timestamp inconsistency by spamming a network

expect(l1BlockNumber.toNumber()).to.deep.equal(l1Block.number)

// L1 and L2 blocks will have the same timestamp.
// L1 and L2 blocks will have approximately the same timestamp.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we make the assertion of "strictly greater than" in addition to "approximately equal to"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Which do you mean should be greater than? - an L1 block can have at highest a timestamp of time.Now() + 15s which could be larger than the time.Now that the sequencer assigns to a transaction. This only applies if we do not trail L1 by any amount - then the configurable amount that we trail L1 by impacts which is larger

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I added another test that asserts that the L1 blocknumber and timestamps are ascending, it runs after the stress tests run

log.Error("Could not update execution context", "error", err)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just leaving myself a mental note that we'll need to update the documentation to reflect this new behavior.

// If enough time has passed, then assign the
// transaction to have the timestamp now. Otherwise,
// use the current timestamp
if now.Sub(current) > s.timestampRefreshThreshold {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What is this threshold set to? How often can we expect timestamps to refresh?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why even have a threshold at all?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we are required to have a threshold, it's worth noting that we're using the same threshold for both this logic and for the L1 block number updating logic. If we set the threshold too low we may have monotonicity issues with the L1 block number (wouldn't be good).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There is a threshold here because otherwise we would blow up our batch context overhead, basically every tx would have its own context. The idea would be to set the threshold to 10-15 seconds and then all transactions that happen within that range would get the same timestamp

log.Error("No tx timestamp found when running as verifier", "hash", tx.Hash().Hex())
} else if tx.L1Timestamp() < s.GetLatestL1Timestamp() {
// This should never happen, but sometimes does
log.Error("Timestamp monotonicity violation", "hash", tx.Hash().Hex())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Unrelated but since I'm seeing it, do we keep track of these errors @optimisticben?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We do not track these errors, but that is a good idea

}

// Store the latest timestamp value
s.SetLatestL1Timestamp(tx.L1Timestamp())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we sure we want to set this in all cases? Because we still get to this point even if tx.L1Timestamp() == 0 && s.verifier or tx.L1Timestamp() < s.GetLatestL1Timestamp() gets triggered. Maybe we only want to set if tx.L1Timestamp() > ts.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

So tx.L1Timestamp() == 0 && s.verifier should never happen. The only time when tx.L1Timestamp() == 0 is when a transaction is fresh from a user coming in via RPC

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've noted the above via a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Still wondering if we should gate on tx.L1Timestamp() > s.GetLatestL1Timestamp().

@tynes tynes force-pushed the feat/sequencer-timestamp branch 2 times, most recently from e65889b to 7c27306 Compare January 8, 2022 01:37
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The latest L1 blocknumber logic is now updated, it simply will see if the remote tip is greater than the known latest L1 block number and update it if so

@tynes tynes force-pushed the feat/sequencer-timestamp branch from 7c27306 to fb59ed4 Compare January 8, 2022 02:28
tynes added 4 commits January 10, 2022 12:39
This commit updates the timestamp updating logic
such that `time.Now` is used instead of relying on
L1 timestamps. This gives a higher fidelity for the
`TIMESTAMP` opcode as well as makes the time on L2
be closer to the time on L1.

L1 to L2 transactions no longer have the property of
having the same timestamp on L2 as the timestamp
of the L1 block they were included in.

This should be able to be turned on without needing
hardfork logic as replicas should always accept the
timestamp that the sequencer sets. The sequencer is
a trusted entity in the existing implementation and
it is expected that the sequencer will become more
trustless in future iterations of the protocol.

This change is added to improve both UX and devex.
Users are confused by the timestamps on Etherscan
being ~15 minutes behind. This is due to the timestamps
being set based on L1 block numbers, and the system
only pulls L1 data once a secure amount of PoW
is placed on top. Developers would like the timestamps
to have a higher fidelity and be closer to the timestamps
on L1.
Update the assertion to not expect that the timestamps are
exactly equal but instead assert that the values are within
5%. This is because now the timestamps in L2 no longer
correspond to L1 timestamps and may be updated arbitrarily
by the sequencer.
@tynes tynes force-pushed the feat/sequencer-timestamp branch from fb59ed4 to dad6fd9 Compare January 10, 2022 20:40
Copy link
Copy Markdown
Contributor

@smartcontracts smartcontracts left a comment

Choose a reason for hiding this comment

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

LGTM

@tynes tynes merged commit 89eab8f into develop Jan 10, 2022
@tynes tynes deleted the feat/sequencer-timestamp branch January 10, 2022 21:11
@0xged
Copy link
Copy Markdown

0xged commented Jan 18, 2022

Any ETA for this release on mainnet ? 😇 🙏

@Madalosso
Copy link
Copy Markdown

Any ETA for this release on mainnet ? innocent pray

ETA for kovan as well?

@vinta
Copy link
Copy Markdown

vinta commented Jan 20, 2022

@0xged @Madalosso It's already live on Optimism Kovan. As far as I know, it will be live on mainnet on 25th if everything goes well on testnet.

@Madalosso
Copy link
Copy Markdown

My bad @vinta I thought this would make the timestamps unique until I saw the comment (#1982 (comment)).
As I saw multiple orders with the same timestamp I thought it wasn't live on kovan yet. My bad.

theochap pushed a commit that referenced this pull request Dec 10, 2025
### Description

Sets up the first set of metrics for `kona-derive`.

Closes #1981
Closes #1982
theochap pushed a commit that referenced this pull request Jan 14, 2026
### Description

Sets up the first set of metrics for `kona-derive`.

Closes #1981
Closes #1982
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-cannon Area: cannon A-integration Area: integration tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants