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: Decoupled OptimismPortal #361

Open
tynes opened this issue Sep 5, 2024 · 3 comments
Open

Feat: Decoupled OptimismPortal #361

tynes opened this issue Sep 5, 2024 · 3 comments

Comments

@tynes
Copy link
Contributor

tynes commented Sep 5, 2024

The OptimismPortal currently enshrines the proof system in its implementation. You can observe this fact with the following links:

We should move the proof system outside of the OptimismPortal and instead only enshrine the concept of an authorized caller that can pass through a Types.WithdrawalTransaction to execute. It would be assumed that this other caller did verify the proof.

This will help to reduce the size of the OptimismPortal contract, as it is right at the codesize limits. We do not want to be in a position where we need to move quickly and cannot due to the code being too large. This problem was hit when porting custom gas token to the OptimismPortal2.

This will also help to make it easier to maintain things like op-succinct. This will unblock us from removing the L2OutputOracle from the codebase without breaking other integrations.

The upgrade path can be straight forward for tooling like viem, if the semver is above a certain version then viem can grab the address of the authorized caller contract from the portal and then send its transaction to the authorized caller rather than the portal. The authorized caller can maintain the same ABI of the portal for simplicity.

The name for the authorized caller could be "verifier" as its role would be to verify proofs.

@ajsutton
Copy link
Contributor

ajsutton commented Sep 5, 2024

I would suggest the portal retains the same ABI but can forward to the authorised caller as needed (ie build in backwards compatibility). Breaking the withdrawal API is a big pain in the neck and something we should avoid if possible. Otherwise this will likely be delayed until something else needs to break the API and I'm not sure what that would be...

@clabby
Copy link
Member

clabby commented Sep 27, 2024

I would suggest the portal retains the same ABI but can forward to the authorised caller as needed (ie build in backwards compatibility). Breaking the withdrawal API is a big pain in the neck and something we should avoid if possible. Otherwise this will likely be delayed until something else needs to break the API and I'm not sure what that would be...

Yeah, we should be able to manage this for the critical path (proveWithdrawalTransaction + finalizeWithdrawalTransaction + events)

As for the administrative functions (setRespectedGameType + blacklistDisputeGame) & state vars (respectedGameType, disputeGameBlacklist, respectedGameTypeUpdatedAt), what do you think about these? These should not be consumed by anyone else, except for maybe viem. It would be very nice to move these to a different location (without a fall-through, so that people like succinct don't need to have dead code in their bridge.)


If I could wave a magic wand here, what I'd like to do (roughly) is:

  1. Create a new interface, IProofSystem. This would have:
    • A view function for fetching an output proposal by index.
    • A view function for checking a withdrawal's validity. Things like timestamps, etc. should be passed in. It would be on the portal to pass in honest values. It should not need to call-back to reference external state.
    • For other, lower-level concerns (i.e. the blacklist, respected type, etc.), these can be hidden underneath the interface's function impls.
  2. Remove DG-specific functions and state vars from the OptimismPortal2.
  3. Add in the IProofSubmitter to the portal, re-using the slot that the DisputeGameFactory is currently stored in.
  4. Add gaps to the respectedGameType, respectedGameTypeUpdatedAt, and disputeGameBlacklist slots.
  5. Retain the other ABI verbatim (proveWithdrawalTransaction + finalizeWithdrawalTransaction, events, etc.)

Usage Analysis

  • setRespectedGameType
    • 0 use in viem
    • 0 use in op-challenger
    • 1 usage in DeputyGuardianModule
  • blacklistDisputeGame
    • 0 use in viem
    • 0 use in op-challenger
    • 1 usage in DeputyGuardianModule
  • respectedGameType
    • 1 usage in viem here
    • 0 use in op-challenger
    • 0 use in DeputyGuardianModule
  • disputeGameBlacklist
    • 0 use in op-challenger
    • 0 use in DeputyGuardianModule
    • 0 use in viem
  • respectedGameTypeUpdatedAt
    • 0 use in op-challenger
    • 0 use in DeputyGuardianModule
    • 0 use in viem
  • checkWithdrawal
    • 0 use in op-challenger
    • 0 use in DeputyGuardianModule
    • 1 usage in viem here

With this, breaking the API would not be so painful, it doesn't look like. It would also remove periphery codepaths from our most important contract, which is always good. However on the front of breaking the core withdrawal path API, we should not do that imo.

Monitoring is another concern here though. What would definitely change my opinion here is if these changes complicated or added risk to our monitoring path, cc @ajsutton.

@ajsutton
Copy link
Contributor

Yeah agreed the key priority is maintaining compatibility with the withdrawal flow. Moving things like respectedGameType, disputeGameBlacklist and respectedGameTypeUpatedAt is likely to break some integrations like ENS but I feel like they're digging into a lot of implementation details in a way that isn't particularly ideal for them now anyway. They really just want a function that gives the latest finalized output root which some of the proposed AnchorStateRegistry changes may give if it only updates after the air gap and has a single anchor state for all game types.

I'd expect that respectedGameType is a key part of the withdrawal workflow and we need to preserve compatibility for it. You need to know what type of game to use when proving your withdrawal. We could deprecate it and keep something around for backwards compatibility for a while then delete later but I don't think should just break it. That one use in viem likely translates to a lot of users depending on it.

Same for checkWithdrawal, it seems important to expose a simple way for callers to ask if a withdrawal is ready to be finalized or not. Ideally we'd have a method that makes it easy to check if a given set of params (eg a game) is suitable to be used to prove a withdrawal - it could then check the blacklist as well which viem doesn't seem to be doing and may cause issues if we ever need to blacklist games.

The other question for me is what the point of entry should be for people trying to use the ABI. Do you need to make calls to both OptimismPortal and the IProofSubmitter implementation? If so, all withdrawal code needs to support all possible proof submitter implementations separately. Ideally I think a withdrawal could be completed using only OptimismPortal and be independent of the proof submitter implementation but I'm not sure how you'd find the appropriate game. Not the end of the world if we can't make it that general but having the the main usage be agnostic to the plugin implementation buys us a lot of flexibility. e.g. Succinct could use a different IProofSubmitter implementation and not need to have a custom integration with viem and any other withdrawal tools.

For the fall-through code, I'd say that people like succinct maintaining a fork of the OP Stack can easily remove it - they're already maintaining far more complex changes in the fork.

The functions with permissioned access are fine to just move as we know they're only used in limited fashion.

For monitoring, this shouldn't affect dispute-mon since it only monitors the dispute games. It will likely require updates to our other withdrawal monitoring though and I'm not familiar with how flexible that code is. I don't see anything in this that would hide information and cause monitoring problems - should just be a matter of updating the code to adjust where it gets the info from.

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

No branches or pull requests

3 participants