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

feat(protocol): apply multiple improvements for "ontake" fork [do not merge] #17734

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

dantaik
Copy link
Contributor

@dantaik dantaik commented Jul 4, 2024

BEGIN_COMMIT_OVERRIDE
feat(protocol): allow contract proposers to use calldata for DA
feat(protocol): add preconfirmation support based on #17654 (with some renaming) (#14793)
feat(protocol): add proposeBlock2 in TaikoL1.sol and approve2 in GuardianProver.sol
refactor(protocol): avoid writing livenessBond, proposedAt, and proposedIn to storage
refactor(protocol): enable AddressManager to cache address(0)
END_COMMIT_OVERRIDE

This PR is ready to be reviewed again for merge.

#17679)

BEGIN_COMMIT_OVERRIDE
feat(protocol): allow contract proposers to use calldata as well
feat(protocol): add preconfirmation support based on Brecht's PR (with some renaming) to implement #14793
feat(protocol): add proposeBlock2 in TaikoL1.sol and approve2 in GuardianProver.sol to be used post a fork
refactor(protocol): avoid writing livenessBond to storage to remove unnecessary SSTORE and SLOAD.
refactor(protocol): enable AddressManager to cache address(0) without reading from storage
END_COMMIT_OVERRIDE
@dantaik dantaik marked this pull request as ready for review July 4, 2024 08:52
@dantaik dantaik changed the title feat(protocol): apply multiple improvements for *ontake* fork feat(protocol): apply multiple improvements for "ontake" fork Jul 4, 2024
Copy link

openzeppelin-code bot commented Jul 4, 2024

feat(protocol): apply multiple improvements for "ontake" fork [do not merge]

Generated at commit: c5d75198feaf858c56db1bd78a78894a9f843f56

🚨 Report Summary

Severity Level Results
Contracts Critical
High
Medium
Low
Note
Total
2
2
0
8
41
53
Dependencies Critical
High
Medium
Low
Note
Total
0
0
0
0
0
0

For more details view the full report in OpenZeppelin Code Inspector

@@ -246,7 +270,7 @@ contract TaikoL1 is EssentialContract, ITaikoL1 {
blockMaxGasLimit: 240_000_000,
livenessBond: 125e18, // 125 Taiko token
stateRootSyncInternal: 16,
checkEOAForCalldataDA: true
ontakeForkHeight: 324_512 * 2
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not a constant ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can!

Copy link
Contributor Author

@dantaik dantaik Jul 6, 2024

Choose a reason for hiding this comment

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

Changed to a fixed value

// one
// in the previous L2 block.
if (
params.anchorBlockId + 64 < block.number //
Copy link
Contributor

Choose a reason for hiding this comment

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

I think last info was to make it 4 epoch instead of 2. #17654 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

I increased it for the testnet to make sure there is enough flexibility and depending on an L1 block that can be reorged can be avoided, though there are still other reorg risks. So "the best" value still TBD I guess.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I introduced a config var so testnets can have a different value.

Comment on lines 142 to 143
params.timestamp + 64 * 12 < block.timestamp
|| params.timestamp > block.timestamp || params.timestamp < parentBlk.proposedAt
Copy link
Contributor

Choose a reason for hiding this comment

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

same here, 128 * 12 (4 epoch)

// one
// in the previous L2 block.
if (
params.anchorBlockId + 64 < block.number //
Copy link
Contributor

Choose a reason for hiding this comment

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

I increased it for the testnet to make sure there is enough flexibility and depending on an L1 block that can be reorged can be avoided, though there are still other reorg risks. So "the best" value still TBD I guess.

difficulty: 0, // to be initialized below
meta_ = TaikoData.BlockMetadata2({
anchorBlockHash: blockhash(params.anchorBlockId),
difficulty: keccak256(abi.encode("TAIKO_DIFFICULTY", local.b.numBlocks)),
Copy link
Contributor

Choose a reason for hiding this comment

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

This does make the difficulty completely deterministic for an infinite amount of time. Which is probably okay, but makes it even harder to use it as some random value (which I guess people shouldn't do anyway).

Copy link
Contributor Author

@dantaik dantaik Jul 6, 2024

Choose a reason for hiding this comment

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

True.

Comment on lines -120 to +154
uint64 proposedAt; // timestamp
uint64 proposedIn; // L1 block number, required/used by node/client.
// Before the fork, this field is the L1 timestamp when this block is proposed.
// After the fork, this is the timestamp of the L2 block.
// In a later fork, we an rename this field to `timestamp`.
uint64 proposedAt;
// Before the fork, this field is the L1 block number where this block is proposed.
// After the fork, this is the L1 block number input for the anchor transaction.
// In a later fork, we an rename this field to `anchorBlockId`.
uint64 proposedIn;
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, we could still use the values like we did previously. Or is this part of the optimization?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved "proposedAt" and "proposedIn" to the metadata to save gas, but since we need to write "timestamp" and "anchorBlockId" to storage, to avoid writing to a new slot, I simply reused the "proposedAt" and "proposedIn" fields without renaming them. So yes it's optimizaiton.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think no need to write write timestamp and anchorBlockId to storage? I believe those are only used on L2, not on L1, so just having them as part of the meta hash is sufficient as far as I know.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When a new block is proposed, we now read the parent block's timestamp and anchorBlockId to make sure the new block's values are greater than its parent's. Therefore we need to write these two values into storage.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh right I also implemented it like that haha. In my mind this was already checked on L2 instead, but all good!

@@ -87,6 +95,25 @@ library TaikoData {
address sender; // a.k.a proposer
}

struct BlockMetadata2 {
Copy link
Contributor

Choose a reason for hiding this comment

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

We could still use BlockMetadata if we want to, or any specific reason for this change? We could just use the values as they were previously (that's what we do on the helder deployment). I guess maybe part of the optimization for the storage writing, but still stored in Transition below so not sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would like to take this hard fork opportunity to further optimize storage reads/writes. With this v2 metadata definition, I removed writing "proposedAt" and "proposedIn" into the Block struct in storage. The previous two fields inside the Block struct "proposedAt", and "proposedIn" are used as the L2 block's "timestamp" and "anchorBlockHeight" instead. Otherwise, we'll introduce two new fields into the Block struct.

@@ -37,6 +37,17 @@ abstract contract TierProviderBase is ITierProvider {
});
}

if (_tierId == LibTiers.TIER_SGX2) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This the SGX verifier with "ontake" fork support?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes

@dantaik dantaik changed the title feat(protocol): apply multiple improvements for "ontake" fork feat(protocol): apply multiple improvements for "ontake" fork [do not merge] Jul 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants