-
Notifications
You must be signed in to change notification settings - Fork 6
Raid poc #104
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
base: main
Are you sure you want to change the base?
Raid poc #104
Conversation
@JasonVranek I seems the support for validator proofs are not yet part of this PR. Will you add the code to this PR soon or you'll open another PR? |
I will add them to this PR! |
// @param validatorProof The EIP-4788 proof that proves who the validator was at a given slot | ||
// @param unsafeHeader The PublicationHeader from the previous publication | ||
// @param unsafeAttributeHashes The attribute hashes of the previous publication | ||
// @param replaceUnsafeHead Whether to replace the unsafe head or update the safe head |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we only have one branch of unsafe head? I was thinking we can have the unsafe "branches" and retroactively choose one later so the "eventually-safe" branch can't be kicked out by a malicious actor. But I guess that adds the gas cost and complexity?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the "eventually-safe" branch can't be kicked out by a malicious actor
I guess this can be mitigated by slashing the malicious actor for submitting an "non-eventually-safe" head. However, without EIP-7917 that introduces the risk of slashing an innocent actor when the lookahead changes due to EB change.
// Verify the supplied validator proof is valid. Note this doesn't check | ||
// the validator public key during the slot, that's done below | ||
require( | ||
EIP4788.verifyValidatorProof(getBeaconBlockRootFromTimestamp(unsafeHeader.timestamp), validatorProof), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we handle "early inclusion" of batches? If we are at slot N
, and the next preconfer is proposer of slot N+31
in lookahead, then we would want to let that preconfer submit batches during slot N~N+31
and not just N+31
. I guess one way would be to:
- Enable building upon unsafe "branches" without providing
validatorProof
asvalidatorProof
is only available afterN+32
- At
N+32
not only provide proof forN+31
but also prove that there were no preconfers during all slots betweenN
andN+30
but seems expensive? Also proving that a validator is not opted-in seems hard. Maybe there is a better way, not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also at maximum the next preconfer would be 64 slots ahead. So at max the unsafe branch will have to stay unsafe for 64 slots. But this probably isn't an issue as ZK proving takes time anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also proving that a validator is not opted-in seems hard.
Hmm, this seems the most difficult part. At first glance some fraud-proof mechanism is needed, but needs more thinking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I guess you can say that, if no one proposed for N
~N+31
, even if proposer of N+31
is NOT strictly the next preconfer, it is fine to accept their head as valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, but if N+31
is indeed the next opted in proposer, but there is a proposed block by proposer at N+3
, then we need to somehow prove that proposer of slot N+3
is actually NOT a preconfer.
This is a proof of concept to show how the ideas from Raid can be applied to the minimal-rollup implementation.
Changes to the minimal-rollup implementation:
isAllowedProposer()
modifier that performs sanity checks against the URC to confirm that themsg.sender
was allowed to callpublish()
. The proposer's BLS public key is saved as an attribute in the publication.getBeaconBlockRootFromTimestamp()
function that uses EIP-4788 to fetch the beacon block root from the beacon chain and saves it as an attribute in the publication.publish()
also saves the current block timestamp so that it can be retrieved in future calls topublish()
.How it works:
Raid uses two rounds of filtering to ensure that only valid preconfers can submit publications.
Filter 1: URC
By checking the URC at publication time, we can verify that the publisher was registered to the rollup's dedicated preconf protocol with sufficient collateral. This implies that they are allowed to publish, we just need to enforce that they only publish during their slot.
Filter 2: Validator proofs
Normally to enforce that a proposer can only publish during their slot, we would need a view of the beacon chain lookahead and add an extra filtering step to
publish()
.Raid removes the need for a lookahead by optimistically accepting publications and then retroactively determining if the proposal was during the proposer's slot during rollup derivation. Since the beacon block root is included in the publication, a node can verify a Validator proof against it to confirm the validator BLS key for that slot. If this matches the BLS public key saved during the publication, then the publication is valid and the node will execute the rollup transactions.
Proposers are required to include a Validator proof inside of their blob submissions. The mantra of Raid is you can only add to the rollup if you prove that you're building off of a valid parent, hence they are incentivized to include a valid Validator proof or their blob will be treated as a no-op.
Note that it’s possible to verify the Validator proof during
publish()
and is worth exploring as it simplifies node logic at the cost of more expensive publications.