Crucible Hackathon: Opstack interop builder

:busts_in_silhouette: Team Information

:computer: Project Repository

:dart: Project Goal

  • Project Name: Optimism Interop Builder
  • Brief Description:
    • What is the primary goal of your project?
      • Ensure synchronous inclusion of transactions across more than two rollups
      • Design an RPC method and data structure to express user intent at the op-intent backend
      • Block building according to the interop spec
      • Wanted to make an atonic transaction possible across multiple OP rollups. Developed coordinator services across four different sequencers.
      • Coordinator sends a transactions to the preconfirmation RPC endpoint which returns the log index to be parsed and used for the executing message
        • Accepts a graph bundle for sequential execution across multiple rollups
    • What are the non-goals?
      • Atomic inclusion of interop messages.
      • Handling safety of interop messages. We assumes that the rollups fully trust each other.
      • Considering reorg scenario. We work with the happy path only
      • Account abstraction or EIP 3074 AUTH/AUTHCALL enabled contract to facilitate signing of messages in the DAG

:wrench: Challenges

  • Challenges Faced:
    • Biggest pain point was that you need a log index from the initiating message to put into the executing message
    • If the destination block has earlier timestamp than the source block, synchronous inclusion is impossible due to timestamp invariant
    • Adding chains to dependency set was not trivial because a transaction to addDepndency method in SystemConfig contract had to be proxied via a Safe contract.

:rocket: Current State

  • Project Status at the End of Hackathon:
    • What features are complete?
      • op-intent: multi chain intent coordinator service
        • eth_sendGraphBundle method to include multi chain bundle encoded in a DAG format.

        type Message struct {
        	ChainId *big.Int       `json:"chainId"`
        	Data    hexutil.Bytes  `json:"data"`
        	Target  common.Address `json:"target"`
        	Value   *big.Int       `json:"value"`
        type GraphBundle struct {
        	Root  Message       `json:"root"`
        	Nodes []GraphBundle `json:"nodes"`
  • op-geth with preconfirmation
    • eth_sendInteropBundle RPC method
      • inserts bundles two blocks ahead
      • can be replaced by a bundle with higher gas fees
      • returns the logs emitted by transaction.
  • What is still a work in progress?
    • Canceling the preconfirmed bundles
  • Are there any known bugs or issues?
    • The synchronous transaction is impossible when destination block’s timestamp is lower than source block’s timestamp. If op labs want to pursue this path seriously, they need to rethink their spec on the timestamp invariant

:package: How to Run

  • Prerequisites (e.g., software versions, dependencies)

  • Step-by-step installation and setup guide

    # network-params.yml
        - el_type: geth
        preset: minimal
      - name: "rollup_two"
        - el_type: op-geth
          el_image: jinmel/op-geth:preconf
        - blockscout
          preset: minimal
          network_id: "22"
          seconds_per_slot: 6
      - name: "rollup_one"
        - el_type: op-geth
          el_image: jinmel/op-geth:preconf
          preset: minimal
          network_id: "21"
          seconds_per_slot: 6
        - blockscout

:memo: Additional Notes

  • Future plans for the project
    • Atomic inclusion of transactions
    • Handling large DAG (graph with more than 20 nodes across 4 rollups) inclusion by op-intent
  • Acknowledgments
    • kurtosis team for providing us a easy way to launch multiple l2 devnets on our local machine

:question: Questions:

  • You are using the OP interop spec?
  • Is it atomic (i.e. all or nothing) or is it synchronous?
    • technically synchronous